mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +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(
|
m_flags.set(
|
||||||
DxvkContextFlag::GpDirtyPipelineState,
|
DxvkContextFlag::GpDirtyPipelineState,
|
||||||
DxvkContextFlag::GpDirtyVertexBuffers);
|
DxvkContextFlag::GpDirtyVertexBuffers);
|
||||||
m_flags.clr(
|
|
||||||
DxvkContextFlag::GpEmulateInstanceFetchRate);
|
|
||||||
|
|
||||||
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].location = attributes[i].location;
|
||||||
@ -1402,10 +1400,7 @@ namespace dxvk {
|
|||||||
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].binding = bindings[i].binding;
|
||||||
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
||||||
m_state.vi.vertexFetchRates[bindings[i].binding] = bindings[i].fetchRate;
|
m_state.gp.state.ilDivisors[i] = bindings[i].fetchRate;
|
||||||
|
|
||||||
if (bindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE && bindings[i].fetchRate != 1)
|
|
||||||
m_flags.set(DxvkContextFlag::GpEmulateInstanceFetchRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++)
|
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.ilAttributeCount = attributeCount;
|
||||||
m_state.gp.state.ilBindingCount = bindingCount;
|
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
|
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
||||||
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
||||||
GpDirtyIndexBuffer, ///< Index buffer binding 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
|
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
||||||
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
||||||
@ -42,12 +41,8 @@ namespace dxvk {
|
|||||||
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
||||||
uint32_t bindingMask = 0;
|
uint32_t bindingMask = 0;
|
||||||
|
|
||||||
std::array<DxvkBufferSlice,
|
std::array<DxvkBufferSlice, DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
||||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
std::array<uint32_t, DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
||||||
std::array<uint32_t,
|
|
||||||
DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
|
||||||
std::array<uint32_t,
|
|
||||||
DxvkLimits::MaxNumVertexBindings> vertexFetchRates = { };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,15 +135,40 @@ namespace dxvk {
|
|||||||
if (m_gs != nullptr) stages.push_back(m_gs->stageInfo(&specInfo));
|
if (m_gs != nullptr) stages.push_back(m_gs->stageInfo(&specInfo));
|
||||||
if (m_fs != nullptr) stages.push_back(m_fs->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;
|
VkPipelineVertexInputStateCreateInfo viInfo;
|
||||||
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
viInfo.pNext = nullptr;
|
viInfo.pNext = &viDivisorInfo;
|
||||||
viInfo.flags = 0;
|
viInfo.flags = 0;
|
||||||
viInfo.vertexBindingDescriptionCount = state.ilBindingCount;
|
viInfo.vertexBindingDescriptionCount = state.ilBindingCount;
|
||||||
viInfo.pVertexBindingDescriptions = state.ilBindings;
|
viInfo.pVertexBindingDescriptions = state.ilBindings;
|
||||||
viInfo.vertexAttributeDescriptionCount = state.ilAttributeCount;
|
viInfo.vertexAttributeDescriptionCount = state.ilAttributeCount;
|
||||||
viInfo.pVertexAttributeDescriptions = state.ilAttributes;
|
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;
|
VkPipelineInputAssemblyStateCreateInfo iaInfo;
|
||||||
iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
iaInfo.pNext = nullptr;
|
iaInfo.pNext = nullptr;
|
||||||
|
@ -43,6 +43,7 @@ namespace dxvk {
|
|||||||
uint32_t ilBindingCount;
|
uint32_t ilBindingCount;
|
||||||
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
||||||
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
||||||
|
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
|
||||||
|
|
||||||
VkBool32 rsEnableDepthClamp;
|
VkBool32 rsEnableDepthClamp;
|
||||||
VkBool32 rsEnableDiscard;
|
VkBool32 rsEnableDiscard;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user