forked from eden-emu/eden
		
	Merge pull request #1782 from FernandoS27/dc
Fixed Coordinate Encodings in TEX and TEXS instructions
This commit is contained in:
		
						commit
						0394813401
					
				
					 1 changed files with 188 additions and 116 deletions
				
			
		|  | @ -1292,7 +1292,15 @@ private: | ||||||
|         regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |         regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { |     void WriteTexsInstruction(const Instruction& instr, const std::string& coord, | ||||||
|  |                               const std::string& texture) { | ||||||
|  |         // Add an extra scope and declare the texture coords inside to prevent
 | ||||||
|  |         // overwriting them in case they are used as outputs of the texs instruction.
 | ||||||
|  |         shader.AddLine('{'); | ||||||
|  |         ++shader.scope; | ||||||
|  |         shader.AddLine(coord); | ||||||
|  |         shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||||||
|  | 
 | ||||||
|         // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
 |         // TEXS has two destination registers and a swizzle. The first two elements in the swizzle
 | ||||||
|         // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
 |         // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
 | ||||||
| 
 | 
 | ||||||
|  | @ -1304,17 +1312,19 @@ private: | ||||||
| 
 | 
 | ||||||
|             if (written_components < 2) { |             if (written_components < 2) { | ||||||
|                 // Write the first two swizzle components to gpr0 and gpr0+1
 |                 // Write the first two swizzle components to gpr0 and gpr0+1
 | ||||||
|                 regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false, |                 regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, | ||||||
|                                         written_components % 2); |                                         written_components % 2); | ||||||
|             } else { |             } else { | ||||||
|                 ASSERT(instr.texs.HasTwoDestinations()); |                 ASSERT(instr.texs.HasTwoDestinations()); | ||||||
|                 // Write the rest of the swizzle components to gpr28 and gpr28+1
 |                 // Write the rest of the swizzle components to gpr28 and gpr28+1
 | ||||||
|                 regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false, |                 regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, | ||||||
|                                         written_components % 2); |                                         written_components % 2); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             ++written_components; |             ++written_components; | ||||||
|         } |         } | ||||||
|  |         --shader.scope; | ||||||
|  |         shader.AddLine('}'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |     static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | ||||||
|  | @ -2536,61 +2546,83 @@ private: | ||||||
|                 const bool depth_compare = |                 const bool depth_compare = | ||||||
|                     instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |                     instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | ||||||
|                 u32 num_coordinates = TextureCoordinates(texture_type); |                 u32 num_coordinates = TextureCoordinates(texture_type); | ||||||
|                 if (depth_compare) |                 u32 start_index = 0; | ||||||
|                     num_coordinates += 1; |                 std::string array_elem; | ||||||
|  |                 if (is_array) { | ||||||
|  |                     array_elem = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|  |                     start_index = 1; | ||||||
|  |                 } | ||||||
|  |                 const auto process_mode = instr.tex.GetTextureProcessMode(); | ||||||
|  |                 u32 start_index_b = 0; | ||||||
|  |                 std::string lod_value; | ||||||
|  |                 if (process_mode != Tegra::Shader::TextureProcessMode::LZ && | ||||||
|  |                     process_mode != Tegra::Shader::TextureProcessMode::None) { | ||||||
|  |                     start_index_b = 1; | ||||||
|  |                     lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::string depth_value; | ||||||
|  |                 if (depth_compare) { | ||||||
|  |                     depth_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + start_index_b); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool depth_compare_extra = false; | ||||||
| 
 | 
 | ||||||
|                 switch (num_coordinates) { |                 switch (num_coordinates) { | ||||||
|                 case 1: { |                 case 1: { | ||||||
|  |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||||||
|                     if (is_array) { |                     if (is_array) { | ||||||
|                         const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                         if (depth_compare) { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                             coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " + | ||||||
|                         coord = "vec2 coords = vec2(" + x + ", " + index + ");"; |                                     array_elem + ");"; | ||||||
|  |                         } else { | ||||||
|  |                             coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");"; | ||||||
|  |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                         if (depth_compare) { | ||||||
|                         coord = "float coords = " + x + ';'; |                             coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");"; | ||||||
|  |                         } else { | ||||||
|  |                             coord = "float coords = " + x + ';'; | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case 2: { |                 case 2: { | ||||||
|  |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||||||
|  |                     const std::string y = | ||||||
|  |                         regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | ||||||
|                     if (is_array) { |                     if (is_array) { | ||||||
|                         const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                         if (depth_compare) { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                             coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value + | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |                                     ", " + array_elem + ");"; | ||||||
|                         coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; |                         } else { | ||||||
|  |                             coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");"; | ||||||
|  |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                         if (depth_compare) { | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                             coord = | ||||||
|                         coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                                 "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");"; | ||||||
|  |                         } else { | ||||||
|  |                             coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case 3: { |                 case 3: { | ||||||
|                     if (depth_compare) { |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||||||
|                         if (is_array) { |                     const std::string y = | ||||||
|                             const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                         regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | ||||||
|                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                     const std::string z = | ||||||
|                             const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                         regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); | ||||||
|                             const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |                     if (is_array) { | ||||||
|                             coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + |                         depth_compare_extra = depth_compare; | ||||||
|                                     ");"; |                         coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||||||
|                         } else { |                                 array_elem + ");"; | ||||||
|                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |  | ||||||
|                             const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |  | ||||||
|                             const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |  | ||||||
|                             coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |  | ||||||
|                         } |  | ||||||
|                     } else { |                     } else { | ||||||
|                         if (is_array) { |                         if (depth_compare) { | ||||||
|                             const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                             coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||||||
|                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                                     depth_value + ");"; | ||||||
|                             const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |  | ||||||
|                             const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 3); |  | ||||||
|                             coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + |  | ||||||
|                                     ");"; |  | ||||||
|                         } else { |                         } else { | ||||||
|                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |  | ||||||
|                             const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |  | ||||||
|                             const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |  | ||||||
|                             coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; |                             coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | @ -2606,82 +2638,85 @@ private: | ||||||
|                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     texture_type = Tegra::Shader::TextureType::Texture2D; |                     texture_type = Tegra::Shader::TextureType::Texture2D; | ||||||
|                 } |                 } | ||||||
|                 // TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias
 |  | ||||||
|                 // or lod.
 |  | ||||||
| 
 | 
 | ||||||
|                 const std::string sampler = |                 const std::string sampler = | ||||||
|                     GetSampler(instr.sampler, texture_type, is_array, depth_compare); |                     GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||||||
|                 // Add an extra scope and declare the texture coords inside to prevent
 |                 // Add an extra scope and declare the texture coords inside to prevent
 | ||||||
|                 // overwriting them in case they are used as outputs of the texs instruction.
 |                 // overwriting them in case they are used as outputs of the texs instruction.
 | ||||||
| 
 | 
 | ||||||
|                 shader.AddLine("{"); |                 shader.AddLine('{'); | ||||||
|                 ++shader.scope; |                 ++shader.scope; | ||||||
|                 shader.AddLine(coord); |                 shader.AddLine(coord); | ||||||
|                 std::string texture; |                 std::string texture; | ||||||
| 
 | 
 | ||||||
|                 switch (instr.tex.GetTextureProcessMode()) { |                 switch (instr.tex.GetTextureProcessMode()) { | ||||||
|                 case Tegra::Shader::TextureProcessMode::None: { |                 case Tegra::Shader::TextureProcessMode::None: { | ||||||
|                     texture = "texture(" + sampler + ", coords)"; |                     if (!depth_compare_extra) { | ||||||
|  |                         texture = "texture(" + sampler + ", coords)"; | ||||||
|  |                     } else { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureProcessMode::LZ: { |                 case Tegra::Shader::TextureProcessMode::LZ: { | ||||||
|                     texture = "textureLod(" + sampler + ", coords, 0.0)"; |                     if (!depth_compare_extra) { | ||||||
|  |                         texture = "textureLod(" + sampler + ", coords, 0.0)"; | ||||||
|  |                     } else { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureProcessMode::LB: |                 case Tegra::Shader::TextureProcessMode::LB: | ||||||
|                 case Tegra::Shader::TextureProcessMode::LBA: { |                 case Tegra::Shader::TextureProcessMode::LBA: { | ||||||
|                     const std::string bias = [&]() { |  | ||||||
|                         if (depth_compare) { |  | ||||||
|                             if (is_array) |  | ||||||
|                                 return regs.GetRegisterAsFloat(instr.gpr20.Value() + 2); |  | ||||||
|                             else |  | ||||||
|                                 return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |  | ||||||
|                         } else { |  | ||||||
|                             return regs.GetRegisterAsFloat(instr.gpr20); |  | ||||||
|                         } |  | ||||||
|                     }(); |  | ||||||
|                     shader.AddLine("float bias = " + bias + ';'); |  | ||||||
| 
 |  | ||||||
|                     // TODO: Figure if A suffix changes the equation at all.
 |                     // TODO: Figure if A suffix changes the equation at all.
 | ||||||
|                     texture = "texture(" + sampler + ", coords, bias)"; |                     if (!depth_compare_extra) { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + lod_value + ')'; | ||||||
|  |                     } else { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||||||
|  |                         LOG_WARNING(HW_GPU, | ||||||
|  |                                     "OpenGL Limitation: can't set bias value along depth compare"); | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureProcessMode::LL: |                 case Tegra::Shader::TextureProcessMode::LL: | ||||||
|                 case Tegra::Shader::TextureProcessMode::LLA: { |                 case Tegra::Shader::TextureProcessMode::LLA: { | ||||||
|                     const std::string lod = [&]() { |  | ||||||
|                         if (num_coordinates <= 2) { |  | ||||||
|                             return regs.GetRegisterAsFloat(instr.gpr20); |  | ||||||
|                         } else { |  | ||||||
|                             return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |  | ||||||
|                         } |  | ||||||
|                     }(); |  | ||||||
|                     shader.AddLine("float lod = " + lod + ';'); |  | ||||||
| 
 |  | ||||||
|                     // TODO: Figure if A suffix changes the equation at all.
 |                     // TODO: Figure if A suffix changes the equation at all.
 | ||||||
|                     texture = "textureLod(" + sampler + ", coords, lod)"; |                     if (!depth_compare_extra) { | ||||||
|  |                         texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | ||||||
|  |                     } else { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||||||
|  |                         LOG_WARNING(HW_GPU, | ||||||
|  |                                     "OpenGL Limitation: can't set lod value along depth compare"); | ||||||
|  |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 default: { |                 default: { | ||||||
|                     texture = "texture(" + sampler + ", coords)"; |                     if (!depth_compare_extra) { | ||||||
|  |                         texture = "texture(" + sampler + ", coords)"; | ||||||
|  |                     } else { | ||||||
|  |                         texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||||||
|  |                     } | ||||||
|                     UNIMPLEMENTED_MSG("Unhandled texture process mode {}", |                     UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | ||||||
|                                       static_cast<u32>(instr.tex.GetTextureProcessMode())); |                                       static_cast<u32>(instr.tex.GetTextureProcessMode())); | ||||||
|                 } |                 } | ||||||
|                 } |                 } | ||||||
|                 if (!depth_compare) { |                 if (!depth_compare) { | ||||||
|  |                     shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||||||
|                     std::size_t dest_elem{}; |                     std::size_t dest_elem{}; | ||||||
|                     for (std::size_t elem = 0; elem < 4; ++elem) { |                     for (std::size_t elem = 0; elem < 4; ++elem) { | ||||||
|                         if (!instr.tex.IsComponentEnabled(elem)) { |                         if (!instr.tex.IsComponentEnabled(elem)) { | ||||||
|                             // Skip disabled components
 |                             // Skip disabled components
 | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|                         regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); |                         regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, | ||||||
|  |                                                 dest_elem); | ||||||
|                         ++dest_elem; |                         ++dest_elem; | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |                     regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | ||||||
|                 } |                 } | ||||||
|                 --shader.scope; |                 --shader.scope; | ||||||
|                 shader.AddLine("}"); |                 shader.AddLine('}'); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case OpCode::Id::TEXS: { |             case OpCode::Id::TEXS: { | ||||||
|  | @ -2694,41 +2729,76 @@ private: | ||||||
|                 const bool depth_compare = |                 const bool depth_compare = | ||||||
|                     instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |                     instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | ||||||
|                 u32 num_coordinates = TextureCoordinates(texture_type); |                 u32 num_coordinates = TextureCoordinates(texture_type); | ||||||
|                 if (depth_compare) |                 const auto process_mode = instr.texs.GetTextureProcessMode(); | ||||||
|                     num_coordinates += 1; |                 std::string lod_value; | ||||||
| 
 |                 std::string coord; | ||||||
|                 // Scope to avoid variable name overlaps.
 |                 u32 lod_offset = 0; | ||||||
|                 shader.AddLine('{'); |                 if (process_mode == Tegra::Shader::TextureProcessMode::LL) { | ||||||
|                 ++shader.scope; |                     if (num_coordinates > 2) { | ||||||
|  |                         lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||||||
|  |                         lod_offset = 2; | ||||||
|  |                     } else { | ||||||
|  |                         lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                         lod_offset = 1; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|                 switch (num_coordinates) { |                 switch (num_coordinates) { | ||||||
|  |                 case 1: { | ||||||
|  |                     coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|                 case 2: { |                 case 2: { | ||||||
|                     if (is_array) { |                     if (is_array) { | ||||||
|                         const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                         if (depth_compare) { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                             const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                         shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"); |                             const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                             const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||||||
|  |                             coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | ||||||
|  |                                     ");"; | ||||||
|  |                         } else { | ||||||
|  |                             const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|  |                             const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|  |                             const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                             coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | ||||||
|  |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                         if (lod_offset != 0) { | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                             if (depth_compare) { | ||||||
|                         shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |                                 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|  |                                 const std::string y = | ||||||
|  |                                     regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|  |                                 const std::string z = | ||||||
|  |                                     regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | ||||||
|  |                                 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||||||
|  |                             } else { | ||||||
|  |                                 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|  |                                 const std::string y = | ||||||
|  |                                     regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|  |                                 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|  |                             } | ||||||
|  |                         } else { | ||||||
|  |                             if (depth_compare) { | ||||||
|  |                                 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|  |                                 const std::string y = | ||||||
|  |                                     regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|  |                                 const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                                 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||||||
|  |                             } else { | ||||||
|  |                                 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|  |                                 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|  |                                 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case 3: { |                 case 3: { | ||||||
|                     if (is_array) { |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                         const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |                     const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); |                     coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||||||
|                         const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |  | ||||||
|                         shader.AddLine("vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + |  | ||||||
|                                        index + ");"); |  | ||||||
|                     } else { |  | ||||||
|                         const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |  | ||||||
|                         const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |  | ||||||
|                         const std::string z = regs.GetRegisterAsFloat(instr.gpr20); |  | ||||||
|                         shader.AddLine("vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"); |  | ||||||
|                     } |  | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 default: |                 default: | ||||||
|  | @ -2738,14 +2808,14 @@ private: | ||||||
|                     // Fallback to interpreting as a 2D texture for now
 |                     // Fallback to interpreting as a 2D texture for now
 | ||||||
|                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |                     const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|                     const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |                     const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||||||
|                     shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |                     coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||||||
|                     texture_type = Tegra::Shader::TextureType::Texture2D; |                     texture_type = Tegra::Shader::TextureType::Texture2D; | ||||||
|                     is_array = false; |                     is_array = false; | ||||||
|                 } |                 } | ||||||
|                 const std::string sampler = |                 const std::string sampler = | ||||||
|                     GetSampler(instr.sampler, texture_type, is_array, depth_compare); |                     GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||||||
|                 std::string texture; |                 std::string texture; | ||||||
|                 switch (instr.texs.GetTextureProcessMode()) { |                 switch (process_mode) { | ||||||
|                 case Tegra::Shader::TextureProcessMode::None: { |                 case Tegra::Shader::TextureProcessMode::None: { | ||||||
|                     texture = "texture(" + sampler + ", coords)"; |                     texture = "texture(" + sampler + ", coords)"; | ||||||
|                     break; |                     break; | ||||||
|  | @ -2759,8 +2829,7 @@ private: | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureProcessMode::LL: { |                 case Tegra::Shader::TextureProcessMode::LL: { | ||||||
|                     const std::string op_c = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); |                     texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | ||||||
|                     texture = "textureLod(" + sampler + ", coords, " + op_c + ')'; |  | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 default: { |                 default: { | ||||||
|  | @ -2770,13 +2839,11 @@ private: | ||||||
|                 } |                 } | ||||||
|                 } |                 } | ||||||
|                 if (!depth_compare) { |                 if (!depth_compare) { | ||||||
|                     WriteTexsInstruction(instr, texture); |                     WriteTexsInstruction(instr, coord, texture); | ||||||
|                 } else { |                 } else { | ||||||
|                     WriteTexsInstruction(instr, "vec4(" + texture + ')'); |                     WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 shader.AddLine('}'); |  | ||||||
|                 --shader.scope; |  | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case OpCode::Id::TLDS: { |             case OpCode::Id::TLDS: { | ||||||
|  | @ -2798,11 +2865,12 @@ private: | ||||||
|                 // Scope to avoid variable name overlaps.
 |                 // Scope to avoid variable name overlaps.
 | ||||||
|                 shader.AddLine('{'); |                 shader.AddLine('{'); | ||||||
|                 ++shader.scope; |                 ++shader.scope; | ||||||
|  |                 std::string coords; | ||||||
| 
 | 
 | ||||||
|                 switch (texture_type) { |                 switch (texture_type) { | ||||||
|                 case Tegra::Shader::TextureType::Texture1D: { |                 case Tegra::Shader::TextureType::Texture1D: { | ||||||
|                     const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |                     const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|                     shader.AddLine("int coords = " + x + ';'); |                     coords = "float coords = " + x + ';'; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 case Tegra::Shader::TextureType::Texture2D: { |                 case Tegra::Shader::TextureType::Texture2D: { | ||||||
|  | @ -2810,7 +2878,8 @@ private: | ||||||
| 
 | 
 | ||||||
|                     const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |                     const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | ||||||
|                     const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |                     const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | ||||||
|                     shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |                     // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");");
 | ||||||
|  |                     coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | ||||||
|                     extra_op_offset = 1; |                     extra_op_offset = 1; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  | @ -2838,7 +2907,7 @@ private: | ||||||
|                                       static_cast<u32>(instr.tlds.GetTextureProcessMode())); |                                       static_cast<u32>(instr.tlds.GetTextureProcessMode())); | ||||||
|                 } |                 } | ||||||
|                 } |                 } | ||||||
|                 WriteTexsInstruction(instr, texture); |                 WriteTexsInstruction(instr, coords, texture); | ||||||
| 
 | 
 | ||||||
|                 --shader.scope; |                 --shader.scope; | ||||||
|                 shader.AddLine('}'); |                 shader.AddLine('}'); | ||||||
|  | @ -2897,14 +2966,17 @@ private: | ||||||
| 
 | 
 | ||||||
|                 const std::string texture = "textureGather(" + sampler + ", coords, " + |                 const std::string texture = "textureGather(" + sampler + ", coords, " + | ||||||
|                                             std::to_string(instr.tld4.component) + ')'; |                                             std::to_string(instr.tld4.component) + ')'; | ||||||
|  | 
 | ||||||
|                 if (!depth_compare) { |                 if (!depth_compare) { | ||||||
|  |                     shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||||||
|                     std::size_t dest_elem{}; |                     std::size_t dest_elem{}; | ||||||
|                     for (std::size_t elem = 0; elem < 4; ++elem) { |                     for (std::size_t elem = 0; elem < 4; ++elem) { | ||||||
|                         if (!instr.tex.IsComponentEnabled(elem)) { |                         if (!instr.tex.IsComponentEnabled(elem)) { | ||||||
|                             // Skip disabled components
 |                             // Skip disabled components
 | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|                         regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); |                         regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, | ||||||
|  |                                                 dest_elem); | ||||||
|                         ++dest_elem; |                         ++dest_elem; | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|  | @ -2925,6 +2997,7 @@ private: | ||||||
|                 // Scope to avoid variable name overlaps.
 |                 // Scope to avoid variable name overlaps.
 | ||||||
|                 shader.AddLine('{'); |                 shader.AddLine('{'); | ||||||
|                 ++shader.scope; |                 ++shader.scope; | ||||||
|  |                 std::string coords; | ||||||
| 
 | 
 | ||||||
|                 const bool depth_compare = |                 const bool depth_compare = | ||||||
|                     instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |                     instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | ||||||
|  | @ -2934,20 +3007,19 @@ private: | ||||||
|                 const std::string sampler = GetSampler( |                 const std::string sampler = GetSampler( | ||||||
|                     instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |                     instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | ||||||
|                 if (!depth_compare) { |                 if (!depth_compare) { | ||||||
|                     shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); |                     coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | ||||||
|                 } else { |                 } else { | ||||||
|                     // Note: TLD4S coordinate encoding works just like TEXS's
 |                     // Note: TLD4S coordinate encoding works just like TEXS's
 | ||||||
|                     shader.AddLine( |                     const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||||||
|                         "float op_y = " + regs.GetRegisterAsFloat(instr.gpr8.Value() + 1) + ';'); |                     coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; | ||||||
|                     shader.AddLine("vec3 coords = vec3(" + op_a + ", op_y, " + op_b + ");"); |  | ||||||
|                 } |                 } | ||||||
|                 const std::string texture = "textureGather(" + sampler + ", coords, " + |                 const std::string texture = "textureGather(" + sampler + ", coords, " + | ||||||
|                                             std::to_string(instr.tld4s.component) + ')'; |                                             std::to_string(instr.tld4s.component) + ')'; | ||||||
| 
 | 
 | ||||||
|                 if (!depth_compare) { |                 if (!depth_compare) { | ||||||
|                     WriteTexsInstruction(instr, texture); |                     WriteTexsInstruction(instr, coords, texture); | ||||||
|                 } else { |                 } else { | ||||||
|                     WriteTexsInstruction(instr, "vec4(" + texture + ')'); |                     WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 --shader.scope; |                 --shader.scope; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei