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;
ShaderState state = {
/* register combier stuff */
.combiner_control = pg->regs[NV_PGRAPH_COMBINECTL],
.shader_stage_program = pg->regs[NV_PGRAPH_SHADERPROG],
.other_stage_input = pg->regs[NV_PGRAPH_SHADERCTL],
.final_inputs_0 = pg->regs[NV_PGRAPH_COMBINESPECFOG0],
.final_inputs_1 = pg->regs[NV_PGRAPH_COMBINESPECFOG1],
.psh = (PshState){
/* register combier stuff */
.combiner_control = pg->regs[NV_PGRAPH_COMBINECTL],
.shader_stage_program = pg->regs[NV_PGRAPH_SHADERPROG],
.other_stage_input = pg->regs[NV_PGRAPH_SHADERCTL],
.final_inputs_0 = pg->regs[NV_PGRAPH_COMBINESPECFOG0],
.final_inputs_1 = pg->regs[NV_PGRAPH_COMBINESPECFOG1],
.alpha_test = pg->regs[NV_PGRAPH_CONTROL_0]
& NV_PGRAPH_CONTROL_0_ALPHATESTENABLE,
.alpha_func = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
NV_PGRAPH_CONTROL_0_ALPHAFUNC),
.alpha_test = pg->regs[NV_PGRAPH_CONTROL_0]
& NV_PGRAPH_CONTROL_0_ALPHATESTENABLE,
.alpha_func = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
NV_PGRAPH_CONTROL_0_ALPHAFUNC),
},
.skinning = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_SKIN),
@ -3025,16 +3027,16 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
}
for (i = 0; i < 8; i++) {
state.rgb_inputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORI0 + i * 4];
state.rgb_outputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORO0 + i * 4];
state.alpha_inputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAI0 + i * 4];
state.alpha_outputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAO0 + i * 4];
state.psh.rgb_inputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORI0 + i * 4];
state.psh.rgb_outputs[i] = pg->regs[NV_PGRAPH_COMBINECOLORO0 + i * 4];
state.psh.alpha_inputs[i] = pg->regs[NV_PGRAPH_COMBINEALPHAI0 + 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_1[i] = pg->regs[NV_PGRAPH_COMBINEFACTOR1 + i * 4];
}
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]
& NV_PGRAPH_TEXCTL0_0_ENABLE;
unsigned int color_format =
@ -3042,14 +3044,14 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
NV_PGRAPH_TEXFMT0_COLOR);
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++) {
state.compare_mode[i][j] =
state.psh.compare_mode[i][j] =
(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;
}

View File

@ -194,6 +194,8 @@ struct PSStageInfo {
};
struct PixelShader {
PshState state;
int num_stages, flags;
struct PSStageInfo stage[8];
struct FCInputInfo final_input;
@ -201,21 +203,14 @@ struct PixelShader {
//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 *code;
int cur_stage;
int num_var_refs;
const char var_refs[32][32];
char var_refs[32][32];
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)
@ -569,7 +564,7 @@ static QString* psh_convert(struct PixelShader *ps)
i);
break;
case PS_TEXTUREMODES_PROJECT2D:
if (ps->rect_tex[i]) {
if (ps->state.rect_tex[i]) {
sampler_type = "sampler2DRect";
} else {
sampler_type = "sampler2D";
@ -594,13 +589,13 @@ static QString* psh_convert(struct PixelShader *ps)
assert(false);
break;
case PS_TEXTUREMODES_DPNDNT_AR:
assert(!ps->rect_tex[i]);
assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D";
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.ar);\n",
i, i, ps->input_tex[i]);
break;
case PS_TEXTUREMODES_DPNDNT_GB:
assert(!ps->rect_tex[i]);
assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D";
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, t%d.gb);\n",
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);
/* No break here! Extension of BUMPENVMAP */
case PS_TEXTUREMODES_BUMPENVMAP:
assert(!ps->rect_tex[i]);
assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D";
qstring_append_fmt(preflight, "uniform mat2 bumpMat%d;\n", i);
/* 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++) {
qstring_append_fmt(vars, " if(pT%d.%c %s 0.0) { discard; };\n",
i, "xyzw"[j],
ps->compare_mode[i][j] ? ">=" : "<");
ps->state.compare_mode[i][j] ? ">=" : "<");
}
break;
}
@ -645,7 +640,7 @@ static QString* psh_convert(struct PixelShader *ps)
qstring_append_fmt(preflight, "uniform %s texSamp%d;\n", sampler_type, i);
/* 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",
i);
}
@ -679,13 +674,13 @@ static QString* psh_convert(struct PixelShader *ps)
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");
if (ps->alpha_func == ALPHA_FUNC_NEVER) {
if (ps->state.alpha_func == ALPHA_FUNC_NEVER) {
qstring_append(ps->code, "discard;\n");
} else {
const char* alpha_op;
switch (ps->alpha_func) {
switch (ps->state.alpha_func) {
case ALPHA_FUNC_LESS: alpha_op = "<"; break;
case ALPHA_FUNC_EQUAL: 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;
}
QString *psh_translate(uint32_t combiner_control, uint32_t shader_stage_program,
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)
QString *psh_translate(const PshState state)
{
int i, j;
int i;
struct PixelShader ps;
memset(&ps, 0, sizeof(ps));
ps.num_stages = combiner_control & 0xFF;
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.state = state;
ps.alpha_test = alpha_test;
ps.alpha_func = alpha_func;
ps.num_stages = state.combiner_control & 0xFF;
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[1] = 0;
ps.input_tex[2] = (other_stage_input >> 16) & 0xF;
ps.input_tex[3] = (other_stage_input >> 20) & 0xF;
ps.input_tex[2] = (state.other_stage_input >> 16) & 0xF;
ps.input_tex[3] = (state.other_stage_input >> 20) & 0xF;
for (i = 0; i < ps.num_stages; i++) {
parse_combiner_inputs(rgb_inputs[i], &ps.stage[i].rgb_input.a,
&ps.stage[i].rgb_input.b, &ps.stage[i].rgb_input.c, &ps.stage[i].rgb_input.d);
parse_combiner_inputs(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_inputs(state.rgb_inputs[i],
&ps.stage[i].rgb_input.a, &ps.stage[i].rgb_input.b,
&ps.stage[i].rgb_input.c, &ps.stage[i].rgb_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(alpha_outputs[i], &ps.stage[i].alpha_output);
parse_combiner_output(state.rgb_outputs[i], &ps.stage[i].rgb_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].c1 = (pDef->PSC1Mapping >> (i * 4)) & 0xF;
//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;
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) {
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);
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);
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.inv_v1 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_V1;
ps.final_input.inv_r0 = flags & PS_FINALCOMBINERSETTING_COMPLEMENT_R0;

View File

@ -35,18 +35,25 @@ enum PshAlphaFunc {
ALPHA_FUNC_ALWAYS,
};
QString *psh_translate(uint32_t combiner_control, uint32_t shader_stage_program,
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);
typedef struct PshState {
/* fragment shader - register combiner stuff */
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;
} PshState;
QString *psh_translate(const PshState state);
#endif

View File

@ -815,18 +815,7 @@ ShaderBinding* generate_shaders(const ShaderState state)
/* generate a fragment shader from register combiners */
QString *fragment_shader_code = psh_translate(state.combiner_control,
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);
QString *fragment_shader_code = psh_translate(state.psh);
const char *fragment_shader_code_str = qstring_get_str(fragment_shader_code);

View File

@ -52,22 +52,7 @@ enum ShaderPolygonMode {
};
typedef struct ShaderState {
/* fragment shader - register combiner stuff */
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;
PshState psh;
bool texture_matrix_enable[4];
enum VshTexgen texgen[4][4];