vk_rasterizer: Workaround bug in VK_EXT_vertex_input_dynamic_state
Workaround potential bug on Nvidia's driver where only updating high attributes leaves low attributes out dated.
This commit is contained in:
		| @@ -305,10 +305,6 @@ public: | |||||||
|                 return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); |                 return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             bool IsConstant() const { |  | ||||||
|                 return constant; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             bool IsValid() const { |             bool IsValid() const { | ||||||
|                 return size != Size::Invalid; |                 return size != Size::Invalid; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ void RasterizerOpenGL::SyncVertexFormats() { | |||||||
|         const auto gl_index = static_cast<GLuint>(index); |         const auto gl_index = static_cast<GLuint>(index); | ||||||
|  |  | ||||||
|         // Disable constant attributes. |         // Disable constant attributes. | ||||||
|         if (attrib.IsConstant()) { |         if (attrib.constant) { | ||||||
|             glDisableVertexAttribArray(gl_index); |             glDisableVertexAttribArray(gl_index); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -128,7 +128,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||||||
|                 const auto& input = regs.vertex_attrib_format[index]; |                 const auto& input = regs.vertex_attrib_format[index]; | ||||||
|                 auto& attribute = attributes[index]; |                 auto& attribute = attributes[index]; | ||||||
|                 attribute.raw = 0; |                 attribute.raw = 0; | ||||||
|                 attribute.enabled.Assign(input.IsConstant() ? 0 : 1); |                 attribute.enabled.Assign(input.constant ? 0 : 1); | ||||||
|                 attribute.buffer.Assign(input.buffer); |                 attribute.buffer.Assign(input.buffer); | ||||||
|                 attribute.offset.Assign(input.offset); |                 attribute.offset.Assign(input.offset); | ||||||
|                 attribute.type.Assign(static_cast<u32>(input.type.Value())); |                 attribute.type.Assign(static_cast<u32>(input.type.Value())); | ||||||
|   | |||||||
| @@ -801,26 +801,31 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) | |||||||
|     boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings; |     boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings; | ||||||
|     boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes; |     boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes; | ||||||
|  |  | ||||||
|  |     // There seems to be a bug on Nvidia's driver where updating only higher attributes ends up | ||||||
|  |     // generating dirty state. Track the highest dirty attribute and update all attributes until | ||||||
|  |     // that one. | ||||||
|  |     size_t highest_dirty_attr{}; | ||||||
|     for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { |     for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | ||||||
|         if (!dirty[Dirty::VertexAttribute0 + index]) { |         if (dirty[Dirty::VertexAttribute0 + index]) { | ||||||
|             continue; |             highest_dirty_attr = index; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |     for (size_t index = 0; index < highest_dirty_attr; ++index) { | ||||||
|         const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]}; |         const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]}; | ||||||
|         const u32 binding{attribute.buffer}; |         const u32 binding{attribute.buffer}; | ||||||
|         dirty[Dirty::VertexAttribute0 + index] = false; |         dirty[Dirty::VertexAttribute0 + index] = false; | ||||||
|         dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true; |         dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true; | ||||||
|  |         if (!attribute.constant) { | ||||||
|             attributes.push_back({ |             attributes.push_back({ | ||||||
|                 .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, |                 .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, | ||||||
|                 .pNext = nullptr, |                 .pNext = nullptr, | ||||||
|                 .location = static_cast<u32>(index), |                 .location = static_cast<u32>(index), | ||||||
|                 .binding = binding, |                 .binding = binding, | ||||||
|             .format = attribute.IsConstant() |                 .format = MaxwellToVK::VertexFormat(attribute.type, attribute.size), | ||||||
|                           ? VK_FORMAT_A8B8G8R8_UNORM_PACK32 |  | ||||||
|                           : MaxwellToVK::VertexFormat(attribute.type, attribute.size), |  | ||||||
|                 .offset = attribute.offset, |                 .offset = attribute.offset, | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|     for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { |     for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | ||||||
|         if (!dirty[Dirty::VertexBinding0 + index]) { |         if (!dirty[Dirty::VertexBinding0 + index]) { | ||||||
|             continue; |             continue; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user