From 36ccd46ae7af0aefae58f2d87a9c841ff72d0341 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Oct 2018 21:51:23 +0100 Subject: [PATCH] [dxvk] Move sampler border color handling to the backend --- src/d3d11/d3d11_sampler.cpp | 10 +++------- src/d3d11/d3d11_swapchain.cpp | 2 +- src/d3d11/d3d11_util.cpp | 28 ---------------------------- src/d3d11/d3d11_util.h | 3 --- src/dxvk/dxvk_sampler.cpp | 27 ++++++++++++++++++++++++++- src/dxvk/dxvk_sampler.h | 4 +++- src/dxvk/dxvk_unbound.cpp | 2 +- src/dxvk/hud/dxvk_hud_renderer.cpp | 2 +- 8 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index 189cdb7f..5be83980 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -33,19 +33,15 @@ namespace dxvk { info.compareToDepth = (filterBits & 0x80) ? VK_TRUE : VK_FALSE; info.compareOp = DecodeCompareOp(desc.ComparisonFunc); - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + for (uint32_t i = 0; i < 4; i++) + info.borderColor.float32[i] = desc.BorderColor[i]; + info.usePixelCoord = VK_FALSE; // Not supported in D3D11 // Make sure to use a valid anisotropy value if (desc.MaxAnisotropy < 1) info.maxAnisotropy = 1.0f; if (desc.MaxAnisotropy > 16) info.maxAnisotropy = 16.0f; - // Try to find a matching border color if clamp to border is enabled - if (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.borderColor = DecodeBorderColor(desc.BorderColor); - // Enforce anisotropy specified in the device options int32_t samplerAnisotropyOption = device->GetOptions()->samplerAnisotropy; diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 3d4c6bd6..09fa6883 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -552,7 +552,7 @@ namespace dxvk { samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; samplerInfo.compareToDepth = VK_FALSE; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; - samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + samplerInfo.borderColor = VkClearColorValue(); samplerInfo.usePixelCoord = VK_FALSE; m_samplerFitting = m_device->createSampler(samplerInfo); diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp index 9e781977..6919ebdc 100644 --- a/src/d3d11/d3d11_util.cpp +++ b/src/d3d11/d3d11_util.cpp @@ -46,34 +46,6 @@ namespace dxvk { } - VkBorderColor DecodeBorderColor(const FLOAT BorderColor[4]) { - struct BorderColorEntry { - float r, g, b, a; - VkBorderColor bc; - }; - - // Vulkan only supports a very limited set of border colors - const std::array borderColorMap = {{ - { 0.0f, 0.0f, 0.0f, 0.0f, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK }, - { 0.0f, 0.0f, 0.0f, 1.0f, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK }, - { 1.0f, 1.0f, 1.0f, 1.0f, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE }, - }}; - - for (const auto& e : borderColorMap) { - if (e.r == BorderColor[0] && e.g == BorderColor[1] - && e.b == BorderColor[2] && e.a == BorderColor[3]) - return e.bc; - } - - Logger::warn(str::format( - "D3D11Device: No matching border color found for (", - BorderColor[0], ",", BorderColor[1], ",", - BorderColor[2], ",", BorderColor[3], ")")); - - return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - } - - VkCompareOp DecodeCompareOp(D3D11_COMPARISON_FUNC Mode) { switch (Mode) { case D3D11_COMPARISON_NEVER: return VK_COMPARE_OP_NEVER; diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h index b1f97dd5..5a0360d4 100644 --- a/src/d3d11/d3d11_util.h +++ b/src/d3d11/d3d11_util.h @@ -28,9 +28,6 @@ namespace dxvk { VkSamplerAddressMode DecodeAddressMode( D3D11_TEXTURE_ADDRESS_MODE mode); - VkBorderColor DecodeBorderColor( - const FLOAT BorderColor[4]); - VkCompareOp DecodeCompareOp( D3D11_COMPARISON_FUNC Mode); diff --git a/src/dxvk/dxvk_sampler.cpp b/src/dxvk/dxvk_sampler.cpp index c7def667..43306faa 100644 --- a/src/dxvk/dxvk_sampler.cpp +++ b/src/dxvk/dxvk_sampler.cpp @@ -23,8 +23,13 @@ namespace dxvk { samplerInfo.compareOp = info.compareOp; samplerInfo.minLod = info.mipmapLodMin; samplerInfo.maxLod = info.mipmapLodMax; - samplerInfo.borderColor = info.borderColor; + samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; samplerInfo.unnormalizedCoordinates = info.usePixelCoord; + + if (samplerInfo.addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER + || samplerInfo.addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER + || samplerInfo.addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) + samplerInfo.borderColor = getBorderColor(info.borderColor); if (m_vkd->vkCreateSampler(m_vkd->device(), &samplerInfo, nullptr, &m_sampler) != VK_SUCCESS) @@ -36,5 +41,25 @@ namespace dxvk { m_vkd->vkDestroySampler( m_vkd->device(), m_sampler, nullptr); } + + + VkBorderColor DxvkSampler::getBorderColor(VkClearColorValue borderColor) const { + static const std::array, 3> s_borderColors = {{ + { { 0.0f, 0.0f, 0.0f, 0.0f }, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK }, + { { 0.0f, 0.0f, 0.0f, 1.0f }, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK }, + { { 1.0f, 1.0f, 1.0f, 1.0f }, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE }, + }}; + + for (const auto& e : s_borderColors) { + if (!std::memcmp(&e.first, &borderColor, sizeof(VkClearColorValue))) + return e.second; + } + + Logger::warn(str::format( + "DXVK: No matching border color found for (", + borderColor.float32[0], ",", borderColor.float32[1], ",", + borderColor.float32[2], ",", borderColor.float32[3], ")")); + return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + } } diff --git a/src/dxvk/dxvk_sampler.h b/src/dxvk/dxvk_sampler.h index e2ed1ef7..b7687067 100644 --- a/src/dxvk/dxvk_sampler.h +++ b/src/dxvk/dxvk_sampler.h @@ -32,7 +32,7 @@ namespace dxvk { VkCompareOp compareOp; /// Texture border color - VkBorderColor borderColor; + VkClearColorValue borderColor; /// Enables unnormalized coordinates VkBool32 usePixelCoord; @@ -76,6 +76,8 @@ namespace dxvk { Rc m_vkd; DxvkSamplerCreateInfo m_info; VkSampler m_sampler = VK_NULL_HANDLE; + + VkBorderColor getBorderColor(VkClearColorValue borderColor) const; }; diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index 19d61037..67403e0a 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -55,7 +55,7 @@ namespace dxvk { info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.compareToDepth = VK_FALSE; info.compareOp = VK_COMPARE_OP_NEVER; - info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; + info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_FALSE; return dev->createSampler(info); diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 0430ad34..1df16b66 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -279,7 +279,7 @@ namespace dxvk::hud { info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.compareToDepth = VK_FALSE; info.compareOp = VK_COMPARE_OP_NEVER; - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_TRUE; return device->createSampler(info);