factor psh_translate args into PshState

This commit is contained in:
espes 2015-10-20 22:52:01 +11:00
parent f16f79a1bc
commit 32a04b3f38
5 changed files with 79 additions and 115 deletions

View File

@ -2929,17 +2929,19 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
bool binding_changed = false; bool binding_changed = false;
ShaderState state = { ShaderState state = {
/* register combier stuff */ .psh = (PshState){
.combiner_control = pg->regs[NV_PGRAPH_COMBINECTL], /* register combier stuff */
.shader_stage_program = pg->regs[NV_PGRAPH_SHADERPROG], .combiner_control = pg->regs[NV_PGRAPH_COMBINECTL],
.other_stage_input = pg->regs[NV_PGRAPH_SHADERCTL], .shader_stage_program = pg->regs[NV_PGRAPH_SHADERPROG],
.final_inputs_0 = pg->regs[NV_PGRAPH_COMBINESPECFOG0], .other_stage_input = pg->regs[NV_PGRAPH_SHADERCTL],
.final_inputs_1 = pg->regs[NV_PGRAPH_COMBINESPECFOG1], .final_inputs_0 = pg->regs[NV_PGRAPH_COMBINESPECFOG0],
.final_inputs_1 = pg->regs[NV_PGRAPH_COMBINESPECFOG1],
.alpha_test = pg->regs[NV_PGRAPH_CONTROL_0] .alpha_test = pg->regs[NV_PGRAPH_CONTROL_0]
& NV_PGRAPH_CONTROL_0_ALPHATESTENABLE, & NV_PGRAPH_CONTROL_0_ALPHATESTENABLE,
.alpha_func = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_0], .alpha_func = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
NV_PGRAPH_CONTROL_0_ALPHAFUNC), NV_PGRAPH_CONTROL_0_ALPHAFUNC),
},
.skinning = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D], .skinning = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_SKIN), NV_PGRAPH_CSV0_D_SKIN),
@ -3025,16 +3027,16 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
} }
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
state.rgb_inputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORI0 + i * 4]; state.psh.rgb_inputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORI0 + i * 4];
state.rgb_outputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORO0 + i * 4]; state.psh.rgb_outputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORO0 + i * 4];
state.alpha_inputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAI0 + i * 4]; state.psh.alpha_inputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAI0 + i * 4];
state.alpha_outputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAO0 + i * 4]; state.psh.alpha_outputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAO0 + i * 4];
//constant_0[i] = pg->regs[NV_PGRAPH_COMBINEFACTOR0 + i * 4]; //constant_0[i] = pg->regs[NV_PGRAPH_COMBINEFACTOR0 + i * 4];
//constant_1[i] = pg->regs[NV_PGRAPH_COMBINEFACTOR1 + i * 4]; //constant_1[i] = pg->regs[NV_PGRAPH_COMBINEFACTOR1 + i * 4];
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
state.rect_tex[i] = false; state.psh.rect_tex[i] = false;
bool enabled = pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4] bool enabled = pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4]
& NV_PGRAPH_TEXCTL0_0_ENABLE; & NV_PGRAPH_TEXCTL0_0_ENABLE;
unsigned int color_format = unsigned int color_format =
@ -3042,14 +3044,14 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
NV_PGRAPH_TEXFMT0_COLOR); NV_PGRAPH_TEXFMT0_COLOR);
if (enabled && kelvin_color_format_map[color_format].linear) { if (enabled && kelvin_color_format_map[color_format].linear) {
state.rect_tex[i] = true; state.psh.rect_tex[i] = true;
} }
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
state.compare_mode[i][j] = state.psh.compare_mode[i][j] =
(pg->regs[NV_PGRAPH_SHADERCLIPMODE] >> (4 * i + j)) & 1; (pg->regs[NV_PGRAPH_SHADERCLIPMODE] >> (4 * i + j)) & 1;
} }
state.alphakill[i] = pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4] state.psh.alphakill[i] = pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4]
& NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN; & NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN;
} }

View File

@ -194,6 +194,8 @@ struct PSStageInfo {
}; };
struct PixelShader { struct PixelShader {
PshState state;
int num_stages, flags; int num_stages, flags;
struct PSStageInfo stage[8]; struct PSStageInfo stage[8];
struct FCInputInfo final_input; struct FCInputInfo final_input;
@ -201,21 +203,14 @@ struct PixelShader {
//uint32_t dot_mapping, input_texture; //uint32_t dot_mapping, input_texture;
bool rect_tex[4];
bool compare_mode[4][4];
bool alphakill[4];
bool alpha_test;
enum PshAlphaFunc alpha_func;
QString *varE, *varF; QString *varE, *varF;
QString *code; QString *code;
int cur_stage; int cur_stage;
int num_var_refs; int num_var_refs;
const char var_refs[32][32]; char var_refs[32][32];
int num_const_refs; int num_const_refs;
const char const_refs[32][32]; char const_refs[32][32];
}; };
static void add_var_ref(struct PixelShader *ps, const char *var) static void add_var_ref(struct PixelShader *ps, const char *var)
@ -569,7 +564,7 @@ static QString* psh_convert(struct PixelShader *ps)
i); i);
break; break;
case PS_TEXTUREMODES_PROJECT2D: case PS_TEXTUREMODES_PROJECT2D:
if (ps->rect_tex[i]) { if (ps->state.rect_tex[i]) {
sampler_type = "sampler2DRect"; sampler_type = "sampler2DRect";
} else { } else {
sampler_type = "sampler2D"; sampler_type = "sampler2D";
@ -594,13 +589,13 @@ static QString* psh_convert(struct PixelShader *ps)
assert(false); assert(false);
break; break;
case PS_TEXTUREMODES_DPNDNT_AR: case PS_TEXTUREMODES_DPNDNT_AR:
assert(!ps->rect_tex[i]); assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D"; sampler_type = "sampler2D";
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.ar);\n", qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.ar);\n",
i, i, ps->input_tex[i]); i, i, ps->input_tex[i]);
break; break;
case PS_TEXTUREMODES_DPNDNT_GB: case PS_TEXTUREMODES_DPNDNT_GB:
assert(!ps->rect_tex[i]); assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D"; sampler_type = "sampler2D";
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.gb);\n", qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.gb);\n",
i, i, ps->input_tex[i]); i, i, ps->input_tex[i]);
@ -613,7 +608,7 @@ static QString* psh_convert(struct PixelShader *ps)
i, i, i, ps->input_tex[i], i); i, i, i, ps->input_tex[i], i);
/* No break here! Extension of BUMPENVMAP */ /* No break here! Extension of BUMPENVMAP */
case PS_TEXTUREMODES_BUMPENVMAP: case PS_TEXTUREMODES_BUMPENVMAP:
assert(!ps->rect_tex[i]); assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D"; sampler_type = "sampler2D";
qstring_append_fmt(preflight, "uniform mat2 bumpMat%d;\n", i); qstring_append_fmt(preflight, "uniform mat2 bumpMat%d;\n", i);
/* FIXME: Do bumpMat swizzle on CPU before upload */ /* FIXME: Do bumpMat swizzle on CPU before upload */
@ -627,7 +622,7 @@ static QString* psh_convert(struct PixelShader *ps)
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
qstring_append_fmt(vars, " if(pT%d.%c %s 0.0) { discard; };\n", qstring_append_fmt(vars, " if(pT%d.%c %s 0.0) { discard; };\n",
i, "xyzw"[j], i, "xyzw"[j],
ps->compare_mode[i][j] ? ">=" : "<"); ps->state.compare_mode[i][j] ? ">=" : "<");
} }
break; break;
} }
@ -645,7 +640,7 @@ static QString* psh_convert(struct PixelShader *ps)
qstring_append_fmt(preflight, "uniform %s texSamp%d;\n", sampler_type, i); qstring_append_fmt(preflight, "uniform %s texSamp%d;\n", sampler_type, i);
/* As this means a texture fetch does happen, do alphakill */ /* As this means a texture fetch does happen, do alphakill */
if (ps->alphakill[i]) { if (ps->state.alphakill[i]) {
qstring_append_fmt(vars, "if (t%d.a == 0.0) { discard; };\n", qstring_append_fmt(vars, "if (t%d.a == 0.0) { discard; };\n",
i); i);
} }
@ -679,13 +674,13 @@ static QString* psh_convert(struct PixelShader *ps)
qstring_append_fmt(preflight, "uniform vec4 %s;\n", ps->const_refs[i]); qstring_append_fmt(preflight, "uniform vec4 %s;\n", ps->const_refs[i]);
} }
if (ps->alpha_test && ps->alpha_func != ALPHA_FUNC_ALWAYS) { if (ps->state.alpha_test && ps->state.alpha_func != ALPHA_FUNC_ALWAYS) {
qstring_append_fmt(preflight, "uniform float alphaRef;\n"); qstring_append_fmt(preflight, "uniform float alphaRef;\n");
if (ps->alpha_func == ALPHA_FUNC_NEVER) { if (ps->state.alpha_func == ALPHA_FUNC_NEVER) {
qstring_append(ps->code, "discard;\n"); qstring_append(ps->code, "discard;\n");
} else { } else {
const char* alpha_op; const char* alpha_op;
switch (ps->alpha_func) { switch (ps->state.alpha_func) {
case ALPHA_FUNC_LESS: alpha_op = "<"; break; case ALPHA_FUNC_LESS: alpha_op = "<"; break;
case ALPHA_FUNC_EQUAL: alpha_op = "=="; break; case ALPHA_FUNC_EQUAL: alpha_op = "=="; break;
case ALPHA_FUNC_LEQUAL: alpha_op = "<="; break; case ALPHA_FUNC_LEQUAL: alpha_op = "<="; break;
@ -749,50 +744,34 @@ static void parse_combiner_output(uint32_t value, struct OutputInfo *out)
out->cd_alphablue = flags & 0x40; out->cd_alphablue = flags & 0x40;
} }
QString *psh_translate(uint32_t combiner_control, uint32_t shader_stage_program, QString *psh_translate(const PshState state)
uint32_t other_stage_input,
const uint32_t rgb_inputs[8],
const uint32_t rgb_outputs[8],
const uint32_t alpha_inputs[8],
const uint32_t alpha_outputs[8],
/*uint32_t constant_0[8], uint32_t constant_1[8],*/
uint32_t final_inputs_0, uint32_t final_inputs_1,
/*uint32_t final_constant_0, uint32_t final_constant_1,*/
const bool rect_tex[4],
const bool compare_mode[4][4],
const bool alphakill[4],
bool alpha_test, enum PshAlphaFunc alpha_func)
{ {
int i, j; int i;
struct PixelShader ps; struct PixelShader ps;
memset(&ps, 0, sizeof(ps)); memset(&ps, 0, sizeof(ps));
ps.num_stages = combiner_control & 0xFF; ps.state = state;
ps.flags = combiner_control >> 8;
for (i = 0; i < 4; i++) {
ps.tex_modes[i] = (shader_stage_program >> (i * 5)) & 0x1F;
ps.rect_tex[i] = rect_tex[i];
for (j = 0; j < 4; j++) {
ps.compare_mode[i][j] = compare_mode[i][j];
}
ps.alphakill[i] = alphakill[i];
}
ps.alpha_test = alpha_test; ps.num_stages = state.combiner_control & 0xFF;
ps.alpha_func = alpha_func; ps.flags = state.combiner_control >> 8;
for (i = 0; i < 4; i++) {
ps.tex_modes[i] = (state.shader_stage_program >> (i * 5)) & 0x1F;
}
ps.input_tex[0] = -1; ps.input_tex[0] = -1;
ps.input_tex[1] = 0; ps.input_tex[1] = 0;
ps.input_tex[2] = (other_stage_input >> 16) & 0xF; ps.input_tex[2] = (state.other_stage_input >> 16) & 0xF;
ps.input_tex[3] = (other_stage_input >> 20) & 0xF; ps.input_tex[3] = (state.other_stage_input >> 20) & 0xF;
for (i = 0; i < ps.num_stages; i++) { for (i = 0; i < ps.num_stages; i++) {
parse_combiner_inputs(rgb_inputs[i], &ps.stage[i].rgb_input.a, parse_combiner_inputs(state.rgb_inputs[i],
&ps.stage[i].rgb_input.b, &ps.stage[i].rgb_input.c, &ps.stage[i].rgb_input.d); &ps.stage[i].rgb_input.a, &ps.stage[i].rgb_input.b,
parse_combiner_inputs(alpha_inputs[i], &ps.stage[i].alpha_input.a, &ps.stage[i].rgb_input.c, &ps.stage[i].rgb_input.d);
&ps.stage[i].alpha_input.b, &ps.stage[i].alpha_input.c, &ps.stage[i].alpha_input.d); parse_combiner_inputs(state.alpha_inputs[i],
&ps.stage[i].alpha_input.a, &ps.stage[i].alpha_input.b,
&ps.stage[i].alpha_input.c, &ps.stage[i].alpha_input.d);
parse_combiner_output(rgb_outputs[i], &ps.stage[i].rgb_output); parse_combiner_output(state.rgb_outputs[i], &ps.stage[i].rgb_output);
parse_combiner_output(alpha_outputs[i], &ps.stage[i].alpha_output); parse_combiner_output(state.alpha_outputs[i], &ps.stage[i].alpha_output);
//ps.stage[i].c0 = (pDef->PSC0Mapping >> (i * 4)) & 0xF; //ps.stage[i].c0 = (pDef->PSC0Mapping >> (i * 4)) & 0xF;
//ps.stage[i].c1 = (pDef->PSC1Mapping >> (i * 4)) & 0xF; //ps.stage[i].c1 = (pDef->PSC1Mapping >> (i * 4)) & 0xF;
//ps.stage[i].c0_value = constant_0[i]; //ps.stage[i].c0_value = constant_0[i];
@ -800,13 +779,15 @@ QString *psh_translate(uint32_t combiner_control, uint32_t shader_stage_program,
} }
struct InputInfo blank; struct InputInfo blank;
ps.final_input.enabled = final_inputs_0 || final_inputs_1; ps.final_input.enabled = state.final_inputs_0 || state.final_inputs_1;
if (ps.final_input.enabled) { if (ps.final_input.enabled) {
parse_combiner_inputs(final_inputs_0, &ps.final_input.a, &ps.final_input.b, parse_combiner_inputs(state.final_inputs_0,
&ps.final_input.a, &ps.final_input.b,
&ps.final_input.c, &ps.final_input.d); &ps.final_input.c, &ps.final_input.d);
parse_combiner_inputs(final_inputs_1, &ps.final_input.e, &ps.final_input.f, parse_combiner_inputs(state.final_inputs_1,
&ps.final_input.e, &ps.final_input.f,
&ps.final_input.g, &blank); &ps.final_input.g, &blank);
int flags = final_inputs_1 & 0xFF; int flags = state.final_inputs_1 & 0xFF;
ps.final_input.clamp_sum = flags & PS_FINALCOMBINERSETTING_CLAMP_SUM; ps.final_input.clamp_sum = flags & PS_FINALCOMBINERSETTING_CLAMP_SUM;
ps.final_input.inv_v1 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_V1; ps.final_input.inv_v1 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_V1;
ps.final_input.inv_r0 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_R0; ps.final_input.inv_r0 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_R0;

View File

@ -35,18 +35,25 @@ enum PshAlphaFunc {
ALPHA_FUNC_ALWAYS, ALPHA_FUNC_ALWAYS,
}; };
QString *psh_translate(uint32_t combiner_control, uint32_t shader_stage_program, typedef struct PshState {
uint32_t other_stage_input, /* fragment shader - register combiner stuff */
const uint32_t rgb_inputs[8], uint32_t combiner_control;
const uint32_t rgb_outputs[8], uint32_t shader_stage_program;
const uint32_t alpha_inputs[8], uint32_t other_stage_input;
const uint32_t alpha_outputs[8], uint32_t final_inputs_0;
/*uint32_t constant_0[8], uint32_t constant_1[8],*/ uint32_t final_inputs_1;
uint32_t final_inputs_0, uint32_t final_inputs_1,
/*uint32_t final_constant_0, uint32_t final_constant_1,*/ uint32_t rgb_inputs[8], rgb_outputs[8];
const bool rect_tex[4], uint32_t alpha_inputs[8], alpha_outputs[8];
const bool compare_mode[4][4],
const bool alphakill[4], bool rect_tex[4];
bool alpha_test, enum PshAlphaFunc alpha_func); bool compare_mode[4][4];
bool alphakill[4];
bool alpha_test;
enum PshAlphaFunc alpha_func;
} PshState;
QString *psh_translate(const PshState state);
#endif #endif

View File

@ -815,18 +815,7 @@ ShaderBinding* generate_shaders(const ShaderState state)
/* generate a fragment shader from register combiners */ /* generate a fragment shader from register combiners */
QString *fragment_shader_code = psh_translate(state.combiner_control, QString *fragment_shader_code = psh_translate(state.psh);
state.shader_stage_program,
state.other_stage_input,
state.rgb_inputs, state.rgb_outputs,
state.alpha_inputs, state.alpha_outputs,
/* constant_0, constant_1, */
state.final_inputs_0, state.final_inputs_1,
/* final_constant_0, final_constant_1, */
state.rect_tex,
state.compare_mode,
state.alphakill,
state.alpha_test, state.alpha_func);
const char *fragment_shader_code_str = qstring_get_str(fragment_shader_code); const char *fragment_shader_code_str = qstring_get_str(fragment_shader_code);

View File

@ -52,22 +52,7 @@ enum ShaderPolygonMode {
}; };
typedef struct ShaderState { typedef struct ShaderState {
/* fragment shader - register combiner stuff */ PshState psh;
uint32_t combiner_control;
uint32_t shader_stage_program;
uint32_t other_stage_input;
uint32_t final_inputs_0;
uint32_t final_inputs_1;
uint32_t rgb_inputs[8], rgb_outputs[8];
uint32_t alpha_inputs[8], alpha_outputs[8];
bool rect_tex[4];
bool compare_mode[4][4];
bool alphakill[4];
bool alpha_test;
enum PshAlphaFunc alpha_func;
bool texture_matrix_enable[4]; bool texture_matrix_enable[4];
enum VshTexgen texgen[4][4]; enum VshTexgen texgen[4][4];