mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[d3d11] Treat D3D11SamplerState as state object
This commit is contained in:
parent
7a6e20f3a8
commit
484308347a
@ -1123,50 +1123,16 @@ namespace dxvk {
|
||||
HRESULT STDMETHODCALLTYPE D3D11Device::CreateSamplerState(
|
||||
const D3D11_SAMPLER_DESC* pSamplerDesc,
|
||||
ID3D11SamplerState** ppSamplerState) {
|
||||
DxvkSamplerCreateInfo info;
|
||||
HRESULT hr = D3D11SamplerState::ValidateDesc(pSamplerDesc);
|
||||
|
||||
// While D3D11_FILTER is technically an enum, its value bits
|
||||
// can be used to decode the filter properties more efficiently.
|
||||
const uint32_t filterBits = static_cast<uint32_t>(pSamplerDesc->Filter);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
info.magFilter = (filterBits & 0x04) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
info.minFilter = (filterBits & 0x10) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
info.mipmapMode = (filterBits & 0x01) ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
info.useAnisotropy = (filterBits & 0x40) ? VK_TRUE : VK_FALSE;
|
||||
info.compareToDepth = (filterBits & 0x80) ? VK_TRUE : VK_FALSE;
|
||||
|
||||
// Check for any unknown flags
|
||||
if (filterBits & 0xFFFFFF2A) {
|
||||
Logger::err(str::format("D3D11: Unsupported filter bits: ", filterBits));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Set up the remaining properties, which are
|
||||
// stored directly in the sampler description
|
||||
info.mipmapLodBias = pSamplerDesc->MipLODBias;
|
||||
info.mipmapLodMin = pSamplerDesc->MinLOD;
|
||||
info.mipmapLodMax = pSamplerDesc->MaxLOD;
|
||||
info.maxAnisotropy = pSamplerDesc->MaxAnisotropy;
|
||||
info.addressModeU = DecodeAddressMode(pSamplerDesc->AddressU);
|
||||
info.addressModeV = DecodeAddressMode(pSamplerDesc->AddressV);
|
||||
info.addressModeW = DecodeAddressMode(pSamplerDesc->AddressW);
|
||||
info.compareOp = DecodeCompareOp(pSamplerDesc->ComparisonFunc);
|
||||
info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
info.usePixelCoord = VK_FALSE; // Not supported in D3D11
|
||||
|
||||
// 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(pSamplerDesc->BorderColor);
|
||||
|
||||
// Create sampler object if the application requests it
|
||||
if (ppSamplerState == nullptr)
|
||||
return S_FALSE;
|
||||
|
||||
try {
|
||||
*ppSamplerState = ref(new D3D11SamplerState(this,
|
||||
*pSamplerDesc, m_dxvkDevice->createSampler(info)));
|
||||
*ppSamplerState = m_samplerObjects.Create(this, *pSamplerDesc);
|
||||
return S_OK;
|
||||
} catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
@ -2330,31 +2296,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkSamplerAddressMode D3D11Device::DecodeAddressMode(
|
||||
D3D11_TEXTURE_ADDRESS_MODE mode) const {
|
||||
switch (mode) {
|
||||
case D3D11_TEXTURE_ADDRESS_WRAP:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_MIRROR:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_CLAMP:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_BORDER:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
|
||||
default:
|
||||
Logger::err(str::format("D3D11: Unsupported address mode: ", mode));
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const {
|
||||
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).format;
|
||||
const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt);
|
||||
|
@ -283,6 +283,7 @@ namespace dxvk {
|
||||
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
||||
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
|
||||
|
||||
HRESULT CreateShaderModule(
|
||||
D3D11ShaderModule* pShaderModule,
|
||||
@ -330,9 +331,6 @@ namespace dxvk {
|
||||
ID3D11Resource* pResource,
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc);
|
||||
|
||||
VkSamplerAddressMode DecodeAddressMode(
|
||||
D3D11_TEXTURE_ADDRESS_MODE mode) const;
|
||||
|
||||
HRESULT GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const;
|
||||
|
||||
void CreateCounterBuffer();
|
||||
|
@ -1,16 +1,45 @@
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_sampler.h"
|
||||
#include "d3d11_util.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D11SamplerState::D3D11SamplerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_SAMPLER_DESC& desc,
|
||||
const Rc<DxvkSampler>& sampler)
|
||||
: m_device(device),
|
||||
m_desc(desc),
|
||||
m_sampler(sampler) {
|
||||
const D3D11_SAMPLER_DESC& desc)
|
||||
: m_device(device), m_desc(desc) {
|
||||
DxvkSamplerCreateInfo info;
|
||||
|
||||
// While D3D11_FILTER is technically an enum, its value bits
|
||||
// can be used to decode the filter properties more efficiently.
|
||||
const uint32_t filterBits = static_cast<uint32_t>(desc.Filter);
|
||||
|
||||
info.magFilter = (filterBits & 0x04) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
info.minFilter = (filterBits & 0x10) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
info.mipmapMode = (filterBits & 0x01) ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
info.useAnisotropy = (filterBits & 0x40) ? VK_TRUE : VK_FALSE;
|
||||
info.compareToDepth = (filterBits & 0x80) ? VK_TRUE : VK_FALSE;
|
||||
|
||||
// Set up the remaining properties, which are
|
||||
// stored directly in the sampler description
|
||||
info.mipmapLodBias = desc.MipLODBias;
|
||||
info.mipmapLodMin = desc.MinLOD;
|
||||
info.mipmapLodMax = desc.MaxLOD;
|
||||
info.maxAnisotropy = desc.MaxAnisotropy;
|
||||
info.addressModeU = DecodeAddressMode(desc.AddressU);
|
||||
info.addressModeV = DecodeAddressMode(desc.AddressV);
|
||||
info.addressModeW = DecodeAddressMode(desc.AddressW);
|
||||
info.compareOp = DecodeCompareOp(desc.ComparisonFunc);
|
||||
info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
info.usePixelCoord = VK_FALSE; // Not supported in D3D11
|
||||
|
||||
// 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);
|
||||
|
||||
m_sampler = device->GetDXVKDevice()->createSampler(info);
|
||||
}
|
||||
|
||||
|
||||
@ -38,4 +67,16 @@ namespace dxvk {
|
||||
*pDesc = m_desc;
|
||||
}
|
||||
|
||||
|
||||
HRESULT D3D11SamplerState::ValidateDesc(const D3D11_SAMPLER_DESC* desc) {
|
||||
const uint32_t filterBits = static_cast<uint32_t>(desc->Filter);
|
||||
|
||||
if (filterBits & 0xFFFFFF2A) {
|
||||
Logger::err(str::format("D3D11SamplerState: Unhandled filter: ", filterBits));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,10 +12,11 @@ namespace dxvk {
|
||||
|
||||
public:
|
||||
|
||||
using DescType = D3D11_SAMPLER_DESC;
|
||||
|
||||
D3D11SamplerState(
|
||||
D3D11Device* device,
|
||||
const D3D11_SAMPLER_DESC& desc,
|
||||
const Rc<DxvkSampler>& sampler);
|
||||
const D3D11_SAMPLER_DESC& desc);
|
||||
~D3D11SamplerState();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
@ -32,6 +33,9 @@ namespace dxvk {
|
||||
return m_sampler;
|
||||
}
|
||||
|
||||
static HRESULT ValidateDesc(
|
||||
const D3D11_SAMPLER_DESC* desc);
|
||||
|
||||
private:
|
||||
|
||||
Com<D3D11Device> m_device;
|
||||
|
@ -77,6 +77,26 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
size_t D3D11StateDescHash::operator () (
|
||||
const D3D11_SAMPLER_DESC& desc) const {
|
||||
std::hash<float> fhash;
|
||||
|
||||
DxvkHashState hash;
|
||||
hash.add(desc.Filter);
|
||||
hash.add(desc.AddressU);
|
||||
hash.add(desc.AddressV);
|
||||
hash.add(desc.AddressW);
|
||||
hash.add(fhash(desc.MipLODBias));
|
||||
hash.add(fhash(desc.MaxAnisotropy));
|
||||
hash.add(desc.ComparisonFunc);
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
hash.add(fhash(desc.BorderColor[i]));
|
||||
hash.add(fhash(desc.MinLOD));
|
||||
hash.add(fhash(desc.MaxLOD));
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11StateDescEqual::operator () (
|
||||
const D3D11_BLEND_DESC& a,
|
||||
const D3D11_BLEND_DESC& b) const {
|
||||
@ -147,4 +167,23 @@ namespace dxvk {
|
||||
&& a.RenderTargetWriteMask == b.RenderTargetWriteMask;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11StateDescEqual::operator () (
|
||||
const D3D11_SAMPLER_DESC& a,
|
||||
const D3D11_SAMPLER_DESC& b) const {
|
||||
return a.Filter == b.Filter
|
||||
&& a.AddressU == b.AddressU
|
||||
&& a.AddressV == b.AddressV
|
||||
&& a.AddressW == b.AddressW
|
||||
&& a.MipLODBias == b.MipLODBias
|
||||
&& a.MaxAnisotropy == b.MaxAnisotropy
|
||||
&& a.ComparisonFunc == b.ComparisonFunc
|
||||
&& a.BorderColor[0] == b.BorderColor[0]
|
||||
&& a.BorderColor[1] == b.BorderColor[1]
|
||||
&& a.BorderColor[2] == b.BorderColor[2]
|
||||
&& a.BorderColor[3] == b.BorderColor[3]
|
||||
&& a.MinLOD == b.MinLOD
|
||||
&& a.MaxLOD == b.MaxLOD;
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include "d3d11_blend.h"
|
||||
#include "d3d11_depth_stencil.h"
|
||||
#include "d3d11_rasterizer.h"
|
||||
#include "d3d11_sampler.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
@ -16,6 +17,7 @@ namespace dxvk {
|
||||
size_t operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const;
|
||||
size_t operator () (const D3D11_RASTERIZER_DESC& desc) const;
|
||||
size_t operator () (const D3D11_RENDER_TARGET_BLEND_DESC& desc) const;
|
||||
size_t operator () (const D3D11_SAMPLER_DESC& desc) const;
|
||||
};
|
||||
|
||||
|
||||
@ -25,6 +27,7 @@ namespace dxvk {
|
||||
bool operator () (const D3D11_DEPTH_STENCIL_DESC& a, const D3D11_DEPTH_STENCIL_DESC& b) const;
|
||||
bool operator () (const D3D11_RASTERIZER_DESC& a, const D3D11_RASTERIZER_DESC& b) const;
|
||||
bool operator () (const D3D11_RENDER_TARGET_BLEND_DESC& a, const D3D11_RENDER_TARGET_BLEND_DESC& b) const;
|
||||
bool operator () (const D3D11_SAMPLER_DESC& a, const D3D11_SAMPLER_DESC& b) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -15,6 +15,31 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkSamplerAddressMode DecodeAddressMode(
|
||||
D3D11_TEXTURE_ADDRESS_MODE mode) {
|
||||
switch (mode) {
|
||||
case D3D11_TEXTURE_ADDRESS_WRAP:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_MIRROR:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_CLAMP:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_BORDER:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
|
||||
case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
|
||||
default:
|
||||
Logger::err(str::format("D3D11: Unsupported address mode: ", mode));
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VkBorderColor DecodeBorderColor(const FLOAT BorderColor[4]) {
|
||||
struct BorderColorEntry {
|
||||
float r, g, b, a;
|
||||
|
@ -11,6 +11,9 @@ namespace dxvk {
|
||||
HRESULT GetSampleCount(
|
||||
UINT Count,
|
||||
VkSampleCountFlagBits* pCount);
|
||||
|
||||
VkSamplerAddressMode DecodeAddressMode(
|
||||
D3D11_TEXTURE_ADDRESS_MODE mode);
|
||||
|
||||
VkBorderColor DecodeBorderColor(
|
||||
const FLOAT BorderColor[4]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user