mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-11-23 03:09:55 +00:00
Respect game brightness settings (#1559)
* `RendererVulkan` -> `Presenter` * support for Video Out gamma setting * sRGB hack removed * added post process pass to presenter * splash functionality restored
This commit is contained in:
parent
e98fab4b58
commit
3d04765a3f
@ -657,8 +657,6 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
|||||||
src/video_core/buffer_cache/word_manager.h
|
src/video_core/buffer_cache/word_manager.h
|
||||||
src/video_core/renderer_vulkan/liverpool_to_vk.cpp
|
src/video_core/renderer_vulkan/liverpool_to_vk.cpp
|
||||||
src/video_core/renderer_vulkan/liverpool_to_vk.h
|
src/video_core/renderer_vulkan/liverpool_to_vk.h
|
||||||
src/video_core/renderer_vulkan/renderer_vulkan.cpp
|
|
||||||
src/video_core/renderer_vulkan/renderer_vulkan.h
|
|
||||||
src/video_core/renderer_vulkan/vk_common.cpp
|
src/video_core/renderer_vulkan/vk_common.cpp
|
||||||
src/video_core/renderer_vulkan/vk_common.h
|
src/video_core/renderer_vulkan/vk_common.h
|
||||||
src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
|
src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
|
||||||
@ -677,6 +675,8 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
|||||||
src/video_core/renderer_vulkan/vk_pipeline_common.h
|
src/video_core/renderer_vulkan/vk_pipeline_common.h
|
||||||
src/video_core/renderer_vulkan/vk_platform.cpp
|
src/video_core/renderer_vulkan/vk_platform.cpp
|
||||||
src/video_core/renderer_vulkan/vk_platform.h
|
src/video_core/renderer_vulkan/vk_platform.h
|
||||||
|
src/video_core/renderer_vulkan/vk_presenter.cpp
|
||||||
|
src/video_core/renderer_vulkan/vk_presenter.h
|
||||||
src/video_core/renderer_vulkan/vk_rasterizer.cpp
|
src/video_core/renderer_vulkan/vk_rasterizer.cpp
|
||||||
src/video_core/renderer_vulkan/vk_rasterizer.h
|
src/video_core/renderer_vulkan/vk_rasterizer.h
|
||||||
src/video_core/renderer_vulkan/vk_resource_pool.cpp
|
src/video_core/renderer_vulkan/vk_resource_pool.cpp
|
||||||
|
@ -11,9 +11,12 @@
|
|||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "layer.h"
|
#include "layer.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
#include "widget/frame_dump.h"
|
#include "widget/frame_dump.h"
|
||||||
#include "widget/frame_graph.h"
|
#include "widget/frame_graph.h"
|
||||||
|
|
||||||
|
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
||||||
|
|
||||||
using namespace ImGui;
|
using namespace ImGui;
|
||||||
using namespace Core::Devtools;
|
using namespace Core::Devtools;
|
||||||
using L = Core::Devtools::Layer;
|
using L = Core::Devtools::Layer;
|
||||||
@ -71,6 +74,13 @@ void L::DrawMenuBar() {
|
|||||||
open_popup_help = MenuItem("Help & Tips");
|
open_popup_help = MenuItem("Help & Tips");
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
if (BeginMenu("Display")) {
|
||||||
|
if (BeginMenu("Brightness")) {
|
||||||
|
SliderFloat("Gamma", &presenter->GetGammaRef(), 0.1f, 2.0f);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
EndMainMenuBar();
|
EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
#include "core/platform.h"
|
#include "core/platform.h"
|
||||||
#include "video_core/amdgpu/liverpool.h"
|
#include "video_core/amdgpu/liverpool.h"
|
||||||
#include "video_core/amdgpu/pm4_cmds.h"
|
#include "video_core/amdgpu/pm4_cmds.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
|
|
||||||
extern Frontend::WindowSDL* g_window;
|
extern Frontend::WindowSDL* g_window;
|
||||||
std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
std::unique_ptr<Vulkan::Presenter> presenter;
|
||||||
std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
||||||
|
|
||||||
namespace Libraries::GnmDriver {
|
namespace Libraries::GnmDriver {
|
||||||
@ -2743,9 +2743,9 @@ int PS4_SYSV_ABI Func_F916890425496553() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
|
||||||
LOG_INFO(Lib_GnmDriver, "Initializing renderer");
|
LOG_INFO(Lib_GnmDriver, "Initializing presenter");
|
||||||
liverpool = std::make_unique<AmdGpu::Liverpool>();
|
liverpool = std::make_unique<AmdGpu::Liverpool>();
|
||||||
renderer = std::make_unique<Vulkan::RendererVulkan>(*g_window, liverpool.get());
|
presenter = std::make_unique<Vulkan::Presenter>(*g_window, liverpool.get());
|
||||||
|
|
||||||
const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
||||||
if (result != ORBIS_OK) {
|
if (result != ORBIS_OK) {
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
#include "core/libraries/kernel/time_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
#include "core/libraries/videoout/driver.h"
|
#include "core/libraries/videoout/driver.h"
|
||||||
#include "core/platform.h"
|
#include "core/platform.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
|
|
||||||
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
||||||
extern std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
extern std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
||||||
|
|
||||||
namespace Libraries::VideoOut {
|
namespace Libraries::VideoOut {
|
||||||
@ -136,7 +136,7 @@ int VideoOutDriver::RegisterBuffers(VideoOutPort* port, s32 startIndex, void* co
|
|||||||
.address_right = 0,
|
.address_right = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
renderer->RegisterVideoOutSurface(group, address);
|
presenter->RegisterVideoOutSurface(group, address);
|
||||||
LOG_INFO(Lib_VideoOut, "buffers[{}] = {:#x}", i + startIndex, address);
|
LOG_INFO(Lib_VideoOut, "buffers[{}] = {:#x}", i + startIndex, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +164,9 @@ int VideoOutDriver::UnregisterBuffers(VideoOutPort* port, s32 attributeIndex) {
|
|||||||
|
|
||||||
void VideoOutDriver::Flip(const Request& req) {
|
void VideoOutDriver::Flip(const Request& req) {
|
||||||
// Whatever the game is rendering show splash if it is active
|
// Whatever the game is rendering show splash if it is active
|
||||||
if (!renderer->ShowSplash(req.frame)) {
|
if (!presenter->ShowSplash(req.frame)) {
|
||||||
// Present the frame.
|
// Present the frame.
|
||||||
renderer->Present(req.frame);
|
presenter->Present(req.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update flip status.
|
// Update flip status.
|
||||||
@ -201,8 +201,11 @@ void VideoOutDriver::Flip(const Request& req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VideoOutDriver::DrawBlankFrame() {
|
void VideoOutDriver::DrawBlankFrame() {
|
||||||
const auto empty_frame = renderer->PrepareBlankFrame(false);
|
if (presenter->ShowSplash(nullptr)) {
|
||||||
renderer->Present(empty_frame);
|
return;
|
||||||
|
}
|
||||||
|
const auto empty_frame = presenter->PrepareBlankFrame(false);
|
||||||
|
presenter->Present(empty_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
||||||
@ -226,7 +229,7 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
|
|||||||
// point VO surface is ready to be presented, and we will need have an actual state of
|
// point VO surface is ready to be presented, and we will need have an actual state of
|
||||||
// Vulkan image at the time of frame presentation.
|
// Vulkan image at the time of frame presentation.
|
||||||
liverpool->SendCommand([=, this]() {
|
liverpool->SendCommand([=, this]() {
|
||||||
renderer->FlushDraw();
|
presenter->FlushDraw();
|
||||||
SubmitFlipInternal(port, index, flip_arg, is_eop);
|
SubmitFlipInternal(port, index, flip_arg, is_eop);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -240,11 +243,11 @@ void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_
|
|||||||
bool is_eop /*= false*/) {
|
bool is_eop /*= false*/) {
|
||||||
Vulkan::Frame* frame;
|
Vulkan::Frame* frame;
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
frame = renderer->PrepareBlankFrame(is_eop);
|
frame = presenter->PrepareBlankFrame(is_eop);
|
||||||
} else {
|
} else {
|
||||||
const auto& buffer = port->buffer_slots[index];
|
const auto& buffer = port->buffer_slots[index];
|
||||||
const auto& group = port->groups[buffer.group_index];
|
const auto& group = port->groups[buffer.group_index];
|
||||||
frame = renderer->PrepareFrame(group, buffer.address_left, is_eop);
|
frame = presenter->PrepareFrame(group, buffer.address_left, is_eop);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::scoped_lock lock{mutex};
|
std::scoped_lock lock{mutex};
|
||||||
|
@ -74,7 +74,7 @@ struct ServiceThreadParams {
|
|||||||
|
|
||||||
class VideoOutDriver {
|
class VideoOutDriver {
|
||||||
public:
|
public:
|
||||||
explicit VideoOutDriver(u32 width, u32 height);
|
VideoOutDriver(u32 width, u32 height);
|
||||||
~VideoOutDriver();
|
~VideoOutDriver();
|
||||||
|
|
||||||
int Open(const ServiceThreadParams* params);
|
int Open(const ServiceThreadParams* params);
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "core/libraries/videoout/video_out.h"
|
#include "core/libraries/videoout/video_out.h"
|
||||||
#include "core/loader/symbols_resolver.h"
|
#include "core/loader/symbols_resolver.h"
|
||||||
#include "core/platform.h"
|
#include "core/platform.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
|
|
||||||
|
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
||||||
|
|
||||||
namespace Libraries::VideoOut {
|
namespace Libraries::VideoOut {
|
||||||
|
|
||||||
@ -297,6 +300,28 @@ s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle) {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma) {
|
||||||
|
if (gamma < 0.1f || gamma > 2.0f) {
|
||||||
|
return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
settings->gamma = gamma;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings) {
|
||||||
|
if (settings == nullptr) {
|
||||||
|
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* port = driver->GetPort(handle);
|
||||||
|
if (!port) {
|
||||||
|
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
presenter->GetGammaRef() = settings->gamma;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
||||||
driver = std::make_unique<VideoOutDriver>(Config::getScreenWidth(), Config::getScreenHeight());
|
driver = std::make_unique<VideoOutDriver>(Config::getScreenWidth(), Config::getScreenHeight());
|
||||||
|
|
||||||
@ -329,6 +354,10 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventId);
|
LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventId);
|
||||||
LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||||
sceVideoOutGetEventData);
|
sceVideoOutGetEventData);
|
||||||
|
LIB_FUNCTION("DYhhWbJSeRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||||
|
sceVideoOutColorSettingsSetGamma);
|
||||||
|
LIB_FUNCTION("pv9CI5VC+R0", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||||
|
sceVideoOutAdjustColor);
|
||||||
|
|
||||||
// openOrbis appears to have libSceVideoOut_v1 module libSceVideoOut_v1.1
|
// openOrbis appears to have libSceVideoOut_v1 module libSceVideoOut_v1.1
|
||||||
LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutOpen);
|
LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutOpen);
|
||||||
|
@ -88,6 +88,11 @@ struct SceVideoOutDeviceCapabilityInfo {
|
|||||||
u64 capability;
|
u64 capability;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SceVideoOutColorSettings {
|
||||||
|
float gamma;
|
||||||
|
u32 reserved[3];
|
||||||
|
};
|
||||||
|
|
||||||
void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat,
|
void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat,
|
||||||
u32 tilingMode, u32 aspectRatio, u32 width,
|
u32 tilingMode, u32 aspectRatio, u32 width,
|
||||||
u32 height, u32 pitchInPixel);
|
u32 height, u32 pitchInPixel);
|
||||||
@ -106,6 +111,8 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 i
|
|||||||
s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle);
|
s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle);
|
||||||
int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
|
int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
|
||||||
int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data);
|
int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data);
|
||||||
|
s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma);
|
||||||
|
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings);
|
||||||
|
|
||||||
// Internal system functions
|
// Internal system functions
|
||||||
void sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr);
|
void sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "sdl_window.h"
|
#include "sdl_window.h"
|
||||||
#include "texture_manager.h"
|
#include "texture_manager.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
|
|
||||||
#include "imgui_fonts/notosansjp_regular.ttf.g.cpp"
|
#include "imgui_fonts/notosansjp_regular.ttf.g.cpp"
|
||||||
#include "imgui_fonts/proggyvector_regular.ttf.g.cpp"
|
#include "imgui_fonts/proggyvector_regular.ttf.g.cpp"
|
||||||
|
@ -7,6 +7,8 @@ set(SHADER_FILES
|
|||||||
detile_m32x1.comp
|
detile_m32x1.comp
|
||||||
detile_m32x2.comp
|
detile_m32x2.comp
|
||||||
detile_m32x4.comp
|
detile_m32x4.comp
|
||||||
|
fs_tri.vert
|
||||||
|
post_process.frag
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||||
|
15
src/video_core/host_shaders/fs_tri.vert
Normal file
15
src/video_core/host_shaders/fs_tri.vert
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 uv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 pos = vec2(
|
||||||
|
float((gl_VertexIndex & 1u) << 2u),
|
||||||
|
float((gl_VertexIndex & 2u) << 1u)
|
||||||
|
);
|
||||||
|
gl_Position = vec4(pos - vec2(1.0, 1.0), 0.0, 1.0);
|
||||||
|
uv = pos * 0.5;
|
||||||
|
}
|
19
src/video_core/host_shaders/post_process.frag
Normal file
19
src/video_core/host_shaders/post_process.frag
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 uv;
|
||||||
|
layout (location = 0) out vec4 color;
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D texSampler;
|
||||||
|
|
||||||
|
layout(push_constant) uniform settings {
|
||||||
|
float gamma;
|
||||||
|
} pp;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 color_linear = texture(texSampler, uv);
|
||||||
|
color = pow(color_linear, vec4(1.0/(2.2 + 1.0 - pp.gamma)));
|
||||||
|
}
|
@ -652,7 +652,7 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu
|
|||||||
}
|
}
|
||||||
|
|
||||||
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
||||||
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface) {
|
Liverpool::ColorBuffer::SwapMode comp_swap) {
|
||||||
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
|
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
|
||||||
const bool comp_swap_reverse = comp_swap == Liverpool::ColorBuffer::SwapMode::StandardReverse;
|
const bool comp_swap_reverse = comp_swap == Liverpool::ColorBuffer::SwapMode::StandardReverse;
|
||||||
const bool comp_swap_alt_reverse =
|
const bool comp_swap_alt_reverse =
|
||||||
@ -664,9 +664,9 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||||||
case vk::Format::eB8G8R8A8Unorm:
|
case vk::Format::eB8G8R8A8Unorm:
|
||||||
return vk::Format::eR8G8B8A8Unorm;
|
return vk::Format::eR8G8B8A8Unorm;
|
||||||
case vk::Format::eR8G8B8A8Srgb:
|
case vk::Format::eR8G8B8A8Srgb:
|
||||||
return is_vo_surface ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
return vk::Format::eB8G8R8A8Srgb;
|
||||||
case vk::Format::eB8G8R8A8Srgb:
|
case vk::Format::eB8G8R8A8Srgb:
|
||||||
return is_vo_surface ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
return vk::Format::eR8G8B8A8Srgb;
|
||||||
case vk::Format::eA2B10G10R10UnormPack32:
|
case vk::Format::eA2B10G10R10UnormPack32:
|
||||||
return vk::Format::eA2R10G10B10UnormPack32;
|
return vk::Format::eA2R10G10B10UnormPack32;
|
||||||
default:
|
default:
|
||||||
@ -677,20 +677,10 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||||||
case vk::Format::eR8G8B8A8Unorm:
|
case vk::Format::eR8G8B8A8Unorm:
|
||||||
return vk::Format::eA8B8G8R8UnormPack32;
|
return vk::Format::eA8B8G8R8UnormPack32;
|
||||||
case vk::Format::eR8G8B8A8Srgb:
|
case vk::Format::eR8G8B8A8Srgb:
|
||||||
return is_vo_surface ? vk::Format::eA8B8G8R8UnormPack32
|
return vk::Format::eA8B8G8R8SrgbPack32;
|
||||||
: vk::Format::eA8B8G8R8SrgbPack32;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (comp_swap_alt_reverse) {
|
|
||||||
return base_format;
|
|
||||||
} else {
|
|
||||||
if (is_vo_surface && base_format == vk::Format::eR8G8B8A8Srgb) {
|
|
||||||
return vk::Format::eR8G8B8A8Unorm;
|
|
||||||
}
|
|
||||||
if (is_vo_surface && base_format == vk::Format::eB8G8R8A8Srgb) {
|
|
||||||
return vk::Format::eB8G8R8A8Unorm;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return base_format;
|
return base_format;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ std::span<const SurfaceFormatInfo> SurfaceFormats();
|
|||||||
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format);
|
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format);
|
||||||
|
|
||||||
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
||||||
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface);
|
Liverpool::ColorBuffer::SwapMode comp_swap);
|
||||||
|
|
||||||
struct DepthFormatInfo {
|
struct DepthFormatInfo {
|
||||||
Liverpool::DepthBuffer::ZFormat z_format;
|
Liverpool::DepthBuffer::ZFormat z_format;
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
#include "shader_recompiler/info.h"
|
#include "shader_recompiler/info.h"
|
||||||
#include "shader_recompiler/recompiler.h"
|
#include "shader_recompiler/recompiler.h"
|
||||||
#include "shader_recompiler/runtime_info.h"
|
#include "shader_recompiler/runtime_info.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||||
|
|
||||||
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
@ -265,9 +265,8 @@ bool PipelineCache::RefreshGraphicsKey() {
|
|||||||
}
|
}
|
||||||
const auto base_format =
|
const auto base_format =
|
||||||
LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat());
|
LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat());
|
||||||
const bool is_vo_surface = renderer->IsVideoOutSurface(col_buf);
|
key.color_formats[remapped_cb] =
|
||||||
key.color_formats[remapped_cb] = LiverpoolToVK::AdjustColorBufferFormat(
|
LiverpoolToVK::AdjustColorBufferFormat(base_format, col_buf.info.comp_swap.Value());
|
||||||
base_format, col_buf.info.comp_swap.Value(), false /*is_vo_surface*/);
|
|
||||||
key.color_num_formats[remapped_cb] = col_buf.NumFormat();
|
key.color_num_formats[remapped_cb] = col_buf.NumFormat();
|
||||||
if (base_format == key.color_formats[remapped_cb]) {
|
if (base_format == key.color_formats[remapped_cb]) {
|
||||||
key.mrt_swizzles[remapped_cb] = col_buf.info.comp_swap.Value();
|
key.mrt_swizzles[remapped_cb] = col_buf.info.comp_swap.Value();
|
||||||
|
@ -4,18 +4,21 @@
|
|||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
|
#include "core/debug_state.h"
|
||||||
|
#include "core/devtools/layer.h"
|
||||||
#include "core/file_format/splash.h"
|
#include "core/file_format/splash.h"
|
||||||
#include "core/libraries/system/systemservice.h"
|
#include "core/libraries/system/systemservice.h"
|
||||||
#include "imgui/renderer/imgui_core.h"
|
#include "imgui/renderer/imgui_core.h"
|
||||||
#include "sdl_window.h"
|
#include "sdl_window.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||||
#include "video_core/texture_cache/image.h"
|
#include "video_core/texture_cache/image.h"
|
||||||
|
|
||||||
#include <vk_mem_alloc.h>
|
#include "video_core/host_shaders/fs_tri_vert.h"
|
||||||
|
#include "video_core/host_shaders/post_process_frag.h"
|
||||||
|
|
||||||
#include "core/debug_state.h"
|
#include <vk_mem_alloc.h>
|
||||||
#include "core/devtools/layer.h"
|
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
@ -92,7 +95,203 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice physical_device, vk::Format for
|
|||||||
return MakeImageBlit(frame_width, frame_height, dst_width, dst_height, offset_x, offset_y);
|
return MakeImageBlit(frame_width, frame_height, dst_width, dst_height, offset_x, offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_)
|
static vk::Format FormatToUnorm(vk::Format fmt) {
|
||||||
|
switch (fmt) {
|
||||||
|
case vk::Format::eR8G8B8A8Srgb:
|
||||||
|
return vk::Format::eR8G8B8A8Unorm;
|
||||||
|
case vk::Format::eB8G8R8A8Srgb:
|
||||||
|
return vk::Format::eB8G8R8A8Unorm;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Presenter::CreatePostProcessPipeline() {
|
||||||
|
static const std::array pp_shaders{
|
||||||
|
HostShaders::FS_TRI_VERT,
|
||||||
|
HostShaders::POST_PROCESS_FRAG,
|
||||||
|
};
|
||||||
|
|
||||||
|
boost::container::static_vector<vk::DescriptorSetLayoutBinding, 2> bindings{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = {
|
||||||
|
.flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR,
|
||||||
|
.bindingCount = static_cast<u32>(bindings.size()),
|
||||||
|
.pBindings = bindings.data(),
|
||||||
|
};
|
||||||
|
auto desc_layout_result = instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
|
||||||
|
ASSERT_MSG(desc_layout_result.result == vk::Result::eSuccess,
|
||||||
|
"Failed to create descriptor set layout: {}",
|
||||||
|
vk::to_string(desc_layout_result.result));
|
||||||
|
pp_desc_set_layout = std::move(desc_layout_result.value);
|
||||||
|
|
||||||
|
const vk::PushConstantRange push_constants = {
|
||||||
|
.stageFlags = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.offset = 0,
|
||||||
|
.size = sizeof(PostProcessSettings),
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto& vs_module =
|
||||||
|
Vulkan::Compile(pp_shaders[0], vk::ShaderStageFlagBits::eVertex, instance.GetDevice());
|
||||||
|
ASSERT(vs_module);
|
||||||
|
Vulkan::SetObjectName(instance.GetDevice(), vs_module, "fs_tri.vert");
|
||||||
|
|
||||||
|
const auto& fs_module =
|
||||||
|
Vulkan::Compile(pp_shaders[1], vk::ShaderStageFlagBits::eFragment, instance.GetDevice());
|
||||||
|
ASSERT(fs_module);
|
||||||
|
Vulkan::SetObjectName(instance.GetDevice(), vs_module, "post_process.frag");
|
||||||
|
|
||||||
|
const std::array shaders_ci{
|
||||||
|
vk::PipelineShaderStageCreateInfo{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eVertex,
|
||||||
|
.module = vs_module,
|
||||||
|
.pName = "main",
|
||||||
|
},
|
||||||
|
vk::PipelineShaderStageCreateInfo{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.module = fs_module,
|
||||||
|
.pName = "main",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::DescriptorSetLayout set_layout = *pp_desc_set_layout;
|
||||||
|
const vk::PipelineLayoutCreateInfo layout_info = {
|
||||||
|
.setLayoutCount = 1U,
|
||||||
|
.pSetLayouts = &set_layout,
|
||||||
|
.pushConstantRangeCount = 1,
|
||||||
|
.pPushConstantRanges = &push_constants,
|
||||||
|
};
|
||||||
|
auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info);
|
||||||
|
ASSERT_MSG(layout_result == vk::Result::eSuccess, "Failed to create pipeline layout: {}",
|
||||||
|
vk::to_string(layout_result));
|
||||||
|
pp_pipeline_layout = std::move(layout);
|
||||||
|
|
||||||
|
const std::array pp_color_formats{
|
||||||
|
vk::Format::eB8G8R8A8Unorm, // swapchain.GetSurfaceFormat().format,
|
||||||
|
};
|
||||||
|
const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci = {
|
||||||
|
.colorAttachmentCount = 1u,
|
||||||
|
.pColorAttachmentFormats = pp_color_formats.data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineVertexInputStateCreateInfo vertex_input_info = {
|
||||||
|
.vertexBindingDescriptionCount = 0u,
|
||||||
|
.vertexAttributeDescriptionCount = 0u,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||||
|
.topology = vk::PrimitiveTopology::eTriangleList,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::Viewport viewport = {
|
||||||
|
.x = 0.0f,
|
||||||
|
.y = 0.0f,
|
||||||
|
.width = 1.0f,
|
||||||
|
.height = 1.0f,
|
||||||
|
.minDepth = 0.0f,
|
||||||
|
.maxDepth = 1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::Rect2D scissor = {
|
||||||
|
.offset = {0, 0},
|
||||||
|
.extent = {1, 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineViewportStateCreateInfo viewport_info = {
|
||||||
|
.viewportCount = 1,
|
||||||
|
.pViewports = &viewport,
|
||||||
|
.scissorCount = 1,
|
||||||
|
.pScissors = &scissor,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineRasterizationStateCreateInfo raster_state = {
|
||||||
|
.depthClampEnable = false,
|
||||||
|
.rasterizerDiscardEnable = false,
|
||||||
|
.polygonMode = vk::PolygonMode::eFill,
|
||||||
|
.cullMode = vk::CullModeFlagBits::eBack,
|
||||||
|
.frontFace = vk::FrontFace::eClockwise,
|
||||||
|
.depthBiasEnable = false,
|
||||||
|
.lineWidth = 1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineMultisampleStateCreateInfo multisampling = {
|
||||||
|
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array attachments{
|
||||||
|
vk::PipelineColorBlendAttachmentState{
|
||||||
|
.blendEnable = false,
|
||||||
|
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
||||||
|
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineColorBlendStateCreateInfo color_blending = {
|
||||||
|
.logicOpEnable = false,
|
||||||
|
.logicOp = vk::LogicOp::eCopy,
|
||||||
|
.attachmentCount = attachments.size(),
|
||||||
|
.pAttachments = attachments.data(),
|
||||||
|
.blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array dynamic_states = {
|
||||||
|
vk::DynamicState::eViewport,
|
||||||
|
vk::DynamicState::eScissor,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
||||||
|
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
||||||
|
.pDynamicStates = dynamic_states.data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk::GraphicsPipelineCreateInfo pipeline_info = {
|
||||||
|
.pNext = &pipeline_rendering_ci,
|
||||||
|
.stageCount = static_cast<u32>(shaders_ci.size()),
|
||||||
|
.pStages = shaders_ci.data(),
|
||||||
|
.pVertexInputState = &vertex_input_info,
|
||||||
|
.pInputAssemblyState = &input_assembly,
|
||||||
|
.pViewportState = &viewport_info,
|
||||||
|
.pRasterizationState = &raster_state,
|
||||||
|
.pMultisampleState = &multisampling,
|
||||||
|
.pColorBlendState = &color_blending,
|
||||||
|
.pDynamicState = &dynamic_info,
|
||||||
|
.layout = *pp_pipeline_layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto result = instance.GetDevice().createGraphicsPipelineUnique(
|
||||||
|
/*pipeline_cache*/ {}, pipeline_info);
|
||||||
|
if (result.result == vk::Result::eSuccess) {
|
||||||
|
pp_pipeline = std::move(result.value);
|
||||||
|
} else {
|
||||||
|
UNREACHABLE_MSG("Post process pipeline creation failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once pipeline is compiled, we don't need the shader module anymore
|
||||||
|
instance.GetDevice().destroyShaderModule(vs_module);
|
||||||
|
instance.GetDevice().destroyShaderModule(fs_module);
|
||||||
|
|
||||||
|
// Create sampler resource
|
||||||
|
const vk::SamplerCreateInfo sampler_ci = {
|
||||||
|
.magFilter = vk::Filter::eLinear,
|
||||||
|
.minFilter = vk::Filter::eLinear,
|
||||||
|
.mipmapMode = vk::SamplerMipmapMode::eNearest,
|
||||||
|
.addressModeU = vk::SamplerAddressMode::eClampToEdge,
|
||||||
|
.addressModeV = vk::SamplerAddressMode::eClampToEdge,
|
||||||
|
};
|
||||||
|
auto [sampler_result, smplr] = instance.GetDevice().createSamplerUnique(sampler_ci);
|
||||||
|
ASSERT_MSG(sampler_result == vk::Result::eSuccess, "Failed to create sampler: {}",
|
||||||
|
vk::to_string(sampler_result));
|
||||||
|
pp_sampler = std::move(smplr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Presenter::Presenter(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_)
|
||||||
: window{window_}, liverpool{liverpool_},
|
: window{window_}, liverpool{liverpool_},
|
||||||
instance{window, Config::getGpuId(), Config::vkValidationEnabled(),
|
instance{window, Config::getGpuId(), Config::vkValidationEnabled(),
|
||||||
Config::vkCrashDiagnosticEnabled()},
|
Config::vkCrashDiagnosticEnabled()},
|
||||||
@ -115,12 +314,15 @@ RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool*
|
|||||||
free_queue.push(&frame);
|
free_queue.push(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreatePostProcessPipeline();
|
||||||
|
|
||||||
// Setup ImGui
|
// Setup ImGui
|
||||||
ImGui::Core::Initialize(instance, window, num_images, swapchain.GetSurfaceFormat().format);
|
ImGui::Core::Initialize(instance, window, num_images,
|
||||||
|
FormatToUnorm(swapchain.GetSurfaceFormat().format));
|
||||||
ImGui::Layer::AddLayer(Common::Singleton<Core::Devtools::Layer>::Instance());
|
ImGui::Layer::AddLayer(Common::Singleton<Core::Devtools::Layer>::Instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererVulkan::~RendererVulkan() {
|
Presenter::~Presenter() {
|
||||||
ImGui::Layer::RemoveLayer(Common::Singleton<Core::Devtools::Layer>::Instance());
|
ImGui::Layer::RemoveLayer(Common::Singleton<Core::Devtools::Layer>::Instance());
|
||||||
draw_scheduler.Finish();
|
draw_scheduler.Finish();
|
||||||
const vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
@ -132,7 +334,7 @@ RendererVulkan::~RendererVulkan() {
|
|||||||
ImGui::Core::Shutdown(device);
|
ImGui::Core::Shutdown(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
|
void Presenter::RecreateFrame(Frame* frame, u32 width, u32 height) {
|
||||||
const vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
if (frame->image_view) {
|
if (frame->image_view) {
|
||||||
device.destroyImageView(frame->image_view);
|
device.destroyImageView(frame->image_view);
|
||||||
@ -143,6 +345,7 @@ void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
|
|||||||
|
|
||||||
const vk::Format format = swapchain.GetSurfaceFormat().format;
|
const vk::Format format = swapchain.GetSurfaceFormat().format;
|
||||||
const vk::ImageCreateInfo image_info = {
|
const vk::ImageCreateInfo image_info = {
|
||||||
|
.flags = vk::ImageCreateFlagBits::eMutableFormat,
|
||||||
.imageType = vk::ImageType::e2D,
|
.imageType = vk::ImageType::e2D,
|
||||||
.format = format,
|
.format = format,
|
||||||
.extent = {width, height, 1},
|
.extent = {width, height, 1},
|
||||||
@ -177,7 +380,7 @@ void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
|
|||||||
const vk::ImageViewCreateInfo view_info = {
|
const vk::ImageViewCreateInfo view_info = {
|
||||||
.image = frame->image,
|
.image = frame->image,
|
||||||
.viewType = vk::ImageViewType::e2D,
|
.viewType = vk::ImageViewType::e2D,
|
||||||
.format = format,
|
.format = FormatToUnorm(format),
|
||||||
.subresourceRange{
|
.subresourceRange{
|
||||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
@ -194,7 +397,7 @@ void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
|
|||||||
frame->height = height;
|
frame->height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererVulkan::ShowSplash(Frame* frame /*= nullptr*/) {
|
bool Presenter::ShowSplash(Frame* frame /*= nullptr*/) {
|
||||||
const auto* splash = Common::Singleton<Splash>::Instance();
|
const auto* splash = Common::Singleton<Splash>::Instance();
|
||||||
if (splash->GetImageData().empty()) {
|
if (splash->GetImageData().empty()) {
|
||||||
return false;
|
return false;
|
||||||
@ -204,6 +407,9 @@ bool RendererVulkan::ShowSplash(Frame* frame /*= nullptr*/) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_scheduler.EndRendering();
|
||||||
|
const auto cmdbuf = draw_scheduler.CommandBuffer();
|
||||||
|
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
if (!splash_img.has_value()) {
|
if (!splash_img.has_value()) {
|
||||||
VideoCore::ImageInfo info{};
|
VideoCore::ImageInfo info{};
|
||||||
@ -214,16 +420,74 @@ bool RendererVulkan::ShowSplash(Frame* frame /*= nullptr*/) {
|
|||||||
info.pitch = splash->GetImageInfo().width;
|
info.pitch = splash->GetImageInfo().width;
|
||||||
info.guest_address = VAddr(splash->GetImageData().data());
|
info.guest_address = VAddr(splash->GetImageData().data());
|
||||||
info.guest_size_bytes = splash->GetImageData().size();
|
info.guest_size_bytes = splash->GetImageData().size();
|
||||||
|
info.mips_layout.emplace_back(splash->GetImageData().size(),
|
||||||
|
splash->GetImageInfo().width,
|
||||||
|
splash->GetImageInfo().height, 0);
|
||||||
splash_img.emplace(instance, present_scheduler, info);
|
splash_img.emplace(instance, present_scheduler, info);
|
||||||
texture_cache.RefreshImage(*splash_img);
|
texture_cache.RefreshImage(*splash_img);
|
||||||
|
|
||||||
|
splash_img->Transit(vk::ImageLayout::eTransferSrcOptimal,
|
||||||
|
vk::AccessFlagBits2::eTransferRead, {}, cmdbuf);
|
||||||
}
|
}
|
||||||
frame = PrepareFrameInternal(*splash_img);
|
|
||||||
|
frame = GetRenderFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto frame_subresources = vk::ImageSubresourceRange{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto pre_barrier =
|
||||||
|
vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
||||||
|
.srcAccessMask = vk::AccessFlagBits2::eTransferRead,
|
||||||
|
.dstStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eUndefined,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.image = frame->image,
|
||||||
|
.subresourceRange{frame_subresources}};
|
||||||
|
|
||||||
|
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &pre_barrier,
|
||||||
|
});
|
||||||
|
|
||||||
|
cmdbuf.blitImage(splash_img->image, vk::ImageLayout::eTransferSrcOptimal, frame->image,
|
||||||
|
vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
MakeImageBlitFit(splash->GetImageInfo().width, splash->GetImageInfo().height,
|
||||||
|
frame->width, frame->height),
|
||||||
|
vk::Filter::eLinear);
|
||||||
|
|
||||||
|
const auto post_barrier =
|
||||||
|
vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
||||||
|
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||||
|
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.image = frame->image,
|
||||||
|
.subresourceRange{frame_subresources}};
|
||||||
|
|
||||||
|
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &post_barrier,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Flush frame creation commands.
|
||||||
|
frame->ready_semaphore = draw_scheduler.GetMasterSemaphore()->Handle();
|
||||||
|
frame->ready_tick = draw_scheduler.CurrentTick();
|
||||||
|
SubmitInfo info{};
|
||||||
|
draw_scheduler.Flush(info);
|
||||||
|
|
||||||
Present(frame);
|
Present(frame);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop) {
|
Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) {
|
||||||
// Request a free presentation frame.
|
// Request a free presentation frame.
|
||||||
Frame* frame = GetRenderFrame();
|
Frame* frame = GetRenderFrame();
|
||||||
|
|
||||||
@ -234,9 +498,6 @@ Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop
|
|||||||
scheduler.EndRendering();
|
scheduler.EndRendering();
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead, {},
|
|
||||||
cmdbuf);
|
|
||||||
|
|
||||||
const auto frame_subresources = vk::ImageSubresourceRange{
|
const auto frame_subresources = vk::ImageSubresourceRange{
|
||||||
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
@ -244,62 +505,114 @@ Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop
|
|||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
};
|
};
|
||||||
const std::array pre_barrier{
|
|
||||||
vk::ImageMemoryBarrier{
|
|
||||||
.srcAccessMask = vk::AccessFlagBits::eTransferRead,
|
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferWrite,
|
|
||||||
.oldLayout = vk::ImageLayout::eUndefined,
|
|
||||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = frame->image,
|
|
||||||
.subresourceRange{frame_subresources},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
|
|
||||||
vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlagBits::eByRegion,
|
|
||||||
{}, {}, pre_barrier);
|
|
||||||
|
|
||||||
// Clear the frame image before blitting to avoid artifacts.
|
const auto pre_barrier =
|
||||||
const vk::ClearColorValue clear_color{std::array{0.0f, 0.0f, 0.0f, 1.0f}};
|
|
||||||
cmdbuf.clearColorImage(frame->image, vk::ImageLayout::eTransferDstOptimal, clear_color,
|
|
||||||
frame_subresources);
|
|
||||||
|
|
||||||
const auto blitBarrier =
|
|
||||||
vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
||||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
.srcAccessMask = vk::AccessFlagBits2::eTransferRead,
|
||||||
.dstStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||||
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
.oldLayout = vk::ImageLayout::eUndefined,
|
||||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
.newLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
.image = frame->image,
|
.image = frame->image,
|
||||||
.subresourceRange{frame_subresources}};
|
.subresourceRange{frame_subresources}};
|
||||||
|
|
||||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||||
.imageMemoryBarrierCount = 1,
|
.imageMemoryBarrierCount = 1,
|
||||||
.pImageMemoryBarriers = &blitBarrier,
|
.pImageMemoryBarriers = &pre_barrier,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Post-processing (Anti-aliasing, FSR etc) goes here. For now just blit to the frame image.
|
if (image_id != VideoCore::NULL_IMAGE_ID) {
|
||||||
cmdbuf.blitImage(image.image, image.last_state.layout, frame->image,
|
auto& image = texture_cache.GetImage(image_id);
|
||||||
vk::ImageLayout::eTransferDstOptimal,
|
image.Transit(vk::ImageLayout::eShaderReadOnlyOptimal, vk::AccessFlagBits2::eShaderRead, {},
|
||||||
MakeImageBlitFit(image.info.size.width, image.info.size.height, frame->width,
|
cmdbuf);
|
||||||
frame->height),
|
|
||||||
vk::Filter::eLinear);
|
|
||||||
|
|
||||||
const vk::ImageMemoryBarrier post_barrier{
|
static vk::DescriptorImageInfo image_info{
|
||||||
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
.sampler = *pp_sampler,
|
||||||
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
|
.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
};
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
VideoCore::ImageViewInfo info{};
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
info.format = image.info.pixel_format;
|
||||||
.image = frame->image,
|
if (auto view = image.FindView(info)) {
|
||||||
.subresourceRange{frame_subresources},
|
image_info.imageView = *texture_cache.GetImageView(view).image_view;
|
||||||
};
|
} else {
|
||||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
image_info.imageView = *texture_cache.RegisterImageView(image_id, info).image_view;
|
||||||
vk::PipelineStageFlagBits::eAllCommands,
|
}
|
||||||
vk::DependencyFlagBits::eByRegion, {}, {}, post_barrier);
|
|
||||||
|
static const std::array set_writes{
|
||||||
|
vk::WriteDescriptorSet{
|
||||||
|
.dstSet = VK_NULL_HANDLE,
|
||||||
|
.dstBinding = 0,
|
||||||
|
.dstArrayElement = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.pImageInfo = &image_info,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, *pp_pipeline);
|
||||||
|
|
||||||
|
const std::array viewports = {
|
||||||
|
vk::Viewport{
|
||||||
|
.x = 0.0f,
|
||||||
|
.y = 0.0f,
|
||||||
|
.width = 1.0f * frame->width,
|
||||||
|
.height = 1.0f * frame->height,
|
||||||
|
.minDepth = 0.0f,
|
||||||
|
.maxDepth = 1.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array scissors = {
|
||||||
|
vk::Rect2D{
|
||||||
|
.offset = {0, 0},
|
||||||
|
.extent = {frame->width, frame->height},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cmdbuf.setViewport(0, viewports);
|
||||||
|
cmdbuf.setScissor(0, scissors);
|
||||||
|
|
||||||
|
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pp_pipeline_layout, 0,
|
||||||
|
set_writes);
|
||||||
|
cmdbuf.pushConstants(*pp_pipeline_layout, vk::ShaderStageFlagBits::eFragment, 0,
|
||||||
|
sizeof(PostProcessSettings), &pp_settings);
|
||||||
|
|
||||||
|
const std::array attachments = {vk::RenderingAttachmentInfo{
|
||||||
|
.imageView = frame->image_view,
|
||||||
|
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eDontCare,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
}};
|
||||||
|
|
||||||
|
vk::RenderingInfo rendering_info{
|
||||||
|
.renderArea =
|
||||||
|
vk::Rect2D{
|
||||||
|
.offset = {0, 0},
|
||||||
|
.extent = {frame->width, frame->height},
|
||||||
|
},
|
||||||
|
.layerCount = 1,
|
||||||
|
.colorAttachmentCount = attachments.size(),
|
||||||
|
.pColorAttachments = attachments.data(),
|
||||||
|
};
|
||||||
|
cmdbuf.beginRendering(rendering_info);
|
||||||
|
cmdbuf.draw(3, 1, 0, 0);
|
||||||
|
cmdbuf.endRendering();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto post_barrier =
|
||||||
|
vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||||
|
.srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||||
|
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.image = frame->image,
|
||||||
|
.subresourceRange{frame_subresources}};
|
||||||
|
|
||||||
|
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||||
|
.imageMemoryBarrierCount = 1,
|
||||||
|
.pImageMemoryBarriers = &post_barrier,
|
||||||
|
});
|
||||||
|
|
||||||
// Flush frame creation commands.
|
// Flush frame creation commands.
|
||||||
frame->ready_semaphore = scheduler.GetMasterSemaphore()->Handle();
|
frame->ready_semaphore = scheduler.GetMasterSemaphore()->Handle();
|
||||||
@ -309,7 +622,7 @@ Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererVulkan::Present(Frame* frame) {
|
void Presenter::Present(Frame* frame) {
|
||||||
// Recreate the swapchain if the window was resized.
|
// Recreate the swapchain if the window was resized.
|
||||||
if (window.getWidth() != swapchain.GetExtent().width ||
|
if (window.getWidth() != swapchain.GetExtent().width ||
|
||||||
window.getHeight() != swapchain.GetExtent().height) {
|
window.getHeight() != swapchain.GetExtent().height) {
|
||||||
@ -423,7 +736,7 @@ void RendererVulkan::Present(Frame* frame) {
|
|||||||
DebugState.IncFlipFrameNum();
|
DebugState.IncFlipFrameNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame* RendererVulkan::GetRenderFrame() {
|
Frame* Presenter::GetRenderFrame() {
|
||||||
// Wait for free presentation frames
|
// Wait for free presentation frames
|
||||||
Frame* frame;
|
Frame* frame;
|
||||||
{
|
{
|
@ -40,23 +40,29 @@ enum SchedulerType {
|
|||||||
|
|
||||||
class Rasterizer;
|
class Rasterizer;
|
||||||
|
|
||||||
class RendererVulkan {
|
class Presenter {
|
||||||
|
struct PostProcessSettings {
|
||||||
|
float gamma = 1.0f;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RendererVulkan(Frontend::WindowSDL& window, AmdGpu::Liverpool* liverpool);
|
Presenter(Frontend::WindowSDL& window, AmdGpu::Liverpool* liverpool);
|
||||||
~RendererVulkan();
|
~Presenter();
|
||||||
|
|
||||||
|
float& GetGammaRef() {
|
||||||
|
return pp_settings.gamma;
|
||||||
|
}
|
||||||
|
|
||||||
Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute,
|
Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute,
|
||||||
VAddr cpu_address, bool is_eop) {
|
VAddr cpu_address, bool is_eop) {
|
||||||
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
|
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
|
||||||
const auto image_id = texture_cache.FindImage(info);
|
const auto image_id = texture_cache.FindImage(info);
|
||||||
texture_cache.UpdateImage(image_id, is_eop ? nullptr : &flip_scheduler);
|
texture_cache.UpdateImage(image_id, is_eop ? nullptr : &flip_scheduler);
|
||||||
auto& image = texture_cache.GetImage(image_id);
|
return PrepareFrameInternal(image_id, is_eop);
|
||||||
return PrepareFrameInternal(image, is_eop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame* PrepareBlankFrame(bool is_eop) {
|
Frame* PrepareBlankFrame(bool is_eop) {
|
||||||
auto& image = texture_cache.GetImage(VideoCore::NULL_IMAGE_ID);
|
return PrepareFrameInternal(VideoCore::NULL_IMAGE_ID, is_eop);
|
||||||
return PrepareFrameInternal(image, is_eop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCore::Image& RegisterVideoOutSurface(
|
VideoCore::Image& RegisterVideoOutSurface(
|
||||||
@ -83,10 +89,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Frame* PrepareFrameInternal(VideoCore::Image& image, bool is_eop = true);
|
void CreatePostProcessPipeline();
|
||||||
|
Frame* PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop = true);
|
||||||
Frame* GetRenderFrame();
|
Frame* GetRenderFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PostProcessSettings pp_settings{};
|
||||||
|
vk::UniquePipeline pp_pipeline{};
|
||||||
|
vk::UniquePipelineLayout pp_pipeline_layout{};
|
||||||
|
vk::UniqueDescriptorSetLayout pp_desc_set_layout{};
|
||||||
|
vk::UniqueSampler pp_sampler{};
|
||||||
Frontend::WindowSDL& window;
|
Frontend::WindowSDL& window;
|
||||||
AmdGpu::Liverpool* liverpool;
|
AmdGpu::Liverpool* liverpool;
|
||||||
Instance instance;
|
Instance instance;
|
@ -271,7 +271,7 @@ void Rasterizer::BeginRendering(const GraphicsPipeline& pipeline) {
|
|||||||
|
|
||||||
const auto& hint = liverpool->last_cb_extent[col_buf_id];
|
const auto& hint = liverpool->last_cb_extent[col_buf_id];
|
||||||
VideoCore::ImageInfo image_info{col_buf, hint};
|
VideoCore::ImageInfo image_info{col_buf, hint};
|
||||||
VideoCore::ImageViewInfo view_info{col_buf, false /*!!image.info.usage.vo_buffer*/};
|
VideoCore::ImageViewInfo view_info{col_buf};
|
||||||
const auto& image_view = texture_cache.FindRenderTarget(image_info, view_info);
|
const auto& image_view = texture_cache.FindRenderTarget(image_info, view_info);
|
||||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||||
state.width = std::min<u32>(state.width, image.info.size.width);
|
state.width = std::min<u32>(state.width, image.info.size.width);
|
||||||
|
@ -125,15 +125,14 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer,
|
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept {
|
||||||
bool is_vo_surface) noexcept {
|
|
||||||
const auto base_format =
|
const auto base_format =
|
||||||
Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat());
|
Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat());
|
||||||
range.base.layer = col_buffer.view.slice_start;
|
range.base.layer = col_buffer.view.slice_start;
|
||||||
range.extent.layers = col_buffer.NumSlices() - range.base.layer;
|
range.extent.layers = col_buffer.NumSlices() - range.base.layer;
|
||||||
type = range.extent.layers > 1 ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D;
|
type = range.extent.layers > 1 ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D;
|
||||||
format = Vulkan::LiverpoolToVK::AdjustColorBufferFormat(
|
format = Vulkan::LiverpoolToVK::AdjustColorBufferFormat(base_format,
|
||||||
base_format, col_buffer.info.comp_swap.Value(), is_vo_surface);
|
col_buffer.info.comp_swap.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
||||||
|
@ -19,7 +19,7 @@ namespace VideoCore {
|
|||||||
struct ImageViewInfo {
|
struct ImageViewInfo {
|
||||||
ImageViewInfo() = default;
|
ImageViewInfo() = default;
|
||||||
ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept;
|
ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept;
|
||||||
ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer, bool is_vo_surface) noexcept;
|
ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept;
|
||||||
ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
ImageViewInfo(const AmdGpu::Liverpool::DepthBuffer& depth_buffer,
|
||||||
AmdGpu::Liverpool::DepthView view, AmdGpu::Liverpool::DepthControl ctl);
|
AmdGpu::Liverpool::DepthView view, AmdGpu::Liverpool::DepthControl ctl);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
|
|||||||
info.num_bits = 32;
|
info.num_bits = 32;
|
||||||
info.UpdateSize();
|
info.UpdateSize();
|
||||||
const ImageId null_id = slot_images.insert(instance, scheduler, info);
|
const ImageId null_id = slot_images.insert(instance, scheduler, info);
|
||||||
ASSERT(null_id.index == 0);
|
ASSERT(null_id.index == NULL_IMAGE_ID.index);
|
||||||
const vk::Image& null_image = slot_images[null_id].image;
|
const vk::Image& null_image = slot_images[null_id].image;
|
||||||
Vulkan::SetObjectName(instance.GetDevice(), null_image, "Null Image");
|
Vulkan::SetObjectName(instance.GetDevice(), null_image, "Null Image");
|
||||||
slot_images[null_id].flags = ImageFlagBits::Tracked;
|
slot_images[null_id].flags = ImageFlagBits::Tracked;
|
||||||
@ -36,7 +36,7 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
|
|||||||
ImageViewInfo view_info;
|
ImageViewInfo view_info;
|
||||||
const auto null_view_id =
|
const auto null_view_id =
|
||||||
slot_image_views.insert(instance, view_info, slot_images[null_id], null_id);
|
slot_image_views.insert(instance, view_info, slot_images[null_id], null_id);
|
||||||
ASSERT(null_view_id.index == 0);
|
ASSERT(null_view_id.index == NULL_IMAGE_VIEW_ID.index);
|
||||||
const vk::ImageView& null_image_view = slot_image_views[null_view_id].image_view.get();
|
const vk::ImageView& null_image_view = slot_image_views[null_view_id].image_view.get();
|
||||||
Vulkan::SetObjectName(instance.GetDevice(), null_image_view, "Null Image View");
|
Vulkan::SetObjectName(instance.GetDevice(), null_image_view, "Null Image View");
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,9 @@ public:
|
|||||||
return slot_image_views[id];
|
return slot_image_views[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers an image view for provided image
|
||||||
|
ImageView& RegisterImageView(ImageId image_id, const ImageViewInfo& view_info);
|
||||||
|
|
||||||
bool IsMeta(VAddr address) const {
|
bool IsMeta(VAddr address) const {
|
||||||
return surface_metas.contains(address);
|
return surface_metas.contains(address);
|
||||||
}
|
}
|
||||||
@ -181,9 +184,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers an image view for provided image
|
|
||||||
ImageView& RegisterImageView(ImageId image_id, const ImageViewInfo& view_info);
|
|
||||||
|
|
||||||
/// Create an image from the given parameters
|
/// Create an image from the given parameters
|
||||||
[[nodiscard]] ImageId InsertImage(const ImageInfo& info, VAddr cpu_addr);
|
[[nodiscard]] ImageId InsertImage(const ImageInfo& info, VAddr cpu_addr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user