mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 10:24:10 +01:00
[dxvk] Use packed input layout state
Also move attribute and binding descriptions to the end so that comparisons are more likely to fail early.
This commit is contained in:
parent
c0ae4e38eb
commit
a5ab88d8f2
@ -2259,28 +2259,24 @@ namespace dxvk {
|
|||||||
DxvkContextFlag::GpDirtyVertexBuffers);
|
DxvkContextFlag::GpDirtyVertexBuffers);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < attributeCount; i++) {
|
for (uint32_t i = 0; i < attributeCount; i++) {
|
||||||
m_state.gp.state.ilAttributes[i].location = attributes[i].location;
|
m_state.gp.state.ilAttributes[i] = DxvkIlAttribute(
|
||||||
m_state.gp.state.ilAttributes[i].binding = attributes[i].binding;
|
attributes[i].location, attributes[i].binding,
|
||||||
m_state.gp.state.ilAttributes[i].format = attributes[i].format;
|
attributes[i].format, attributes[i].offset);
|
||||||
m_state.gp.state.ilAttributes[i].offset = attributes[i].offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = attributeCount; i < m_state.gp.state.ilAttributeCount; i++)
|
for (uint32_t i = attributeCount; i < m_state.gp.state.il.attributeCount(); i++)
|
||||||
m_state.gp.state.ilAttributes[i] = VkVertexInputAttributeDescription();
|
m_state.gp.state.ilAttributes[i] = DxvkIlAttribute();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||||
m_state.gp.state.ilBindings[i].binding = bindings[i].binding;
|
m_state.gp.state.ilBindings[i] = DxvkIlBinding(
|
||||||
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
bindings[i].binding, 0, bindings[i].inputRate,
|
||||||
m_state.gp.state.ilDivisors[i] = bindings[i].fetchRate;
|
bindings[i].fetchRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++) {
|
for (uint32_t i = bindingCount; i < m_state.gp.state.il.bindingCount(); i++)
|
||||||
m_state.gp.state.ilBindings[i] = VkVertexInputBindingDescription();
|
m_state.gp.state.ilBindings[i] = DxvkIlBinding();
|
||||||
m_state.gp.state.ilDivisors[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_state.gp.state.ilAttributeCount = attributeCount;
|
m_state.gp.state.il = DxvkIlInfo(attributeCount, bindingCount);
|
||||||
m_state.gp.state.ilBindingCount = bindingCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3620,9 +3616,9 @@ namespace dxvk {
|
|||||||
this->pauseTransformFeedback();
|
this->pauseTransformFeedback();
|
||||||
|
|
||||||
// Set up vertex buffer strides for active bindings
|
// Set up vertex buffer strides for active bindings
|
||||||
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
|
for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) {
|
||||||
const uint32_t binding = m_state.gp.state.ilBindings[i].binding;
|
const uint32_t binding = m_state.gp.state.ilBindings[i].binding();
|
||||||
m_state.gp.state.ilBindings[i].stride = m_state.vi.vertexStrides[binding];
|
m_state.gp.state.ilBindings[i].setStride(m_state.vi.vertexStrides[binding]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check which dynamic states need to be active. States that
|
// Check which dynamic states need to be active. States that
|
||||||
@ -4015,15 +4011,15 @@ namespace dxvk {
|
|||||||
void DxvkContext::updateVertexBufferBindings() {
|
void DxvkContext::updateVertexBufferBindings() {
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyVertexBuffers);
|
m_flags.clr(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||||
|
|
||||||
if (unlikely(!m_state.gp.state.ilBindingCount))
|
if (unlikely(!m_state.gp.state.il.bindingCount()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::array<VkBuffer, MaxNumVertexBindings> buffers;
|
std::array<VkBuffer, MaxNumVertexBindings> buffers;
|
||||||
std::array<VkDeviceSize, MaxNumVertexBindings> offsets;
|
std::array<VkDeviceSize, MaxNumVertexBindings> offsets;
|
||||||
|
|
||||||
// Set buffer handles and offsets for active bindings
|
// Set buffer handles and offsets for active bindings
|
||||||
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
|
for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) {
|
||||||
uint32_t binding = m_state.gp.state.ilBindings[i].binding;
|
uint32_t binding = m_state.gp.state.ilBindings[i].binding();
|
||||||
|
|
||||||
if (likely(m_state.vi.vertexBuffers[binding].defined())) {
|
if (likely(m_state.vi.vertexBuffers[binding].defined())) {
|
||||||
auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor();
|
auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor();
|
||||||
@ -4042,7 +4038,7 @@ namespace dxvk {
|
|||||||
// Vertex bindigs get remapped when compiling the
|
// Vertex bindigs get remapped when compiling the
|
||||||
// pipeline, so this actually does the right thing
|
// pipeline, so this actually does the right thing
|
||||||
m_cmd->cmdBindVertexBuffers(
|
m_cmd->cmdBindVertexBuffers(
|
||||||
0, m_state.gp.state.ilBindingCount,
|
0, m_state.gp.state.il.bindingCount(),
|
||||||
buffers.data(), offsets.data());
|
buffers.data(), offsets.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,13 +232,13 @@ namespace dxvk {
|
|||||||
std::array<VkVertexInputBindingDivisorDescriptionEXT, MaxNumVertexBindings> viDivisorDesc;
|
std::array<VkVertexInputBindingDivisorDescriptionEXT, MaxNumVertexBindings> viDivisorDesc;
|
||||||
uint32_t viDivisorCount = 0;
|
uint32_t viDivisorCount = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < state.ilBindingCount; i++) {
|
for (uint32_t i = 0; i < state.il.bindingCount(); i++) {
|
||||||
if (state.ilBindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE
|
if (state.ilBindings[i].inputRate() == VK_VERTEX_INPUT_RATE_INSTANCE
|
||||||
&& state.ilDivisors[i] != 1) {
|
&& state.ilBindings[i].divisor() != 1) {
|
||||||
const uint32_t id = viDivisorCount++;
|
const uint32_t id = viDivisorCount++;
|
||||||
|
|
||||||
viDivisorDesc[id].binding = i;
|
viDivisorDesc[id].binding = i; /* see below */
|
||||||
viDivisorDesc[id].divisor = state.ilDivisors[i];
|
viDivisorDesc[id].divisor = state.ilBindings[i].divisor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,15 +251,15 @@ namespace dxvk {
|
|||||||
std::array<VkVertexInputBindingDescription, MaxNumVertexBindings> viBindings;
|
std::array<VkVertexInputBindingDescription, MaxNumVertexBindings> viBindings;
|
||||||
std::array<uint32_t, MaxNumVertexBindings> viBindingMap = { };
|
std::array<uint32_t, MaxNumVertexBindings> viBindingMap = { };
|
||||||
|
|
||||||
for (uint32_t i = 0; i < state.ilBindingCount; i++) {
|
for (uint32_t i = 0; i < state.il.bindingCount(); i++) {
|
||||||
viBindings[i] = state.ilBindings[i];
|
viBindings[i] = state.ilBindings[i].description();
|
||||||
viBindings[i].binding = i;
|
viBindings[i].binding = i;
|
||||||
viBindingMap[state.ilBindings[i].binding] = i;
|
viBindingMap[state.ilBindings[i].binding()] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < state.ilAttributeCount; i++) {
|
for (uint32_t i = 0; i < state.il.attributeCount(); i++) {
|
||||||
viAttribs[i] = state.ilAttributes[i];
|
viAttribs[i] = state.ilAttributes[i].description();
|
||||||
viAttribs[i].binding = viBindingMap[state.ilAttributes[i].binding];
|
viAttribs[i].binding = viBindingMap[state.ilAttributes[i].binding()];
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo;
|
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo;
|
||||||
@ -272,9 +272,9 @@ namespace dxvk {
|
|||||||
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
viInfo.pNext = &viDivisorInfo;
|
viInfo.pNext = &viDivisorInfo;
|
||||||
viInfo.flags = 0;
|
viInfo.flags = 0;
|
||||||
viInfo.vertexBindingDescriptionCount = state.ilBindingCount;
|
viInfo.vertexBindingDescriptionCount = state.il.bindingCount();
|
||||||
viInfo.pVertexBindingDescriptions = viBindings.data();
|
viInfo.pVertexBindingDescriptions = viBindings.data();
|
||||||
viInfo.vertexAttributeDescriptionCount = state.ilAttributeCount;
|
viInfo.vertexAttributeDescriptionCount = state.il.attributeCount();
|
||||||
viInfo.pVertexAttributeDescriptions = viAttribs.data();
|
viInfo.pVertexAttributeDescriptions = viAttribs.data();
|
||||||
|
|
||||||
if (viDivisorCount == 0)
|
if (viDivisorCount == 0)
|
||||||
@ -453,8 +453,8 @@ namespace dxvk {
|
|||||||
// vertex shader must be provided by the input layout.
|
// vertex shader must be provided by the input layout.
|
||||||
uint32_t providedVertexInputs = 0;
|
uint32_t providedVertexInputs = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < state.ilAttributeCount; i++)
|
for (uint32_t i = 0; i < state.il.attributeCount(); i++)
|
||||||
providedVertexInputs |= 1u << state.ilAttributes[i].location;
|
providedVertexInputs |= 1u << state.ilAttributes[i].location();
|
||||||
|
|
||||||
if ((providedVertexInputs & m_vsIn) != m_vsIn)
|
if ((providedVertexInputs & m_vsIn) != m_vsIn)
|
||||||
return false;
|
return false;
|
||||||
@ -470,8 +470,8 @@ namespace dxvk {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Prevent unintended out-of-bounds access to the IL arrays
|
// Prevent unintended out-of-bounds access to the IL arrays
|
||||||
if (state.ilAttributeCount > DxvkLimits::MaxNumVertexAttributes
|
if (state.il.attributeCount() > DxvkLimits::MaxNumVertexAttributes
|
||||||
|| state.ilBindingCount > DxvkLimits::MaxNumVertexBindings)
|
|| state.il.bindingCount() > DxvkLimits::MaxNumVertexBindings)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// No errors
|
// No errors
|
||||||
@ -505,13 +505,13 @@ namespace dxvk {
|
|||||||
if (m_shaders.gs != nullptr) Logger::log(level, str::format(" gs : ", m_shaders.gs ->debugName()));
|
if (m_shaders.gs != nullptr) Logger::log(level, str::format(" gs : ", m_shaders.gs ->debugName()));
|
||||||
if (m_shaders.fs != nullptr) Logger::log(level, str::format(" fs : ", m_shaders.fs ->debugName()));
|
if (m_shaders.fs != nullptr) Logger::log(level, str::format(" fs : ", m_shaders.fs ->debugName()));
|
||||||
|
|
||||||
for (uint32_t i = 0; i < state.ilAttributeCount; i++) {
|
for (uint32_t i = 0; i < state.il.attributeCount(); i++) {
|
||||||
const VkVertexInputAttributeDescription& attr = state.ilAttributes[i];
|
const auto& attr = state.ilAttributes[i];
|
||||||
Logger::log(level, str::format(" attr ", i, " : location ", attr.location, ", binding ", attr.binding, ", format ", attr.format, ", offset ", attr.offset));
|
Logger::log(level, str::format(" attr ", i, " : location ", attr.location(), ", binding ", attr.binding(), ", format ", attr.format(), ", offset ", attr.offset()));
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < state.ilBindingCount; i++) {
|
for (uint32_t i = 0; i < state.il.bindingCount(); i++) {
|
||||||
const VkVertexInputBindingDescription& bind = state.ilBindings[i];
|
const auto& bind = state.ilBindings[i];
|
||||||
Logger::log(level, str::format(" binding ", i, " : binding ", bind.binding, ", stride ", bind.stride, ", rate ", bind.inputRate, ", divisor ", state.ilDivisors[i]));
|
Logger::log(level, str::format(" binding ", i, " : binding ", bind.binding(), ", stride ", bind.stride(), ", rate ", bind.inputRate(), ", divisor ", bind.divisor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO log more pipeline state
|
// TODO log more pipeline state
|
||||||
|
@ -51,6 +51,162 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 graphics pipeline state
|
* \brief Packed graphics pipeline state
|
||||||
*
|
*
|
||||||
@ -108,12 +264,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkBindingMask bsBindingMask;
|
DxvkBindingMask bsBindingMask;
|
||||||
DxvkIaInfo ia;
|
DxvkIaInfo ia;
|
||||||
|
DxvkIlInfo il;
|
||||||
uint32_t ilAttributeCount;
|
|
||||||
uint32_t ilBindingCount;
|
|
||||||
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
|
||||||
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
|
||||||
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
|
|
||||||
|
|
||||||
VkBool32 rsDepthClipEnable;
|
VkBool32 rsDepthClipEnable;
|
||||||
VkBool32 rsDepthBiasEnable;
|
VkBool32 rsDepthBiasEnable;
|
||||||
@ -141,6 +292,9 @@ namespace dxvk {
|
|||||||
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
|
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
|
||||||
|
|
||||||
uint32_t scSpecConstants[MaxNumSpecConstants];
|
uint32_t scSpecConstants[MaxNumSpecConstants];
|
||||||
|
|
||||||
|
DxvkIlAttribute ilAttributes [DxvkLimits::MaxNumVertexAttributes];
|
||||||
|
DxvkIlBinding ilBindings [DxvkLimits::MaxNumVertexBindings];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user