mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
Measured to be over twice as fast as memcmp on Ryzen for the 512-byte graphics pipeline state struct, achieving two cycles per iteration.
724 lines
19 KiB
C++
724 lines
19 KiB
C++
#pragma once
|
|
|
|
#include "dxvk_limits.h"
|
|
|
|
#include <cstring>
|
|
|
|
namespace dxvk {
|
|
|
|
/**
|
|
* \brief Packed input assembly state
|
|
*
|
|
* Stores the primitive topology
|
|
* and primitive restart info.
|
|
*/
|
|
class DxvkIaInfo {
|
|
|
|
public:
|
|
|
|
DxvkIaInfo() = default;
|
|
|
|
DxvkIaInfo(
|
|
VkPrimitiveTopology primitiveTopology,
|
|
VkBool32 primitiveRestart,
|
|
uint32_t patchVertexCount)
|
|
: m_primitiveTopology (uint16_t(primitiveTopology)),
|
|
m_primitiveRestart (uint16_t(primitiveRestart)),
|
|
m_patchVertexCount (uint16_t(patchVertexCount)),
|
|
m_reserved (0) { }
|
|
|
|
VkPrimitiveTopology primitiveTopology() const {
|
|
return m_primitiveTopology <= VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
|
|
? VkPrimitiveTopology(m_primitiveTopology)
|
|
: VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
|
|
}
|
|
|
|
VkBool32 primitiveRestart() const {
|
|
return VkBool32(m_primitiveRestart);
|
|
}
|
|
|
|
uint32_t patchVertexCount() const {
|
|
return m_patchVertexCount;
|
|
}
|
|
|
|
private:
|
|
|
|
uint16_t m_primitiveTopology : 4;
|
|
uint16_t m_primitiveRestart : 1;
|
|
uint16_t m_patchVertexCount : 6;
|
|
uint16_t m_reserved : 5;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed input layout metadata
|
|
*
|
|
* Stores the number of vertex attributes
|
|
* and bindings in one byte each.
|
|
*/
|
|
class DxvkIlInfo {
|
|
|
|
public:
|
|
|
|
DxvkIlInfo() = default;
|
|
|
|
DxvkIlInfo(
|
|
uint32_t attributeCount,
|
|
uint32_t bindingCount)
|
|
: m_attributeCount(uint8_t(attributeCount)),
|
|
m_bindingCount (uint8_t(bindingCount)) { }
|
|
|
|
uint32_t attributeCount() const {
|
|
return m_attributeCount;
|
|
}
|
|
|
|
uint32_t bindingCount() const {
|
|
return m_bindingCount;
|
|
}
|
|
|
|
private:
|
|
|
|
uint8_t m_attributeCount;
|
|
uint8_t m_bindingCount;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed vertex attribute
|
|
*
|
|
* Stores a vertex attribute description. Assumes
|
|
* that all vertex formats have numerical values
|
|
* of 127 or less (i.e. fit into 7 bits).
|
|
*/
|
|
class DxvkIlAttribute {
|
|
|
|
public:
|
|
|
|
DxvkIlAttribute() = default;
|
|
|
|
DxvkIlAttribute(
|
|
uint32_t location,
|
|
uint32_t binding,
|
|
VkFormat format,
|
|
uint32_t offset)
|
|
: m_location(uint32_t(location)),
|
|
m_binding (uint32_t(binding)),
|
|
m_format (uint32_t(format)),
|
|
m_offset (uint32_t(offset)),
|
|
m_reserved(0) { }
|
|
|
|
uint32_t location() const {
|
|
return m_location;
|
|
}
|
|
|
|
uint32_t binding() const {
|
|
return m_binding;
|
|
}
|
|
|
|
VkFormat format() const {
|
|
return VkFormat(m_format);
|
|
}
|
|
|
|
uint32_t offset() const {
|
|
return m_offset;
|
|
}
|
|
|
|
VkVertexInputAttributeDescription description() const {
|
|
VkVertexInputAttributeDescription result;
|
|
result.location = m_location;
|
|
result.binding = m_binding;
|
|
result.format = VkFormat(m_format);
|
|
result.offset = m_offset;
|
|
return result;
|
|
}
|
|
|
|
private:
|
|
|
|
uint32_t m_location : 5;
|
|
uint32_t m_binding : 5;
|
|
uint32_t m_format : 7;
|
|
uint32_t m_offset : 11;
|
|
uint32_t m_reserved : 4;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed vertex binding
|
|
*
|
|
* Stores a vertex binding description,
|
|
* including the 32-bit divisor.
|
|
*/
|
|
class DxvkIlBinding {
|
|
|
|
public:
|
|
|
|
DxvkIlBinding() = default;
|
|
|
|
DxvkIlBinding(
|
|
uint32_t binding,
|
|
uint32_t stride,
|
|
VkVertexInputRate inputRate,
|
|
uint32_t divisor)
|
|
: m_binding (uint32_t(binding)),
|
|
m_stride (uint32_t(stride)),
|
|
m_inputRate (uint32_t(inputRate)),
|
|
m_reserved (0),
|
|
m_divisor (divisor) { }
|
|
|
|
uint32_t binding() const {
|
|
return m_binding;
|
|
}
|
|
|
|
uint32_t stride() const {
|
|
return m_stride;
|
|
}
|
|
|
|
VkVertexInputRate inputRate() const {
|
|
return VkVertexInputRate(m_inputRate);
|
|
}
|
|
|
|
uint32_t divisor() const {
|
|
return m_divisor;
|
|
}
|
|
|
|
VkVertexInputBindingDescription description() const {
|
|
VkVertexInputBindingDescription result;
|
|
result.binding = m_binding;
|
|
result.stride = m_stride;
|
|
result.inputRate = VkVertexInputRate(m_inputRate);
|
|
return result;
|
|
}
|
|
|
|
void setStride(uint32_t stride) {
|
|
m_stride = stride;
|
|
}
|
|
|
|
private:
|
|
|
|
uint32_t m_binding : 5;
|
|
uint32_t m_stride : 12;
|
|
uint32_t m_inputRate : 1;
|
|
uint32_t m_reserved : 14;
|
|
uint32_t m_divisor;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed rasterizer state
|
|
*
|
|
* Stores a bunch of flags and parameters
|
|
* related to rasterization in four bytes.
|
|
*/
|
|
class DxvkRsInfo {
|
|
|
|
public:
|
|
|
|
DxvkRsInfo() = default;
|
|
|
|
DxvkRsInfo(
|
|
VkBool32 depthClipEnable,
|
|
VkBool32 depthBiasEnable,
|
|
VkPolygonMode polygonMode,
|
|
VkCullModeFlags cullMode,
|
|
VkFrontFace frontFace,
|
|
uint32_t viewportCount,
|
|
VkSampleCountFlags sampleCount)
|
|
: m_depthClipEnable (uint32_t(depthClipEnable)),
|
|
m_depthBiasEnable (uint32_t(depthBiasEnable)),
|
|
m_polygonMode (uint32_t(polygonMode)),
|
|
m_cullMode (uint32_t(cullMode)),
|
|
m_frontFace (uint32_t(frontFace)),
|
|
m_viewportCount (uint32_t(viewportCount)),
|
|
m_sampleCount (uint32_t(sampleCount)),
|
|
m_reserved (0) { }
|
|
|
|
VkBool32 depthClipEnable() const {
|
|
return VkBool32(m_depthClipEnable);
|
|
}
|
|
|
|
VkBool32 depthBiasEnable() const {
|
|
return VkBool32(m_depthBiasEnable);
|
|
}
|
|
|
|
VkPolygonMode polygonMode() const {
|
|
return VkPolygonMode(m_polygonMode);
|
|
}
|
|
|
|
VkCullModeFlags cullMode() const {
|
|
return VkCullModeFlags(m_cullMode);
|
|
}
|
|
|
|
VkFrontFace frontFace() const {
|
|
return VkFrontFace(m_frontFace);
|
|
}
|
|
|
|
uint32_t viewportCount() const {
|
|
return m_viewportCount;
|
|
}
|
|
|
|
VkSampleCountFlags sampleCount() const {
|
|
return VkSampleCountFlags(m_sampleCount);
|
|
}
|
|
|
|
void setViewportCount(uint32_t viewportCount) {
|
|
m_viewportCount = viewportCount;
|
|
}
|
|
|
|
private:
|
|
|
|
uint32_t m_depthClipEnable : 1;
|
|
uint32_t m_depthBiasEnable : 1;
|
|
uint32_t m_polygonMode : 2;
|
|
uint32_t m_cullMode : 2;
|
|
uint32_t m_frontFace : 1;
|
|
uint32_t m_viewportCount : 5;
|
|
uint32_t m_sampleCount : 5;
|
|
uint32_t m_reserved : 15;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed multisample info
|
|
*
|
|
* Stores the sample mask, sample count override
|
|
* and alpha-to-coverage state in four bytes.
|
|
*/
|
|
class DxvkMsInfo {
|
|
|
|
public:
|
|
|
|
DxvkMsInfo() = default;
|
|
|
|
DxvkMsInfo(
|
|
VkSampleCountFlags sampleCount,
|
|
uint32_t sampleMask,
|
|
VkBool32 enableAlphaToCoverage)
|
|
: m_sampleCount (uint16_t(sampleCount)),
|
|
m_enableAlphaToCoverage (uint16_t(enableAlphaToCoverage)),
|
|
m_reserved (0),
|
|
m_sampleMask (uint16_t(sampleMask)) { }
|
|
|
|
VkSampleCountFlags sampleCount() const {
|
|
return VkSampleCountFlags(m_sampleCount);
|
|
}
|
|
|
|
uint32_t sampleMask() const {
|
|
return m_sampleMask;
|
|
}
|
|
|
|
VkBool32 enableAlphaToCoverage() const {
|
|
return VkBool32(m_enableAlphaToCoverage);
|
|
}
|
|
|
|
void setSampleCount(VkSampleCountFlags sampleCount) {
|
|
m_sampleCount = uint16_t(sampleCount);
|
|
}
|
|
|
|
private:
|
|
|
|
uint16_t m_sampleCount : 5;
|
|
uint16_t m_enableAlphaToCoverage : 1;
|
|
uint16_t m_reserved : 10;
|
|
uint16_t m_sampleMask;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed depth-stencil metadata
|
|
*
|
|
* Stores some flags and the depth-compare op in
|
|
* two bytes. Stencil ops are stored separately.
|
|
*/
|
|
class DxvkDsInfo {
|
|
|
|
public:
|
|
|
|
DxvkDsInfo() = default;
|
|
|
|
DxvkDsInfo(
|
|
VkBool32 enableDepthTest,
|
|
VkBool32 enableDepthWrite,
|
|
VkBool32 enableDepthBoundsTest,
|
|
VkBool32 enableStencilTest,
|
|
VkCompareOp depthCompareOp)
|
|
: m_enableDepthTest (uint16_t(enableDepthTest)),
|
|
m_enableDepthWrite (uint16_t(enableDepthWrite)),
|
|
m_enableDepthBoundsTest (uint16_t(enableDepthBoundsTest)),
|
|
m_enableStencilTest (uint16_t(enableStencilTest)),
|
|
m_depthCompareOp (uint16_t(depthCompareOp)),
|
|
m_reserved (0) { }
|
|
|
|
VkBool32 enableDepthTest() const {
|
|
return VkBool32(m_enableDepthTest);
|
|
}
|
|
|
|
VkBool32 enableDepthWrite() const {
|
|
return VkBool32(m_enableDepthWrite);
|
|
}
|
|
|
|
VkBool32 enableDepthBoundsTest() const {
|
|
return VkBool32(m_enableDepthBoundsTest);
|
|
}
|
|
|
|
VkBool32 enableStencilTest() const {
|
|
return VkBool32(m_enableStencilTest);
|
|
}
|
|
|
|
VkCompareOp depthCompareOp() const {
|
|
return VkCompareOp(m_depthCompareOp);
|
|
}
|
|
|
|
void setEnableDepthBoundsTest(VkBool32 enableDepthBoundsTest) {
|
|
m_enableDepthBoundsTest = VkBool32(enableDepthBoundsTest);
|
|
}
|
|
|
|
private:
|
|
|
|
uint16_t m_enableDepthTest : 1;
|
|
uint16_t m_enableDepthWrite : 1;
|
|
uint16_t m_enableDepthBoundsTest : 1;
|
|
uint16_t m_enableStencilTest : 1;
|
|
uint16_t m_depthCompareOp : 3;
|
|
uint16_t m_reserved : 9;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed stencil op
|
|
*
|
|
* Stores various stencil op parameters
|
|
* for one single face in four bytes.
|
|
*/
|
|
class DxvkDsStencilOp {
|
|
|
|
public:
|
|
|
|
DxvkDsStencilOp() = default;
|
|
|
|
DxvkDsStencilOp(VkStencilOpState state)
|
|
: m_failOp (uint32_t(state.failOp)),
|
|
m_passOp (uint32_t(state.passOp)),
|
|
m_depthFailOp (uint32_t(state.depthFailOp)),
|
|
m_compareOp (uint32_t(state.compareOp)),
|
|
m_reserved (0),
|
|
m_compareMask (uint32_t(state.compareMask)),
|
|
m_writeMask (uint32_t(state.writeMask)) { }
|
|
|
|
VkStencilOpState state() const {
|
|
VkStencilOpState result;
|
|
result.failOp = VkStencilOp(m_failOp);
|
|
result.passOp = VkStencilOp(m_passOp);
|
|
result.depthFailOp = VkStencilOp(m_depthFailOp);
|
|
result.compareOp = VkCompareOp(m_compareOp);
|
|
result.compareMask = m_compareMask;
|
|
result.writeMask = m_writeMask;
|
|
result.reference = 0;
|
|
return result;
|
|
}
|
|
|
|
private:
|
|
|
|
uint32_t m_failOp : 3;
|
|
uint32_t m_passOp : 3;
|
|
uint32_t m_depthFailOp : 3;
|
|
uint32_t m_compareOp : 3;
|
|
uint32_t m_reserved : 4;
|
|
uint32_t m_compareMask : 8;
|
|
uint32_t m_writeMask : 8;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* \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 Specialization constant state
|
|
*
|
|
* Stores the raw 32-bit spec constant values.
|
|
*/
|
|
struct DxvkScInfo {
|
|
uint32_t specConstants[DxvkLimits::MaxNumSpecConstants];
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Packed graphics pipeline state
|
|
*
|
|
* Stores a compressed representation of the full
|
|
* graphics pipeline state which is optimized for
|
|
* lookup performance.
|
|
*/
|
|
struct alignas(32) DxvkGraphicsPipelineStateInfo {
|
|
DxvkGraphicsPipelineStateInfo() {
|
|
std::memset(this, 0, sizeof(*this));
|
|
}
|
|
|
|
DxvkGraphicsPipelineStateInfo(const DxvkGraphicsPipelineStateInfo& other) {
|
|
std::memcpy(this, &other, sizeof(*this));
|
|
}
|
|
|
|
DxvkGraphicsPipelineStateInfo& operator = (const DxvkGraphicsPipelineStateInfo& other) {
|
|
std::memcpy(this, &other, sizeof(*this));
|
|
return *this;
|
|
}
|
|
|
|
bool operator == (const DxvkGraphicsPipelineStateInfo& other) const {
|
|
return bit::bcmpeq(this, &other);
|
|
}
|
|
|
|
bool operator != (const DxvkGraphicsPipelineStateInfo& other) const {
|
|
return !bit::bcmpeq(this, &other);
|
|
}
|
|
|
|
bool useDynamicStencilRef() const {
|
|
return ds.enableStencilTest();
|
|
}
|
|
|
|
bool useDynamicDepthBias() const {
|
|
return rs.depthBiasEnable();
|
|
}
|
|
|
|
bool useDynamicDepthBounds() const {
|
|
return ds.enableDepthBoundsTest();
|
|
}
|
|
|
|
bool useDynamicBlendConstants() const {
|
|
bool result = false;
|
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) {
|
|
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;
|
|
}
|
|
|
|
DxvkBindingMask bsBindingMask;
|
|
DxvkIaInfo ia;
|
|
DxvkIlInfo il;
|
|
DxvkRsInfo rs;
|
|
DxvkMsInfo ms;
|
|
DxvkDsInfo ds;
|
|
DxvkOmInfo om;
|
|
DxvkScInfo sc;
|
|
DxvkDsStencilOp dsFront;
|
|
DxvkDsStencilOp dsBack;
|
|
DxvkOmAttachmentSwizzle omSwizzle [DxvkLimits::MaxNumRenderTargets];
|
|
DxvkOmAttachmentBlend omBlend [DxvkLimits::MaxNumRenderTargets];
|
|
DxvkIlAttribute ilAttributes [DxvkLimits::MaxNumVertexAttributes];
|
|
DxvkIlBinding ilBindings [DxvkLimits::MaxNumVertexBindings];
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Compute pipeline state info
|
|
*/
|
|
struct alignas(32) DxvkComputePipelineStateInfo {
|
|
DxvkComputePipelineStateInfo() {
|
|
std::memset(this, 0, sizeof(*this));
|
|
}
|
|
|
|
DxvkComputePipelineStateInfo(const DxvkComputePipelineStateInfo& other) {
|
|
std::memcpy(this, &other, sizeof(*this));
|
|
}
|
|
|
|
DxvkComputePipelineStateInfo& operator = (const DxvkComputePipelineStateInfo& other) {
|
|
std::memcpy(this, &other, sizeof(*this));
|
|
return *this;
|
|
}
|
|
|
|
bool operator == (const DxvkComputePipelineStateInfo& other) const {
|
|
return bit::bcmpeq(this, &other);
|
|
}
|
|
|
|
bool operator != (const DxvkComputePipelineStateInfo& other) const {
|
|
return !bit::bcmpeq(this, &other);
|
|
}
|
|
|
|
DxvkBindingMask bsBindingMask;
|
|
DxvkScInfo sc;
|
|
};
|
|
|
|
}
|