rsx: Fix texcoord transformation bug caused by incorrect BFE usage

This commit is contained in:
kd-11 2025-01-18 23:51:56 +03:00 committed by kd-11
parent 58a09e6838
commit 2af497efbb

View File

@ -86,8 +86,11 @@ layout(location=0) in vec4 in_regs[16];
#define CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT 0xe #define CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT 0xe
#define CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS 0x40 #define CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS 0x40
#define GET_BITS(word, offset, count) bitfieldExtract(inst.words[word], offset, count) #define GET_BITS(bitfield, offset, count) bitfieldExtract(bitfield, offset, count)
#define TEST_BIT(word, offset) (GET_BITS(word, offset, 1) > 0) #define TEST_BIT(bitfield, offset) (GET_BITS(bitfield, offset, 1) > 0)
#define GET_INST_BITS(word, offset, count) GET_BITS(inst.words[word], offset, count)
#define TEST_INST_BIT(word, offset) (GET_INST_BITS(word, offset, 1) > 0)
#define select mix #define select mix
#define reg_mov(d, s, m) d = select(d, s, m) #define reg_mov(d, s, m) d = select(d, s, m)
@ -174,7 +177,7 @@ int counter = 0;
vec4 read_src(const in int index) vec4 read_src(const in int index)
{ {
ur0 = GET_BITS(index + 1, 0, 2); ur0 = GET_INST_BITS(index + 1, 0, 2);
switch (ur0) switch (ur0)
{ {
@ -183,14 +186,14 @@ vec4 read_src(const in int index)
switch(index) switch(index)
{ {
case 0: case 0:
ur1 = GET_BITS(1, 2, 6); break; ur1 = GET_INST_BITS(1, 2, 6); break;
case 1: case 1:
ur1 = GET_BITS(2, 2, 6); break; ur1 = GET_INST_BITS(2, 2, 6); break;
case 2: case 2:
ur1 = GET_BITS(3, 2, 6); break; ur1 = GET_INST_BITS(3, 2, 6); break;
} }
if (TEST_BIT(index + 1, 8)) if (TEST_INST_BIT(index + 1, 8))
{ {
vr0 = regs16[ur1]; vr0 = regs16[ur1];
} }
@ -202,7 +205,7 @@ vec4 read_src(const in int index)
} }
case RSX_FP_REGISTER_TYPE_INPUT: case RSX_FP_REGISTER_TYPE_INPUT:
{ {
ur1 = GET_BITS(0, 13, 4); ur1 = GET_INST_BITS(0, 13, 4);
switch (ur1) switch (ur1)
{ {
case 0: case 0:
@ -235,27 +238,27 @@ vec4 read_src(const in int index)
} }
} }
ur1 = GET_BITS(index + 1, 9, 8); ur1 = GET_INST_BITS(index + 1, 9, 8);
vr0 = shuffle(vr0, ur1); vr0 = shuffle(vr0, ur1);
// abs // abs
if (index == 0) if (index == 0)
{ {
if (TEST_BIT(1, 29)) vr0 = abs(vr0); if (TEST_INST_BIT(1, 29)) vr0 = abs(vr0);
} }
else else
{ {
ur1 = index + 1; ur1 = index + 1;
if (TEST_BIT(ur1, 18)) vr0 = abs(vr0); if (TEST_INST_BIT(ur1, 18)) vr0 = abs(vr0);
} }
// neg // neg
return (TEST_BIT(index + 1, 17))? -vr0 : vr0; return (TEST_INST_BIT(index + 1, 17))? -vr0 : vr0;
} }
vec4 read_cond() vec4 read_cond()
{ {
return shuffle(cc[GET_BITS(1, 31, 1)], GET_BITS(1, 21, 8)); return shuffle(cc[GET_INST_BITS(1, 31, 1)], GET_INST_BITS(1, 21, 8));
} }
bvec4 decode_cond(const in uint mode, const in vec4 cond) bvec4 decode_cond(const in uint mode, const in vec4 cond)
@ -283,7 +286,7 @@ bvec4 decode_cond(const in uint mode, const in vec4 cond)
bool check_cond() bool check_cond()
{ {
ur0 = GET_BITS(1, 18, 3); ur0 = GET_INST_BITS(1, 18, 3);
if (ur0 == 0x7) if (ur0 == 0x7)
{ {
return true; return true;
@ -351,14 +354,14 @@ vec3 _texcoord_xform(const in vec3 coord, const in sampler_info params)
vec4 _texture(in vec4 coord, float bias) vec4 _texture(in vec4 coord, float bias)
{ {
ur0 = GET_BITS(0, 17, 4); ur0 = GET_INST_BITS(0, 17, 4);
if (!IS_TEXTURE_RESIDENT(ur0)) if (!IS_TEXTURE_RESIDENT(ur0))
{ {
return vr_zero; return vr_zero;
} }
ur1 = ur0 + ur0; ur1 = ur0 + ur0;
const uint type = bitfieldExtract(texture_control, int(ur1), 2); const uint type = GET_BITS(texture_control, int(ur1), 2);
switch (type) switch (type)
{ {
@ -380,7 +383,7 @@ vec4 _texture(in vec4 coord, float bias)
break; break;
} }
if (TEST_BIT(0, 21)) if (TEST_INST_BIT(0, 21))
{ {
vr0 = vr0 * 2. - 1.; vr0 = vr0 * 2. - 1.;
} }
@ -390,14 +393,14 @@ vec4 _texture(in vec4 coord, float bias)
vec4 _textureLod(in vec4 coord, float lod) vec4 _textureLod(in vec4 coord, float lod)
{ {
ur0 = GET_BITS(0, 17, 4); ur0 = GET_INST_BITS(0, 17, 4);
if (!IS_TEXTURE_RESIDENT(ur0)) if (!IS_TEXTURE_RESIDENT(ur0))
{ {
return vr_zero; return vr_zero;
} }
ur1 = ur0 + ur0; ur1 = ur0 + ur0;
const uint type = bitfieldExtract(texture_control, int(ur1), 2); const uint type = GET_BITS(texture_control, int(ur1), 2);
switch (type) switch (type)
{ {
@ -419,7 +422,7 @@ vec4 _textureLod(in vec4 coord, float lod)
break; break;
} }
if (TEST_BIT(0, 21)) if (TEST_INST_BIT(0, 21))
{ {
// Normal-expand, v = 2v - 1 // Normal-expand, v = 2v - 1
vr0 += vr0; vr0 += vr0;
@ -436,27 +439,27 @@ void write_dst(const in vec4 value)
uvr0 = uvec4(uint(1 << 9), uint(1 << 10), uint(1 << 11), uint(1 << 12)); uvr0 = uvec4(uint(1 << 9), uint(1 << 10), uint(1 << 11), uint(1 << 12));
bvr0 = bvec4(uvr0 & inst.words.xxxx); bvr0 = bvec4(uvr0 & inst.words.xxxx);
if (TEST_BIT(0, 8)) // SET COND if (TEST_INST_BIT(0, 8)) // SET COND
{ {
ur0 = GET_BITS(1, 30, 1); ur0 = GET_INST_BITS(1, 30, 1);
reg_mov(cc[ur0], value, bvr0); reg_mov(cc[ur0], value, bvr0);
} }
if (TEST_BIT(0, 30)) // NO DEST if (TEST_INST_BIT(0, 30)) // NO DEST
{ {
return; return;
} }
ur1 = GET_BITS(2, 28, 3); ur1 = GET_INST_BITS(2, 28, 3);
sr0 = modifier_scale[ur1]; sr0 = modifier_scale[ur1];
vr0 = value * sr0; vr0 = value * sr0;
if (TEST_BIT(0, 31)) // SAT if (TEST_INST_BIT(0, 31)) // SAT
{ {
vr0 = clamp(vr0, 0, 1); vr0 = clamp(vr0, 0, 1);
} }
ur0 = GET_BITS(1, 18, 3); ur0 = GET_INST_BITS(1, 18, 3);
if (ur0 != 0x7) if (ur0 != 0x7)
{ {
vr1 = read_cond(); vr1 = read_cond();
@ -464,8 +467,8 @@ void write_dst(const in vec4 value)
bvr0 = bvec4(uvec4(bvr0) & uvec4(bvr1)); bvr0 = bvec4(uvec4(bvr0) & uvec4(bvr1));
} }
ur1 = GET_BITS(0, 1, 6); ur1 = GET_INST_BITS(0, 1, 6);
if (TEST_BIT(0, 7)) if (TEST_INST_BIT(0, 7))
{ {
reg_mov(regs16[ur1], vr0, bvr0); reg_mov(regs16[ur1], vr0, bvr0);
} }
@ -481,7 +484,7 @@ void initialize()
// NOTE: Register count is the number of 'full' registers that will be consumed. Hardware seems to do some renaming. // NOTE: Register count is the number of 'full' registers that will be consumed. Hardware seems to do some renaming.
// NOTE: Attempting to zero-initialize all the registers will slow things to a crawl! // NOTE: Attempting to zero-initialize all the registers will slow things to a crawl!
uint register_count = bitfieldExtract(shader_control, 24, 6); uint register_count = GET_BITS(shader_control, 24, 6);
ur0 = 0, ur1 = 0; ur0 = 0, ur1 = 0;
while (register_count > 0) while (register_count > 0)
{ {
@ -587,11 +590,11 @@ void main()
((fp_instructions[ip] << 8) & uvec4(0xFF00FF00)) | ((fp_instructions[ip] << 8) & uvec4(0xFF00FF00)) |
((fp_instructions[ip] >> 8) & uvec4(0x00FF00FF)); ((fp_instructions[ip] >> 8) & uvec4(0x00FF00FF));
inst.opcode = GET_BITS(0, 24, 6); inst.opcode = GET_INST_BITS(0, 24, 6);
inst.end = TEST_BIT(0, 0); inst.end = TEST_INST_BIT(0, 0);
#ifdef WITH_FLOW_CTRL #ifdef WITH_FLOW_CTRL
if (TEST_BIT(2, 31)) if (TEST_INST_BIT(2, 31))
{ {
// Flow control // Flow control
switch (inst.opcode | (1 << 6)) switch (inst.opcode | (1 << 6))
@ -623,8 +626,8 @@ void main()
case RSX_FP_OPCODE_REP: case RSX_FP_OPCODE_REP:
if (check_cond()) if (check_cond())
{ {
counter = int(GET_BITS(2, 2, 8) - GET_BITS(2, 10, 8)); counter = int(GET_INST_BITS(2, 2, 8) - GET_INST_BITS(2, 10, 8));
counter /= int(GET_BITS(2, 19, 8)); counter /= int(GET_INST_BITS(2, 19, 8));
loop_start_addr = ip + 1; loop_start_addr = ip + 1;
loop_end_addr = int(inst.words.w >> 2); loop_end_addr = int(inst.words.w >> 2);
} }