mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Port PR 2720 R12 oPos concurrency fix
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user