diff options
Diffstat (limited to 'src/video_core')
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 | ||
| 42 | void FixedPipelineState::DepthStencil::Fill(const Maxwell& regs) noexcept { | 42 | void 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 | ||
| 66 | void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept { | 59 | void 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 | ||
| 133 | void 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 | |||
| 150 | void FixedPipelineState::Fill(const Maxwell& regs) { | 177 | void 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 | ||
| 157 | std::size_t FixedPipelineState::Hash() const noexcept { | 185 | 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 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( | |||
| 177 | vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpass_params, | 177 | vk::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; | |||
| 44 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 44 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 45 | 45 | ||
| 46 | struct GraphicsPipelineCacheKey { | 46 | struct 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 | ||
| 943 | void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, | 943 | void 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 | ||