Skip to content

Commit

Permalink
GPUDevice: Expose swap chain clear colour
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Aug 6, 2024
1 parent aeb9d38 commit 4f16cb6
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 44 deletions.
4 changes: 2 additions & 2 deletions src/core/gpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions src/util/d3d11_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/util/d3d11_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class D3D11Device final : public GPUDevice
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;

Expand Down
17 changes: 8 additions & 9 deletions src/util/d3d12_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -1147,7 +1146,7 @@ bool D3D12Device::BeginPresent(bool frame_skip)
return false;
}

BeginSwapChainRenderPass();
BeginSwapChainRenderPass(clear_color);
return true;
}

Expand Down Expand Up @@ -1844,7 +1843,7 @@ void D3D12Device::BeginRenderPass()
SetInitialPipelineState();
}

void D3D12Device::BeginSwapChainRenderPass()
void D3D12Device::BeginSwapChainRenderPass(u32 clear_color)
{
DebugAssert(!InRenderPass());

Expand All @@ -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));
Expand Down
4 changes: 2 additions & 2 deletions src/util/d3d12_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class D3D12Device final : public GPUDevice
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;

Expand Down Expand Up @@ -276,7 +276,7 @@ class D3D12Device final : public GPUDevice
// 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();

Expand Down
3 changes: 2 additions & 1 deletion src/util/gpu_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ class GPUDevice
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();
Expand Down Expand Up @@ -700,7 +701,7 @@ class GPUDevice
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;

Expand Down
2 changes: 1 addition & 1 deletion src/util/metal_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class MetalDevice final : public GPUDevice

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;

Expand Down
4 changes: 3 additions & 1 deletion src/util/metal_device.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2313,7 +2313,7 @@ static void DumpShader(u32 n, std::string_view suffix, std::string_view data)
}
}

bool MetalDevice::BeginPresent(bool skip_present)
bool MetalDevice::BeginPresent(bool skip_present, u32 clear_color)
{
@autoreleasepool
{
Expand All @@ -2338,9 +2338,11 @@ static void DumpShader(u32 n, std::string_view suffix, std::string_view data)
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));
Expand Down
7 changes: 3 additions & 4 deletions src/util/opengl_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/util/opengl_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class OpenGLDevice final : public GPUDevice

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;

Expand Down
35 changes: 18 additions & 17 deletions src/util/vulkan_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -2486,7 +2484,7 @@ bool VulkanDevice::BeginPresent(bool frame_skip)
}
}

BeginSwapChainRenderPass();
BeginSwapChainRenderPass(clear_color);
return true;
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -3527,7 +3526,7 @@ void VulkanDevice::BeginRenderPass()
SetInitialPipelineState();
}

void VulkanDevice::BeginSwapChainRenderPass()
void VulkanDevice::BeginSwapChainRenderPass(u32 clear_color)
{
DebugAssert(!InRenderPass());

Expand All @@ -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,
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/util/vulkan_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class VulkanDevice final : public GPUDevice

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;

Expand Down Expand Up @@ -381,7 +381,7 @@ class VulkanDevice final : public GPUDevice
// 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();

Expand Down

0 comments on commit 4f16cb6

Please sign in to comment.