diff options
| author | 2018-04-10 01:26:15 -0400 | |
|---|---|---|
| committer | 2018-04-17 16:36:38 -0400 | |
| commit | 8b4443c966c1f00ca468f41584b74fe22a4580af (patch) | |
| tree | 361d7f72d11b7deb442f749f57bb3d35d616c7ac /src | |
| parent | gl_shader_decompiler: Use fragment output color for GPR 0-3. (diff) | |
| download | yuzu-8b4443c966c1f00ca468f41584b74fe22a4580af.tar.gz yuzu-8b4443c966c1f00ca468f41584b74fe22a4580af.tar.xz yuzu-8b4443c966c1f00ca468f41584b74fe22a4580af.zip | |
gl_shader_decompiler: Add support for TEXS instruction.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 36 |
2 files changed, 43 insertions, 12 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index eff0c35a1..51cf4af9f 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -16,10 +16,6 @@ struct Register { | |||
| 16 | 16 | ||
| 17 | constexpr Register(u64 value) : value(value) {} | 17 | constexpr Register(u64 value) : value(value) {} |
| 18 | 18 | ||
| 19 | constexpr u64 GetIndex() const { | ||
| 20 | return value; | ||
| 21 | } | ||
| 22 | |||
| 23 | constexpr operator u64() const { | 19 | constexpr operator u64() const { |
| 24 | return value; | 20 | return value; |
| 25 | } | 21 | } |
| @@ -71,6 +67,19 @@ union Attribute { | |||
| 71 | u64 value; | 67 | u64 value; |
| 72 | }; | 68 | }; |
| 73 | 69 | ||
| 70 | union Sampler { | ||
| 71 | Sampler() = default; | ||
| 72 | |||
| 73 | constexpr Sampler(u64 value) : value(value) {} | ||
| 74 | |||
| 75 | enum class Index : u64 { | ||
| 76 | Sampler_0 = 8, | ||
| 77 | }; | ||
| 78 | |||
| 79 | BitField<36, 13, Index> index; | ||
| 80 | u64 value; | ||
| 81 | }; | ||
| 82 | |||
| 74 | union Uniform { | 83 | union Uniform { |
| 75 | BitField<20, 14, u64> offset; | 84 | BitField<20, 14, u64> offset; |
| 76 | BitField<34, 5, u64> index; | 85 | BitField<34, 5, u64> index; |
| @@ -295,7 +304,6 @@ union Instruction { | |||
| 295 | BitField<20, 8, Register> gpr20; | 304 | BitField<20, 8, Register> gpr20; |
| 296 | BitField<20, 7, SubOp> sub_op; | 305 | BitField<20, 7, SubOp> sub_op; |
| 297 | BitField<28, 8, Register> gpr28; | 306 | BitField<28, 8, Register> gpr28; |
| 298 | BitField<36, 13, u64> imm36; | ||
| 299 | BitField<39, 8, Register> gpr39; | 307 | BitField<39, 8, Register> gpr39; |
| 300 | 308 | ||
| 301 | union { | 309 | union { |
| @@ -316,6 +324,7 @@ union Instruction { | |||
| 316 | 324 | ||
| 317 | Attribute attribute; | 325 | Attribute attribute; |
| 318 | Uniform uniform; | 326 | Uniform uniform; |
| 327 | Sampler sampler; | ||
| 319 | 328 | ||
| 320 | u64 hex; | 329 | u64 hex; |
| 321 | }; | 330 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index ba3aa7dd1..a8f1ac5b5 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -17,6 +17,7 @@ using Tegra::Shader::Attribute; | |||
| 17 | using Tegra::Shader::Instruction; | 17 | using Tegra::Shader::Instruction; |
| 18 | using Tegra::Shader::OpCode; | 18 | using Tegra::Shader::OpCode; |
| 19 | using Tegra::Shader::Register; | 19 | using Tegra::Shader::Register; |
| 20 | using Tegra::Shader::Sampler; | ||
| 20 | using Tegra::Shader::SubOp; | 21 | using Tegra::Shader::SubOp; |
| 21 | using Tegra::Shader::Uniform; | 22 | using Tegra::Shader::Uniform; |
| 22 | 23 | ||
| @@ -186,13 +187,13 @@ private: | |||
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | /// Generates code representing a temporary (GPR) register. | 189 | /// Generates code representing a temporary (GPR) register. |
| 189 | std::string GetRegister(const Register& reg) { | 190 | std::string GetRegister(const Register& reg, unsigned elem = 0) { |
| 190 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg.GetIndex() < 4) { | 191 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) { |
| 191 | // GPRs 0-3 are output color for the fragment shader | 192 | // GPRs 0-3 are output color for the fragment shader |
| 192 | return std::string{"color."} + "rgba"[reg.GetIndex()]; | 193 | return std::string{"color."} + "rgba"[reg + elem]; |
| 193 | } | 194 | } |
| 194 | 195 | ||
| 195 | return *declr_register.insert("register_" + std::to_string(reg)).first; | 196 | return *declr_register.insert("register_" + std::to_string(reg + elem)).first; |
| 196 | } | 197 | } |
| 197 | 198 | ||
| 198 | /// Generates code representing a uniform (C buffer) register. | 199 | /// Generates code representing a uniform (C buffer) register. |
| @@ -201,6 +202,15 @@ private: | |||
| 201 | return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']'; | 202 | return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']'; |
| 202 | } | 203 | } |
| 203 | 204 | ||
| 205 | /// Generates code representing a texture sampler. | ||
| 206 | std::string GetSampler(const Sampler& sampler) const { | ||
| 207 | // TODO(Subv): Support more than just texture sampler 0 | ||
| 208 | ASSERT_MSG(sampler.index == Sampler::Index::Sampler_0, "unsupported"); | ||
| 209 | const unsigned index{static_cast<unsigned>(sampler.index.Value()) - | ||
| 210 | static_cast<unsigned>(Sampler::Index::Sampler_0)}; | ||
| 211 | return "tex[" + std::to_string(index) + "]"; | ||
| 212 | } | ||
| 213 | |||
| 204 | /** | 214 | /** |
| 205 | * Adds code that calls a subroutine. | 215 | * Adds code that calls a subroutine. |
| 206 | * @param subroutine the subroutine to call. | 216 | * @param subroutine the subroutine to call. |
| @@ -245,7 +255,7 @@ private: | |||
| 245 | 255 | ||
| 246 | switch (OpCode::GetInfo(instr.opcode).type) { | 256 | switch (OpCode::GetInfo(instr.opcode).type) { |
| 247 | case OpCode::Type::Arithmetic: { | 257 | case OpCode::Type::Arithmetic: { |
| 248 | ASSERT(!instr.alu.abs_d); | 258 | ASSERT_MSG(!instr.alu.abs_d, "unimplemented"); |
| 249 | 259 | ||
| 250 | std::string dest = GetRegister(instr.gpr0); | 260 | std::string dest = GetRegister(instr.gpr0); |
| 251 | std::string op_a = instr.alu.negate_a ? "-" : ""; | 261 | std::string op_a = instr.alu.negate_a ? "-" : ""; |
| @@ -330,15 +340,27 @@ private: | |||
| 330 | 340 | ||
| 331 | switch (instr.opcode.EffectiveOpCode()) { | 341 | switch (instr.opcode.EffectiveOpCode()) { |
| 332 | case OpCode::Id::LD_A: { | 342 | case OpCode::Id::LD_A: { |
| 333 | ASSERT(instr.attribute.fmt20.size == 0); | 343 | ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested"); |
| 334 | SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4); | 344 | SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4); |
| 335 | break; | 345 | break; |
| 336 | } | 346 | } |
| 337 | case OpCode::Id::ST_A: { | 347 | case OpCode::Id::ST_A: { |
| 338 | ASSERT(instr.attribute.fmt20.size == 0); | 348 | ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested"); |
| 339 | SetDest(instr.attribute.fmt20.element, GetOutputAttribute(attribute), gpr0, 4, 1); | 349 | SetDest(instr.attribute.fmt20.element, GetOutputAttribute(attribute), gpr0, 4, 1); |
| 340 | break; | 350 | break; |
| 341 | } | 351 | } |
| 352 | case OpCode::Id::TEXS: { | ||
| 353 | ASSERT_MSG(instr.attribute.fmt20.size == 4, "untested"); | ||
| 354 | const std::string op_a = GetRegister(instr.gpr8); | ||
| 355 | const std::string op_b = GetRegister(instr.gpr20); | ||
| 356 | const std::string sampler = GetSampler(instr.sampler); | ||
| 357 | const std::string coord = "vec2(" + op_a + ", " + op_b + ")"; | ||
| 358 | const std::string texture = "texture(" + sampler + ", " + coord + ")"; | ||
| 359 | for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) { | ||
| 360 | SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4); | ||
| 361 | } | ||
| 362 | break; | ||
| 363 | } | ||
| 342 | default: { | 364 | default: { |
| 343 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: 0x%02x (%s): 0x%08x", | 365 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: 0x%02x (%s): 0x%08x", |
| 344 | static_cast<unsigned>(instr.opcode.EffectiveOpCode()), | 366 | static_cast<unsigned>(instr.opcode.EffectiveOpCode()), |