diff options
| author | 2020-03-02 21:36:25 -0300 | |
|---|---|---|
| committer | 2020-03-13 18:33:05 -0300 | |
| commit | 7acebd7eb67032e51dd2985d847e40c216944f92 (patch) | |
| tree | 659db2e0083a821853ac099da7385e1074504e29 /src/video_core | |
| parent | gl_rasterizer: Implement transform feedback bindings (diff) | |
| download | yuzu-7acebd7eb67032e51dd2985d847e40c216944f92.tar.gz yuzu-7acebd7eb67032e51dd2985d847e40c216944f92.tar.xz yuzu-7acebd7eb67032e51dd2985d847e40c216944f92.zip | |
vk_shader_decompiler: Use registry for specialization
Diffstat (limited to 'src/video_core')
4 files changed, 37 insertions, 31 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ebf85f311..056ef495c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -273,9 +273,9 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 273 | specialization.workgroup_size = key.workgroup_size; | 273 | specialization.workgroup_size = key.workgroup_size; |
| 274 | specialization.shared_memory_size = key.shared_memory_size; | 274 | specialization.shared_memory_size = key.shared_memory_size; |
| 275 | 275 | ||
| 276 | const SPIRVShader spirv_shader{ | 276 | const SPIRVShader spirv_shader{Decompile(device, shader->GetIR(), ShaderType::Compute, |
| 277 | Decompile(device, shader->GetIR(), ShaderType::Compute, specialization), | 277 | shader->GetRegistry(), specialization), |
| 278 | shader->GetEntries()}; | 278 | shader->GetEntries()}; |
| 279 | entry = std::make_unique<VKComputePipeline>(device, scheduler, descriptor_pool, | 279 | entry = std::make_unique<VKComputePipeline>(device, scheduler, descriptor_pool, |
| 280 | update_descriptor_queue, spirv_shader); | 280 | update_descriptor_queue, spirv_shader); |
| 281 | return *entry; | 281 | return *entry; |
| @@ -324,8 +324,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 324 | const auto& gpu = system.GPU().Maxwell3D(); | 324 | const auto& gpu = system.GPU().Maxwell3D(); |
| 325 | 325 | ||
| 326 | Specialization specialization; | 326 | Specialization specialization; |
| 327 | specialization.primitive_topology = fixed_state.input_assembly.topology; | 327 | if (fixed_state.input_assembly.topology == Maxwell::PrimitiveTopology::Points) { |
| 328 | if (specialization.primitive_topology == Maxwell::PrimitiveTopology::Points) { | ||
| 329 | ASSERT(fixed_state.input_assembly.point_size != 0.0f); | 328 | ASSERT(fixed_state.input_assembly.point_size != 0.0f); |
| 330 | specialization.point_size = fixed_state.input_assembly.point_size; | 329 | specialization.point_size = fixed_state.input_assembly.point_size; |
| 331 | } | 330 | } |
| @@ -333,9 +332,6 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 333 | specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].type; | 332 | specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].type; |
| 334 | } | 333 | } |
| 335 | specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; | 334 | specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; |
| 336 | specialization.tessellation.primitive = fixed_state.tessellation.primitive; | ||
| 337 | specialization.tessellation.spacing = fixed_state.tessellation.spacing; | ||
| 338 | specialization.tessellation.clockwise = fixed_state.tessellation.clockwise; | ||
| 339 | 335 | ||
| 340 | SPIRVProgram program; | 336 | SPIRVProgram program; |
| 341 | std::vector<vk::DescriptorSetLayoutBinding> bindings; | 337 | std::vector<vk::DescriptorSetLayoutBinding> bindings; |
| @@ -356,8 +352,9 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 356 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 | 352 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 |
| 357 | const auto program_type = GetShaderType(program_enum); | 353 | const auto program_type = GetShaderType(program_enum); |
| 358 | const auto& entries = shader->GetEntries(); | 354 | const auto& entries = shader->GetEntries(); |
| 359 | program[stage] = {Decompile(device, shader->GetIR(), program_type, specialization), | 355 | program[stage] = { |
| 360 | entries}; | 356 | Decompile(device, shader->GetIR(), program_type, shader->GetRegistry(), specialization), |
| 357 | entries}; | ||
| 361 | 358 | ||
| 362 | if (program_enum == Maxwell::ShaderProgram::VertexA) { | 359 | if (program_enum == Maxwell::ShaderProgram::VertexA) { |
| 363 | // VertexB was combined with VertexA, so we skip the VertexB iteration | 360 | // VertexB was combined with VertexA, so we skip the VertexB iteration |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index e292526bb..21340c9a4 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -132,6 +132,10 @@ public: | |||
| 132 | return shader_ir; | 132 | return shader_ir; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | const VideoCommon::Shader::Registry& GetRegistry() const { | ||
| 136 | return registry; | ||
| 137 | } | ||
| 138 | |||
| 135 | const VideoCommon::Shader::ShaderIR& GetIR() const { | 139 | const VideoCommon::Shader::ShaderIR& GetIR() const { |
| 136 | return shader_ir; | 140 | return shader_ir; |
| 137 | } | 141 | } |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index cfcca5af0..699a538d6 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "video_core/renderer_vulkan/vk_shader_decompiler.h" | 24 | #include "video_core/renderer_vulkan/vk_shader_decompiler.h" |
| 25 | #include "video_core/shader/node.h" | 25 | #include "video_core/shader/node.h" |
| 26 | #include "video_core/shader/shader_ir.h" | 26 | #include "video_core/shader/shader_ir.h" |
| 27 | #include "video_core/shader/transform_feedback.h" | ||
| 27 | 28 | ||
| 28 | namespace Vulkan { | 29 | namespace Vulkan { |
| 29 | 30 | ||
| @@ -266,9 +267,10 @@ bool IsPrecise(Operation operand) { | |||
| 266 | class SPIRVDecompiler final : public Sirit::Module { | 267 | class SPIRVDecompiler final : public Sirit::Module { |
| 267 | public: | 268 | public: |
| 268 | explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, | 269 | explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, |
| 269 | const Specialization& specialization) | 270 | const Registry& registry, const Specialization& specialization) |
| 270 | : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()}, | 271 | : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()}, |
| 271 | specialization{specialization} { | 272 | registry{registry}, specialization{specialization}, |
| 273 | transform_feedback{BuildTransformFeedback(registry.GetGraphicsInfo())} { | ||
| 272 | AddCapability(spv::Capability::Shader); | 274 | AddCapability(spv::Capability::Shader); |
| 273 | AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess); | 275 | AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess); |
| 274 | AddCapability(spv::Capability::ImageQuery); | 276 | AddCapability(spv::Capability::ImageQuery); |
| @@ -318,25 +320,29 @@ public: | |||
| 318 | AddExecutionMode(main, spv::ExecutionMode::OutputVertices, | 320 | AddExecutionMode(main, spv::ExecutionMode::OutputVertices, |
| 319 | header.common2.threads_per_input_primitive); | 321 | header.common2.threads_per_input_primitive); |
| 320 | break; | 322 | break; |
| 321 | case ShaderType::TesselationEval: | 323 | case ShaderType::TesselationEval: { |
| 324 | const auto& info = registry.GetGraphicsInfo(); | ||
| 322 | AddCapability(spv::Capability::Tessellation); | 325 | AddCapability(spv::Capability::Tessellation); |
| 323 | AddEntryPoint(spv::ExecutionModel::TessellationEvaluation, main, "main", interfaces); | 326 | AddEntryPoint(spv::ExecutionModel::TessellationEvaluation, main, "main", interfaces); |
| 324 | AddExecutionMode(main, GetExecutionMode(specialization.tessellation.primitive)); | 327 | AddExecutionMode(main, GetExecutionMode(info.tessellation_primitive)); |
| 325 | AddExecutionMode(main, GetExecutionMode(specialization.tessellation.spacing)); | 328 | AddExecutionMode(main, GetExecutionMode(info.tessellation_spacing)); |
| 326 | AddExecutionMode(main, specialization.tessellation.clockwise | 329 | AddExecutionMode(main, info.tessellation_clockwise |
| 327 | ? spv::ExecutionMode::VertexOrderCw | 330 | ? spv::ExecutionMode::VertexOrderCw |
| 328 | : spv::ExecutionMode::VertexOrderCcw); | 331 | : spv::ExecutionMode::VertexOrderCcw); |
| 329 | break; | 332 | break; |
| 330 | case ShaderType::Geometry: | 333 | } |
| 334 | case ShaderType::Geometry: { | ||
| 335 | const auto& info = registry.GetGraphicsInfo(); | ||
| 331 | AddCapability(spv::Capability::Geometry); | 336 | AddCapability(spv::Capability::Geometry); |
| 332 | AddEntryPoint(spv::ExecutionModel::Geometry, main, "main", interfaces); | 337 | AddEntryPoint(spv::ExecutionModel::Geometry, main, "main", interfaces); |
| 333 | AddExecutionMode(main, GetExecutionMode(specialization.primitive_topology)); | 338 | AddExecutionMode(main, GetExecutionMode(info.primitive_topology)); |
| 334 | AddExecutionMode(main, GetExecutionMode(header.common3.output_topology)); | 339 | AddExecutionMode(main, GetExecutionMode(header.common3.output_topology)); |
| 335 | AddExecutionMode(main, spv::ExecutionMode::OutputVertices, | 340 | AddExecutionMode(main, spv::ExecutionMode::OutputVertices, |
| 336 | header.common4.max_output_vertices); | 341 | header.common4.max_output_vertices); |
| 337 | // TODO(Rodrigo): Where can we get this info from? | 342 | // TODO(Rodrigo): Where can we get this info from? |
| 338 | AddExecutionMode(main, spv::ExecutionMode::Invocations, 1U); | 343 | AddExecutionMode(main, spv::ExecutionMode::Invocations, 1U); |
| 339 | break; | 344 | break; |
| 345 | } | ||
| 340 | case ShaderType::Fragment: | 346 | case ShaderType::Fragment: |
| 341 | AddEntryPoint(spv::ExecutionModel::Fragment, main, "main", interfaces); | 347 | AddEntryPoint(spv::ExecutionModel::Fragment, main, "main", interfaces); |
| 342 | AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); | 348 | AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); |
| @@ -545,7 +551,8 @@ private: | |||
| 545 | if (stage != ShaderType::Geometry) { | 551 | if (stage != ShaderType::Geometry) { |
| 546 | return; | 552 | return; |
| 547 | } | 553 | } |
| 548 | const u32 num_input = GetNumPrimitiveTopologyVertices(specialization.primitive_topology); | 554 | const auto& info = registry.GetGraphicsInfo(); |
| 555 | const u32 num_input = GetNumPrimitiveTopologyVertices(info.primitive_topology); | ||
| 549 | DeclareInputVertexArray(num_input); | 556 | DeclareInputVertexArray(num_input); |
| 550 | DeclareOutputVertex(); | 557 | DeclareOutputVertex(); |
| 551 | } | 558 | } |
| @@ -898,7 +905,7 @@ private: | |||
| 898 | u32 GetNumInputVertices() const { | 905 | u32 GetNumInputVertices() const { |
| 899 | switch (stage) { | 906 | switch (stage) { |
| 900 | case ShaderType::Geometry: | 907 | case ShaderType::Geometry: |
| 901 | return GetNumPrimitiveTopologyVertices(specialization.primitive_topology); | 908 | return GetNumPrimitiveTopologyVertices(registry.GetGraphicsInfo().primitive_topology); |
| 902 | case ShaderType::TesselationControl: | 909 | case ShaderType::TesselationControl: |
| 903 | case ShaderType::TesselationEval: | 910 | case ShaderType::TesselationEval: |
| 904 | return NumInputPatches; | 911 | return NumInputPatches; |
| @@ -2495,7 +2502,9 @@ private: | |||
| 2495 | const ShaderIR& ir; | 2502 | const ShaderIR& ir; |
| 2496 | const ShaderType stage; | 2503 | const ShaderType stage; |
| 2497 | const Tegra::Shader::Header header; | 2504 | const Tegra::Shader::Header header; |
| 2505 | const Registry& registry; | ||
| 2498 | const Specialization& specialization; | 2506 | const Specialization& specialization; |
| 2507 | const std::unordered_map<u8, VaryingTFB> transform_feedback; | ||
| 2499 | 2508 | ||
| 2500 | const Id t_void = Name(TypeVoid(), "void"); | 2509 | const Id t_void = Name(TypeVoid(), "void"); |
| 2501 | 2510 | ||
| @@ -2870,8 +2879,9 @@ ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir) { | |||
| 2870 | } | 2879 | } |
| 2871 | 2880 | ||
| 2872 | std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, | 2881 | std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, |
| 2873 | ShaderType stage, const Specialization& specialization) { | 2882 | ShaderType stage, const VideoCommon::Shader::Registry& registry, |
| 2874 | return SPIRVDecompiler(device, ir, stage, specialization).Assemble(); | 2883 | const Specialization& specialization) { |
| 2884 | return SPIRVDecompiler(device, ir, stage, registry, specialization).Assemble(); | ||
| 2875 | } | 2885 | } |
| 2876 | 2886 | ||
| 2877 | } // namespace Vulkan | 2887 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h index f5dc14d9e..ffea4709e 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 16 | #include "video_core/engines/maxwell_3d.h" | 16 | #include "video_core/engines/maxwell_3d.h" |
| 17 | #include "video_core/engines/shader_type.h" | 17 | #include "video_core/engines/shader_type.h" |
| 18 | #include "video_core/shader/registry.h" | ||
| 18 | #include "video_core/shader/shader_ir.h" | 19 | #include "video_core/shader/shader_ir.h" |
| 19 | 20 | ||
| 20 | namespace Vulkan { | 21 | namespace Vulkan { |
| @@ -91,17 +92,9 @@ struct Specialization final { | |||
| 91 | u32 shared_memory_size{}; | 92 | u32 shared_memory_size{}; |
| 92 | 93 | ||
| 93 | // Graphics specific | 94 | // Graphics specific |
| 94 | Maxwell::PrimitiveTopology primitive_topology{}; | ||
| 95 | std::optional<float> point_size{}; | 95 | std::optional<float> point_size{}; |
| 96 | std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; | 96 | std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; |
| 97 | bool ndc_minus_one_to_one{}; | 97 | bool ndc_minus_one_to_one{}; |
| 98 | |||
| 99 | // Tessellation specific | ||
| 100 | struct { | ||
| 101 | Maxwell::TessellationPrimitive primitive{}; | ||
| 102 | Maxwell::TessellationSpacing spacing{}; | ||
| 103 | bool clockwise{}; | ||
| 104 | } tessellation; | ||
| 105 | }; | 98 | }; |
| 106 | // Old gcc versions don't consider this trivially copyable. | 99 | // Old gcc versions don't consider this trivially copyable. |
| 107 | // static_assert(std::is_trivially_copyable_v<Specialization>); | 100 | // static_assert(std::is_trivially_copyable_v<Specialization>); |
| @@ -114,6 +107,8 @@ struct SPIRVShader { | |||
| 114 | ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir); | 107 | ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir); |
| 115 | 108 | ||
| 116 | std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, | 109 | std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, |
| 117 | Tegra::Engines::ShaderType stage, const Specialization& specialization); | 110 | Tegra::Engines::ShaderType stage, |
| 111 | const VideoCommon::Shader::Registry& registry, | ||
| 112 | const Specialization& specialization); | ||
| 118 | 113 | ||
| 119 | } // namespace Vulkan | 114 | } // namespace Vulkan |