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); | ||||
|             } | ||||
|  | ||||
|             bool IsConstant() const { | ||||
|                 return constant; | ||||
|             } | ||||
|  | ||||
|             bool IsValid() const { | ||||
|                 return size != Size::Invalid; | ||||
|             } | ||||
|   | ||||
| @@ -97,7 +97,7 @@ void RasterizerOpenGL::SyncVertexFormats() { | ||||
|         const auto gl_index = static_cast<GLuint>(index); | ||||
|  | ||||
|         // Disable constant attributes. | ||||
|         if (attrib.IsConstant()) { | ||||
|         if (attrib.constant) { | ||||
|             glDisableVertexAttribArray(gl_index); | ||||
|             continue; | ||||
|         } | ||||
|   | ||||
| @@ -128,7 +128,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | ||||
|                 const auto& input = regs.vertex_attrib_format[index]; | ||||
|                 auto& attribute = attributes[index]; | ||||
|                 attribute.raw = 0; | ||||
|                 attribute.enabled.Assign(input.IsConstant() ? 0 : 1); | ||||
|                 attribute.enabled.Assign(input.constant ? 0 : 1); | ||||
|                 attribute.buffer.Assign(input.buffer); | ||||
|                 attribute.offset.Assign(input.offset); | ||||
|                 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<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) { | ||||
|         if (!dirty[Dirty::VertexAttribute0 + index]) { | ||||
|             continue; | ||||
|         if (dirty[Dirty::VertexAttribute0 + index]) { | ||||
|             highest_dirty_attr = index; | ||||
|         } | ||||
|     } | ||||
|     for (size_t index = 0; index < highest_dirty_attr; ++index) { | ||||
|         const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]}; | ||||
|         const u32 binding{attribute.buffer}; | ||||
|         dirty[Dirty::VertexAttribute0 + index] = false; | ||||
|         dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true; | ||||
|  | ||||
|         if (!attribute.constant) { | ||||
|             attributes.push_back({ | ||||
|                 .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, | ||||
|                 .pNext = nullptr, | ||||
|                 .location = static_cast<u32>(index), | ||||
|                 .binding = binding, | ||||
|             .format = attribute.IsConstant() | ||||
|                           ? VK_FORMAT_A8B8G8R8_UNORM_PACK32 | ||||
|                           : MaxwellToVK::VertexFormat(attribute.type, attribute.size), | ||||
|                 .format = MaxwellToVK::VertexFormat(attribute.type, attribute.size), | ||||
|                 .offset = attribute.offset, | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|     for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | ||||
|         if (!dirty[Dirty::VertexBinding0 + index]) { | ||||
|             continue; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user