mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Implement vertex binding divisors
Uses VK_EXT_vertex_attribute_divisor when available.
This commit is contained in:
parent
a248ae985d
commit
9a8263f465
@ -1386,8 +1386,6 @@ namespace dxvk {
|
||||
m_flags.set(
|
||||
DxvkContextFlag::GpDirtyPipelineState,
|
||||
DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
m_flags.clr(
|
||||
DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||
|
||||
for (uint32_t i = 0; i < attributeCount; i++) {
|
||||
m_state.gp.state.ilAttributes[i].location = attributes[i].location;
|
||||
@ -1402,10 +1400,7 @@ namespace dxvk {
|
||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||
m_state.gp.state.ilBindings[i].binding = bindings[i].binding;
|
||||
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
||||
m_state.vi.vertexFetchRates[bindings[i].binding] = bindings[i].fetchRate;
|
||||
|
||||
if (bindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE && bindings[i].fetchRate != 1)
|
||||
m_flags.set(DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||
m_state.gp.state.ilDivisors[i] = bindings[i].fetchRate;
|
||||
}
|
||||
|
||||
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++)
|
||||
@ -1413,13 +1408,6 @@ namespace dxvk {
|
||||
|
||||
m_state.gp.state.ilAttributeCount = attributeCount;
|
||||
m_state.gp.state.ilBindingCount = bindingCount;
|
||||
|
||||
if (m_flags.test(DxvkContextFlag::GpEmulateInstanceFetchRate)) {
|
||||
static bool errorShown = false;
|
||||
|
||||
if (!std::exchange(errorShown, true))
|
||||
Logger::warn("Dxvk: GpEmulateInstanceFetchRate not handled yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,6 @@ namespace dxvk {
|
||||
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
||||
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
||||
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
|
||||
GpEmulateInstanceFetchRate, ///< The current input layout uses fetch rates != 1
|
||||
|
||||
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
||||
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
||||
@ -42,12 +41,8 @@ namespace dxvk {
|
||||
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
||||
uint32_t bindingMask = 0;
|
||||
|
||||
std::array<DxvkBufferSlice,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
||||
std::array<uint32_t,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
||||
std::array<uint32_t,
|
||||
DxvkLimits::MaxNumVertexBindings> vertexFetchRates = { };
|
||||
std::array<DxvkBufferSlice, DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
||||
std::array<uint32_t, DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
||||
};
|
||||
|
||||
|
||||
|
@ -135,15 +135,40 @@ namespace dxvk {
|
||||
if (m_gs != nullptr) stages.push_back(m_gs->stageInfo(&specInfo));
|
||||
if (m_fs != nullptr) stages.push_back(m_fs->stageInfo(&specInfo));
|
||||
|
||||
std::array<VkVertexInputBindingDivisorDescriptionEXT, MaxNumVertexBindings> viDivisorDesc;
|
||||
uint32_t viDivisorCount = 0;
|
||||
|
||||
for (uint32_t i = 0; i < state.ilBindingCount; i++) {
|
||||
if (state.ilBindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) {
|
||||
const uint32_t id = viDivisorCount++;
|
||||
|
||||
viDivisorDesc[id].binding = state.ilBindings[i].binding;
|
||||
viDivisorDesc[id].divisor = state.ilDivisors[i];
|
||||
}
|
||||
}
|
||||
|
||||
VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo;
|
||||
viDivisorInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
|
||||
viDivisorInfo.pNext = nullptr;
|
||||
viDivisorInfo.vertexBindingDivisorCount = viDivisorCount;
|
||||
viDivisorInfo.pVertexBindingDivisors = viDivisorDesc.data();
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo viInfo;
|
||||
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
viInfo.pNext = nullptr;
|
||||
viInfo.pNext = &viDivisorInfo;
|
||||
viInfo.flags = 0;
|
||||
viInfo.vertexBindingDescriptionCount = state.ilBindingCount;
|
||||
viInfo.pVertexBindingDescriptions = state.ilBindings;
|
||||
viInfo.vertexAttributeDescriptionCount = state.ilAttributeCount;
|
||||
viInfo.pVertexAttributeDescriptions = state.ilAttributes;
|
||||
|
||||
if (viDivisorCount == 0)
|
||||
viInfo.pNext = viDivisorInfo.pNext;
|
||||
|
||||
// TODO make this extension required when widely supported
|
||||
if (!m_device->extensions().extVertexAttributeDivisor.enabled())
|
||||
viInfo.pNext = viDivisorInfo.pNext;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo iaInfo;
|
||||
iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
iaInfo.pNext = nullptr;
|
||||
|
@ -43,6 +43,7 @@ namespace dxvk {
|
||||
uint32_t ilBindingCount;
|
||||
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
||||
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
||||
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
|
||||
|
||||
VkBool32 rsEnableDepthClamp;
|
||||
VkBool32 rsEnableDiscard;
|
||||
|
Loading…
x
Reference in New Issue
Block a user