1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxvk] Use packed blend state

This commit is contained in:
Philip Rebohle 2019-10-07 13:09:10 +02:00
parent 079b480602
commit b2087b2e7e
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 211 additions and 40 deletions

View File

@ -2320,8 +2320,9 @@ namespace dxvk {
void DxvkContext::setLogicOpState(const DxvkLogicOpState& lo) { void DxvkContext::setLogicOpState(const DxvkLogicOpState& lo) {
m_state.gp.state.omEnableLogicOp = lo.enableLogicOp; m_state.gp.state.om = DxvkOmInfo(
m_state.gp.state.omLogicOp = lo.logicOp; lo.enableLogicOp,
lo.logicOp);
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
} }
@ -2330,14 +2331,15 @@ namespace dxvk {
void DxvkContext::setBlendMode( void DxvkContext::setBlendMode(
uint32_t attachment, uint32_t attachment,
const DxvkBlendMode& blendMode) { const DxvkBlendMode& blendMode) {
m_state.gp.state.omBlendAttachments[attachment].blendEnable = blendMode.enableBlending; m_state.gp.state.omBlend[attachment] = DxvkOmAttachmentBlend(
m_state.gp.state.omBlendAttachments[attachment].srcColorBlendFactor = blendMode.colorSrcFactor; blendMode.enableBlending,
m_state.gp.state.omBlendAttachments[attachment].dstColorBlendFactor = blendMode.colorDstFactor; blendMode.colorSrcFactor,
m_state.gp.state.omBlendAttachments[attachment].colorBlendOp = blendMode.colorBlendOp; blendMode.colorDstFactor,
m_state.gp.state.omBlendAttachments[attachment].srcAlphaBlendFactor = blendMode.alphaSrcFactor; blendMode.colorBlendOp,
m_state.gp.state.omBlendAttachments[attachment].dstAlphaBlendFactor = blendMode.alphaDstFactor; blendMode.alphaSrcFactor,
m_state.gp.state.omBlendAttachments[attachment].alphaBlendOp = blendMode.alphaBlendOp; blendMode.alphaDstFactor,
m_state.gp.state.omBlendAttachments[attachment].colorWriteMask = blendMode.writeMask; blendMode.alphaBlendOp,
blendMode.writeMask);
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
} }
@ -3984,9 +3986,11 @@ namespace dxvk {
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
Rc<DxvkImageView> attachment = fb->getColorTarget(i).view; Rc<DxvkImageView> attachment = fb->getColorTarget(i).view;
m_state.gp.state.omComponentMapping[i] = attachment != nullptr VkComponentMapping mapping = attachment != nullptr
? util::invertComponentMapping(attachment->info().swizzle) ? util::invertComponentMapping(attachment->info().swizzle)
: VkComponentMapping(); : VkComponentMapping();
m_state.gp.state.omSwizzle[i] = DxvkOmAttachmentSwizzle(mapping);
} }
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);

View File

@ -173,10 +173,10 @@ namespace dxvk {
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if ((m_fsOut & (1 << i)) != 0) { if ((m_fsOut & (1 << i)) != 0) {
uint32_t specId = uint32_t(DxvkSpecConstantId::ColorComponentMappings) + 4 * i; uint32_t specId = uint32_t(DxvkSpecConstantId::ColorComponentMappings) + 4 * i;
specData.set(specId + 0, util::getComponentIndex(state.omComponentMapping[i].r, 0), 0u); specData.set(specId + 0, state.omSwizzle[i].rIndex(), 0u);
specData.set(specId + 1, util::getComponentIndex(state.omComponentMapping[i].g, 1), 1u); specData.set(specId + 1, state.omSwizzle[i].gIndex(), 1u);
specData.set(specId + 2, util::getComponentIndex(state.omComponentMapping[i].b, 2), 2u); specData.set(specId + 2, state.omSwizzle[i].bIndex(), 2u);
specData.set(specId + 3, util::getComponentIndex(state.omComponentMapping[i].a, 3), 3u); specData.set(specId + 3, state.omSwizzle[i].aIndex(), 3u);
} }
} }
@ -186,11 +186,11 @@ namespace dxvk {
VkSpecializationInfo specInfo = specData.getSpecInfo(); VkSpecializationInfo specInfo = specData.getSpecInfo();
DxvkShaderModuleCreateInfo moduleInfo; DxvkShaderModuleCreateInfo moduleInfo;
moduleInfo.fsDualSrcBlend = state.omBlendAttachments[0].blendEnable && ( moduleInfo.fsDualSrcBlend = state.omBlend[0].blendEnable() && (
util::isDualSourceBlendFactor(state.omBlendAttachments[0].srcColorBlendFactor) || util::isDualSourceBlendFactor(state.omBlend[0].srcColorBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].dstColorBlendFactor) || util::isDualSourceBlendFactor(state.omBlend[0].dstColorBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].srcAlphaBlendFactor) || util::isDualSourceBlendFactor(state.omBlend[0].srcAlphaBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].dstAlphaBlendFactor)); util::isDualSourceBlendFactor(state.omBlend[0].dstAlphaBlendFactor()));
auto vsm = createShaderModule(m_shaders.vs, moduleInfo); auto vsm = createShaderModule(m_shaders.vs, moduleInfo);
auto gsm = createShaderModule(m_shaders.gs, moduleInfo); auto gsm = createShaderModule(m_shaders.gs, moduleInfo);
@ -213,15 +213,11 @@ namespace dxvk {
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
omBlendAttachments[i] = state.omBlendAttachments[i]; omBlendAttachments[i] = state.omBlend[i].state();
if (state.omBlendAttachments[i].colorWriteMask == fullMask) { if (omBlendAttachments[i].colorWriteMask != fullMask) {
// Avoid unnecessary partial color write masks
omBlendAttachments[i].colorWriteMask = fullMask;
} else {
omBlendAttachments[i].colorWriteMask = util::remapComponentMask( omBlendAttachments[i].colorWriteMask = util::remapComponentMask(
state.omBlendAttachments[i].colorWriteMask, state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping());
state.omComponentMapping[i]);
} }
if ((m_fsOut & (1 << i)) == 0) if ((m_fsOut & (1 << i)) == 0)
@ -372,8 +368,8 @@ namespace dxvk {
cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
cbInfo.pNext = nullptr; cbInfo.pNext = nullptr;
cbInfo.flags = 0; cbInfo.flags = 0;
cbInfo.logicOpEnable = state.omEnableLogicOp; cbInfo.logicOpEnable = state.om.enableLogicOp();
cbInfo.logicOp = state.omLogicOp; cbInfo.logicOp = state.om.logicOp();
cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets; cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets;
cbInfo.pAttachments = omBlendAttachments.data(); cbInfo.pAttachments = omBlendAttachments.data();

View File

@ -436,6 +436,179 @@ namespace dxvk {
}; };
/**
* \brief Packed output merger metadata
*
* Stores the logic op state in two bytes.
* Blend modes are stored separately.
*/
class DxvkOmInfo {
public:
DxvkOmInfo() = default;
DxvkOmInfo(
VkBool32 enableLogicOp,
VkLogicOp logicOp)
: m_enableLogicOp (uint16_t(enableLogicOp)),
m_logicOp (uint16_t(logicOp)),
m_reserved (0) { }
VkBool32 enableLogicOp() const {
return VkBool32(m_enableLogicOp);
}
VkLogicOp logicOp() const {
return VkLogicOp(m_logicOp);
}
private:
uint16_t m_enableLogicOp : 1;
uint16_t m_logicOp : 4;
uint16_t m_reserved : 11;
};
/**
* \brief Packed attachment blend mode
*
* Stores blendig parameters for a single
* color attachment in four bytes.
*/
class DxvkOmAttachmentBlend {
public:
DxvkOmAttachmentBlend() = default;
DxvkOmAttachmentBlend(
VkBool32 blendEnable,
VkBlendFactor srcColorBlendFactor,
VkBlendFactor dstColorBlendFactor,
VkBlendOp colorBlendOp,
VkBlendFactor srcAlphaBlendFactor,
VkBlendFactor dstAlphaBlendFactor,
VkBlendOp alphaBlendOp,
VkColorComponentFlags colorWriteMask)
: m_blendEnable (uint32_t(blendEnable)),
m_srcColorBlendFactor (uint32_t(srcColorBlendFactor)),
m_dstColorBlendFactor (uint32_t(dstColorBlendFactor)),
m_colorBlendOp (uint32_t(colorBlendOp)),
m_srcAlphaBlendFactor (uint32_t(srcAlphaBlendFactor)),
m_dstAlphaBlendFactor (uint32_t(dstAlphaBlendFactor)),
m_alphaBlendOp (uint32_t(alphaBlendOp)),
m_colorWriteMask (uint32_t(colorWriteMask)),
m_reserved (0) { }
VkBool32 blendEnable() const {
return m_blendEnable;
}
VkBlendFactor srcColorBlendFactor() const {
return VkBlendFactor(m_srcColorBlendFactor);
}
VkBlendFactor dstColorBlendFactor() const {
return VkBlendFactor(m_dstColorBlendFactor);
}
VkBlendOp colorBlendOp() const {
return VkBlendOp(m_colorBlendOp);
}
VkBlendFactor srcAlphaBlendFactor() const {
return VkBlendFactor(m_srcAlphaBlendFactor);
}
VkBlendFactor dstAlphaBlendFactor() const {
return VkBlendFactor(m_dstAlphaBlendFactor);
}
VkBlendOp alphaBlendOp() const {
return VkBlendOp(m_alphaBlendOp);
}
VkColorComponentFlags colorWriteMask() const {
return VkColorComponentFlags(m_colorWriteMask);
}
VkPipelineColorBlendAttachmentState state() const {
VkPipelineColorBlendAttachmentState result;
result.blendEnable = VkBool32(m_blendEnable);
result.srcColorBlendFactor = VkBlendFactor(m_srcColorBlendFactor);
result.dstColorBlendFactor = VkBlendFactor(m_dstColorBlendFactor);
result.colorBlendOp = VkBlendOp(m_colorBlendOp);
result.srcAlphaBlendFactor = VkBlendFactor(m_srcAlphaBlendFactor);
result.dstAlphaBlendFactor = VkBlendFactor(m_dstAlphaBlendFactor);
result.alphaBlendOp = VkBlendOp(m_alphaBlendOp);
result.colorWriteMask = VkColorComponentFlags(m_colorWriteMask);
return result;
}
private:
uint32_t m_blendEnable : 1;
uint32_t m_srcColorBlendFactor : 5;
uint32_t m_dstColorBlendFactor : 5;
uint32_t m_colorBlendOp : 3;
uint32_t m_srcAlphaBlendFactor : 5;
uint32_t m_dstAlphaBlendFactor : 5;
uint32_t m_alphaBlendOp : 3;
uint32_t m_colorWriteMask : 4;
uint32_t m_reserved : 1;
};
/**
* \brief Packed attachment swizzle
*
* Stores the component mapping for one
* single color attachment in one byte.
*/
class DxvkOmAttachmentSwizzle {
public:
DxvkOmAttachmentSwizzle() = default;
DxvkOmAttachmentSwizzle(VkComponentMapping mapping)
: m_r(util::getComponentIndex(mapping.r, 0)),
m_g(util::getComponentIndex(mapping.g, 1)),
m_b(util::getComponentIndex(mapping.b, 2)),
m_a(util::getComponentIndex(mapping.a, 3)) { }
uint32_t rIndex() const { return m_r; }
uint32_t gIndex() const { return m_g; }
uint32_t bIndex() const { return m_b; }
uint32_t aIndex() const { return m_a; }
VkComponentMapping mapping() const {
VkComponentMapping result;
result.r = decodeSwizzle(m_r);
result.g = decodeSwizzle(m_g);
result.b = decodeSwizzle(m_b);
result.a = decodeSwizzle(m_a);
return result;
}
private:
uint8_t m_r : 2;
uint8_t m_g : 2;
uint8_t m_b : 2;
uint8_t m_a : 2;
static VkComponentSwizzle decodeSwizzle(uint8_t swizzle) {
return VkComponentSwizzle(uint32_t(swizzle) + uint32_t(VK_COMPONENT_SWIZZLE_R));
}
};
/** /**
* \brief Packed graphics pipeline state * \brief Packed graphics pipeline state
* *
@ -481,11 +654,11 @@ namespace dxvk {
bool result = false; bool result = false;
for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) {
result |= omBlendAttachments[i].blendEnable result |= omBlend[i].blendEnable()
&& (util::isBlendConstantBlendFactor(omBlendAttachments[i].srcColorBlendFactor) && (util::isBlendConstantBlendFactor(omBlend[i].srcColorBlendFactor())
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstColorBlendFactor) || util::isBlendConstantBlendFactor(omBlend[i].dstColorBlendFactor())
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].srcAlphaBlendFactor) || util::isBlendConstantBlendFactor(omBlend[i].srcAlphaBlendFactor())
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstAlphaBlendFactor)); || util::isBlendConstantBlendFactor(omBlend[i].dstAlphaBlendFactor()));
} }
return result; return result;
@ -497,16 +670,14 @@ namespace dxvk {
DxvkRsInfo rs; DxvkRsInfo rs;
DxvkMsInfo ms; DxvkMsInfo ms;
DxvkDsInfo ds; DxvkDsInfo ds;
DxvkOmInfo om;
VkBool32 omEnableLogicOp;
VkLogicOp omLogicOp;
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
uint32_t scSpecConstants[MaxNumSpecConstants]; uint32_t scSpecConstants[MaxNumSpecConstants];
DxvkDsStencilOp dsFront; DxvkDsStencilOp dsFront;
DxvkDsStencilOp dsBack; DxvkDsStencilOp dsBack;
DxvkOmAttachmentSwizzle omSwizzle [DxvkLimits::MaxNumRenderTargets];
DxvkOmAttachmentBlend omBlend [DxvkLimits::MaxNumRenderTargets];
DxvkIlAttribute ilAttributes [DxvkLimits::MaxNumVertexAttributes]; DxvkIlAttribute ilAttributes [DxvkLimits::MaxNumVertexAttributes];
DxvkIlBinding ilBindings [DxvkLimits::MaxNumVertexBindings]; DxvkIlBinding ilBindings [DxvkLimits::MaxNumVertexBindings];
}; };