diff options
4 files changed, 84 insertions, 121 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 6b5264c22..07358b0f9 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -39,24 +39,7 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = { | |||
| 39 | 39 | ||
| 40 | } // Anonymous namespace | 40 | } // Anonymous namespace |
| 41 | 41 | ||
| 42 | void FixedPipelineState::VertexInput::Fill(const Maxwell& regs) noexcept { | 42 | void FixedPipelineState::Fill(const Maxwell& regs) { |
| 43 | for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | ||
| 44 | const auto& input = regs.vertex_attrib_format[index]; | ||
| 45 | auto& attribute = attributes[index]; | ||
| 46 | attribute.raw = 0; | ||
| 47 | attribute.enabled.Assign(input.IsConstant() ? 0 : 1); | ||
| 48 | attribute.buffer.Assign(input.buffer); | ||
| 49 | attribute.offset.Assign(input.offset); | ||
| 50 | attribute.type.Assign(static_cast<u32>(input.type.Value())); | ||
| 51 | attribute.size.Assign(static_cast<u32>(input.size.Value())); | ||
| 52 | } | ||
| 53 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | ||
| 54 | binding_divisors[index] = | ||
| 55 | regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept { | ||
| 60 | const auto& clip = regs.view_volume_clip_control; | 43 | const auto& clip = regs.view_volume_clip_control; |
| 61 | const std::array enabled_lut = {regs.polygon_offset_point_enable, | 44 | const std::array enabled_lut = {regs.polygon_offset_point_enable, |
| 62 | regs.polygon_offset_line_enable, | 45 | regs.polygon_offset_line_enable, |
| @@ -76,19 +59,34 @@ void FixedPipelineState::Rasterizer::Fill(const Maxwell& regs) noexcept { | |||
| 76 | logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); | 59 | logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); |
| 77 | logic_op.Assign(PackLogicOp(regs.logic_op.operation)); | 60 | logic_op.Assign(PackLogicOp(regs.logic_op.operation)); |
| 78 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); | 61 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); |
| 62 | |||
| 79 | std::memcpy(&point_size, ®s.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast | 63 | std::memcpy(&point_size, ®s.point_size, sizeof(point_size)); // TODO: C++20 std::bit_cast |
| 80 | } | ||
| 81 | 64 | ||
| 82 | void FixedPipelineState::ColorBlending::Fill(const Maxwell& regs) noexcept { | 65 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 66 | binding_divisors[index] = | ||
| 67 | regs.instanced_arrays.IsInstancingEnabled(index) ? regs.vertex_array[index].divisor : 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | ||
| 71 | const auto& input = regs.vertex_attrib_format[index]; | ||
| 72 | auto& attribute = attributes[index]; | ||
| 73 | attribute.raw = 0; | ||
| 74 | attribute.enabled.Assign(input.IsConstant() ? 0 : 1); | ||
| 75 | attribute.buffer.Assign(input.buffer); | ||
| 76 | attribute.offset.Assign(input.offset); | ||
| 77 | attribute.type.Assign(static_cast<u32>(input.type.Value())); | ||
| 78 | attribute.size.Assign(static_cast<u32>(input.size.Value())); | ||
| 79 | } | ||
| 80 | |||
| 83 | for (std::size_t index = 0; index < std::size(attachments); ++index) { | 81 | for (std::size_t index = 0; index < std::size(attachments); ++index) { |
| 84 | attachments[index].Fill(regs, index); | 82 | attachments[index].Fill(regs, index); |
| 85 | } | 83 | } |
| 86 | } | ||
| 87 | 84 | ||
| 88 | void FixedPipelineState::ViewportSwizzles::Fill(const Maxwell& regs) noexcept { | ||
| 89 | const auto& transform = regs.viewport_transform; | 85 | const auto& transform = regs.viewport_transform; |
| 90 | std::transform(transform.begin(), transform.end(), swizzles.begin(), | 86 | std::transform(transform.begin(), transform.end(), viewport_swizzles.begin(), |
| 91 | [](const auto& viewport) { return static_cast<u16>(viewport.swizzle.raw); }); | 87 | [](const auto& viewport) { return static_cast<u16>(viewport.swizzle.raw); }); |
| 88 | |||
| 89 | dynamic_state.Fill(regs); | ||
| 92 | } | 90 | } |
| 93 | 91 | ||
| 94 | void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) { | 92 | void FixedPipelineState::BlendingAttachment::Fill(const Maxwell& regs, std::size_t index) { |
| @@ -174,14 +172,6 @@ void FixedPipelineState::DynamicState::Fill(const Maxwell& regs) { | |||
| 174 | } | 172 | } |
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | void FixedPipelineState::Fill(const Maxwell& regs) { | ||
| 178 | vertex_input.Fill(regs); | ||
| 179 | rasterizer.Fill(regs); | ||
| 180 | color_blending.Fill(regs); | ||
| 181 | viewport_swizzles.Fill(regs); | ||
| 182 | dynamic_state.Fill(regs); | ||
| 183 | } | ||
| 184 | |||
| 185 | std::size_t FixedPipelineState::Hash() const noexcept { | 175 | std::size_t FixedPipelineState::Hash() const noexcept { |
| 186 | const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); | 176 | const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); |
| 187 | return static_cast<std::size_t>(hash); | 177 | return static_cast<std::size_t>(hash); |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 54474fee7..09d05702d 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -89,63 +89,21 @@ struct FixedPipelineState { | |||
| 89 | } | 89 | } |
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | struct VertexInput { | 92 | union VertexAttribute { |
| 93 | union Attribute { | 93 | u32 raw; |
| 94 | u32 raw; | 94 | BitField<0, 1, u32> enabled; |
| 95 | BitField<0, 1, u32> enabled; | 95 | BitField<1, 5, u32> buffer; |
| 96 | BitField<1, 5, u32> buffer; | 96 | BitField<6, 14, u32> offset; |
| 97 | BitField<6, 14, u32> offset; | 97 | BitField<20, 3, u32> type; |
| 98 | BitField<20, 3, u32> type; | 98 | BitField<23, 6, u32> size; |
| 99 | BitField<23, 6, u32> size; | 99 | |
| 100 | 100 | constexpr Maxwell::VertexAttribute::Type Type() const noexcept { | |
| 101 | constexpr Maxwell::VertexAttribute::Type Type() const noexcept { | 101 | return static_cast<Maxwell::VertexAttribute::Type>(type.Value()); |
| 102 | return static_cast<Maxwell::VertexAttribute::Type>(type.Value()); | 102 | } |
| 103 | } | ||
| 104 | |||
| 105 | constexpr Maxwell::VertexAttribute::Size Size() const noexcept { | ||
| 106 | return static_cast<Maxwell::VertexAttribute::Size>(size.Value()); | ||
| 107 | } | ||
| 108 | }; | ||
| 109 | |||
| 110 | std::array<u32, Maxwell::NumVertexArrays> binding_divisors; | ||
| 111 | std::array<Attribute, Maxwell::NumVertexAttributes> attributes; | ||
| 112 | |||
| 113 | void Fill(const Maxwell& regs) noexcept; | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct Rasterizer { | ||
| 117 | union { | ||
| 118 | u32 raw; | ||
| 119 | BitField<0, 1, u32> primitive_restart_enable; | ||
| 120 | BitField<1, 1, u32> depth_bias_enable; | ||
| 121 | BitField<2, 1, u32> depth_clamp_disabled; | ||
| 122 | BitField<3, 1, u32> ndc_minus_one_to_one; | ||
| 123 | BitField<4, 2, u32> polygon_mode; | ||
| 124 | BitField<6, 5, u32> patch_control_points_minus_one; | ||
| 125 | BitField<11, 2, u32> tessellation_primitive; | ||
| 126 | BitField<13, 2, u32> tessellation_spacing; | ||
| 127 | BitField<15, 1, u32> tessellation_clockwise; | ||
| 128 | BitField<16, 1, u32> logic_op_enable; | ||
| 129 | BitField<17, 4, u32> logic_op; | ||
| 130 | BitField<21, 1, u32> rasterize_enable; | ||
| 131 | }; | ||
| 132 | |||
| 133 | // TODO(Rodrigo): Move this to push constants | ||
| 134 | u32 point_size; | ||
| 135 | |||
| 136 | void Fill(const Maxwell& regs) noexcept; | ||
| 137 | }; | ||
| 138 | |||
| 139 | struct ColorBlending { | ||
| 140 | std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments; | ||
| 141 | |||
| 142 | void Fill(const Maxwell& regs) noexcept; | ||
| 143 | }; | ||
| 144 | |||
| 145 | struct ViewportSwizzles { | ||
| 146 | std::array<u16, Maxwell::NumViewports> swizzles; | ||
| 147 | 103 | ||
| 148 | void Fill(const Maxwell& regs) noexcept; | 104 | constexpr Maxwell::VertexAttribute::Size Size() const noexcept { |
| 105 | return static_cast<Maxwell::VertexAttribute::Size>(size.Value()); | ||
| 106 | } | ||
| 149 | }; | 107 | }; |
| 150 | 108 | ||
| 151 | template <std::size_t Position> | 109 | template <std::size_t Position> |
| @@ -217,10 +175,26 @@ struct FixedPipelineState { | |||
| 217 | } | 175 | } |
| 218 | }; | 176 | }; |
| 219 | 177 | ||
| 220 | VertexInput vertex_input; | 178 | union { |
| 221 | Rasterizer rasterizer; | 179 | u32 raw; |
| 222 | ColorBlending color_blending; | 180 | BitField<0, 1, u32> primitive_restart_enable; |
| 223 | ViewportSwizzles viewport_swizzles; | 181 | BitField<1, 1, u32> depth_bias_enable; |
| 182 | BitField<2, 1, u32> depth_clamp_disabled; | ||
| 183 | BitField<3, 1, u32> ndc_minus_one_to_one; | ||
| 184 | BitField<4, 2, u32> polygon_mode; | ||
| 185 | BitField<6, 5, u32> patch_control_points_minus_one; | ||
| 186 | BitField<11, 2, u32> tessellation_primitive; | ||
| 187 | BitField<13, 2, u32> tessellation_spacing; | ||
| 188 | BitField<15, 1, u32> tessellation_clockwise; | ||
| 189 | BitField<16, 1, u32> logic_op_enable; | ||
| 190 | BitField<17, 4, u32> logic_op; | ||
| 191 | BitField<21, 1, u32> rasterize_enable; | ||
| 192 | }; | ||
| 193 | u32 point_size; | ||
| 194 | std::array<u32, Maxwell::NumVertexArrays> binding_divisors; | ||
| 195 | std::array<VertexAttribute, Maxwell::NumVertexAttributes> attributes; | ||
| 196 | std::array<BlendingAttachment, Maxwell::NumRenderTargets> attachments; | ||
| 197 | std::array<u16, Maxwell::NumViewports> viewport_swizzles; | ||
| 224 | DynamicState dynamic_state; | 198 | DynamicState dynamic_state; |
| 225 | 199 | ||
| 226 | void Fill(const Maxwell& regs); | 200 | void Fill(const Maxwell& regs); |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 739801f5d..15d9ac3b0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -176,20 +176,18 @@ std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules( | |||
| 176 | 176 | ||
| 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& state = fixed_state; |
| 180 | const auto& cd = fixed_state.color_blending; | 180 | const auto& dynamic = fixed_state.dynamic_state; |
| 181 | const auto& rs = fixed_state.rasterizer; | 181 | const auto& viewport_swizzles = fixed_state.viewport_swizzles; |
| 182 | const auto& ds = fixed_state.dynamic_state; | ||
| 183 | const auto& viewport_swizzles = fixed_state.viewport_swizzles.swizzles; | ||
| 184 | 182 | ||
| 185 | std::vector<VkVertexInputBindingDescription> vertex_bindings; | 183 | std::vector<VkVertexInputBindingDescription> vertex_bindings; |
| 186 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; | 184 | std::vector<VkVertexInputBindingDivisorDescriptionEXT> vertex_binding_divisors; |
| 187 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 185 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 188 | const auto& binding = ds.vertex_bindings[index]; | 186 | const auto& binding = dynamic.vertex_bindings[index]; |
| 189 | if (!binding.enabled) { | 187 | if (!binding.enabled) { |
| 190 | continue; | 188 | continue; |
| 191 | } | 189 | } |
| 192 | const bool instanced = vi.binding_divisors[index] != 0; | 190 | const bool instanced = state.binding_divisors[index] != 0; |
| 193 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; | 191 | const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; |
| 194 | 192 | ||
| 195 | auto& vertex_binding = vertex_bindings.emplace_back(); | 193 | auto& vertex_binding = vertex_bindings.emplace_back(); |
| @@ -200,14 +198,14 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 200 | if (instanced) { | 198 | if (instanced) { |
| 201 | auto& binding_divisor = vertex_binding_divisors.emplace_back(); | 199 | auto& binding_divisor = vertex_binding_divisors.emplace_back(); |
| 202 | binding_divisor.binding = static_cast<u32>(index); | 200 | binding_divisor.binding = static_cast<u32>(index); |
| 203 | binding_divisor.divisor = vi.binding_divisors[index]; | 201 | binding_divisor.divisor = state.binding_divisors[index]; |
| 204 | } | 202 | } |
| 205 | } | 203 | } |
| 206 | 204 | ||
| 207 | std::vector<VkVertexInputAttributeDescription> vertex_attributes; | 205 | std::vector<VkVertexInputAttributeDescription> vertex_attributes; |
| 208 | const auto& input_attributes = program[0]->entries.attributes; | 206 | const auto& input_attributes = program[0]->entries.attributes; |
| 209 | for (std::size_t index = 0; index < std::size(vi.attributes); ++index) { | 207 | for (std::size_t index = 0; index < state.attributes.size(); ++index) { |
| 210 | const auto& attribute = vi.attributes[index]; | 208 | const auto& attribute = state.attributes[index]; |
| 211 | if (!attribute.enabled) { | 209 | if (!attribute.enabled) { |
| 212 | continue; | 210 | continue; |
| 213 | } | 211 | } |
| @@ -244,15 +242,15 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 244 | input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; | 242 | input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; |
| 245 | input_assembly_ci.pNext = nullptr; | 243 | input_assembly_ci.pNext = nullptr; |
| 246 | input_assembly_ci.flags = 0; | 244 | input_assembly_ci.flags = 0; |
| 247 | input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, ds.Topology()); | 245 | input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology()); |
| 248 | input_assembly_ci.primitiveRestartEnable = | 246 | input_assembly_ci.primitiveRestartEnable = |
| 249 | rs.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology); | 247 | state.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology); |
| 250 | 248 | ||
| 251 | VkPipelineTessellationStateCreateInfo tessellation_ci; | 249 | VkPipelineTessellationStateCreateInfo tessellation_ci; |
| 252 | tessellation_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; | 250 | tessellation_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; |
| 253 | tessellation_ci.pNext = nullptr; | 251 | tessellation_ci.pNext = nullptr; |
| 254 | tessellation_ci.flags = 0; | 252 | tessellation_ci.flags = 0; |
| 255 | tessellation_ci.patchControlPoints = rs.patch_control_points_minus_one.Value() + 1; | 253 | tessellation_ci.patchControlPoints = state.patch_control_points_minus_one.Value() + 1; |
| 256 | 254 | ||
| 257 | VkPipelineViewportStateCreateInfo viewport_ci; | 255 | VkPipelineViewportStateCreateInfo viewport_ci; |
| 258 | viewport_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; | 256 | viewport_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; |
| @@ -280,13 +278,13 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 280 | rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; | 278 | rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; |
| 281 | rasterization_ci.pNext = nullptr; | 279 | rasterization_ci.pNext = nullptr; |
| 282 | rasterization_ci.flags = 0; | 280 | rasterization_ci.flags = 0; |
| 283 | rasterization_ci.depthClampEnable = rs.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE; | 281 | rasterization_ci.depthClampEnable = state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE; |
| 284 | rasterization_ci.rasterizerDiscardEnable = rs.rasterize_enable == 0 ? VK_TRUE : VK_FALSE; | 282 | rasterization_ci.rasterizerDiscardEnable = state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE; |
| 285 | rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; | 283 | rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; |
| 286 | rasterization_ci.cullMode = | 284 | rasterization_ci.cullMode = |
| 287 | ds.cull_enable ? MaxwellToVK::CullFace(ds.CullFace()) : VK_CULL_MODE_NONE; | 285 | dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE; |
| 288 | rasterization_ci.frontFace = MaxwellToVK::FrontFace(ds.FrontFace()); | 286 | rasterization_ci.frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()); |
| 289 | rasterization_ci.depthBiasEnable = rs.depth_bias_enable; | 287 | rasterization_ci.depthBiasEnable = state.depth_bias_enable; |
| 290 | rasterization_ci.depthBiasConstantFactor = 0.0f; | 288 | rasterization_ci.depthBiasConstantFactor = 0.0f; |
| 291 | rasterization_ci.depthBiasClamp = 0.0f; | 289 | rasterization_ci.depthBiasClamp = 0.0f; |
| 292 | rasterization_ci.depthBiasSlopeFactor = 0.0f; | 290 | rasterization_ci.depthBiasSlopeFactor = 0.0f; |
| @@ -307,14 +305,15 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 307 | depth_stencil_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; | 305 | depth_stencil_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; |
| 308 | depth_stencil_ci.pNext = nullptr; | 306 | depth_stencil_ci.pNext = nullptr; |
| 309 | depth_stencil_ci.flags = 0; | 307 | depth_stencil_ci.flags = 0; |
| 310 | depth_stencil_ci.depthTestEnable = ds.depth_test_enable; | 308 | depth_stencil_ci.depthTestEnable = dynamic.depth_test_enable; |
| 311 | depth_stencil_ci.depthWriteEnable = ds.depth_write_enable; | 309 | depth_stencil_ci.depthWriteEnable = dynamic.depth_write_enable; |
| 312 | depth_stencil_ci.depthCompareOp = | 310 | depth_stencil_ci.depthCompareOp = dynamic.depth_test_enable |
| 313 | ds.depth_test_enable ? MaxwellToVK::ComparisonOp(ds.DepthTestFunc()) : VK_COMPARE_OP_ALWAYS; | 311 | ? MaxwellToVK::ComparisonOp(dynamic.DepthTestFunc()) |
| 314 | depth_stencil_ci.depthBoundsTestEnable = ds.depth_bounds_enable; | 312 | : VK_COMPARE_OP_ALWAYS; |
| 315 | depth_stencil_ci.stencilTestEnable = ds.stencil_enable; | 313 | depth_stencil_ci.depthBoundsTestEnable = dynamic.depth_bounds_enable; |
| 316 | depth_stencil_ci.front = GetStencilFaceState(ds.front); | 314 | depth_stencil_ci.stencilTestEnable = dynamic.stencil_enable; |
| 317 | depth_stencil_ci.back = GetStencilFaceState(ds.back); | 315 | depth_stencil_ci.front = GetStencilFaceState(dynamic.front); |
| 316 | depth_stencil_ci.back = GetStencilFaceState(dynamic.back); | ||
| 318 | depth_stencil_ci.minDepthBounds = 0.0f; | 317 | depth_stencil_ci.minDepthBounds = 0.0f; |
| 319 | depth_stencil_ci.maxDepthBounds = 0.0f; | 318 | depth_stencil_ci.maxDepthBounds = 0.0f; |
| 320 | 319 | ||
| @@ -324,7 +323,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa | |||
| 324 | static constexpr std::array COMPONENT_TABLE = { | 323 | static constexpr std::array COMPONENT_TABLE = { |
| 325 | VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, | 324 | VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, |
| 326 | VK_COLOR_COMPONENT_A_BIT}; | 325 | VK_COLOR_COMPONENT_A_BIT}; |
| 327 | const auto& blend = cd.attachments[index]; | 326 | const auto& blend = state.attachments[index]; |
| 328 | 327 | ||
| 329 | VkColorComponentFlags color_components = 0; | 328 | VkColorComponentFlags color_components = 0; |
| 330 | for (std::size_t i = 0; i < COMPONENT_TABLE.size(); ++i) { | 329 | for (std::size_t i = 0; i < COMPONENT_TABLE.size(); ++i) { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 9fcb46f8a..e684c17a6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -314,16 +314,16 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 314 | Specialization specialization; | 314 | Specialization specialization; |
| 315 | if (fixed_state.dynamic_state.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.point_size, sizeof(float)); |
| 318 | specialization.point_size = point_size; | 318 | specialization.point_size = point_size; |
| 319 | ASSERT(point_size != 0.0f); | 319 | ASSERT(point_size != 0.0f); |
| 320 | } | 320 | } |
| 321 | for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) { | 321 | for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) { |
| 322 | const auto& attribute = fixed_state.vertex_input.attributes[i]; | 322 | const auto& attribute = fixed_state.attributes[i]; |
| 323 | specialization.enabled_attributes[i] = attribute.enabled.Value() != 0; | 323 | specialization.enabled_attributes[i] = attribute.enabled.Value() != 0; |
| 324 | specialization.attribute_types[i] = attribute.Type(); | 324 | specialization.attribute_types[i] = attribute.Type(); |
| 325 | } | 325 | } |
| 326 | specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; | 326 | specialization.ndc_minus_one_to_one = fixed_state.ndc_minus_one_to_one; |
| 327 | 327 | ||
| 328 | SPIRVProgram program; | 328 | SPIRVProgram program; |
| 329 | std::vector<VkDescriptorSetLayoutBinding> bindings; | 329 | std::vector<VkDescriptorSetLayoutBinding> bindings; |