GPUDevice: Expose swap chain clear colour

This commit is contained in:
Stenzek 2024-08-06 17:33:05 +10:00
parent aeb9d383ce
commit 4f16cb61b4
No known key found for this signature in database
12 changed files with 45 additions and 44 deletions

View File

@ -1992,7 +1992,7 @@ bool GPU::RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool pos
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
if (really_postfx)
{
g_gpu_device->ClearRenderTarget(PostProcessing::DisplayChain.GetInputTexture(), 0);
g_gpu_device->ClearRenderTarget(PostProcessing::DisplayChain.GetInputTexture(), GPUDevice::DEFAULT_CLEAR_COLOR);
g_gpu_device->SetRenderTarget(PostProcessing::DisplayChain.GetInputTexture());
}
else
@ -2633,7 +2633,7 @@ bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_
if (!render_texture)
return false;
g_gpu_device->ClearRenderTarget(render_texture.get(), 0);
g_gpu_device->ClearRenderTarget(render_texture.get(), GPUDevice::DEFAULT_CLEAR_COLOR);
// TODO: this should use copy shader instead.
RenderDisplay(render_texture.get(), draw_rect, postfx);

View File

@ -640,7 +640,7 @@ void D3D11Device::SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle)
}
}
bool D3D11Device::BeginPresent(bool skip_present)
bool D3D11Device::BeginPresent(bool skip_present, u32 clear_color)
{
if (skip_present)
return false;
@ -671,8 +671,7 @@ bool D3D11Device::BeginPresent(bool skip_present)
if (m_vsync_mode == GPUVSyncMode::FIFO && m_gpu_timing_enabled)
PopTimestampQuery();
static constexpr float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
m_context->ClearRenderTargetView(m_swap_chain_rtv.Get(), clear_color);
m_context->ClearRenderTargetView(m_swap_chain_rtv.Get(), GSVector4::rgba32(clear_color).F32);
m_context->OMSetRenderTargets(1, m_swap_chain_rtv.GetAddressOf(), nullptr);
s_stats.num_render_passes++;
m_num_current_render_targets = 0;

View File

@ -104,7 +104,7 @@ public:
bool SetGPUTimingEnabled(bool enabled) override;
float GetAndResetAccumulatedGPUTime() override;
bool BeginPresent(bool skip_present) override;
bool BeginPresent(bool skip_present, u32 clear_color) override;
void EndPresent(bool explicit_present) override;
void SubmitPresent() override;

View File

@ -57,7 +57,6 @@ enum : u32
// We need to synchronize instance creation because of adapter enumeration from the UI thread.
static std::mutex s_instance_mutex;
static constexpr D3D12_CLEAR_VALUE s_present_clear_color = {DXGI_FORMAT_R8G8B8A8_UNORM, {{0.0f, 0.0f, 0.0f, 1.0f}}};
static constexpr GPUTexture::Format s_swap_chain_format = GPUTexture::Format::RGBA8;
// We just need to keep this alive, never reference it.
@ -987,7 +986,7 @@ void D3D12Device::RenderBlankFrame()
m_current_swap_chain_buffer = ((m_current_swap_chain_buffer + 1) % static_cast<u32>(m_swap_chain_buffers.size()));
D3D12Texture::TransitionSubresourceToState(cmdlist, swap_chain_buf.first.Get(), 0, D3D12_RESOURCE_STATE_COMMON,
D3D12_RESOURCE_STATE_RENDER_TARGET);
cmdlist->ClearRenderTargetView(swap_chain_buf.second, s_present_clear_color.Color, 0, nullptr);
cmdlist->ClearRenderTargetView(swap_chain_buf.second, GSVector4::cxpr(0.0f, 0.0f, 0.0f, 1.0f).F32, 0, nullptr);
D3D12Texture::TransitionSubresourceToState(cmdlist, swap_chain_buf.first.Get(), 0, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PRESENT);
SubmitCommandList(false);
@ -1118,7 +1117,7 @@ void D3D12Device::SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle)
}
}
bool D3D12Device::BeginPresent(bool frame_skip)
bool D3D12Device::BeginPresent(bool frame_skip, u32 clear_color)
{
if (InRenderPass())
EndRenderPass();
@ -1147,7 +1146,7 @@ bool D3D12Device::BeginPresent(bool frame_skip)
return false;
}
BeginSwapChainRenderPass();
BeginSwapChainRenderPass(clear_color);
return true;
}
@ -1844,7 +1843,7 @@ void D3D12Device::BeginRenderPass()
SetInitialPipelineState();
}
void D3D12Device::BeginSwapChainRenderPass()
void D3D12Device::BeginSwapChainRenderPass(u32 clear_color)
{
DebugAssert(!InRenderPass());
@ -1862,10 +1861,10 @@ void D3D12Device::BeginSwapChainRenderPass()
m_current_textures[i]->TransitionToState(cmdlist, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
}
const D3D12_RENDER_PASS_RENDER_TARGET_DESC rt_desc = {
swap_chain_buf.second,
{D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, {s_present_clear_color}},
{D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, {}}};
D3D12_RENDER_PASS_RENDER_TARGET_DESC rt_desc = {swap_chain_buf.second,
{D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, {}},
{D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, {}}};
GSVector4::store<false>(rt_desc.BeginningAccess.Clear.ClearValue.Color, GSVector4::rgba32(clear_color));
cmdlist->BeginRenderPass(1, &rt_desc, nullptr, D3D12_RENDER_PASS_FLAG_NONE);
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));

View File

@ -126,7 +126,7 @@ public:
bool SetGPUTimingEnabled(bool enabled) override;
float GetAndResetAccumulatedGPUTime() override;
bool BeginPresent(bool skip_present) override;
bool BeginPresent(bool skip_present, u32 clear_color) override;
void EndPresent(bool explicit_present) override;
void SubmitPresent() override;
@ -276,7 +276,7 @@ private:
// Ends a render pass if we're currently in one.
// When Bind() is next called, the pass will be restarted.
void BeginRenderPass();
void BeginSwapChainRenderPass();
void BeginSwapChainRenderPass(u32 clear_color);
void EndRenderPass();
bool InRenderPass();

View File

@ -532,6 +532,7 @@ public:
static constexpr u32 MIN_TEXEL_BUFFER_ELEMENTS = 4 * 1024 * 512;
static constexpr u32 MAX_RENDER_TARGETS = 4;
static constexpr u32 MAX_IMAGE_RENDER_TARGETS = 2;
static constexpr u32 DEFAULT_CLEAR_COLOR = 0xFF000000u;
static_assert(sizeof(GPUPipeline::GraphicsConfig::color_formats) == sizeof(GPUTexture::Format) * MAX_RENDER_TARGETS);
GPUDevice();
@ -700,7 +701,7 @@ public:
virtual void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) = 0;
/// Returns false if the window was completely occluded.
virtual bool BeginPresent(bool skip_present) = 0;
virtual bool BeginPresent(bool skip_present, u32 clear_color = DEFAULT_CLEAR_COLOR) = 0;
virtual void EndPresent(bool explicit_submit) = 0;
virtual void SubmitPresent() = 0;

View File

@ -265,7 +265,7 @@ public:
void SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle) override;
bool BeginPresent(bool skip_present) override;
bool BeginPresent(bool skip_present, u32 clear_color) override;
void EndPresent(bool explicit_submit) override;
void SubmitPresent() override;

View File

@ -2313,7 +2313,7 @@ id<MTLBlitCommandEncoder> MetalDevice::GetBlitEncoder(bool is_inline)
}
}
bool MetalDevice::BeginPresent(bool skip_present)
bool MetalDevice::BeginPresent(bool skip_present, u32 clear_color)
{
@autoreleasepool
{
@ -2338,9 +2338,11 @@ bool MetalDevice::BeginPresent(bool skip_present)
SetViewportAndScissor(0, 0, m_window_info.surface_width, m_window_info.surface_height);
// Set up rendering to layer.
const GSVector4 clear_color_v = GSVector4::rgba32(clear_color);
id<MTLTexture> layer_texture = [m_layer_drawable texture];
m_layer_pass_desc.colorAttachments[0].texture = layer_texture;
m_layer_pass_desc.colorAttachments[0].loadAction = MTLLoadActionClear;
m_layer_pass_desc.colorAttachments[0].clearColor = MTLClearColorMake(clear_color_v.r, clear_color_v.g, clear_color_v.g, clear_color_v.a);
m_render_encoder = [[m_render_cmdbuf renderCommandEncoderWithDescriptor:m_layer_pass_desc] retain];
s_stats.num_render_passes++;
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));

View File

@ -21,7 +21,6 @@
Log_SetChannel(OpenGLDevice);
static constexpr const std::array<float, 4> s_clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
static constexpr const std::array<GLenum, GPUDevice::MAX_RENDER_TARGETS> s_draw_buffers = {
{GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}};
@ -616,7 +615,7 @@ void OpenGLDevice::RenderBlankFrame()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDisable(GL_SCISSOR_TEST);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClearBufferfv(GL_COLOR, 0, s_clear_color.data());
glClearBufferfv(GL_COLOR, 0, GSVector4::cxpr(0.0f, 0.0f, 0.0f, 1.0f).F32);
glColorMask(m_last_blend_state.write_r, m_last_blend_state.write_g, m_last_blend_state.write_b,
m_last_blend_state.write_a);
glEnable(GL_SCISSOR_TEST);
@ -742,7 +741,7 @@ void OpenGLDevice::DestroyBuffers()
m_vertex_buffer.reset();
}
bool OpenGLDevice::BeginPresent(bool skip_present)
bool OpenGLDevice::BeginPresent(bool skip_present, u32 clear_color)
{
if (skip_present || m_window_info.type == WindowInfo::Type::Surfaceless)
{
@ -758,7 +757,7 @@ bool OpenGLDevice::BeginPresent(bool skip_present)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_SCISSOR_TEST);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClearBufferfv(GL_COLOR, 0, s_clear_color.data());
glClearBufferfv(GL_COLOR, 0, GSVector4::rgba32(clear_color).F32);
glColorMask(m_last_blend_state.write_r, m_last_blend_state.write_g, m_last_blend_state.write_b,
m_last_blend_state.write_a);
glEnable(GL_SCISSOR_TEST);

View File

@ -104,7 +104,7 @@ public:
void SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle) override;
bool BeginPresent(bool skip_present) override;
bool BeginPresent(bool skip_present, u32 clear_color) override;
void EndPresent(bool explicit_present) override;
void SubmitPresent() override;

View File

@ -98,8 +98,6 @@ const std::array<VkFormat, static_cast<u32>(GPUTexture::Format::MaxCount)> Vulka
VK_FORMAT_A2R10G10B10_UNORM_PACK32, // RGB10A2
};
static constexpr VkClearValue s_present_clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
// Handles are always 64-bit, even on 32-bit platforms.
static const VkRenderPass DYNAMIC_RENDERING_RENDER_PASS = ((VkRenderPass) static_cast<s64>(-1LL));
@ -2423,7 +2421,7 @@ void VulkanDevice::SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle)
}
}
bool VulkanDevice::BeginPresent(bool frame_skip)
bool VulkanDevice::BeginPresent(bool frame_skip, u32 clear_color)
{
if (InRenderPass())
EndRenderPass();
@ -2486,7 +2484,7 @@ bool VulkanDevice::BeginPresent(bool frame_skip)
}
}
BeginSwapChainRenderPass();
BeginSwapChainRenderPass(clear_color);
return true;
}
@ -3166,9 +3164,10 @@ void VulkanDevice::RenderBlankFrame()
const VkImage image = m_swap_chain->GetCurrentImage();
static constexpr VkImageSubresourceRange srr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
static constexpr VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
VulkanTexture::TransitionSubresourcesToLayout(cmdbuf, image, GPUTexture::Type::RenderTarget, 0, 1, 0, 1,
VulkanTexture::Layout::Undefined, VulkanTexture::Layout::TransferDst);
vkCmdClearColorImage(cmdbuf, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &s_present_clear_color.color, 1, &srr);
vkCmdClearColorImage(cmdbuf, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &srr);
VulkanTexture::TransitionSubresourcesToLayout(cmdbuf, image, GPUTexture::Type::RenderTarget, 0, 1, 0, 1,
VulkanTexture::Layout::TransferDst, VulkanTexture::Layout::PresentSrc);
@ -3527,7 +3526,7 @@ void VulkanDevice::BeginRenderPass()
SetInitialPipelineState();
}
void VulkanDevice::BeginSwapChainRenderPass()
void VulkanDevice::BeginSwapChainRenderPass(u32 clear_color)
{
DebugAssert(!InRenderPass());
@ -3547,18 +3546,20 @@ void VulkanDevice::BeginSwapChainRenderPass()
m_current_textures[i]->TransitionToLayout(VulkanTexture::Layout::ShaderReadOnly);
}
VkClearValue clear_value;
GSVector4::store<false>(&clear_value.color.float32, GSVector4::rgba32(clear_color));
if (m_optional_extensions.vk_khr_dynamic_rendering)
{
const VkRenderingAttachmentInfo ai = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
nullptr,
m_swap_chain->GetCurrentImageView(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_RESOLVE_MODE_NONE_KHR,
VK_NULL_HANDLE,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_ATTACHMENT_LOAD_OP_CLEAR,
VK_ATTACHMENT_STORE_OP_STORE,
s_present_clear_color};
VkRenderingAttachmentInfo ai = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,
nullptr,
m_swap_chain->GetCurrentImageView(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_RESOLVE_MODE_NONE_KHR,
VK_NULL_HANDLE,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_ATTACHMENT_LOAD_OP_CLEAR,
VK_ATTACHMENT_STORE_OP_STORE,
clear_value};
const VkRenderingInfoKHR ri = {VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
nullptr,
@ -3586,7 +3587,7 @@ void VulkanDevice::BeginSwapChainRenderPass()
m_swap_chain->GetCurrentFramebuffer(),
{{0, 0}, {m_swap_chain->GetWidth(), m_swap_chain->GetHeight()}},
1u,
&s_present_clear_color};
&clear_value};
vkCmdBeginRenderPass(GetCurrentCommandBuffer(), &rp, VK_SUBPASS_CONTENTS_INLINE);
}

View File

@ -142,7 +142,7 @@ public:
void SetVSyncMode(GPUVSyncMode mode, bool allow_present_throttle) override;
bool BeginPresent(bool skip_present) override;
bool BeginPresent(bool skip_present, u32 clear_color) override;
void EndPresent(bool explicit_present) override;
void SubmitPresent() override;
@ -381,7 +381,7 @@ private:
// Ends a render pass if we're currently in one.
// When Bind() is next called, the pass will be restarted.
void BeginRenderPass();
void BeginSwapChainRenderPass();
void BeginSwapChainRenderPass(u32 clear_color);
void EndRenderPass();
bool InRenderPass();