mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22: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(
|
HRESULT STDMETHODCALLTYPE D3D11Device::CreateSamplerState(
|
||||||
const D3D11_SAMPLER_DESC* pSamplerDesc,
|
const D3D11_SAMPLER_DESC* pSamplerDesc,
|
||||||
ID3D11SamplerState** ppSamplerState) {
|
ID3D11SamplerState** ppSamplerState) {
|
||||||
DxvkSamplerCreateInfo info;
|
HRESULT hr = D3D11SamplerState::ValidateDesc(pSamplerDesc);
|
||||||
|
|
||||||
// While D3D11_FILTER is technically an enum, its value bits
|
if (FAILED(hr))
|
||||||
// can be used to decode the filter properties more efficiently.
|
return hr;
|
||||||
const uint32_t filterBits = static_cast<uint32_t>(pSamplerDesc->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;
|
|
||||||
|
|
||||||
// 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)
|
if (ppSamplerState == nullptr)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
*ppSamplerState = ref(new D3D11SamplerState(this,
|
*ppSamplerState = m_samplerObjects.Create(this, *pSamplerDesc);
|
||||||
*pSamplerDesc, m_dxvkDevice->createSampler(info)));
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
Logger::err(e.message());
|
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 {
|
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const {
|
||||||
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).format;
|
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).format;
|
||||||
const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt);
|
const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt);
|
||||||
|
@ -283,6 +283,7 @@ namespace dxvk {
|
|||||||
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||||
|
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
|
||||||
|
|
||||||
HRESULT CreateShaderModule(
|
HRESULT CreateShaderModule(
|
||||||
D3D11ShaderModule* pShaderModule,
|
D3D11ShaderModule* pShaderModule,
|
||||||
@ -330,9 +331,6 @@ namespace dxvk {
|
|||||||
ID3D11Resource* pResource,
|
ID3D11Resource* pResource,
|
||||||
D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc);
|
D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc);
|
||||||
|
|
||||||
VkSamplerAddressMode DecodeAddressMode(
|
|
||||||
D3D11_TEXTURE_ADDRESS_MODE mode) const;
|
|
||||||
|
|
||||||
HRESULT GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const;
|
HRESULT GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const;
|
||||||
|
|
||||||
void CreateCounterBuffer();
|
void CreateCounterBuffer();
|
||||||
|
@ -1,16 +1,45 @@
|
|||||||
#include "d3d11_device.h"
|
#include "d3d11_device.h"
|
||||||
#include "d3d11_sampler.h"
|
#include "d3d11_sampler.h"
|
||||||
|
#include "d3d11_util.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
D3D11SamplerState::D3D11SamplerState(
|
D3D11SamplerState::D3D11SamplerState(
|
||||||
D3D11Device* device,
|
D3D11Device* device,
|
||||||
const D3D11_SAMPLER_DESC& desc,
|
const D3D11_SAMPLER_DESC& desc)
|
||||||
const Rc<DxvkSampler>& sampler)
|
: m_device(device), m_desc(desc) {
|
||||||
: m_device(device),
|
DxvkSamplerCreateInfo info;
|
||||||
m_desc(desc),
|
|
||||||
m_sampler(sampler) {
|
|
||||||
|
|
||||||
|
// 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;
|
*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:
|
public:
|
||||||
|
|
||||||
|
using DescType = D3D11_SAMPLER_DESC;
|
||||||
|
|
||||||
D3D11SamplerState(
|
D3D11SamplerState(
|
||||||
D3D11Device* device,
|
D3D11Device* device,
|
||||||
const D3D11_SAMPLER_DESC& desc,
|
const D3D11_SAMPLER_DESC& desc);
|
||||||
const Rc<DxvkSampler>& sampler);
|
|
||||||
~D3D11SamplerState();
|
~D3D11SamplerState();
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
@ -32,6 +33,9 @@ namespace dxvk {
|
|||||||
return m_sampler;
|
return m_sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT ValidateDesc(
|
||||||
|
const D3D11_SAMPLER_DESC* desc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<D3D11Device> m_device;
|
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 () (
|
bool D3D11StateDescEqual::operator () (
|
||||||
const D3D11_BLEND_DESC& a,
|
const D3D11_BLEND_DESC& a,
|
||||||
const D3D11_BLEND_DESC& b) const {
|
const D3D11_BLEND_DESC& b) const {
|
||||||
@ -147,4 +167,23 @@ namespace dxvk {
|
|||||||
&& a.RenderTargetWriteMask == b.RenderTargetWriteMask;
|
&& 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_blend.h"
|
||||||
#include "d3d11_depth_stencil.h"
|
#include "d3d11_depth_stencil.h"
|
||||||
#include "d3d11_rasterizer.h"
|
#include "d3d11_rasterizer.h"
|
||||||
|
#include "d3d11_sampler.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ namespace dxvk {
|
|||||||
size_t operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const;
|
size_t operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const;
|
||||||
size_t operator () (const D3D11_RASTERIZER_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_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_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_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_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]) {
|
VkBorderColor DecodeBorderColor(const FLOAT BorderColor[4]) {
|
||||||
struct BorderColorEntry {
|
struct BorderColorEntry {
|
||||||
float r, g, b, a;
|
float r, g, b, a;
|
||||||
|
@ -11,6 +11,9 @@ namespace dxvk {
|
|||||||
HRESULT GetSampleCount(
|
HRESULT GetSampleCount(
|
||||||
UINT Count,
|
UINT Count,
|
||||||
VkSampleCountFlagBits* pCount);
|
VkSampleCountFlagBits* pCount);
|
||||||
|
|
||||||
|
VkSamplerAddressMode DecodeAddressMode(
|
||||||
|
D3D11_TEXTURE_ADDRESS_MODE mode);
|
||||||
|
|
||||||
VkBorderColor DecodeBorderColor(
|
VkBorderColor DecodeBorderColor(
|
||||||
const FLOAT BorderColor[4]);
|
const FLOAT BorderColor[4]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user