diff options
| author | 2021-03-19 19:28:31 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 260743f371236f7c57b01334b1c3474b15a47c39 (patch) | |
| tree | 312d89fa8215199ef5f7ec1fc84b025df526e107 /src/shader_recompiler/backend/spirv/emit_context.cpp | |
| parent | shader: Implement DADD (diff) | |
| download | yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.gz yuzu-260743f371236f7c57b01334b1c3474b15a47c39.tar.xz yuzu-260743f371236f7c57b01334b1c3474b15a47c39.zip | |
shader: Add partial rasterizer integration
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 204389d74..6c79b611b 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -62,18 +62,15 @@ void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_vie | |||
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | EmitContext::EmitContext(const Profile& profile_, IR::Program& program) | 65 | EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& binding) |
| 66 | : Sirit::Module(0x00010000), profile{profile_} { | 66 | : Sirit::Module(0x00010000), profile{profile_} { |
| 67 | AddCapability(spv::Capability::Shader); | 67 | AddCapability(spv::Capability::Shader); |
| 68 | DefineCommonTypes(program.info); | 68 | DefineCommonTypes(program.info); |
| 69 | DefineCommonConstants(); | 69 | DefineCommonConstants(); |
| 70 | DefineSpecialVariables(program.info); | 70 | DefineInterfaces(program.info, program.stage); |
| 71 | |||
| 72 | u32 binding{}; | ||
| 73 | DefineConstantBuffers(program.info, binding); | 71 | DefineConstantBuffers(program.info, binding); |
| 74 | DefineStorageBuffers(program.info, binding); | 72 | DefineStorageBuffers(program.info, binding); |
| 75 | DefineTextures(program.info, binding); | 73 | DefineTextures(program.info, binding); |
| 76 | |||
| 77 | DefineLabels(program); | 74 | DefineLabels(program); |
| 78 | } | 75 | } |
| 79 | 76 | ||
| @@ -96,6 +93,8 @@ Id EmitContext::Def(const IR::Value& value) { | |||
| 96 | return Constant(F32[1], value.F32()); | 93 | return Constant(F32[1], value.F32()); |
| 97 | case IR::Type::F64: | 94 | case IR::Type::F64: |
| 98 | return Constant(F64[1], value.F64()); | 95 | return Constant(F64[1], value.F64()); |
| 96 | case IR::Type::Label: | ||
| 97 | return value.Label()->Definition<Id>(); | ||
| 99 | default: | 98 | default: |
| 100 | throw NotImplementedException("Immediate type {}", value.Type()); | 99 | throw NotImplementedException("Immediate type {}", value.Type()); |
| 101 | } | 100 | } |
| @@ -109,6 +108,9 @@ void EmitContext::DefineCommonTypes(const Info& info) { | |||
| 109 | F32.Define(*this, TypeFloat(32), "f32"); | 108 | F32.Define(*this, TypeFloat(32), "f32"); |
| 110 | U32.Define(*this, TypeInt(32, false), "u32"); | 109 | U32.Define(*this, TypeInt(32, false), "u32"); |
| 111 | 110 | ||
| 111 | input_f32 = Name(TypePointer(spv::StorageClass::Input, F32[1]), "input_f32"); | ||
| 112 | output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); | ||
| 113 | |||
| 112 | if (info.uses_int8) { | 114 | if (info.uses_int8) { |
| 113 | AddCapability(spv::Capability::Int8); | 115 | AddCapability(spv::Capability::Int8); |
| 114 | U8 = Name(TypeInt(8, false), "u8"); | 116 | U8 = Name(TypeInt(8, false), "u8"); |
| @@ -139,15 +141,20 @@ void EmitContext::DefineCommonConstants() { | |||
| 139 | u32_zero_value = Constant(U32[1], 0U); | 141 | u32_zero_value = Constant(U32[1], 0U); |
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | void EmitContext::DefineSpecialVariables(const Info& info) { | 144 | void EmitContext::DefineInterfaces(const Info& info, Stage stage) { |
| 143 | const auto define{[this](Id type, spv::BuiltIn builtin, spv::StorageClass storage_class) { | 145 | const auto define{ |
| 144 | const Id pointer_type{TypePointer(storage_class, type)}; | 146 | [this](Id type, std::optional<spv::BuiltIn> builtin, spv::StorageClass storage_class) { |
| 145 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::Input)}; | 147 | const Id pointer_type{TypePointer(storage_class, type)}; |
| 146 | Decorate(id, spv::Decoration::BuiltIn, builtin); | 148 | const Id id{AddGlobalVariable(pointer_type, storage_class)}; |
| 147 | return id; | 149 | if (builtin) { |
| 148 | }}; | 150 | Decorate(id, spv::Decoration::BuiltIn, *builtin); |
| 151 | } | ||
| 152 | interfaces.push_back(id); | ||
| 153 | return id; | ||
| 154 | }}; | ||
| 149 | using namespace std::placeholders; | 155 | using namespace std::placeholders; |
| 150 | const auto define_input{std::bind(define, _1, _2, spv::StorageClass::Input)}; | 156 | const auto define_input{std::bind(define, _1, _2, spv::StorageClass::Input)}; |
| 157 | const auto define_output{std::bind(define, _1, _2, spv::StorageClass::Output)}; | ||
| 151 | 158 | ||
| 152 | if (info.uses_workgroup_id) { | 159 | if (info.uses_workgroup_id) { |
| 153 | workgroup_id = define_input(U32[3], spv::BuiltIn::WorkgroupId); | 160 | workgroup_id = define_input(U32[3], spv::BuiltIn::WorkgroupId); |
| @@ -155,6 +162,39 @@ void EmitContext::DefineSpecialVariables(const Info& info) { | |||
| 155 | if (info.uses_local_invocation_id) { | 162 | if (info.uses_local_invocation_id) { |
| 156 | local_invocation_id = define_input(U32[3], spv::BuiltIn::LocalInvocationId); | 163 | local_invocation_id = define_input(U32[3], spv::BuiltIn::LocalInvocationId); |
| 157 | } | 164 | } |
| 165 | if (info.loads_position) { | ||
| 166 | const bool is_fragment{stage != Stage::Fragment}; | ||
| 167 | const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord}; | ||
| 168 | input_position = define_input(F32[4], built_in); | ||
| 169 | } | ||
| 170 | for (size_t i = 0; i < info.loads_generics.size(); ++i) { | ||
| 171 | if (info.loads_generics[i]) { | ||
| 172 | // FIXME: Declare size from input | ||
| 173 | input_generics[i] = define_input(F32[4], std::nullopt); | ||
| 174 | Decorate(input_generics[i], spv::Decoration::Location, static_cast<u32>(i)); | ||
| 175 | Name(input_generics[i], fmt::format("in_attr{}", i)); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | if (info.stores_position) { | ||
| 179 | output_position = define_output(F32[4], spv::BuiltIn::Position); | ||
| 180 | } | ||
| 181 | for (size_t i = 0; i < info.stores_generics.size(); ++i) { | ||
| 182 | if (info.stores_generics[i]) { | ||
| 183 | output_generics[i] = define_output(F32[4], std::nullopt); | ||
| 184 | Decorate(output_generics[i], spv::Decoration::Location, static_cast<u32>(i)); | ||
| 185 | Name(output_generics[i], fmt::format("out_attr{}", i)); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | if (stage == Stage::Fragment) { | ||
| 189 | for (size_t i = 0; i < 8; ++i) { | ||
| 190 | if (!info.stores_frag_color[i]) { | ||
| 191 | continue; | ||
| 192 | } | ||
| 193 | frag_color[i] = define_output(F32[4], std::nullopt); | ||
| 194 | Decorate(frag_color[i], spv::Decoration::Location, static_cast<u32>(i)); | ||
| 195 | Name(frag_color[i], fmt::format("frag_color{}", i)); | ||
| 196 | } | ||
| 197 | } | ||
| 158 | } | 198 | } |
| 159 | 199 | ||
| 160 | void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | 200 | void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { |