summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp92
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h165
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp20
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h3
7 files changed, 143 insertions, 155 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 424278816..6b5264c22 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -39,28 +39,21 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
39 39
40} // Anonymous namespace 40} // Anonymous namespace
41 41
42void FixedPipelineState::DepthStencil::Fill(const Maxwell& regs) noexcept { 42void FixedPipelineState::VertexInput::Fill(const Maxwell& regs) noexcept {
43 raw = 0; 43 for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
44 front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail)); 44 const auto& input = regs.vertex_attrib_format[index];
45 front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail)); 45 auto& attribute = attributes[index];
46 front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass)); 46 attribute.raw = 0;
47 front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func)); 47 attribute.enabled.Assign(input.IsConstant() ? 0 : 1);
48 if (regs.stencil_two_side_enable) { 48 attribute.buffer.Assign(input.buffer);
49 back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail)); 49 attribute.offset.Assign(input.offset);
50 back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail)); 50 attribute.type.Assign(static_cast<u32>(input.type.Value()));
51 back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass)); 51 attribute.size.Assign(static_cast<u32>(input.size.Value()));
52 back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func)); 52 }
53 } else { 53 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
54 back.action_stencil_fail.Assign(front.action_stencil_fail); 54 binding_divisors[index] =
55 back.action_depth_fail.Assign(front.action_depth_fail); 55 regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0;
56 back.action_depth_pass.Assign(front.action_depth_pass);
57 back.test_func.Assign(front.test_func);
58 } 56 }
59 depth_test_enable.Assign(regs.depth_test_enable);
60 depth_write_enable.Assign(regs.depth_write_enabled);
61 depth_bounds_enable.Assign(regs.depth_bounds_enable);
62 stencil_enable.Assign(regs.stencil_enable);
63 depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
64} 57}
65 58
66void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept { 59void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
@@ -70,21 +63,11 @@ void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept {
70 regs.polygon_offset_fill_enable}; 63 regs.polygon_offset_fill_enable};
71 const u32 topology_index = static_cast<u32>(regs.draw.topology.Value()); 64 const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
72 65
73 u32 packed_front_face = PackFrontFace(regs.front_face);
74 if (regs.screen_y_control.triangle_rast_flip != 0) {
75 // Flip front face
76 packed_front_face = 1 - packed_front_face;
77 }
78
79 raw = 0; 66 raw = 0;
80 topology.Assign(topology_index);
81 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); 67 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
82 cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);
83 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); 68 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
84 depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); 69 depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value());
85 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); 70 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
86 cull_face.Assign(PackCullFace(regs.cull_face));
87 front_face.Assign(packed_front_face);
88 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); 71 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
89 patch_control_points_minus_one.Assign(regs.patch_vertices - 1); 72 patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
90 tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value())); 73 tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value()));
@@ -147,11 +130,56 @@ void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size
147 enable.Assign(1); 130 enable.Assign(1);
148} 131}
149 132
133void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) {
134 const u32 topology_index = static_cast<u32>(regs.draw.topology.Value());
135 u32 packed_front_face = PackFrontFace(regs.front_face);
136 if (regs.screen_y_control.triangle_rast_flip != 0) {
137 // Flip front face
138 packed_front_face = 1 - packed_front_face;
139 }
140
141 raw1 = 0;
142 raw2 = 0;
143 front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail));
144 front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail));
145 front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass));
146 front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func));
147 if (regs.stencil_two_side_enable) {
148 back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail));
149 back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail));
150 back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass));
151 back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func));
152 } else {
153 back.action_stencil_fail.Assign(front.action_stencil_fail);
154 back.action_depth_fail.Assign(front.action_depth_fail);
155 back.action_depth_pass.Assign(front.action_depth_pass);
156 back.test_func.Assign(front.test_func);
157 }
158 stencil_enable.Assign(regs.stencil_enable);
159 depth_write_enable.Assign(regs.depth_write_enabled);
160 depth_bounds_enable.Assign(regs.depth_bounds_enable);
161 depth_test_enable.Assign(regs.depth_test_enable);
162 front_face.Assign(packed_front_face);
163 depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
164 topology.Assign(topology_index);
165 cull_face.Assign(PackCullFace(regs.cull_face));
166 cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);
167
168 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
169 const auto& input = regs.vertex_array[index];
170 VertexBinding& binding = vertex_bindings[index];
171 binding.raw = 0;
172 binding.enabled.Assign(input.IsEnabled() ? 1 : 0);
173 binding.stride.Assign(static_cast<u16>(input.stride.Value()));
174 }
175}
176
150void FixedPipelineState::Fill(const Maxwell& regs) { 177void FixedPipelineState::Fill(const Maxwell& regs) {
178 vertex_input.Fill(regs);
151 rasterizer.Fill(regs); 179 rasterizer.Fill(regs);
152 depth_stencil.Fill(regs);
153 color_blending.Fill(regs); 180 color_blending.Fill(regs);
154 viewport_swizzles.Fill(regs); 181 viewport_swizzles.Fill(regs);
182 dynamic_state.Fill(regs);
155} 183}
156 184
157std::size_t FixedPipelineState::Hash() const noexcept { 185std::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 31a6398f2..54474fee7 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -60,14 +60,6 @@ struct FixedPipelineState {
60 60
61 void Fill(const Maxwell& regs, std::size_t index); 61 void Fill(const Maxwell& regs, std::size_t index);
62 62
63 std::size_t Hash() const noexcept;
64
65 bool operator==(const BlendingAttachment& rhs) const noexcept;
66
67 bool operator!=(const BlendingAttachment& rhs) const noexcept {
68 return !operator==(rhs);
69 }
70
71 constexpr std::array<bool, 4> Mask() const noexcept { 63 constexpr std::array<bool, 4> Mask() const noexcept {
72 return {mask_r != 0, mask_g != 0, mask_b != 0, mask_a != 0}; 64 return {mask_r != 0, mask_g != 0, mask_b != 0, mask_a != 0};
73 } 65 }
@@ -98,12 +90,6 @@ struct FixedPipelineState {
98 }; 90 };
99 91
100 struct VertexInput { 92 struct VertexInput {
101 union Binding {
102 u16 raw;
103 BitField<0, 1, u16> enabled;
104 BitField<1, 12, u16> stride;
105 };
106
107 union Attribute { 93 union Attribute {
108 u32 raw; 94 u32 raw;
109 BitField<0, 1, u32> enabled; 95 BitField<0, 1, u32> enabled;
@@ -121,130 +107,121 @@ struct FixedPipelineState {
121 } 107 }
122 }; 108 };
123 109
124 std::array<Binding, Maxwell::NumVertexArrays> bindings;
125 std::array<u32, Maxwell::NumVertexArrays> binding_divisors; 110 std::array<u32, Maxwell::NumVertexArrays> binding_divisors;
126 std::array<Attribute, Maxwell::NumVertexAttributes> attributes; 111 std::array<Attribute, Maxwell::NumVertexAttributes> attributes;
127 112
128 void SetBinding(std::size_t index, bool enabled, u32 stride, u32 divisor) noexcept { 113 void Fill(const Maxwell& regs) noexcept;
129 auto& binding = bindings[index];
130 binding.raw = 0;
131 binding.enabled.Assign(enabled ? 1 : 0);
132 binding.stride.Assign(static_cast<u16>(stride));
133 binding_divisors[index] = divisor;
134 }
135
136 void SetAttribute(std::size_t index, bool enabled, u32 buffer, u32 offset,
137 Maxwell::VertexAttribute::Type type,
138 Maxwell::VertexAttribute::Size size) noexcept {
139 auto& attribute = attributes[index];
140 attribute.raw = 0;
141 attribute.enabled.Assign(enabled ? 1 : 0);
142 attribute.buffer.Assign(buffer);
143 attribute.offset.Assign(offset);
144 attribute.type.Assign(static_cast<u32>(type));
145 attribute.size.Assign(static_cast<u32>(size));
146 }
147 }; 114 };
148 115
149 struct Rasterizer { 116 struct Rasterizer {
150 union { 117 union {
151 u32 raw; 118 u32 raw;
152 BitField<0, 4, u32> topology; 119 BitField<0, 1, u32> primitive_restart_enable;
153 BitField<4, 1, u32> primitive_restart_enable; 120 BitField<1, 1, u32> depth_bias_enable;
154 BitField<5, 1, u32> cull_enable; 121 BitField<2, 1, u32> depth_clamp_disabled;
155 BitField<6, 1, u32> depth_bias_enable; 122 BitField<3, 1, u32> ndc_minus_one_to_one;
156 BitField<7, 1, u32> depth_clamp_disabled; 123 BitField<4, 2, u32> polygon_mode;
157 BitField<8, 1, u32> ndc_minus_one_to_one; 124 BitField<6, 5, u32> patch_control_points_minus_one;
158 BitField<9, 2, u32> cull_face; 125 BitField<11, 2, u32> tessellation_primitive;
159 BitField<11, 1, u32> front_face; 126 BitField<13, 2, u32> tessellation_spacing;
160 BitField<12, 2, u32> polygon_mode; 127 BitField<15, 1, u32> tessellation_clockwise;
161 BitField<14, 5, u32> patch_control_points_minus_one; 128 BitField<16, 1, u32> logic_op_enable;
162 BitField<19, 2, u32> tessellation_primitive; 129 BitField<17, 4, u32> logic_op;
163 BitField<21, 2, u32> tessellation_spacing; 130 BitField<21, 1, u32> rasterize_enable;
164 BitField<23, 1, u32> tessellation_clockwise;
165 BitField<24, 1, u32> logic_op_enable;
166 BitField<25, 4, u32> logic_op;
167 BitField<29, 1, u32> rasterize_enable;
168 }; 131 };
169 132
170 // TODO(Rodrigo): Move this to push constants 133 // TODO(Rodrigo): Move this to push constants
171 u32 point_size; 134 u32 point_size;
172 135
173 void Fill(const Maxwell& regs) noexcept; 136 void Fill(const Maxwell& regs) noexcept;
137 };
174 138
175 constexpr Maxwell::PrimitiveTopology Topology() const noexcept { 139 struct ColorBlending {
176 return static_cast<Maxwell::PrimitiveTopology>(topology.Value()); 140 std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments;
177 }
178 141
179 Maxwell::CullFace CullFace() const noexcept { 142 void Fill(const Maxwell& regs) noexcept;
180 return UnpackCullFace(cull_face.Value()); 143 };
181 }
182 144
183 Maxwell::FrontFace FrontFace() const noexcept { 145 struct ViewportSwizzles {
184 return UnpackFrontFace(front_face.Value()); 146 std::array<u16, Maxwell::NumViewports> swizzles;
185 } 147
148 void Fill(const Maxwell& regs) noexcept;
186 }; 149 };
187 150
188 struct DepthStencil { 151 template <std::size_t Position>
189 template <std::size_t Position> 152 union StencilFace {
190 union StencilFace { 153 BitField<Position + 0, 3, u32> action_stencil_fail;
191 BitField<Position + 0, 3, u32> action_stencil_fail; 154 BitField<Position + 3, 3, u32> action_depth_fail;
192 BitField<Position + 3, 3, u32> action_depth_fail; 155 BitField<Position + 6, 3, u32> action_depth_pass;
193 BitField<Position + 6, 3, u32> action_depth_pass; 156 BitField<Position + 9, 3, u32> test_func;
194 BitField<Position + 9, 3, u32> test_func;
195 157
196 Maxwell::StencilOp ActionStencilFail() const noexcept { 158 Maxwell::StencilOp ActionStencilFail() const noexcept {
197 return UnpackStencilOp(action_stencil_fail); 159 return UnpackStencilOp(action_stencil_fail);
198 } 160 }
199 161
200 Maxwell::StencilOp ActionDepthFail() const noexcept { 162 Maxwell::StencilOp ActionDepthFail() const noexcept {
201 return UnpackStencilOp(action_depth_fail); 163 return UnpackStencilOp(action_depth_fail);
202 } 164 }
203 165
204 Maxwell::StencilOp ActionDepthPass() const noexcept { 166 Maxwell::StencilOp ActionDepthPass() const noexcept {
205 return UnpackStencilOp(action_depth_pass); 167 return UnpackStencilOp(action_depth_pass);
206 } 168 }
207 169
208 Maxwell::ComparisonOp TestFunc() const noexcept { 170 Maxwell::ComparisonOp TestFunc() const noexcept {
209 return UnpackComparisonOp(test_func); 171 return UnpackComparisonOp(test_func);
210 } 172 }
211 }; 173 };
174
175 union VertexBinding {
176 u16 raw;
177 BitField<0, 12, u16> stride;
178 BitField<12, 1, u16> enabled;
179 };
212 180
181 struct DynamicState {
213 union { 182 union {
214 u32 raw; 183 u32 raw1;
215 StencilFace<0> front; 184 StencilFace<0> front;
216 StencilFace<12> back; 185 StencilFace<12> back;
217 BitField<24, 1, u32> depth_test_enable; 186 BitField<24, 1, u32> stencil_enable;
218 BitField<25, 1, u32> depth_write_enable; 187 BitField<25, 1, u32> depth_write_enable;
219 BitField<26, 1, u32> depth_bounds_enable; 188 BitField<26, 1, u32> depth_bounds_enable;
220 BitField<27, 1, u32> stencil_enable; 189 BitField<27, 1, u32> depth_test_enable;
221 BitField<28, 3, u32> depth_test_func; 190 BitField<28, 1, u32> front_face;
191 BitField<29, 3, u32> depth_test_func;
192 };
193 union {
194 u32 raw2;
195 BitField<0, 4, u32> topology;
196 BitField<4, 2, u32> cull_face;
197 BitField<6, 1, u32> cull_enable;
222 }; 198 };
199 std::array<VertexBinding, Maxwell::NumVertexArrays> vertex_bindings;
223 200
224 void Fill(const Maxwell& regs) noexcept; 201 void Fill(const Maxwell& regs);
225 202
226 Maxwell::ComparisonOp DepthTestFunc() const noexcept { 203 Maxwell::ComparisonOp DepthTestFunc() const noexcept {
227 return UnpackComparisonOp(depth_test_func); 204 return UnpackComparisonOp(depth_test_func);
228 } 205 }
229 };
230
231 struct ColorBlending {
232 std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments;
233 206
234 void Fill(const Maxwell& regs) noexcept; 207 Maxwell::CullFace CullFace() const noexcept {
235 }; 208 return UnpackCullFace(cull_face.Value());
209 }
236 210
237 struct ViewportSwizzles { 211 Maxwell::FrontFace FrontFace() const noexcept {
238 std::array<u16, Maxwell::NumViewports> swizzles; 212 return UnpackFrontFace(front_face.Value());
213 }
239 214
240 void Fill(const Maxwell& regs) noexcept; 215 constexpr Maxwell::PrimitiveTopology Topology() const noexcept {
216 return static_cast<Maxwell::PrimitiveTopology>(topology.Value());
217 }
241 }; 218 };
242 219
243 VertexInput vertex_input; 220 VertexInput vertex_input;
244 Rasterizer rasterizer; 221 Rasterizer rasterizer;
245 DepthStencil depth_stencil;
246 ColorBlending color_blending; 222 ColorBlending color_blending;
247 ViewportSwizzles viewport_swizzles; 223 ViewportSwizzles viewport_swizzles;
224 DynamicState dynamic_state;
248 225
249 void Fill(const Maxwell& regs); 226 void Fill(const Maxwell& regs);
250 227
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 69b6bba00..b892df412 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -177,15 +177,15 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules(
177vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, 177vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params,
178 const SPIRVProgram& program) const { 178 const SPIRVProgram& program) const {
179 const auto& vi = fixed_state.vertex_input; 179 const auto& vi = fixed_state.vertex_input;
180 const auto& ds = fixed_state.depth_stencil;
181 const auto& cd = fixed_state.color_blending; 180 const auto& cd = fixed_state.color_blending;
182 const auto& rs = fixed_state.rasterizer; 181 const auto& rs = fixed_state.rasterizer;
182 const auto& ds = fixed_state.dynamic_state;
183 const auto& viewport_swizzles = fixed_state.viewport_swizzles.swizzles; 183 const auto& viewport_swizzles = fixed_state.viewport_swizzles.swizzles;
184 184
185 std::vector<VkVertexInputBindingDescription> vertex_bindings; 185 std::vector<VkVertexInputBindingDescription> vertex_bindings;
186 std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; 186 std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors;
187 for (std::size_t index = 0; index < std::size(vi.bindings); ++index) { 187 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
188 const auto& binding = vi.bindings[index]; 188 const auto& binding = ds.vertex_bindings[index];
189 if (!binding.enabled) { 189 if (!binding.enabled) {
190 continue; 190 continue;
191 } 191 }
@@ -244,7 +244,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
244 input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 244 input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
245 input_assembly_ci.pNext = nullptr; 245 input_assembly_ci.pNext = nullptr;
246 input_assembly_ci.flags = 0; 246 input_assembly_ci.flags = 0;
247 input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, rs.Topology()); 247 input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, ds.Topology());
248 input_assembly_ci.primitiveRestartEnable = 248 input_assembly_ci.primitiveRestartEnable =
249 rs.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology); 249 rs.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology);
250 250
@@ -284,8 +284,8 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
284 rasterization_ci.rasterizerDiscardEnable = rs.rasterize_enable == 0 ? VK_TRUE : VK_FALSE; 284 rasterization_ci.rasterizerDiscardEnable = rs.rasterize_enable == 0 ? VK_TRUE : VK_FALSE;
285 rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; 285 rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL;
286 rasterization_ci.cullMode = 286 rasterization_ci.cullMode =
287 rs.cull_enable ? MaxwellToVK::CullFace(rs.CullFace()) : VK_CULL_MODE_NONE; 287 ds.cull_enable ? MaxwellToVK::CullFace(ds.CullFace()) : VK_CULL_MODE_NONE;
288 rasterization_ci.frontFace = MaxwellToVK::FrontFace(rs.FrontFace()); 288 rasterization_ci.frontFace = MaxwellToVK::FrontFace(ds.FrontFace());
289 rasterization_ci.depthBiasEnable = rs.depth_bias_enable; 289 rasterization_ci.depthBiasEnable = rs.depth_bias_enable;
290 rasterization_ci.depthBiasConstantFactor = 0.0f; 290 rasterization_ci.depthBiasConstantFactor = 0.0f;
291 rasterization_ci.depthBiasClamp = 0.0f; 291 rasterization_ci.depthBiasClamp = 0.0f;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index ea66e621e..9fcb46f8a 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -312,7 +312,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
312 const auto& gpu = system.GPU().Maxwell3D(); 312 const auto& gpu = system.GPU().Maxwell3D();
313 313
314 Specialization specialization; 314 Specialization specialization;
315 if (fixed_state.rasterizer.Topology() == Maxwell::PrimitiveTopology::Points) { 315 if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points) {
316 float point_size; 316 float point_size;
317 std::memcpy(&point_size, &fixed_state.rasterizer.point_size, sizeof(float)); 317 std::memcpy(&point_size, &fixed_state.rasterizer.point_size, sizeof(float));
318 specialization.point_size = point_size; 318 specialization.point_size = point_size;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 0a36e5112..7f6c56261 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -44,10 +44,10 @@ class VKUpdateDescriptorQueue;
44using Maxwell = Tegra::Engines::Maxwell3D::Regs; 44using Maxwell = Tegra::Engines::Maxwell3D::Regs;
45 45
46struct GraphicsPipelineCacheKey { 46struct GraphicsPipelineCacheKey {
47 FixedPipelineState fixed_state;
48 RenderPassParams renderpass_params; 47 RenderPassParams renderpass_params;
48 u32 padding;
49 std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders; 49 std::array<GPUVAddr, Maxwell::MaxShaderProgram> shaders;
50 u64 padding; // This is necessary for unique object representations 50 FixedPipelineState fixed_state;
51 51
52 std::size_t Hash() const noexcept; 52 std::size_t Hash() const noexcept;
53 53
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index a8d94eac3..a42f8c564 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -822,7 +822,7 @@ RasterizerVulkan::DrawParameters RasterizerVulkan::SetupGeometry(FixedPipelineSt
822 const auto& gpu = system.GPU().Maxwell3D(); 822 const auto& gpu = system.GPU().Maxwell3D();
823 const auto& regs = gpu.regs; 823 const auto& regs = gpu.regs;
824 824
825 SetupVertexArrays(fixed_state.vertex_input, buffer_bindings); 825 SetupVertexArrays(buffer_bindings);
826 826
827 const u32 base_instance = regs.vb_base_instance; 827 const u32 base_instance = regs.vb_base_instance;
828 const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1; 828 const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1;
@@ -940,30 +940,14 @@ void RasterizerVulkan::EndTransformFeedback() {
940 [](vk::CommandBuffer cmdbuf) { cmdbuf.EndTransformFeedbackEXT(0, 0, nullptr, nullptr); }); 940 [](vk::CommandBuffer cmdbuf) { cmdbuf.EndTransformFeedbackEXT(0, 0, nullptr, nullptr); });
941} 941}
942 942
943void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, 943void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) {
944 BufferBindings& buffer_bindings) {
945 const auto& regs = system.GPU().Maxwell3D().regs; 944 const auto& regs = system.GPU().Maxwell3D().regs;
946 945
947 for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
948 const auto& attrib = regs.vertex_attrib_format[index];
949 if (attrib.IsConstant()) {
950 vertex_input.SetAttribute(index, false, 0, 0, {}, {});
951 continue;
952 }
953 vertex_input.SetAttribute(index, true, attrib.buffer, attrib.offset, attrib.type.Value(),
954 attrib.size.Value());
955 }
956
957 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 946 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
958 const auto& vertex_array = regs.vertex_array[index]; 947 const auto& vertex_array = regs.vertex_array[index];
959 if (!vertex_array.IsEnabled()) { 948 if (!vertex_array.IsEnabled()) {
960 vertex_input.SetBinding(index, false, 0, 0);
961 continue; 949 continue;
962 } 950 }
963 vertex_input.SetBinding(
964 index, true, vertex_array.stride,
965 regs.instanced_arrays.IsInstancingEnabled(index) ? vertex_array.divisor : 0);
966
967 const GPUVAddr start{vertex_array.StartAddress()}; 951 const GPUVAddr start{vertex_array.StartAddress()};
968 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; 952 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
969 953
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 83e00e7e9..e1cd1e392 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -185,8 +185,7 @@ private:
185 185
186 bool WalkAttachmentOverlaps(const CachedSurfaceView& attachment); 186 bool WalkAttachmentOverlaps(const CachedSurfaceView& attachment);
187 187
188 void SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, 188 void SetupVertexArrays(BufferBindings& buffer_bindings);
189 BufferBindings& buffer_bindings);
190 189
191 void SetupIndexBuffer(BufferBindings& buffer_bindings, DrawParameters& params, bool is_indexed); 190 void SetupIndexBuffer(BufferBindings& buffer_bindings, DrawParameters& params, bool is_indexed);
192 191