3
0
Fork 0
forked from suyu/suyu

vk_shader_decompiler: Use registry for specialization

This commit is contained in:
ReinUsesLisp 2020-03-02 21:36:25 -03:00
parent 8e9f23f393
commit 7acebd7eb6
4 changed files with 37 additions and 31 deletions

View file

@ -273,9 +273,9 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
specialization.workgroup_size = key.workgroup_size; specialization.workgroup_size = key.workgroup_size;
specialization.shared_memory_size = key.shared_memory_size; specialization.shared_memory_size = key.shared_memory_size;
const SPIRVShader spirv_shader{ const SPIRVShader spirv_shader{Decompile(device, shader->GetIR(), ShaderType::Compute,
Decompile(device, shader->GetIR(), ShaderType::Compute, specialization), shader->GetRegistry(), specialization),
shader->GetEntries()}; shader->GetEntries()};
entry = std::make_unique<VKComputePipeline>(device, scheduler, descriptor_pool, entry = std::make_unique<VKComputePipeline>(device, scheduler, descriptor_pool,
update_descriptor_queue, spirv_shader); update_descriptor_queue, spirv_shader);
return *entry; return *entry;
@ -324,8 +324,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
const auto& gpu = system.GPU().Maxwell3D(); const auto& gpu = system.GPU().Maxwell3D();
Specialization specialization; Specialization specialization;
specialization.primitive_topology = fixed_state.input_assembly.topology; if (fixed_state.input_assembly.topology == Maxwell::PrimitiveTopology::Points) {
if (specialization.primitive_topology == Maxwell::PrimitiveTopology::Points) {
ASSERT(fixed_state.input_assembly.point_size != 0.0f); ASSERT(fixed_state.input_assembly.point_size != 0.0f);
specialization.point_size = fixed_state.input_assembly.point_size; specialization.point_size = fixed_state.input_assembly.point_size;
} }
@ -333,9 +332,6 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].type; specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].type;
} }
specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one;
specialization.tessellation.primitive = fixed_state.tessellation.primitive;
specialization.tessellation.spacing = fixed_state.tessellation.spacing;
specialization.tessellation.clockwise = fixed_state.tessellation.clockwise;
SPIRVProgram program; SPIRVProgram program;
std::vector<vk::DescriptorSetLayoutBinding> bindings; std::vector<vk::DescriptorSetLayoutBinding> bindings;
@ -356,8 +352,9 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5
const auto program_type = GetShaderType(program_enum); const auto program_type = GetShaderType(program_enum);
const auto& entries = shader->GetEntries(); const auto& entries = shader->GetEntries();
program[stage] = {Decompile(device, shader->GetIR(), program_type, specialization), program[stage] = {
entries}; Decompile(device, shader->GetIR(), program_type, shader->GetRegistry(), specialization),
entries};
if (program_enum == Maxwell::ShaderProgram::VertexA) { if (program_enum == Maxwell::ShaderProgram::VertexA) {
// VertexB was combined with VertexA, so we skip the VertexB iteration // VertexB was combined with VertexA, so we skip the VertexB iteration

View file

@ -132,6 +132,10 @@ public:
return shader_ir; return shader_ir;
} }
const VideoCommon::Shader::Registry& GetRegistry() const {
return registry;
}
const VideoCommon::Shader::ShaderIR& GetIR() const { const VideoCommon::Shader::ShaderIR& GetIR() const {
return shader_ir; return shader_ir;
} }

View file

@ -24,6 +24,7 @@
#include "video_core/renderer_vulkan/vk_shader_decompiler.h" #include "video_core/renderer_vulkan/vk_shader_decompiler.h"
#include "video_core/shader/node.h" #include "video_core/shader/node.h"
#include "video_core/shader/shader_ir.h" #include "video_core/shader/shader_ir.h"
#include "video_core/shader/transform_feedback.h"
namespace Vulkan { namespace Vulkan {
@ -266,9 +267,10 @@ bool IsPrecise(Operation operand) {
class SPIRVDecompiler final : public Sirit::Module { class SPIRVDecompiler final : public Sirit::Module {
public: public:
explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage,
const Specialization& specialization) const Registry& registry, const Specialization& specialization)
: Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()}, : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()},
specialization{specialization} { registry{registry}, specialization{specialization},
transform_feedback{BuildTransformFeedback(registry.GetGraphicsInfo())} {
AddCapability(spv::Capability::Shader); AddCapability(spv::Capability::Shader);
AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess); AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess);
AddCapability(spv::Capability::ImageQuery); AddCapability(spv::Capability::ImageQuery);
@ -318,25 +320,29 @@ public:
AddExecutionMode(main, spv::ExecutionMode::OutputVertices, AddExecutionMode(main, spv::ExecutionMode::OutputVertices,
header.common2.threads_per_input_primitive); header.common2.threads_per_input_primitive);
break; break;
case ShaderType::TesselationEval: case ShaderType::TesselationEval: {
const auto& info = registry.GetGraphicsInfo();
AddCapability(spv::Capability::Tessellation); AddCapability(spv::Capability::Tessellation);
AddEntryPoint(spv::ExecutionModel::TessellationEvaluation, main, "main", interfaces); AddEntryPoint(spv::ExecutionModel::TessellationEvaluation, main, "main", interfaces);
AddExecutionMode(main, GetExecutionMode(specialization.tessellation.primitive)); AddExecutionMode(main, GetExecutionMode(info.tessellation_primitive));
AddExecutionMode(main, GetExecutionMode(specialization.tessellation.spacing)); AddExecutionMode(main, GetExecutionMode(info.tessellation_spacing));
AddExecutionMode(main, specialization.tessellation.clockwise AddExecutionMode(main, info.tessellation_clockwise
? spv::ExecutionMode::VertexOrderCw ? spv::ExecutionMode::VertexOrderCw
: spv::ExecutionMode::VertexOrderCcw); : spv::ExecutionMode::VertexOrderCcw);
break; break;
case ShaderType::Geometry: }
case ShaderType::Geometry: {
const auto& info = registry.GetGraphicsInfo();
AddCapability(spv::Capability::Geometry); AddCapability(spv::Capability::Geometry);
AddEntryPoint(spv::ExecutionModel::Geometry, main, "main", interfaces); AddEntryPoint(spv::ExecutionModel::Geometry, main, "main", interfaces);
AddExecutionMode(main, GetExecutionMode(specialization.primitive_topology)); AddExecutionMode(main, GetExecutionMode(info.primitive_topology));
AddExecutionMode(main, GetExecutionMode(header.common3.output_topology)); AddExecutionMode(main, GetExecutionMode(header.common3.output_topology));
AddExecutionMode(main, spv::ExecutionMode::OutputVertices, AddExecutionMode(main, spv::ExecutionMode::OutputVertices,
header.common4.max_output_vertices); header.common4.max_output_vertices);
// TODO(Rodrigo): Where can we get this info from? // TODO(Rodrigo): Where can we get this info from?
AddExecutionMode(main, spv::ExecutionMode::Invocations, 1U); AddExecutionMode(main, spv::ExecutionMode::Invocations, 1U);
break; break;
}
case ShaderType::Fragment: case ShaderType::Fragment:
AddEntryPoint(spv::ExecutionModel::Fragment, main, "main", interfaces); AddEntryPoint(spv::ExecutionModel::Fragment, main, "main", interfaces);
AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
@ -545,7 +551,8 @@ private:
if (stage != ShaderType::Geometry) { if (stage != ShaderType::Geometry) {
return; return;
} }
const u32 num_input = GetNumPrimitiveTopologyVertices(specialization.primitive_topology); const auto& info = registry.GetGraphicsInfo();
const u32 num_input = GetNumPrimitiveTopologyVertices(info.primitive_topology);
DeclareInputVertexArray(num_input); DeclareInputVertexArray(num_input);
DeclareOutputVertex(); DeclareOutputVertex();
} }
@ -898,7 +905,7 @@ private:
u32 GetNumInputVertices() const { u32 GetNumInputVertices() const {
switch (stage) { switch (stage) {
case ShaderType::Geometry: case ShaderType::Geometry:
return GetNumPrimitiveTopologyVertices(specialization.primitive_topology); return GetNumPrimitiveTopologyVertices(registry.GetGraphicsInfo().primitive_topology);
case ShaderType::TesselationControl: case ShaderType::TesselationControl:
case ShaderType::TesselationEval: case ShaderType::TesselationEval:
return NumInputPatches; return NumInputPatches;
@ -2495,7 +2502,9 @@ private:
const ShaderIR& ir; const ShaderIR& ir;
const ShaderType stage; const ShaderType stage;
const Tegra::Shader::Header header; const Tegra::Shader::Header header;
const Registry& registry;
const Specialization& specialization; const Specialization& specialization;
const std::unordered_map<u8, VaryingTFB> transform_feedback;
const Id t_void = Name(TypeVoid(), "void"); const Id t_void = Name(TypeVoid(), "void");
@ -2870,8 +2879,9 @@ ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir) {
} }
std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir,
ShaderType stage, const Specialization& specialization) { ShaderType stage, const VideoCommon::Shader::Registry& registry,
return SPIRVDecompiler(device, ir, stage, specialization).Assemble(); const Specialization& specialization) {
return SPIRVDecompiler(device, ir, stage, registry, specialization).Assemble();
} }
} // namespace Vulkan } // namespace Vulkan

View file

@ -15,6 +15,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h"
#include "video_core/engines/shader_type.h" #include "video_core/engines/shader_type.h"
#include "video_core/shader/registry.h"
#include "video_core/shader/shader_ir.h" #include "video_core/shader/shader_ir.h"
namespace Vulkan { namespace Vulkan {
@ -91,17 +92,9 @@ struct Specialization final {
u32 shared_memory_size{}; u32 shared_memory_size{};
// Graphics specific // Graphics specific
Maxwell::PrimitiveTopology primitive_topology{};
std::optional<float> point_size{}; std::optional<float> point_size{};
std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
bool ndc_minus_one_to_one{}; bool ndc_minus_one_to_one{};
// Tessellation specific
struct {
Maxwell::TessellationPrimitive primitive{};
Maxwell::TessellationSpacing spacing{};
bool clockwise{};
} tessellation;
}; };
// Old gcc versions don't consider this trivially copyable. // Old gcc versions don't consider this trivially copyable.
// static_assert(std::is_trivially_copyable_v<Specialization>); // static_assert(std::is_trivially_copyable_v<Specialization>);
@ -114,6 +107,8 @@ struct SPIRVShader {
ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir); ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir);
std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir, std::vector<u32> Decompile(const VKDevice& device, const VideoCommon::Shader::ShaderIR& ir,
Tegra::Engines::ShaderType stage, const Specialization& specialization); Tegra::Engines::ShaderType stage,
const VideoCommon::Shader::Registry& registry,
const Specialization& specialization);
} // namespace Vulkan } // namespace Vulkan