mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
Merge branch 'master' of https://github.com/doitsujin/dxvk
This commit is contained in:
commit
16a25db846
@ -148,8 +148,63 @@ namespace dxvk {
|
||||
|
||||
|
||||
HRESULT D3D11BlendState::NormalizeDesc(D3D11_BLEND_DESC1* pDesc) {
|
||||
// TODO validate
|
||||
// TODO clear unused values
|
||||
const D3D11_BLEND_DESC1 defaultDesc = DefaultDesc();
|
||||
|
||||
if (pDesc->AlphaToCoverageEnable)
|
||||
pDesc->AlphaToCoverageEnable = TRUE;
|
||||
|
||||
if (pDesc->IndependentBlendEnable)
|
||||
pDesc->IndependentBlendEnable = TRUE;
|
||||
|
||||
const uint32_t numRenderTargets = pDesc->IndependentBlendEnable ? 8 : 1;
|
||||
|
||||
for (uint32_t i = 0; i < numRenderTargets; i++) {
|
||||
D3D11_RENDER_TARGET_BLEND_DESC1* rt = &pDesc->RenderTarget[i];
|
||||
|
||||
if (rt->BlendEnable) {
|
||||
rt->BlendEnable = TRUE;
|
||||
|
||||
if (rt->LogicOpEnable)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!ValidateBlendOperations(
|
||||
rt->SrcBlend, rt->SrcBlendAlpha,
|
||||
rt->DestBlend, rt->DestBlendAlpha,
|
||||
rt->BlendOp, rt->BlendOpAlpha))
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
rt->SrcBlend = defaultDesc.RenderTarget[0].SrcBlend;
|
||||
rt->DestBlend = defaultDesc.RenderTarget[0].DestBlend;
|
||||
rt->BlendOp = defaultDesc.RenderTarget[0].BlendOp;
|
||||
rt->SrcBlendAlpha = defaultDesc.RenderTarget[0].SrcBlendAlpha;
|
||||
rt->DestBlendAlpha = defaultDesc.RenderTarget[0].DestBlendAlpha;
|
||||
rt->BlendOpAlpha = defaultDesc.RenderTarget[0].BlendOpAlpha;
|
||||
}
|
||||
|
||||
if (rt->LogicOpEnable) {
|
||||
rt->LogicOpEnable = TRUE;
|
||||
|
||||
// Blending must be disabled
|
||||
// if the logic op is enabled
|
||||
if (rt->BlendEnable
|
||||
|| pDesc->IndependentBlendEnable
|
||||
|| !ValidateLogicOp(rt->LogicOp))
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
rt->LogicOp = defaultDesc.RenderTarget[0].LogicOp;
|
||||
}
|
||||
|
||||
if (rt->RenderTargetWriteMask > D3D11_COLOR_WRITE_ENABLE_ALL)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
for (uint32_t i = numRenderTargets; i < 8; i++) {
|
||||
// Render targets blend operations are the same
|
||||
// across all render targets when blend is enabled
|
||||
// on rendertarget[0] with independent blend disabled
|
||||
pDesc->RenderTarget[i] = pDesc->RenderTarget[0];
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -188,11 +243,8 @@ namespace dxvk {
|
||||
case D3D11_BLEND_INV_SRC1_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
|
||||
case D3D11_BLEND_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA;
|
||||
case D3D11_BLEND_INV_SRC1_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
|
||||
default: return VK_BLEND_FACTOR_ZERO;
|
||||
}
|
||||
|
||||
if (BlendFactor != 0) // prevent log spamming when apps use ZeroMemory
|
||||
Logger::err(str::format("D3D11: Invalid blend factor: ", BlendFactor));
|
||||
return VK_BLEND_FACTOR_ZERO;
|
||||
}
|
||||
|
||||
|
||||
@ -203,11 +255,8 @@ namespace dxvk {
|
||||
case D3D11_BLEND_OP_REV_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
|
||||
case D3D11_BLEND_OP_MIN: return VK_BLEND_OP_MIN;
|
||||
case D3D11_BLEND_OP_MAX: return VK_BLEND_OP_MAX;
|
||||
default: return VK_BLEND_OP_ADD;
|
||||
}
|
||||
|
||||
if (BlendOp != 0) // prevent log spamming when apps use ZeroMemory
|
||||
Logger::err(str::format("D3D11: Invalid blend op: ", BlendOp));
|
||||
return VK_BLEND_OP_ADD;
|
||||
}
|
||||
|
||||
|
||||
@ -229,11 +278,54 @@ namespace dxvk {
|
||||
case D3D11_LOGIC_OP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
|
||||
case D3D11_LOGIC_OP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
|
||||
case D3D11_LOGIC_OP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
|
||||
default: return VK_LOGIC_OP_NO_OP;
|
||||
}
|
||||
|
||||
if (LogicOp != 0)
|
||||
Logger::err(str::format("D3D11: Invalid logic op: ", LogicOp));
|
||||
return VK_LOGIC_OP_NO_OP;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11BlendState::ValidateBlendFactor(D3D11_BLEND Blend) {
|
||||
return Blend >= D3D11_BLEND_ZERO
|
||||
&& Blend <= D3D11_BLEND_INV_SRC1_ALPHA;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11BlendState::ValidateBlendFactorAlpha(D3D11_BLEND BlendAlpha) {
|
||||
return BlendAlpha >= D3D11_BLEND_ZERO
|
||||
&& BlendAlpha <= D3D11_BLEND_INV_SRC1_ALPHA
|
||||
&& BlendAlpha != D3D11_BLEND_SRC_COLOR
|
||||
&& BlendAlpha != D3D11_BLEND_INV_SRC_COLOR
|
||||
&& BlendAlpha != D3D11_BLEND_DEST_COLOR
|
||||
&& BlendAlpha != D3D11_BLEND_INV_DEST_COLOR
|
||||
&& BlendAlpha != D3D11_BLEND_SRC1_COLOR
|
||||
&& BlendAlpha != D3D11_BLEND_INV_SRC1_COLOR;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11BlendState::ValidateBlendOp(D3D11_BLEND_OP BlendOp) {
|
||||
return BlendOp >= D3D11_BLEND_OP_ADD
|
||||
&& BlendOp <= D3D11_BLEND_OP_MAX;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11BlendState::ValidateLogicOp(D3D11_LOGIC_OP LogicOp) {
|
||||
return LogicOp >= D3D11_LOGIC_OP_CLEAR
|
||||
&& LogicOp <= D3D11_LOGIC_OP_OR_INVERTED;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11BlendState::ValidateBlendOperations(
|
||||
D3D11_BLEND SrcBlend,
|
||||
D3D11_BLEND SrcBlendAlpha,
|
||||
D3D11_BLEND DestBlend,
|
||||
D3D11_BLEND DestBlendAlpha,
|
||||
D3D11_BLEND_OP BlendOp,
|
||||
D3D11_BLEND_OP BlendOpAlpha) {
|
||||
return ValidateBlendOp(BlendOp)
|
||||
&& ValidateBlendOp(BlendOpAlpha)
|
||||
&& ValidateBlendFactor(SrcBlend)
|
||||
&& ValidateBlendFactor(DestBlend)
|
||||
&& ValidateBlendFactorAlpha(SrcBlendAlpha)
|
||||
&& ValidateBlendFactorAlpha(DestBlendAlpha);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ namespace dxvk {
|
||||
|
||||
static HRESULT NormalizeDesc(
|
||||
D3D11_BLEND_DESC1* pDesc);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -66,7 +68,26 @@ namespace dxvk {
|
||||
|
||||
static VkLogicOp DecodeLogicOp(
|
||||
D3D11_LOGIC_OP LogicOp);
|
||||
|
||||
|
||||
static bool ValidateBlendFactor(
|
||||
D3D11_BLEND Blend);
|
||||
|
||||
static bool ValidateBlendFactorAlpha(
|
||||
D3D11_BLEND BlendAlpha);
|
||||
|
||||
static bool ValidateBlendOp(
|
||||
D3D11_BLEND_OP BlendOp);
|
||||
|
||||
static bool ValidateLogicOp(
|
||||
D3D11_LOGIC_OP LogicOp);
|
||||
|
||||
static bool ValidateBlendOperations(
|
||||
D3D11_BLEND SrcBlend,
|
||||
D3D11_BLEND SrcBlendAlpha,
|
||||
D3D11_BLEND SestBlend,
|
||||
D3D11_BLEND DestBlendAlpha,
|
||||
D3D11_BLEND_OP BlendOp,
|
||||
D3D11_BLEND_OP BlendOpAlpha);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -50,8 +50,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11DepthStencilState::BindToContext(
|
||||
const Rc<DxvkContext>& ctx) {
|
||||
void D3D11DepthStencilState::BindToContext(const Rc<DxvkContext>& ctx) {
|
||||
ctx->setDepthStencilState(m_state);
|
||||
}
|
||||
|
||||
@ -77,8 +76,42 @@ namespace dxvk {
|
||||
|
||||
|
||||
HRESULT D3D11DepthStencilState::NormalizeDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) {
|
||||
// TODO validate
|
||||
// TODO clear unused values
|
||||
const D3D11_DEPTH_STENCIL_DESC defaultDesc = DefaultDesc();
|
||||
|
||||
if (pDesc->DepthEnable) {
|
||||
pDesc->DepthEnable = TRUE;
|
||||
|
||||
if (!ValidateDepthFunc(pDesc->DepthFunc))
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
pDesc->DepthFunc = defaultDesc.DepthFunc;
|
||||
pDesc->DepthWriteMask = defaultDesc.DepthWriteMask;
|
||||
}
|
||||
|
||||
if (!ValidateDepthWriteMask(pDesc->DepthWriteMask))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (pDesc->StencilEnable) {
|
||||
pDesc->StencilEnable = TRUE;
|
||||
|
||||
if (!ValidateStencilFunc(pDesc->FrontFace.StencilFunc)
|
||||
|| !ValidateStencilOp(pDesc->FrontFace.StencilFailOp)
|
||||
|| !ValidateStencilOp(pDesc->FrontFace.StencilDepthFailOp)
|
||||
|| !ValidateStencilOp(pDesc->FrontFace.StencilPassOp))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!ValidateStencilFunc(pDesc->BackFace.StencilFunc)
|
||||
|| !ValidateStencilOp(pDesc->BackFace.StencilFailOp)
|
||||
|| !ValidateStencilOp(pDesc->BackFace.StencilDepthFailOp)
|
||||
|| !ValidateStencilOp(pDesc->BackFace.StencilPassOp))
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
pDesc->FrontFace = defaultDesc.FrontFace;
|
||||
pDesc->BackFace = defaultDesc.BackFace;
|
||||
pDesc->StencilReadMask = defaultDesc.StencilReadMask;
|
||||
pDesc->StencilWriteMask = defaultDesc.StencilWriteMask;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -116,11 +149,32 @@ namespace dxvk {
|
||||
case D3D11_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT;
|
||||
case D3D11_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
|
||||
case D3D11_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
|
||||
default: return VK_STENCIL_OP_KEEP;
|
||||
}
|
||||
|
||||
if (Op != 0)
|
||||
Logger::err(str::format("D3D11: Invalid stencil op: ", Op));
|
||||
return VK_STENCIL_OP_KEEP;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11DepthStencilState::ValidateDepthFunc(D3D11_COMPARISON_FUNC Comparison) {
|
||||
return Comparison >= D3D11_COMPARISON_NEVER
|
||||
&& Comparison <= D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11DepthStencilState::ValidateStencilFunc(D3D11_COMPARISON_FUNC Comparison) {
|
||||
return Comparison >= D3D11_COMPARISON_NEVER
|
||||
&& Comparison <= D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11DepthStencilState::ValidateStencilOp(D3D11_STENCIL_OP StencilOp) {
|
||||
return StencilOp >= D3D11_STENCIL_OP_KEEP
|
||||
&& StencilOp <= D3D11_STENCIL_OP_DECR;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11DepthStencilState::ValidateDepthWriteMask(D3D11_DEPTH_WRITE_MASK Mask) {
|
||||
return Mask == D3D11_DEPTH_WRITE_MASK_ZERO
|
||||
|| Mask == D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ namespace dxvk {
|
||||
|
||||
static HRESULT NormalizeDesc(
|
||||
D3D11_DEPTH_STENCIL_DESC* pDesc);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -51,6 +53,17 @@ namespace dxvk {
|
||||
VkStencilOp DecodeStencilOp(
|
||||
D3D11_STENCIL_OP Op) const;
|
||||
|
||||
static bool ValidateDepthFunc(
|
||||
D3D11_COMPARISON_FUNC Comparison);
|
||||
|
||||
static bool ValidateStencilFunc(
|
||||
D3D11_COMPARISON_FUNC Comparison);
|
||||
|
||||
static bool ValidateStencilOp(
|
||||
D3D11_STENCIL_OP StencilOp);
|
||||
|
||||
static bool ValidateDepthWriteMask(
|
||||
D3D11_DEPTH_WRITE_MASK Mask);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace dxvk {
|
||||
: m_device(device), m_desc(desc) {
|
||||
|
||||
// State that is not supported in D3D11
|
||||
m_state.enableDiscard = VK_FALSE;
|
||||
m_state.enableDiscard = VK_FALSE;
|
||||
|
||||
// Polygon mode. Determines whether the rasterizer fills
|
||||
// a polygon or renders lines connecting the vertices.
|
||||
@ -151,7 +151,34 @@ namespace dxvk {
|
||||
|
||||
HRESULT D3D11RasterizerState::NormalizeDesc(
|
||||
D3D11_RASTERIZER_DESC1* pDesc) {
|
||||
// TODO validate
|
||||
if (pDesc->FillMode < D3D11_FILL_WIREFRAME
|
||||
|| pDesc->FillMode > D3D11_FILL_SOLID)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (pDesc->CullMode < D3D11_CULL_NONE
|
||||
|| pDesc->CullMode > D3D11_CULL_BACK)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (pDesc->FrontCounterClockwise)
|
||||
pDesc->FrontCounterClockwise = TRUE;
|
||||
|
||||
if (pDesc->DepthClipEnable)
|
||||
pDesc->DepthClipEnable = TRUE;
|
||||
|
||||
if (pDesc->ScissorEnable)
|
||||
pDesc->ScissorEnable = TRUE;
|
||||
|
||||
if (pDesc->MultisampleEnable)
|
||||
pDesc->MultisampleEnable = TRUE;
|
||||
|
||||
if (pDesc->AntialiasedLineEnable)
|
||||
pDesc->AntialiasedLineEnable = TRUE;
|
||||
|
||||
if (pDesc->ForcedSampleCount != 0) {
|
||||
if (FAILED(DecodeSampleCount(pDesc->ForcedSampleCount, nullptr)))
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -82,11 +82,58 @@ namespace dxvk {
|
||||
const uint32_t filterBits = static_cast<uint32_t>(pDesc->Filter);
|
||||
|
||||
if (filterBits & 0xFFFFFF2A) {
|
||||
Logger::err(str::format("D3D11SamplerState: Unhandled filter: ", filterBits));
|
||||
Logger::err(str::format(
|
||||
"D3D11SamplerState: Unhandled filter: ", filterBits));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (filterBits & 0x40 /* anisotropic */) {
|
||||
if (pDesc->MaxAnisotropy < 1
|
||||
|| pDesc->MaxAnisotropy > 16)
|
||||
return E_INVALIDARG;
|
||||
} else if (pDesc->MaxAnisotropy < 0
|
||||
|| pDesc->MaxAnisotropy > 16) {
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
// Reset anisotropy if it is not used
|
||||
pDesc->MaxAnisotropy = 0;
|
||||
}
|
||||
|
||||
if (filterBits & 0x80 /* compare-to-depth */) {
|
||||
if (!ValidateComparisonFunc(pDesc->ComparisonFunc))
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
// Reset compare func if it is not used
|
||||
pDesc->ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
}
|
||||
|
||||
if (!ValidateAddressMode(pDesc->AddressU)
|
||||
|| !ValidateAddressMode(pDesc->AddressV)
|
||||
|| !ValidateAddressMode(pDesc->AddressW))
|
||||
return E_INVALIDARG;
|
||||
|
||||
// Clear BorderColor to 0 if none of the address
|
||||
// modes are D3D11_TEXTURE_ADDRESS_BORDER
|
||||
if (pDesc->AddressU != D3D11_TEXTURE_ADDRESS_BORDER
|
||||
&& pDesc->AddressV != D3D11_TEXTURE_ADDRESS_BORDER
|
||||
&& pDesc->AddressW != D3D11_TEXTURE_ADDRESS_BORDER) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
pDesc->BorderColor[i] = 0.0f;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11SamplerState::ValidateAddressMode(D3D11_TEXTURE_ADDRESS_MODE Mode) {
|
||||
return Mode >= D3D11_TEXTURE_ADDRESS_WRAP
|
||||
&& Mode <= D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
|
||||
}
|
||||
|
||||
|
||||
bool D3D11SamplerState::ValidateComparisonFunc(D3D11_COMPARISON_FUNC Comparison) {
|
||||
return Comparison >= D3D11_COMPARISON_NEVER
|
||||
&& Comparison <= D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,12 @@ namespace dxvk {
|
||||
D3D11Device* const m_device;
|
||||
D3D11_SAMPLER_DESC m_desc;
|
||||
Rc<DxvkSampler> m_sampler;
|
||||
|
||||
static bool ValidateAddressMode(
|
||||
D3D11_TEXTURE_ADDRESS_MODE Mode);
|
||||
|
||||
static bool ValidateComparisonFunc(
|
||||
D3D11_COMPARISON_FUNC Comparison);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user