mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
HostDisplay: Use border sampling for post processing shaders
This commit is contained in:
parent
c528a96215
commit
ccfe3925fc
|
@ -440,6 +440,11 @@ void SamplerBuilder::SetAddressMode(VkSamplerAddressMode u, VkSamplerAddressMode
|
|||
m_ci.addressModeW = w;
|
||||
}
|
||||
|
||||
void SamplerBuilder::SetBorderColor(VkBorderColor color)
|
||||
{
|
||||
m_ci.borderColor = color;
|
||||
}
|
||||
|
||||
void SamplerBuilder::SetPointSampler(VkSamplerAddressMode address_mode /* = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER */)
|
||||
{
|
||||
Clear();
|
||||
|
|
|
@ -149,9 +149,10 @@ public:
|
|||
|
||||
void SetFilter(VkFilter mag_filter, VkFilter min_filter, VkSamplerMipmapMode mip_filter);
|
||||
void SetAddressMode(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w);
|
||||
void SetBorderColor(VkBorderColor color);
|
||||
|
||||
void SetPointSampler(VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
void SetLinearSampler(bool mipmaps, VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
void SetPointSampler(VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
void SetLinearSampler(bool mipmaps, VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
private:
|
||||
VkSamplerCreateInfo m_ci;
|
||||
|
|
|
@ -521,7 +521,7 @@ bool GPU_HW_Vulkan::CreateSamplers()
|
|||
VkDevice device = g_vulkan_context->GetDevice();
|
||||
|
||||
Vulkan::SamplerBuilder sbuilder;
|
||||
sbuilder.SetPointSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetPointSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
sbuilder.SetAddressMode(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_REPEAT);
|
||||
m_point_sampler = sbuilder.Create(device);
|
||||
|
@ -529,7 +529,7 @@ bool GPU_HW_Vulkan::CreateSamplers()
|
|||
return false;
|
||||
Vulkan::Util::SetObjectName(g_vulkan_context->GetDevice(), m_point_sampler, "Point Sampler");
|
||||
|
||||
sbuilder.SetLinearSampler(false, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetLinearSampler(false, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
sbuilder.SetAddressMode(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_REPEAT);
|
||||
m_linear_sampler = sbuilder.Create(device);
|
||||
|
@ -537,7 +537,7 @@ bool GPU_HW_Vulkan::CreateSamplers()
|
|||
return false;
|
||||
Vulkan::Util::SetObjectName(g_vulkan_context->GetDevice(), m_linear_sampler, "Linear Sampler");
|
||||
|
||||
sbuilder.SetLinearSampler(true, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetLinearSampler(true, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
m_trilinear_sampler = sbuilder.Create(device);
|
||||
if (m_trilinear_sampler == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
|
|
@ -655,6 +655,17 @@ bool D3D11HostDisplay::CreateResources()
|
|||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampler_desc.BorderColor[0] = 0.0f;
|
||||
sampler_desc.BorderColor[1] = 0.0f;
|
||||
sampler_desc.BorderColor[2] = 0.0f;
|
||||
sampler_desc.BorderColor[3] = 1.0f;
|
||||
hr = m_device->CreateSamplerState(&sampler_desc, m_border_sampler.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -665,6 +676,7 @@ void D3D11HostDisplay::DestroyResources()
|
|||
m_post_processing_stages.clear();
|
||||
|
||||
m_display_uniform_buffer.Release();
|
||||
m_border_sampler.Reset();
|
||||
m_linear_sampler.Reset();
|
||||
m_point_sampler.Reset();
|
||||
m_display_alpha_pixel_shader.Reset();
|
||||
|
@ -1082,7 +1094,7 @@ void D3D11HostDisplay::ApplyPostProcessingChain(ID3D11RenderTargetView* final_ta
|
|||
m_context->VSSetShader(pps.vertex_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(pps.pixel_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShaderResources(0, 1, texture->GetD3DSRVArray());
|
||||
m_context->PSSetSamplers(0, 1, m_point_sampler.GetAddressOf());
|
||||
m_context->PSSetSamplers(0, 1, m_border_sampler.GetAddressOf());
|
||||
|
||||
const auto map =
|
||||
m_display_uniform_buffer.Map(m_context.Get(), m_display_uniform_buffer.GetSize(), pps.uniforms_size);
|
||||
|
|
|
@ -132,6 +132,7 @@ protected:
|
|||
ComPtr<ID3D11PixelShader> m_display_alpha_pixel_shader;
|
||||
ComPtr<ID3D11SamplerState> m_point_sampler;
|
||||
ComPtr<ID3D11SamplerState> m_linear_sampler;
|
||||
ComPtr<ID3D11SamplerState> m_border_sampler;
|
||||
|
||||
D3D11::StreamBuffer m_display_uniform_buffer;
|
||||
ComPtr<ID3D11Texture2D> m_readback_staging_texture;
|
||||
|
|
|
@ -565,6 +565,18 @@ bool D3D12HostDisplay::CreateResources()
|
|||
|
||||
g_d3d12_context->GetDevice()->CreateSampler(&desc, m_linear_sampler.cpu_handle);
|
||||
|
||||
if (!g_d3d12_context->GetSamplerHeapManager().Allocate(&m_border_sampler))
|
||||
return false;
|
||||
|
||||
desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||
desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
|
||||
desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||
desc.BorderColor[0] = 0.0f;
|
||||
desc.BorderColor[1] = 0.0f;
|
||||
desc.BorderColor[2] = 0.0f;
|
||||
desc.BorderColor[3] = 1.0f;
|
||||
g_d3d12_context->GetDevice()->CreateSampler(&desc, m_border_sampler.cpu_handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -578,6 +590,7 @@ void D3D12HostDisplay::DestroyResources()
|
|||
m_post_processing_root_signature.Reset();
|
||||
|
||||
m_readback_staging_texture.Destroy(false);
|
||||
g_d3d12_context->GetSamplerHeapManager().Free(&m_border_sampler);
|
||||
g_d3d12_context->GetSamplerHeapManager().Free(&m_linear_sampler);
|
||||
g_d3d12_context->GetSamplerHeapManager().Free(&m_point_sampler);
|
||||
m_software_cursor_pipeline.Reset();
|
||||
|
@ -1074,7 +1087,7 @@ void D3D12HostDisplay::ApplyPostProcessingChain(ID3D12GraphicsCommandList* cmdli
|
|||
|
||||
cmdlist->SetPipelineState(pps.pipeline.Get());
|
||||
cmdlist->SetGraphicsRootDescriptorTable(1, texture->GetSRVDescriptor());
|
||||
cmdlist->SetGraphicsRootDescriptorTable(2, m_point_sampler);
|
||||
cmdlist->SetGraphicsRootDescriptorTable(2, m_border_sampler);
|
||||
|
||||
cmdlist->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
cmdlist->DrawInstanced(3, 1, 0, 0);
|
||||
|
|
|
@ -124,6 +124,7 @@ protected:
|
|||
ComPtr<ID3D12PipelineState> m_software_cursor_pipeline;
|
||||
D3D12::DescriptorHandle m_point_sampler;
|
||||
D3D12::DescriptorHandle m_linear_sampler;
|
||||
D3D12::DescriptorHandle m_border_sampler;
|
||||
|
||||
D3D12::Texture m_display_pixels_texture;
|
||||
D3D12::StagingTexture m_readback_staging_texture;
|
||||
|
|
|
@ -457,9 +457,9 @@ static bool ImGui_ImplVulkan_CreateFontSampler(VkDevice device)
|
|||
info.magFilter = VK_FILTER_LINEAR;
|
||||
info.minFilter = VK_FILTER_LINEAR;
|
||||
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
info.minLod = -1000;
|
||||
info.maxLod = 1000;
|
||||
info.maxAnisotropy = 1.0f;
|
||||
|
|
|
@ -510,6 +510,20 @@ void main()
|
|||
glGenSamplers(1, &m_display_linear_sampler);
|
||||
glSamplerParameteri(m_display_linear_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glSamplerParameteri(m_display_linear_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glGenSamplers(1, &m_display_border_sampler);
|
||||
glSamplerParameteri(m_display_border_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glSamplerParameteri(m_display_border_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// If we don't have border clamp.. too bad, just hope for the best.
|
||||
if (!m_gl_context->IsGLES() || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_NV_texture_border_clamp ||
|
||||
GLAD_GL_EXT_texture_border_clamp || GLAD_GL_OES_texture_border_clamp)
|
||||
{
|
||||
static constexpr const float border_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
glSamplerParameteri(m_display_border_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glSamplerParameteri(m_display_border_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameterfv(m_display_border_sampler, GL_TEXTURE_BORDER_COLOR, border_color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -594,6 +608,11 @@ void OpenGLHostDisplay::DestroyResources()
|
|||
glDeleteVertexArrays(1, &m_display_vao);
|
||||
m_display_vao = 0;
|
||||
}
|
||||
if (m_display_border_sampler != 0)
|
||||
{
|
||||
glDeleteSamplers(1, &m_display_border_sampler);
|
||||
m_display_border_sampler = 0;
|
||||
}
|
||||
if (m_display_linear_sampler != 0)
|
||||
{
|
||||
glDeleteSamplers(1, &m_display_linear_sampler);
|
||||
|
@ -657,9 +676,9 @@ bool OpenGLHostDisplay::RenderScreenshot(u32 width, u32 height, std::vector<u32>
|
|||
if (HasDisplayTexture() && !m_post_processing_chain.IsEmpty())
|
||||
{
|
||||
ApplyPostProcessingChain(texture.GetGLFramebufferID(), left, height - top - draw_height, draw_width, draw_height,
|
||||
static_cast<GL::Texture*>(m_display_texture), m_display_texture_view_x,
|
||||
m_display_texture_view_y, m_display_texture_view_width, m_display_texture_view_height,
|
||||
width, height);
|
||||
static_cast<GL::Texture*>(m_display_texture), m_display_texture_view_x,
|
||||
m_display_texture_view_y, m_display_texture_view_width, m_display_texture_view_height,
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -952,7 +971,7 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_
|
|||
pps.program.Bind();
|
||||
|
||||
static_cast<const GL::Texture*>(texture)->Bind();
|
||||
glBindSampler(0, m_display_nearest_sampler);
|
||||
glBindSampler(0, m_display_border_sampler);
|
||||
|
||||
const auto map_result = m_post_processing_ubo->Map(m_uniform_buffer_alignment, pps.uniforms_size);
|
||||
m_post_processing_chain.GetShaderStage(i).FillUniformBuffer(
|
||||
|
|
|
@ -112,6 +112,7 @@ protected:
|
|||
GLuint m_display_vao = 0;
|
||||
GLuint m_display_nearest_sampler = 0;
|
||||
GLuint m_display_linear_sampler = 0;
|
||||
GLuint m_display_border_sampler = 0;
|
||||
GLuint m_uniform_buffer_alignment = 1;
|
||||
|
||||
std::unique_ptr<GL::StreamBuffer> m_texture_stream_buffer;
|
||||
|
|
|
@ -507,16 +507,22 @@ void main()
|
|||
vkDestroyShaderModule(device, cursor_fragment_shader, nullptr);
|
||||
|
||||
Vulkan::SamplerBuilder sbuilder;
|
||||
sbuilder.SetPointSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetPointSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
m_point_sampler = sbuilder.Create(device, true);
|
||||
if (m_point_sampler == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
sbuilder.SetLinearSampler(false, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetLinearSampler(false, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
m_linear_sampler = sbuilder.Create(device);
|
||||
if (m_linear_sampler == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
sbuilder.SetPointSampler(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
sbuilder.SetBorderColor(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
|
||||
m_border_sampler = sbuilder.Create(device);
|
||||
if (m_border_sampler == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -536,6 +542,7 @@ void VulkanHostDisplay::DestroyResources()
|
|||
Vulkan::Util::SafeDestroyPipeline(m_cursor_pipeline);
|
||||
Vulkan::Util::SafeDestroyPipelineLayout(m_pipeline_layout);
|
||||
Vulkan::Util::SafeDestroyDescriptorSetLayout(m_descriptor_set_layout);
|
||||
Vulkan::Util::SafeDestroySampler(m_border_sampler);
|
||||
Vulkan::Util::SafeDestroySampler(m_point_sampler);
|
||||
Vulkan::Util::SafeDestroySampler(m_linear_sampler);
|
||||
}
|
||||
|
@ -1149,7 +1156,7 @@ void VulkanHostDisplay::ApplyPostProcessingChain(VkFramebuffer target_fb, s32 fi
|
|||
}
|
||||
|
||||
Vulkan::DescriptorSetUpdateBuilder dsupdate;
|
||||
dsupdate.AddCombinedImageSamplerDescriptorWrite(ds, 1, texture->GetView(), m_point_sampler, texture->GetLayout());
|
||||
dsupdate.AddCombinedImageSamplerDescriptorWrite(ds, 1, texture->GetView(), m_border_sampler, texture->GetLayout());
|
||||
|
||||
if (use_push_constants)
|
||||
{
|
||||
|
|
|
@ -121,6 +121,7 @@ protected:
|
|||
VkPipeline m_display_pipeline = VK_NULL_HANDLE;
|
||||
VkSampler m_point_sampler = VK_NULL_HANDLE;
|
||||
VkSampler m_linear_sampler = VK_NULL_HANDLE;
|
||||
VkSampler m_border_sampler = VK_NULL_HANDLE;
|
||||
|
||||
VmaAllocation m_readback_staging_allocation = VK_NULL_HANDLE;
|
||||
VkBuffer m_readback_staging_buffer = VK_NULL_HANDLE;
|
||||
|
|
Loading…
Reference in a new issue