diff options
Diffstat (limited to 'src')
3 files changed, 12 insertions, 26 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 5ec43db11..08662f4a8 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -75,7 +75,7 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta | |||
| 75 | regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0; | 75 | regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | 78 | for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { |
| 79 | const auto& input = regs.vertex_attrib_format[index]; | 79 | const auto& input = regs.vertex_attrib_format[index]; |
| 80 | auto& attribute = attributes[index]; | 80 | auto& attribute = attributes[index]; |
| 81 | attribute.raw = 0; | 81 | attribute.raw = 0; |
| @@ -84,6 +84,7 @@ void FixedPipelineState::Fill(const Maxwell& regs, bool has_extended_dynamic_sta | |||
| 84 | attribute.offset.Assign(input.offset); | 84 | attribute.offset.Assign(input.offset); |
| 85 | attribute.type.Assign(static_cast<u32>(input.type.Value())); | 85 | attribute.type.Assign(static_cast<u32>(input.type.Value())); |
| 86 | attribute.size.Assign(static_cast<u32>(input.size.Value())); | 86 | attribute.size.Assign(static_cast<u32>(input.size.Value())); |
| 87 | attribute.binding_index_enabled.Assign(regs.vertex_array[index].IsEnabled() ? 1 : 0); | ||
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | for (std::size_t index = 0; index < std::size(attachments); ++index) { | 90 | for (std::size_t index = 0; index < std::size(attachments); ++index) { |
| @@ -171,14 +172,9 @@ void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) { | |||
| 171 | depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); | 172 | depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); |
| 172 | cull_face.Assign(PackCullFace(regs.cull_face)); | 173 | cull_face.Assign(PackCullFace(regs.cull_face)); |
| 173 | cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0); | 174 | cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0); |
| 174 | 175 | std::ranges::transform(regs.vertex_array, vertex_strides.begin(), [](const auto& array) { | |
| 175 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 176 | return static_cast<u16>(array.stride.Value()); |
| 176 | const auto& input = regs.vertex_array[index]; | 177 | }); |
| 177 | VertexBinding& binding = vertex_bindings[index]; | ||
| 178 | binding.raw = 0; | ||
| 179 | binding.enabled.Assign(input.IsEnabled() ? 1 : 0); | ||
| 180 | binding.stride.Assign(static_cast<u16>(input.stride.Value())); | ||
| 181 | } | ||
| 182 | } | 178 | } |
| 183 | 179 | ||
| 184 | std::size_t FixedPipelineState::Hash() const noexcept { | 180 | std::size_t FixedPipelineState::Hash() const noexcept { |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index c26b77790..9b18301c1 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -96,6 +96,8 @@ struct FixedPipelineState { | |||
| 96 | BitField<6, 14, u32> offset; | 96 | BitField<6, 14, u32> offset; |
| 97 | BitField<20, 3, u32> type; | 97 | BitField<20, 3, u32> type; |
| 98 | BitField<23, 6, u32> size; | 98 | BitField<23, 6, u32> size; |
| 99 | // Not really an element of a vertex attribute, but it can be packed here | ||
| 100 | BitField<29, 1, u32> binding_index_enabled; | ||
| 99 | 101 | ||
| 100 | constexpr Maxwell::VertexAttribute::Type Type() const noexcept { | 102 | constexpr Maxwell::VertexAttribute::Type Type() const noexcept { |
| 101 | return static_cast<Maxwell::VertexAttribute::Type>(type.Value()); | 103 | return static_cast<Maxwell::VertexAttribute::Type>(type.Value()); |
| @@ -130,12 +132,6 @@ struct FixedPipelineState { | |||
| 130 | } | 132 | } |
| 131 | }; | 133 | }; |
| 132 | 134 | ||
| 133 | union VertexBinding { | ||
| 134 | u16 raw; | ||
| 135 | BitField<0, 12, u16> stride; | ||
| 136 | BitField<12, 1, u16> enabled; | ||
| 137 | }; | ||
| 138 | |||
| 139 | struct DynamicState { | 135 | struct DynamicState { |
| 140 | union { | 136 | union { |
| 141 | u32 raw1; | 137 | u32 raw1; |
| @@ -153,7 +149,8 @@ struct FixedPipelineState { | |||
| 153 | BitField<0, 2, u32> cull_face; | 149 | BitField<0, 2, u32> cull_face; |
| 154 | BitField<2, 1, u32> cull_enable; | 150 | BitField<2, 1, u32> cull_enable; |
| 155 | }; | 151 | }; |
| 156 | std::array<VertexBinding, Maxwell::NumVertexArrays> vertex_bindings; | 152 | // Vertex stride is a 12 bits value, we have 4 bits to spare per element |
| 153 | std::array<u16, Maxwell::NumVertexArrays> vertex_strides; | ||
| 157 | 154 | ||
| 158 | void Fill(const Maxwell& regs); | 155 | void Fill(const Maxwell& regs); |
| 159 | 156 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 970979fa1..a1a217b7c 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -190,11 +190,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 190 | // state is ignored | 190 | // state is ignored |
| 191 | dynamic.raw1 = 0; | 191 | dynamic.raw1 = 0; |
| 192 | dynamic.raw2 = 0; | 192 | dynamic.raw2 = 0; |
| 193 | for (FixedPipelineState::VertexBinding& binding : dynamic.vertex_bindings) { | 193 | dynamic.vertex_strides.fill(0); |
| 194 | // Enable all vertex bindings | ||
| 195 | binding.raw = 0; | ||
| 196 | binding.enabled.Assign(1); | ||
| 197 | } | ||
| 198 | } else { | 194 | } else { |
| 199 | dynamic = state.dynamic_state; | 195 | dynamic = state.dynamic_state; |
| 200 | } | 196 | } |
| @@ -202,19 +198,16 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 202 | std::vector<VkVertexInputBindingDescription> vertex_bindings; | 198 | std::vector<VkVertexInputBindingDescription> vertex_bindings; |
| 203 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; | 199 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; |
| 204 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 200 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 205 | const auto& binding = dynamic.vertex_bindings[index]; | 201 | if (state.attributes[index].binding_index_enabled == 0) { |
| 206 | if (!binding.enabled) { | ||
| 207 | continue; | 202 | continue; |
| 208 | } | 203 | } |
| 209 | const bool instanced = state.binding_divisors[index] != 0; | 204 | const bool instanced = state.binding_divisors[index] != 0; |
| 210 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; | 205 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; |
| 211 | |||
| 212 | vertex_bindings.push_back({ | 206 | vertex_bindings.push_back({ |
| 213 | .binding = static_cast<u32>(index), | 207 | .binding = static_cast<u32>(index), |
| 214 | .stride = binding.stride, | 208 | .stride = dynamic.vertex_strides[index], |
| 215 | .inputRate = rate, | 209 | .inputRate = rate, |
| 216 | }); | 210 | }); |
| 217 | |||
| 218 | if (instanced) { | 211 | if (instanced) { |
| 219 | vertex_binding_divisors.push_back({ | 212 | vertex_binding_divisors.push_back({ |
| 220 | .binding = static_cast<u32>(index), | 213 | .binding = static_cast<u32>(index), |