@ -96,6 +96,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
}
break ;
}
case OpCode : : Id : : TLD4_B : {
is_bindless = true ;
[[fallthrough]] ;
}
case OpCode : : Id : : TLD4 : {
ASSERT ( instr . tld4 . array = = 0 ) ;
UNIMPLEMENTED_IF_MSG ( instr . tld4 . UsesMiscMode ( TextureMiscMode : : NDV ) ,
@ -108,11 +112,14 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
}
const auto texture_type = instr . tld4 . texture_type . Value ( ) ;
const bool depth_compare = instr . tld4 . UsesMiscMode ( TextureMiscMode : : DC ) ;
const bool depth_compare = is_bindless ? instr . tld4_b . UsesMiscMode ( TextureMiscMode : : DC )
: instr . tld4 . UsesMiscMode ( TextureMiscMode : : DC ) ;
const bool is_array = instr . tld4 . array ! = 0 ;
const bool is_aoffi = instr . tld4 . UsesMiscMode ( TextureMiscMode : : AOFFI ) ;
const bool is_aoffi = is_bindless ? instr . tld4_b . UsesMiscMode ( TextureMiscMode : : AOFFI )
: instr . tld4 . UsesMiscMode ( TextureMiscMode : : AOFFI ) ;
WriteTexInstructionFloat (
bb , instr , GetTld4Code ( instr , texture_type , depth_compare , is_array , is_aoffi ) ) ;
bb , instr ,
GetTld4Code ( instr , texture_type , depth_compare , is_array , is_aoffi , is_bindless ) , true ) ;
break ;
}
case OpCode : : Id : : TLD4S : {
@ -359,10 +366,11 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
return * used_samplers . emplace ( entry ) . first ;
}
void ShaderIR : : WriteTexInstructionFloat ( NodeBlock & bb , Instruction instr , const Node4 & components ) {
void ShaderIR : : WriteTexInstructionFloat ( NodeBlock & bb , Instruction instr , const Node4 & components ,
bool is_tld4 ) {
u32 dest_elem = 0 ;
for ( u32 elem = 0 ; elem < 4 ; + + elem ) {
if ( ! i nstr. tex . IsComponentEnabled ( elem ) ) {
if ( ! i s_tld4 & & ! i nstr. tex . IsComponentEnabled ( elem ) ) {
// Skip disabled components
continue ;
}
@ -583,7 +591,7 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
}
Node4 ShaderIR : : GetTld4Code ( Instruction instr , TextureType texture_type , bool depth_compare ,
bool is_array , bool is_aoffi ) {
bool is_array , bool is_aoffi , bool is_bindless ) {
const std : : size_t coord_count = GetCoordCount ( texture_type ) ;
// If enabled arrays index is always stored in the gpr8 field
@ -597,6 +605,12 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
}
u64 parameter_register = instr . gpr20 . Value ( ) ;
const auto & sampler =
is_bindless
? GetBindlessSampler ( parameter_register + + , { { texture_type , is_array , depth_compare } } )
: GetSampler ( instr . sampler , { { texture_type , is_array , depth_compare } } ) ;
std : : vector < Node > aoffi ;
if ( is_aoffi ) {
aoffi = GetAoffiCoordinates ( GetRegister ( parameter_register + + ) , coord_count , true ) ;
@ -607,12 +621,14 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
dc = GetRegister ( parameter_register + + ) ;
}
const auto & sampler = GetSampler ( instr . sampler , { { texture_type , is_array , depth_compare } } ) ;
const Node component = is_bindless ? Immediate ( static_cast < u32 > ( instr . tld4_b . component ) )
: Immediate ( static_cast < u32 > ( instr . tld4 . component ) ) ;
Node4 values ;
for ( u32 element = 0 ; element < values . size ( ) ; + + element ) {
auto coords_copy = coords ;
MetaTexture meta { sampler , GetRegister ( array_register ) , dc , aoffi , { } , { } , { } , element } ;
MetaTexture meta { sampler , GetRegister ( array_register ) , dc , aoffi , { } , { } , component ,
element } ;
values [ element ] = Operation ( OperationCode : : TextureGather , meta , std : : move ( coords_copy ) ) ;
}