mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-28 02:19:26 +01:00
[dxvk,d3d9,d3d11] Refactor blend state object
This commit is contained in:
parent
4a5c50b2de
commit
e25f9db61b
@ -12,7 +12,7 @@ namespace dxvk {
|
||||
// blend modes for render target 1 to 7. In Vulkan, all
|
||||
// blend modes need to be identical in that case.
|
||||
for (uint32_t i = 0; i < m_blendModes.size(); i++) {
|
||||
m_blendModes.at(i) = DecodeBlendMode(
|
||||
m_blendModes[i] = DecodeBlendMode(
|
||||
desc.IndependentBlendEnable
|
||||
? desc.RenderTarget[i]
|
||||
: desc.RenderTarget[0]);
|
||||
@ -89,16 +89,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D11BlendState::BindToContext(
|
||||
DxvkContext* ctx) const {
|
||||
// We handled Independent Blend during object creation
|
||||
// already, so if it is disabled, all elements in the
|
||||
// blend mode array will be identical
|
||||
for (uint32_t i = 0; i < m_blendModes.size(); i++)
|
||||
ctx->setBlendMode(i, m_blendModes.at(i));
|
||||
}
|
||||
|
||||
|
||||
D3D11_BLEND_DESC1 D3D11BlendState::PromoteDesc(const D3D11_BLEND_DESC* pSrcDesc) {
|
||||
D3D11_BLEND_DESC1 dstDesc;
|
||||
dstDesc.AlphaToCoverageEnable = pSrcDesc->AlphaToCoverageEnable;
|
||||
@ -183,15 +173,15 @@ namespace dxvk {
|
||||
|
||||
DxvkBlendMode D3D11BlendState::DecodeBlendMode(
|
||||
const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc) {
|
||||
DxvkBlendMode mode;
|
||||
mode.enableBlending = BlendDesc.BlendEnable;
|
||||
mode.colorSrcFactor = DecodeBlendFactor(BlendDesc.SrcBlend, false);
|
||||
mode.colorDstFactor = DecodeBlendFactor(BlendDesc.DestBlend, false);
|
||||
mode.colorBlendOp = DecodeBlendOp(BlendDesc.BlendOp);
|
||||
mode.alphaSrcFactor = DecodeBlendFactor(BlendDesc.SrcBlendAlpha, true);
|
||||
mode.alphaDstFactor = DecodeBlendFactor(BlendDesc.DestBlendAlpha, true);
|
||||
mode.alphaBlendOp = DecodeBlendOp(BlendDesc.BlendOpAlpha);
|
||||
mode.writeMask = BlendDesc.RenderTargetWriteMask;
|
||||
DxvkBlendMode mode = { };
|
||||
mode.setBlendEnable(BlendDesc.BlendEnable);
|
||||
mode.setColorOp(DecodeBlendFactor(BlendDesc.SrcBlend, false),
|
||||
DecodeBlendFactor(BlendDesc.DestBlend, false),
|
||||
DecodeBlendOp(BlendDesc.BlendOp));
|
||||
mode.setAlphaOp(DecodeBlendFactor(BlendDesc.SrcBlendAlpha, true),
|
||||
DecodeBlendFactor(BlendDesc.DestBlendAlpha, true),
|
||||
DecodeBlendOp(BlendDesc.BlendOpAlpha));
|
||||
mode.setWriteMask(BlendDesc.RenderTargetWriteMask);
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,10 @@ namespace dxvk {
|
||||
return m_loState;
|
||||
}
|
||||
|
||||
void BindToContext(
|
||||
DxvkContext* ctx) const;
|
||||
|
||||
std::array<DxvkBlendMode, 8> GetBlendState() const {
|
||||
return m_blendModes;
|
||||
}
|
||||
|
||||
D3D10BlendState* GetD3D10Iface() {
|
||||
return &m_d3d10;
|
||||
}
|
||||
@ -59,7 +60,7 @@ namespace dxvk {
|
||||
|
||||
D3D11_BLEND_DESC1 m_desc;
|
||||
|
||||
std::array<DxvkBlendMode, 8> m_blendModes;
|
||||
std::array<DxvkBlendMode, 8> m_blendModes = { };
|
||||
DxvkMultisampleState m_msState = { };
|
||||
DxvkLogicOpState m_loState = { };
|
||||
|
||||
|
@ -3370,11 +3370,12 @@ namespace dxvk {
|
||||
void D3D11CommonContext<ContextType>::ApplyBlendState() {
|
||||
if (m_state.om.cbState != nullptr) {
|
||||
EmitCs([
|
||||
cBlendState = m_state.om.cbState,
|
||||
cBlendState = m_state.om.cbState->GetBlendState(),
|
||||
cMsState = m_state.om.cbState->GetMsState(m_state.om.sampleMask),
|
||||
cLoState = m_state.om.cbState->GetLoState()
|
||||
] (DxvkContext* ctx) {
|
||||
cBlendState->BindToContext(ctx);
|
||||
for (uint32_t i = 0; i < cBlendState.size(); i++)
|
||||
ctx->setBlendMode(i, cBlendState[i]);
|
||||
|
||||
ctx->setMultisampleState(cMsState);
|
||||
ctx->setLogicOpState(cLoState);
|
||||
@ -3383,8 +3384,7 @@ namespace dxvk {
|
||||
EmitCs([
|
||||
cSampleMask = m_state.om.sampleMask
|
||||
] (DxvkContext* ctx) {
|
||||
DxvkBlendMode cbState;
|
||||
InitDefaultBlendState(&cbState);
|
||||
DxvkBlendMode cbState = InitDefaultBlendState();
|
||||
|
||||
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
ctx->setBlendMode(i, cbState);
|
||||
@ -4730,15 +4730,14 @@ namespace dxvk {
|
||||
DxvkRasterizerState rsState;
|
||||
InitDefaultRasterizerState(&rsState);
|
||||
|
||||
DxvkBlendMode cbState;
|
||||
InitDefaultBlendState(&cbState);
|
||||
|
||||
ctx->setInputAssemblyState(iaState);
|
||||
ctx->setDepthStencilState(InitDefaultDepthStencilState());
|
||||
ctx->setRasterizerState(rsState);
|
||||
ctx->setLogicOpState(InitDefaultLogicOpState());
|
||||
ctx->setMultisampleState(InitDefaultMultisampleState(D3D11_DEFAULT_SAMPLE_MASK));
|
||||
|
||||
DxvkBlendMode cbState = InitDefaultBlendState();
|
||||
|
||||
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
ctx->setBlendMode(i, cbState);
|
||||
|
||||
@ -5830,17 +5829,14 @@ namespace dxvk {
|
||||
|
||||
|
||||
template<typename ContextType>
|
||||
void D3D11CommonContext<ContextType>::InitDefaultBlendState(
|
||||
DxvkBlendMode* pCbState) {
|
||||
pCbState->enableBlending = VK_FALSE;
|
||||
pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE;
|
||||
pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO;
|
||||
pCbState->colorBlendOp = VK_BLEND_OP_ADD;
|
||||
pCbState->alphaSrcFactor = VK_BLEND_FACTOR_ONE;
|
||||
pCbState->alphaDstFactor = VK_BLEND_FACTOR_ZERO;
|
||||
pCbState->alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
pCbState->writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
DxvkBlendMode D3D11CommonContext<ContextType>::InitDefaultBlendState() {
|
||||
DxvkBlendMode cbState = { };
|
||||
cbState.setBlendEnable(false);
|
||||
cbState.setColorOp(VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD);
|
||||
cbState.setAlphaOp(VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD);
|
||||
cbState.setWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
||||
return cbState;
|
||||
}
|
||||
|
||||
// Explicitly instantiate here
|
||||
|
@ -1156,8 +1156,7 @@ namespace dxvk {
|
||||
|
||||
static DxvkLogicOpState InitDefaultLogicOpState();
|
||||
|
||||
static void InitDefaultBlendState(
|
||||
DxvkBlendMode* pCbState);
|
||||
static DxvkBlendMode InitDefaultBlendState();
|
||||
|
||||
template<bool AllowFlush = true, typename Cmd>
|
||||
void EmitCs(Cmd&& command) {
|
||||
|
@ -6821,71 +6821,64 @@ namespace dxvk {
|
||||
|
||||
auto& state = m_state.renderStates;
|
||||
|
||||
bool separateAlpha = state[D3DRS_SEPARATEALPHABLENDENABLE];
|
||||
DxvkBlendMode mode = { };
|
||||
mode.setBlendEnable(state[D3DRS_ALPHABLENDENABLE]);
|
||||
|
||||
DxvkBlendMode mode;
|
||||
mode.enableBlending = state[D3DRS_ALPHABLENDENABLE] != FALSE;
|
||||
|
||||
D3D9BlendState color, alpha;
|
||||
D3D9BlendState color = { };
|
||||
|
||||
color.Src = D3DBLEND(state[D3DRS_SRCBLEND]);
|
||||
color.Dst = D3DBLEND(state[D3DRS_DESTBLEND]);
|
||||
color.Op = D3DBLENDOP(state[D3DRS_BLENDOP]);
|
||||
FixupBlendState(color);
|
||||
|
||||
if (separateAlpha) {
|
||||
D3D9BlendState alpha = color;
|
||||
|
||||
if (state[D3DRS_SEPARATEALPHABLENDENABLE]) {
|
||||
alpha.Src = D3DBLEND(state[D3DRS_SRCBLENDALPHA]);
|
||||
alpha.Dst = D3DBLEND(state[D3DRS_DESTBLENDALPHA]);
|
||||
alpha.Op = D3DBLENDOP(state[D3DRS_BLENDOPALPHA]);
|
||||
FixupBlendState(alpha);
|
||||
}
|
||||
else
|
||||
alpha = color;
|
||||
|
||||
mode.colorSrcFactor = DecodeBlendFactor(color.Src, false);
|
||||
mode.colorDstFactor = DecodeBlendFactor(color.Dst, false);
|
||||
mode.colorBlendOp = DecodeBlendOp (color.Op);
|
||||
mode.setColorOp(DecodeBlendFactor(color.Src, false),
|
||||
DecodeBlendFactor(color.Dst, false),
|
||||
DecodeBlendOp(color.Op));
|
||||
|
||||
mode.alphaSrcFactor = DecodeBlendFactor(alpha.Src, true);
|
||||
mode.alphaDstFactor = DecodeBlendFactor(alpha.Dst, true);
|
||||
mode.alphaBlendOp = DecodeBlendOp (alpha.Op);
|
||||
mode.setAlphaOp(DecodeBlendFactor(alpha.Src, true),
|
||||
DecodeBlendFactor(alpha.Dst, true),
|
||||
DecodeBlendOp(alpha.Op));
|
||||
|
||||
mode.writeMask = state[ColorWriteIndex(0)];
|
||||
uint16_t writeMasks = 0;
|
||||
|
||||
std::array<VkColorComponentFlags, 3> extraWriteMasks;
|
||||
for (uint32_t i = 0; i < 3; i++)
|
||||
extraWriteMasks[i] = state[ColorWriteIndex(i + 1)];
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
writeMasks |= (state[ColorWriteIndex(i)] & 0xfu) << (4u * i);
|
||||
|
||||
EmitCs([
|
||||
cMode = mode,
|
||||
cWriteMasks = extraWriteMasks,
|
||||
cWriteMasks = writeMasks,
|
||||
cAlphaMasks = m_alphaSwizzleRTs
|
||||
](DxvkContext* ctx) {
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
DxvkBlendMode mode = cMode;
|
||||
if (i != 0)
|
||||
mode.writeMask = cWriteMasks[i - 1];
|
||||
mode.setWriteMask(cWriteMasks >> (4u * i));
|
||||
|
||||
// Adjust the blend factor based on the render target alpha swizzle bit mask.
|
||||
// Specific formats such as the XRGB ones require a ONE swizzle for alpha
|
||||
// which cannot be directly applied with the image view of the attachment.
|
||||
const bool alphaSwizzle = cAlphaMasks & (1 << i);
|
||||
|
||||
auto NormalizeFactor = [alphaSwizzle](VkBlendFactor Factor) {
|
||||
if (alphaSwizzle) {
|
||||
if (cAlphaMasks & (1 << i)) {
|
||||
auto NormalizeFactor = [] (VkBlendFactor Factor) {
|
||||
if (Factor == VK_BLEND_FACTOR_DST_ALPHA)
|
||||
return VK_BLEND_FACTOR_ONE;
|
||||
else if (Factor == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA)
|
||||
return VK_BLEND_FACTOR_ZERO;
|
||||
}
|
||||
return Factor;
|
||||
};
|
||||
|
||||
return Factor;
|
||||
};
|
||||
|
||||
mode.colorSrcFactor = NormalizeFactor(mode.colorSrcFactor);
|
||||
mode.colorDstFactor = NormalizeFactor(mode.colorDstFactor);
|
||||
mode.alphaSrcFactor = NormalizeFactor(mode.alphaSrcFactor);
|
||||
mode.alphaDstFactor = NormalizeFactor(mode.alphaDstFactor);
|
||||
mode.setColorOp(NormalizeFactor(mode.colorSrcFactor()),
|
||||
NormalizeFactor(mode.colorDstFactor()), mode.colorBlendOp());
|
||||
mode.setAlphaOp(NormalizeFactor(mode.alphaSrcFactor()),
|
||||
NormalizeFactor(mode.alphaDstFactor()), mode.alphaBlendOp());
|
||||
}
|
||||
|
||||
ctx->setBlendMode(i, mode);
|
||||
}
|
||||
|
@ -344,15 +344,74 @@ namespace dxvk {
|
||||
* Stores the blend state for a single color attachment.
|
||||
* Blend modes can be set separately for each attachment.
|
||||
*/
|
||||
struct DxvkBlendMode {
|
||||
VkBool32 enableBlending;
|
||||
VkBlendFactor colorSrcFactor;
|
||||
VkBlendFactor colorDstFactor;
|
||||
VkBlendOp colorBlendOp;
|
||||
VkBlendFactor alphaSrcFactor;
|
||||
VkBlendFactor alphaDstFactor;
|
||||
VkBlendOp alphaBlendOp;
|
||||
VkColorComponentFlags writeMask;
|
||||
class DxvkBlendMode {
|
||||
|
||||
public:
|
||||
|
||||
bool blendEnable() const {
|
||||
return m_enableBlending;
|
||||
}
|
||||
|
||||
VkBlendFactor colorSrcFactor() const {
|
||||
return VkBlendFactor(m_colorSrcFactor);
|
||||
}
|
||||
|
||||
VkBlendFactor colorDstFactor() const {
|
||||
return VkBlendFactor(m_colorDstFactor);
|
||||
}
|
||||
|
||||
VkBlendOp colorBlendOp() const {
|
||||
return VkBlendOp(m_colorBlendOp);
|
||||
}
|
||||
|
||||
VkBlendFactor alphaSrcFactor() const {
|
||||
return VkBlendFactor(m_alphaSrcFactor);
|
||||
}
|
||||
|
||||
VkBlendFactor alphaDstFactor() const {
|
||||
return VkBlendFactor(m_alphaDstFactor);
|
||||
}
|
||||
|
||||
VkBlendOp alphaBlendOp() const {
|
||||
return VkBlendOp(m_alphaBlendOp);
|
||||
}
|
||||
|
||||
VkColorComponentFlags writeMask() const {
|
||||
return VkColorComponentFlags(m_writeMask);
|
||||
}
|
||||
|
||||
void setBlendEnable(bool enable) {
|
||||
m_enableBlending = enable;
|
||||
}
|
||||
|
||||
void setColorOp(VkBlendFactor srcFactor, VkBlendFactor dstFactor, VkBlendOp op) {
|
||||
m_colorSrcFactor = uint32_t(srcFactor);
|
||||
m_colorDstFactor = uint32_t(dstFactor);
|
||||
m_colorBlendOp = uint32_t(op);
|
||||
}
|
||||
|
||||
void setAlphaOp(VkBlendFactor srcFactor, VkBlendFactor dstFactor, VkBlendOp op) {
|
||||
m_alphaSrcFactor = uint32_t(srcFactor);
|
||||
m_alphaDstFactor = uint32_t(dstFactor);
|
||||
m_alphaBlendOp = uint32_t(op);
|
||||
}
|
||||
|
||||
void setWriteMask(VkColorComponentFlags writeMask) {
|
||||
m_writeMask = writeMask;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint32_t m_enableBlending : 1;
|
||||
uint32_t m_colorSrcFactor : 5;
|
||||
uint32_t m_colorDstFactor : 5;
|
||||
uint32_t m_colorBlendOp : 3;
|
||||
uint32_t m_alphaSrcFactor : 5;
|
||||
uint32_t m_alphaDstFactor : 5;
|
||||
uint32_t m_alphaBlendOp : 3;
|
||||
uint32_t m_writeMask : 4;
|
||||
uint32_t m_reserved : 1;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -2937,15 +2937,15 @@ namespace dxvk {
|
||||
uint32_t attachment,
|
||||
const DxvkBlendMode& blendMode) {
|
||||
m_state.gp.state.omBlend[attachment] = DxvkOmAttachmentBlend(
|
||||
blendMode.enableBlending,
|
||||
blendMode.colorSrcFactor,
|
||||
blendMode.colorDstFactor,
|
||||
blendMode.colorBlendOp,
|
||||
blendMode.alphaSrcFactor,
|
||||
blendMode.alphaDstFactor,
|
||||
blendMode.alphaBlendOp,
|
||||
blendMode.writeMask);
|
||||
|
||||
blendMode.blendEnable(),
|
||||
blendMode.colorSrcFactor(),
|
||||
blendMode.colorDstFactor(),
|
||||
blendMode.colorBlendOp(),
|
||||
blendMode.alphaSrcFactor(),
|
||||
blendMode.alphaDstFactor(),
|
||||
blendMode.alphaBlendOp(),
|
||||
blendMode.writeMask());
|
||||
|
||||
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user