diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.h | 99 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 20 |
6 files changed, 85 insertions, 101 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 5cf6a4cc3..59d5752d2 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -1149,7 +1149,7 @@ public: | |||
| 1149 | 1149 | ||
| 1150 | /// Returns whether the vertex array specified by index is supposed to be | 1150 | /// Returns whether the vertex array specified by index is supposed to be |
| 1151 | /// accessed per instance or not. | 1151 | /// accessed per instance or not. |
| 1152 | bool IsInstancingEnabled(u32 index) const { | 1152 | bool IsInstancingEnabled(std::size_t index) const { |
| 1153 | return is_instanced[index]; | 1153 | return is_instanced[index]; |
| 1154 | } | 1154 | } |
| 1155 | } instanced_arrays; | 1155 | } instanced_arrays; |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 2bb376555..97aab951a 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <boost/functional/hash.hpp> | 7 | #include <boost/functional/hash.hpp> |
| 8 | 8 | ||
| 9 | #include "common/cityhash.h" | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" | 11 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" |
| 11 | 12 | ||
| @@ -128,25 +129,6 @@ constexpr FixedPipelineState::Rasterizer GetRasterizerState(const Maxwell& regs) | |||
| 128 | 129 | ||
| 129 | } // Anonymous namespace | 130 | } // Anonymous namespace |
| 130 | 131 | ||
| 131 | std::size_t FixedPipelineState::VertexBinding::Hash() const noexcept { | ||
| 132 | return (index << stride) ^ divisor; | ||
| 133 | } | ||
| 134 | |||
| 135 | bool FixedPipelineState::VertexBinding::operator==(const VertexBinding& rhs) const noexcept { | ||
| 136 | return std::tie(index, stride, divisor) == std::tie(rhs.index, rhs.stride, rhs.divisor); | ||
| 137 | } | ||
| 138 | |||
| 139 | std::size_t FixedPipelineState::VertexAttribute::Hash() const noexcept { | ||
| 140 | return static_cast<std::size_t>(index) ^ (static_cast<std::size_t>(buffer) << 13) ^ | ||
| 141 | (static_cast<std::size_t>(type) << 22) ^ (static_cast<std::size_t>(size) << 31) ^ | ||
| 142 | (static_cast<std::size_t>(offset) << 36); | ||
| 143 | } | ||
| 144 | |||
| 145 | bool FixedPipelineState::VertexAttribute::operator==(const VertexAttribute& rhs) const noexcept { | ||
| 146 | return std::tie(index, buffer, type, size, offset) == | ||
| 147 | std::tie(rhs.index, rhs.buffer, rhs.type, rhs.size, rhs.offset); | ||
| 148 | } | ||
| 149 | |||
| 150 | std::size_t FixedPipelineState::StencilFace::Hash() const noexcept { | 132 | std::size_t FixedPipelineState::StencilFace::Hash() const noexcept { |
| 151 | return static_cast<std::size_t>(action_stencil_fail) ^ | 133 | return static_cast<std::size_t>(action_stencil_fail) ^ |
| 152 | (static_cast<std::size_t>(action_depth_fail) << 4) ^ | 134 | (static_cast<std::size_t>(action_depth_fail) << 4) ^ |
| @@ -182,21 +164,12 @@ bool FixedPipelineState::BlendingAttachment::operator==(const BlendingAttachment | |||
| 182 | } | 164 | } |
| 183 | 165 | ||
| 184 | std::size_t FixedPipelineState::VertexInput::Hash() const noexcept { | 166 | std::size_t FixedPipelineState::VertexInput::Hash() const noexcept { |
| 185 | std::size_t hash = num_bindings ^ (num_attributes << 32); | 167 | // TODO(Rodrigo): Replace this |
| 186 | for (std::size_t i = 0; i < num_bindings; ++i) { | 168 | return Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); |
| 187 | boost::hash_combine(hash, bindings[i].Hash()); | ||
| 188 | } | ||
| 189 | for (std::size_t i = 0; i < num_attributes; ++i) { | ||
| 190 | boost::hash_combine(hash, attributes[i].Hash()); | ||
| 191 | } | ||
| 192 | return hash; | ||
| 193 | } | 169 | } |
| 194 | 170 | ||
| 195 | bool FixedPipelineState::VertexInput::operator==(const VertexInput& rhs) const noexcept { | 171 | bool FixedPipelineState::VertexInput::operator==(const VertexInput& rhs) const noexcept { |
| 196 | return std::equal(bindings.begin(), bindings.begin() + num_bindings, rhs.bindings.begin(), | 172 | return std::memcmp(this, &rhs, sizeof *this) == 0; |
| 197 | rhs.bindings.begin() + rhs.num_bindings) && | ||
| 198 | std::equal(attributes.begin(), attributes.begin() + num_attributes, | ||
| 199 | rhs.attributes.begin(), rhs.attributes.begin() + rhs.num_attributes); | ||
| 200 | } | 173 | } |
| 201 | 174 | ||
| 202 | std::size_t FixedPipelineState::InputAssembly::Hash() const noexcept { | 175 | std::size_t FixedPipelineState::InputAssembly::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 4c8ba7f90..d82a82f75 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <type_traits> | 8 | #include <type_traits> |
| 9 | 9 | ||
| 10 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | 12 | ||
| 12 | #include "video_core/engines/maxwell_3d.h" | 13 | #include "video_core/engines/maxwell_3d.h" |
| @@ -18,48 +19,11 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs; | |||
| 18 | 19 | ||
| 19 | // TODO(Rodrigo): Optimize this structure. | 20 | // TODO(Rodrigo): Optimize this structure. |
| 20 | 21 | ||
| 21 | struct FixedPipelineState { | 22 | template <class T> |
| 22 | using PixelFormat = VideoCore::Surface::PixelFormat; | 23 | inline constexpr bool IsHashable = std::has_unique_object_representations_v<T>&& |
| 23 | 24 | std::is_trivially_copyable_v<T>&& std::is_trivially_constructible_v<T>; | |
| 24 | struct VertexBinding { | ||
| 25 | constexpr VertexBinding(u32 index, u32 stride, u32 divisor) | ||
| 26 | : index{index}, stride{stride}, divisor{divisor} {} | ||
| 27 | VertexBinding() = default; | ||
| 28 | |||
| 29 | u32 index; | ||
| 30 | u32 stride; | ||
| 31 | u32 divisor; | ||
| 32 | |||
| 33 | std::size_t Hash() const noexcept; | ||
| 34 | |||
| 35 | bool operator==(const VertexBinding& rhs) const noexcept; | ||
| 36 | |||
| 37 | bool operator!=(const VertexBinding& rhs) const noexcept { | ||
| 38 | return !operator==(rhs); | ||
| 39 | } | ||
| 40 | }; | ||
| 41 | |||
| 42 | struct VertexAttribute { | ||
| 43 | constexpr VertexAttribute(u32 index, u32 buffer, Maxwell::VertexAttribute::Type type, | ||
| 44 | Maxwell::VertexAttribute::Size size, u32 offset) | ||
| 45 | : index{index}, buffer{buffer}, type{type}, size{size}, offset{offset} {} | ||
| 46 | VertexAttribute() = default; | ||
| 47 | |||
| 48 | u32 index; | ||
| 49 | u32 buffer; | ||
| 50 | Maxwell::VertexAttribute::Type type; | ||
| 51 | Maxwell::VertexAttribute::Size size; | ||
| 52 | u32 offset; | ||
| 53 | |||
| 54 | std::size_t Hash() const noexcept; | ||
| 55 | |||
| 56 | bool operator==(const VertexAttribute& rhs) const noexcept; | ||
| 57 | |||
| 58 | bool operator!=(const VertexAttribute& rhs) const noexcept { | ||
| 59 | return !operator==(rhs); | ||
| 60 | } | ||
| 61 | }; | ||
| 62 | 25 | ||
| 26 | struct FixedPipelineState { | ||
| 63 | struct StencilFace { | 27 | struct StencilFace { |
| 64 | constexpr StencilFace(Maxwell::StencilOp action_stencil_fail, | 28 | constexpr StencilFace(Maxwell::StencilOp action_stencil_fail, |
| 65 | Maxwell::StencilOp action_depth_fail, | 29 | Maxwell::StencilOp action_depth_fail, |
| @@ -114,10 +78,52 @@ struct FixedPipelineState { | |||
| 114 | }; | 78 | }; |
| 115 | 79 | ||
| 116 | struct VertexInput { | 80 | struct VertexInput { |
| 117 | std::size_t num_bindings = 0; | 81 | union Binding { |
| 118 | std::size_t num_attributes = 0; | 82 | u16 raw; |
| 119 | std::array<VertexBinding, Maxwell::NumVertexArrays> bindings; | 83 | BitField<0, 1, u16> enabled; |
| 120 | std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; | 84 | BitField<1, 12, u16> stride; |
| 85 | }; | ||
| 86 | |||
| 87 | union Attribute { | ||
| 88 | u32 raw; | ||
| 89 | BitField<0, 1, u32> enabled; | ||
| 90 | BitField<1, 5, u32> buffer; | ||
| 91 | BitField<6, 14, u32> offset; | ||
| 92 | BitField<20, 3, u32> type; | ||
| 93 | BitField<23, 6, u32> size; | ||
| 94 | |||
| 95 | constexpr Maxwell::VertexAttribute::Type Type() const noexcept { | ||
| 96 | return static_cast<Maxwell::VertexAttribute::Type>(type.Value()); | ||
| 97 | } | ||
| 98 | |||
| 99 | constexpr Maxwell::VertexAttribute::Size Size() const noexcept { | ||
| 100 | return static_cast<Maxwell::VertexAttribute::Size>(size.Value()); | ||
| 101 | } | ||
| 102 | }; | ||
| 103 | |||
| 104 | std::array<Binding, Maxwell::NumVertexArrays> bindings; | ||
| 105 | std::array<u32, Maxwell::NumVertexArrays> binding_divisors; | ||
| 106 | std::array<Attribute, Maxwell::NumVertexAttributes> attributes; | ||
| 107 | |||
| 108 | void SetBinding(std::size_t index, bool enabled, u32 stride, u32 divisor) noexcept { | ||
| 109 | auto& binding = bindings[index]; | ||
| 110 | binding.raw = 0; | ||
| 111 | binding.enabled.Assign(enabled ? 1 : 0); | ||
| 112 | binding.stride.Assign(stride); | ||
| 113 | binding_divisors[index] = divisor; | ||
| 114 | } | ||
| 115 | |||
| 116 | void SetAttribute(std::size_t index, bool enabled, u32 buffer, u32 offset, | ||
| 117 | Maxwell::VertexAttribute::Type type, | ||
| 118 | Maxwell::VertexAttribute::Size size) noexcept { | ||
| 119 | auto& attribute = attributes[index]; | ||
| 120 | attribute.raw = 0; | ||
| 121 | attribute.enabled.Assign(enabled ? 1 : 0); | ||
| 122 | attribute.buffer.Assign(buffer); | ||
| 123 | attribute.offset.Assign(offset); | ||
| 124 | attribute.type.Assign(static_cast<u32>(type)); | ||
| 125 | attribute.size.Assign(static_cast<u32>(size)); | ||
| 126 | } | ||
| 121 | 127 | ||
| 122 | std::size_t Hash() const noexcept; | 128 | std::size_t Hash() const noexcept; |
| 123 | 129 | ||
| @@ -127,6 +133,7 @@ struct FixedPipelineState { | |||
| 127 | return !operator==(rhs); | 133 | return !operator==(rhs); |
| 128 | } | 134 | } |
| 129 | }; | 135 | }; |
| 136 | static_assert(IsHashable<VertexInput>); | ||
| 130 | 137 | ||
| 131 | struct InputAssembly { | 138 | struct InputAssembly { |
| 132 | constexpr InputAssembly(Maxwell::PrimitiveTopology topology, bool primitive_restart_enable, | 139 | constexpr InputAssembly(Maxwell::PrimitiveTopology topology, bool primitive_restart_enable, |
| @@ -256,8 +263,6 @@ struct FixedPipelineState { | |||
| 256 | DepthStencil depth_stencil; | 263 | DepthStencil depth_stencil; |
| 257 | ColorBlending color_blending; | 264 | ColorBlending color_blending; |
| 258 | }; | 265 | }; |
| 259 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::VertexBinding>); | ||
| 260 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::VertexAttribute>); | ||
| 261 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::StencilFace>); | 266 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::StencilFace>); |
| 262 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::BlendingAttachment>); | 267 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::BlendingAttachment>); |
| 263 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::VertexInput>); | 268 | static_assert(std::is_trivially_copyable_v<FixedPipelineState::VertexInput>); |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index b540b838d..718feafbd 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -165,35 +165,41 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 165 | 165 | ||
| 166 | std::vector<VkVertexInputBindingDescription> vertex_bindings; | 166 | std::vector<VkVertexInputBindingDescription> vertex_bindings; |
| 167 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; | 167 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; |
| 168 | for (std::size_t i = 0; i < vi.num_bindings; ++i) { | 168 | for (std::size_t index = 0; index < std::size(vi.bindings); ++index) { |
| 169 | const auto& binding = vi.bindings[i]; | 169 | const auto& binding = vi.bindings[index]; |
| 170 | const bool instanced = binding.divisor != 0; | 170 | if (!binding.enabled) { |
| 171 | continue; | ||
| 172 | } | ||
| 173 | const bool instanced = vi.binding_divisors[index] != 0; | ||
| 171 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; | 174 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; |
| 172 | 175 | ||
| 173 | auto& vertex_binding = vertex_bindings.emplace_back(); | 176 | auto& vertex_binding = vertex_bindings.emplace_back(); |
| 174 | vertex_binding.binding = binding.index; | 177 | vertex_binding.binding = static_cast<u32>(index); |
| 175 | vertex_binding.stride = binding.stride; | 178 | vertex_binding.stride = binding.stride; |
| 176 | vertex_binding.inputRate = rate; | 179 | vertex_binding.inputRate = rate; |
| 177 | 180 | ||
| 178 | if (instanced) { | 181 | if (instanced) { |
| 179 | auto& binding_divisor = vertex_binding_divisors.emplace_back(); | 182 | auto& binding_divisor = vertex_binding_divisors.emplace_back(); |
| 180 | binding_divisor.binding = binding.index; | 183 | binding_divisor.binding = static_cast<u32>(index); |
| 181 | binding_divisor.divisor = binding.divisor; | 184 | binding_divisor.divisor = vi.binding_divisors[index]; |
| 182 | } | 185 | } |
| 183 | } | 186 | } |
| 184 | 187 | ||
| 185 | std::vector<VkVertexInputAttributeDescription> vertex_attributes; | 188 | std::vector<VkVertexInputAttributeDescription> vertex_attributes; |
| 186 | const auto& input_attributes = program[0]->entries.attributes; | 189 | const auto& input_attributes = program[0]->entries.attributes; |
| 187 | for (std::size_t i = 0; i < vi.num_attributes; ++i) { | 190 | for (std::size_t index = 0; index < std::size(vi.attributes); ++index) { |
| 188 | const auto& attribute = vi.attributes[i]; | 191 | const auto& attribute = vi.attributes[index]; |
| 189 | if (input_attributes.find(attribute.index) == input_attributes.end()) { | 192 | if (!attribute.enabled) { |
| 193 | continue; | ||
| 194 | } | ||
| 195 | if (input_attributes.find(static_cast<u32>(index)) == input_attributes.end()) { | ||
| 190 | // Skip attributes not used by the vertex shaders. | 196 | // Skip attributes not used by the vertex shaders. |
| 191 | continue; | 197 | continue; |
| 192 | } | 198 | } |
| 193 | auto& vertex_attribute = vertex_attributes.emplace_back(); | 199 | auto& vertex_attribute = vertex_attributes.emplace_back(); |
| 194 | vertex_attribute.location = attribute.index; | 200 | vertex_attribute.location = static_cast<u32>(index); |
| 195 | vertex_attribute.binding = attribute.buffer; | 201 | vertex_attribute.binding = attribute.buffer; |
| 196 | vertex_attribute.format = MaxwellToVK::VertexFormat(attribute.type, attribute.size); | 202 | vertex_attribute.format = MaxwellToVK::VertexFormat(attribute.Type(), attribute.Size()); |
| 197 | vertex_attribute.offset = attribute.offset; | 203 | vertex_attribute.offset = attribute.offset; |
| 198 | } | 204 | } |
| 199 | 205 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 90e3a8edd..083da9999 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -334,7 +334,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 334 | specialization.point_size = fixed_state.input_assembly.point_size; | 334 | specialization.point_size = fixed_state.input_assembly.point_size; |
| 335 | } | 335 | } |
| 336 | for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) { | 336 | for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) { |
| 337 | specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].type; | 337 | specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].Type(); |
| 338 | } | 338 | } |
| 339 | specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; | 339 | specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; |
| 340 | 340 | ||
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 4ca0febb8..7a6aa52bc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -806,25 +806,29 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex | |||
| 806 | BufferBindings& buffer_bindings) { | 806 | BufferBindings& buffer_bindings) { |
| 807 | const auto& regs = system.GPU().Maxwell3D().regs; | 807 | const auto& regs = system.GPU().Maxwell3D().regs; |
| 808 | 808 | ||
| 809 | for (u32 index = 0; index < static_cast<u32>(Maxwell::NumVertexAttributes); ++index) { | 809 | for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { |
| 810 | const auto& attrib = regs.vertex_attrib_format[index]; | 810 | const auto& attrib = regs.vertex_attrib_format[index]; |
| 811 | if (!attrib.IsValid()) { | 811 | if (!attrib.IsValid()) { |
| 812 | vertex_input.SetAttribute(index, false, 0, 0, {}, {}); | ||
| 812 | continue; | 813 | continue; |
| 813 | } | 814 | } |
| 814 | 815 | ||
| 815 | const auto& buffer = regs.vertex_array[attrib.buffer]; | 816 | [[maybe_unused]] const auto& buffer = regs.vertex_array[attrib.buffer]; |
| 816 | ASSERT(buffer.IsEnabled()); | 817 | ASSERT(buffer.IsEnabled()); |
| 817 | 818 | ||
| 818 | vertex_input.attributes[vertex_input.num_attributes++] = | 819 | vertex_input.SetAttribute(index, true, attrib.buffer, attrib.offset, attrib.type.Value(), |
| 819 | FixedPipelineState::VertexAttribute(index, attrib.buffer, attrib.type, attrib.size, | 820 | attrib.size.Value()); |
| 820 | attrib.offset); | ||
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | for (u32 index = 0; index < static_cast<u32>(Maxwell::NumVertexArrays); ++index) { | 823 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 824 | const auto& vertex_array = regs.vertex_array[index]; | 824 | const auto& vertex_array = regs.vertex_array[index]; |
| 825 | if (!vertex_array.IsEnabled()) { | 825 | if (!vertex_array.IsEnabled()) { |
| 826 | vertex_input.SetBinding(index, false, 0, 0); | ||
| 826 | continue; | 827 | continue; |
| 827 | } | 828 | } |
| 829 | vertex_input.SetBinding( | ||
| 830 | index, true, vertex_array.stride, | ||
| 831 | regs.instanced_arrays.IsInstancingEnabled(index) ? vertex_array.divisor : 0); | ||
| 828 | 832 | ||
| 829 | const GPUVAddr start{vertex_array.StartAddress()}; | 833 | const GPUVAddr start{vertex_array.StartAddress()}; |
| 830 | const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; | 834 | const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; |
| @@ -832,10 +836,6 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex | |||
| 832 | ASSERT(end > start); | 836 | ASSERT(end > start); |
| 833 | const std::size_t size{end - start + 1}; | 837 | const std::size_t size{end - start + 1}; |
| 834 | const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); | 838 | const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); |
| 835 | |||
| 836 | vertex_input.bindings[vertex_input.num_bindings++] = FixedPipelineState::VertexBinding( | ||
| 837 | index, vertex_array.stride, | ||
| 838 | regs.instanced_arrays.IsInstancingEnabled(index) ? vertex_array.divisor : 0); | ||
| 839 | buffer_bindings.AddVertexBinding(buffer, offset); | 839 | buffer_bindings.AddVertexBinding(buffer, offset); |
| 840 | } | 840 | } |
| 841 | } | 841 | } |