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

View File

@ -7,7 +7,7 @@
#include "dxvk_state_cache.h"
namespace dxvk {
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
DxvkPipelineManager* pipeMgr,
DxvkGraphicsPipelineShaders shaders)
@ -173,10 +173,10 @@ namespace dxvk {
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if ((m_fsOut & (1 << i)) != 0) {
uint32_t specId = uint32_t(DxvkSpecConstantId::ColorComponentMappings) + 4 * i;
specData.set(specId + 0, util::getComponentIndex(state.omComponentMapping[i].r, 0), 0u);
specData.set(specId + 1, util::getComponentIndex(state.omComponentMapping[i].g, 1), 1u);
specData.set(specId + 2, util::getComponentIndex(state.omComponentMapping[i].b, 2), 2u);
specData.set(specId + 3, util::getComponentIndex(state.omComponentMapping[i].a, 3), 3u);
specData.set(specId + 0, state.omSwizzle[i].rIndex(), 0u);
specData.set(specId + 1, state.omSwizzle[i].gIndex(), 1u);
specData.set(specId + 2, state.omSwizzle[i].bIndex(), 2u);
specData.set(specId + 3, state.omSwizzle[i].aIndex(), 3u);
}
}
@ -186,11 +186,11 @@ namespace dxvk {
VkSpecializationInfo specInfo = specData.getSpecInfo();
DxvkShaderModuleCreateInfo moduleInfo;
moduleInfo.fsDualSrcBlend = state.omBlendAttachments[0].blendEnable && (
util::isDualSourceBlendFactor(state.omBlendAttachments[0].srcColorBlendFactor) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].dstColorBlendFactor) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].srcAlphaBlendFactor) ||
util::isDualSourceBlendFactor(state.omBlendAttachments[0].dstAlphaBlendFactor));
moduleInfo.fsDualSrcBlend = state.omBlend[0].blendEnable() && (
util::isDualSourceBlendFactor(state.omBlend[0].srcColorBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlend[0].dstColorBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlend[0].srcAlphaBlendFactor()) ||
util::isDualSourceBlendFactor(state.omBlend[0].dstAlphaBlendFactor()));
auto vsm = createShaderModule(m_shaders.vs, moduleInfo);
auto gsm = createShaderModule(m_shaders.gs, moduleInfo);
@ -213,15 +213,11 @@ namespace dxvk {
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
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) {
// Avoid unnecessary partial color write masks
omBlendAttachments[i].colorWriteMask = fullMask;
} else {
if (omBlendAttachments[i].colorWriteMask != fullMask) {
omBlendAttachments[i].colorWriteMask = util::remapComponentMask(
state.omBlendAttachments[i].colorWriteMask,
state.omComponentMapping[i]);
state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping());
}
if ((m_fsOut & (1 << i)) == 0)
@ -372,8 +368,8 @@ namespace dxvk {
cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
cbInfo.pNext = nullptr;
cbInfo.flags = 0;
cbInfo.logicOpEnable = state.omEnableLogicOp;
cbInfo.logicOp = state.omLogicOp;
cbInfo.logicOpEnable = state.om.enableLogicOp();
cbInfo.logicOp = state.om.logicOp();
cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets;
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
*
@ -481,11 +654,11 @@ namespace dxvk {
bool result = false;
for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) {
result |= omBlendAttachments[i].blendEnable
&& (util::isBlendConstantBlendFactor(omBlendAttachments[i].srcColorBlendFactor)
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstColorBlendFactor)
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].srcAlphaBlendFactor)
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstAlphaBlendFactor));
result |= omBlend[i].blendEnable()
&& (util::isBlendConstantBlendFactor(omBlend[i].srcColorBlendFactor())
|| util::isBlendConstantBlendFactor(omBlend[i].dstColorBlendFactor())
|| util::isBlendConstantBlendFactor(omBlend[i].srcAlphaBlendFactor())
|| util::isBlendConstantBlendFactor(omBlend[i].dstAlphaBlendFactor()));
}
return result;
@ -497,16 +670,14 @@ namespace dxvk {
DxvkRsInfo rs;
DxvkMsInfo ms;
DxvkDsInfo ds;
DxvkOmInfo om;
VkBool32 omEnableLogicOp;
VkLogicOp omLogicOp;
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
uint32_t scSpecConstants[MaxNumSpecConstants];
DxvkDsStencilOp dsFront;
DxvkDsStencilOp dsBack;
DxvkOmAttachmentSwizzle omSwizzle [DxvkLimits::MaxNumRenderTargets];
DxvkOmAttachmentBlend omBlend [DxvkLimits::MaxNumRenderTargets];
DxvkIlAttribute ilAttributes [DxvkLimits::MaxNumVertexAttributes];
DxvkIlBinding ilBindings [DxvkLimits::MaxNumVertexBindings];
};