Port PR 2720 R12 oPos concurrency fix

This commit is contained in:
izzy2lost
2026-04-08 02:34:53 -04:00
parent 28e6ac2942
commit d5374eb522
+33 -9
View File
@@ -209,6 +209,7 @@ static bool ilu_force_scalar[] = {
false,
};
#define OUTPUT_REG_POS 0
#define OUTPUT_REG_FOG 5
static const char* out_reg_name[] = {
@@ -304,7 +305,6 @@ static MString *decode_opcode_input(const uint32_t *shader_token,
MString *ret_str = mstring_new();
if (vsh_get_field(shader_token, neg_field) > 0) {
mstring_append_fmt(ret_str, "-");
}
@@ -354,6 +354,7 @@ static MString *decode_opcode(const uint32_t *shader_token,
MString *ret = mstring_new();
int reg_num = vsh_get_field(shader_token, FLD_OUT_R);
bool use_temp_var = false;
bool use_temp_opos = false;
/* Test for paired opcodes (in other words : Are both <> NOP?) */
if (out_mux == OMUX_MAC
@@ -369,6 +370,8 @@ static MString *decode_opcode(const uint32_t *shader_token,
reg_num = 1;
}
const char *write_mask_str = NULL;
/* See if we must add a muxed opcode too: */
if (vsh_get_field(shader_token, FLD_OUT_MUX) == out_mux
/* Only if it's not masked away: */
@@ -386,12 +389,18 @@ static MString *decode_opcode(const uint32_t *shader_token,
shader_token, FLD_OUT_ADDRESS)));
} else {
int out_reg = vsh_get_field(shader_token, FLD_OUT_ADDRESS) & 0xF;
mstring_append(ret,out_reg_name[out_reg]);
if (out_reg == OUTPUT_REG_POS && (use_temp_var || mask)) {
use_temp_opos = true;
mstring_append(ret, "_temp_r12");
} else {
mstring_append(ret, out_reg_name[out_reg]);
}
write_fog_register = out_reg == OUTPUT_REG_FOG;
}
int write_mask = vsh_get_field(shader_token, FLD_OUT_O_MASK);
const char *write_mask_str = write_fog_register ? fog_mask_str[write_mask] : mask_str[write_mask];
write_mask_str = write_fog_register ? fog_mask_str[write_mask]
: mask_str[write_mask];
mstring_append(ret, write_mask_str);
mstring_append(ret, inputs);
mstring_append(ret, ");\n");
@@ -428,6 +437,16 @@ static MString *decode_opcode(const uint32_t *shader_token,
}
}
if (use_temp_opos) {
if (!*suffix) {
*suffix = mstring_new();
}
assert(write_mask_str && "Temp oPos flagged without a mask");
const char *write_mask_components = write_mask_str + 1;
mstring_append_fmt(*suffix, " oPos.%s = _temp_r12.%s;\n",
write_mask_components, write_mask_components);
}
return ret;
}
@@ -451,7 +470,7 @@ static MString *decode_token(const uint32_t *shader_token)
(vsh_get_field(shader_token, FLD_C_R_HIGH) << 2)
| vsh_get_field(shader_token, FLD_C_R_LOW));
MString *mac_suffix = NULL;
MString *suffix = NULL;
if (mac != MAC_NOP) {
MString *inputs_mac = mstring_new();
if (mac_opcode_params[mac].A) {
@@ -485,7 +504,7 @@ static MString *decode_token(const uint32_t *shader_token)
vsh_get_field(shader_token, FLD_OUT_MAC_MASK),
mac_opcode[mac],
mstring_get_str(inputs_mac),
&mac_suffix);
&suffix);
mstring_unref(inputs_mac);
} else {
ret = mstring_new();
@@ -502,7 +521,7 @@ static MString *decode_token(const uint32_t *shader_token)
vsh_get_field(shader_token, FLD_OUT_ILU_MASK),
ilu_opcode[ilu],
mstring_get_str(inputs_c),
NULL);
&suffix);
mstring_append(ret, mstring_get_str(ilu_op));
@@ -512,9 +531,9 @@ static MString *decode_token(const uint32_t *shader_token)
mstring_unref(input_c);
if (mac_suffix) {
mstring_append(ret, mstring_get_str(mac_suffix));
mstring_unref(mac_suffix);
if (suffix) {
mstring_append(ret, mstring_get_str(suffix));
mstring_unref(suffix);
}
return ret;
@@ -543,6 +562,11 @@ static const char* vsh_header =
"vec4 _temp_vec;\n"
"int _temp_addr;\n"
/* Used to emulate concurrency of multi-output / paired instructions that
* write to oPos and read from R12
*/
"vec4 _temp_r12;\n"
/* See:
* http://msdn.microsoft.com/en-us/library/windows/desktop/bb174703%28v=vs.85%29.aspx
* https://www.opengl.org/registry/specs/NV/vertex_program1_1.txt