nv2a: Implement dot texture modes and dotmapping

This commit is contained in:
Matt Borgerson 2020-10-27 15:57:54 -07:00 committed by mborgerson
parent 9060302670
commit 3c6596975d
4 changed files with 134 additions and 34 deletions

View File

@ -1148,6 +1148,7 @@
# define NV097_SET_COMBINER_CONTROL 0x00001E60
# define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68
# define NV097_SET_SHADER_STAGE_PROGRAM 0x00001E70
# define NV097_SET_DOT_RGBMAPPING 0X00001E74
# define NV097_SET_SHADER_OTHER_STAGE_INPUT 0x00001E78
# define NV097_SET_TRANSFORM_EXECUTION_MODE 0x00001E94
# define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE 0x00000003

View File

@ -2668,8 +2668,14 @@ void pgraph_method(NV2AState *d,
pg->regs[NV_PGRAPH_SHADERPROG] = parameter;
break;
case NV097_SET_DOT_RGBMAPPING:
SET_MASK(pg->regs[NV_PGRAPH_SHADERCTL], 0xFFF,
GET_MASK(parameter, 0xFFF));
break;
case NV097_SET_SHADER_OTHER_STAGE_INPUT:
pg->regs[NV_PGRAPH_SHADERCTL] = parameter;
SET_MASK(pg->regs[NV_PGRAPH_SHADERCTL], 0xFFFF000,
GET_MASK(parameter, 0xFFFF000));
break;
case NV097_SET_TRANSFORM_EXECUTION_MODE:

View File

@ -161,6 +161,17 @@ enum PS_FINALCOMBINERSETTING
PS_FINALCOMBINERSETTING_COMPLEMENT_R0= 0x20, // unsigned invert mapping
};
enum PS_DOTMAPPING
{ // valid in stage 0 1 2 3
PS_DOTMAPPING_ZERO_TO_ONE= 0x00L, // - * * *
PS_DOTMAPPING_MINUS1_TO_1_D3D= 0x01L, // - * * *
PS_DOTMAPPING_MINUS1_TO_1_GL= 0x02L, // - * * *
PS_DOTMAPPING_MINUS1_TO_1= 0x03L, // - * * *
PS_DOTMAPPING_HILO_1= 0x04L, // - * * *
PS_DOTMAPPING_HILO_HEMISPHERE_D3D= 0x05L, // - * * *
PS_DOTMAPPING_HILO_HEMISPHERE_GL= 0x06L, // - * * *
PS_DOTMAPPING_HILO_HEMISPHERE= 0x07L, // - * * *
};
// Structures to describe the PS definition
@ -195,9 +206,7 @@ struct PixelShader {
int num_stages, flags;
struct PSStageInfo stage[8];
struct FCInputInfo final_input;
int tex_modes[4], input_tex[4];
//uint32_t dot_mapping, input_texture;
int tex_modes[4], input_tex[4], dot_map[4];
QString *varE, *varF;
QString *code;
@ -459,8 +468,8 @@ static void add_stage_code(struct PixelShader *ps,
if (output.muxsum_op == PS_COMBINEROUTPUT_AB_CD_SUM) {
sum = qstring_from_fmt("(%s + %s)", qstring_get_str(ab), qstring_get_str(cd));
} else {
sum = qstring_from_fmt("((r0.a >= 0.5) ? %s : %s)",
qstring_get_str(cd), qstring_get_str(ab));
sum = qstring_from_fmt("((r0.a >= 0.5) ? %s(%s) : %s(%s))",
caster, qstring_get_str(cd), caster, qstring_get_str(ab));
}
QString *sum_mapping = get_output(sum, output.mapping);
@ -512,8 +521,6 @@ static void add_final_stage_code(struct PixelShader *ps, struct FCInputInfo fina
ps->varE = ps->varF = NULL;
}
static QString* psh_convert(struct PixelShader *ps)
{
int i;
@ -527,6 +534,58 @@ static QString* psh_convert(struct PixelShader *ps)
qstring_append(preflight, "\n");
qstring_append(preflight, "uniform vec4 fogColor;\n");
const char *dotmap_funcs[] = {
"dotmap_zero_to_one",
"dotmap_minus1_to_1_d3d",
"dotmap_minus1_to_1_gl",
"dotmap_minus1_to_1",
"dotmap_hilo_1",
"dotmap_hilo_hemisphere_d3d",
"dotmap_hilo_hemisphere_gl",
"dotmap_hilo_hemisphere",
};
qstring_append_fmt(preflight,
"float sign1(float x) {\n"
" x *= 255.0;\n"
" return (x-128.0)/127.0;\n"
"}\n"
"float sign2(float x) {\n"
" x *= 255.0;\n"
" if (x >= 128.0) return (x-255.5)/127.5;\n"
" else return (x+0.5)/127.5;\n"
"}\n"
"float sign3(float x) {\n"
" x *= 255.0;\n"
" if (x >= 128.0) return (x-256.0)/127.0;\n"
" else return (x)/127.0;\n"
"}\n"
"vec3 dotmap_zero_to_one(vec3 col) {\n"
" return col;\n"
"}\n"
"vec3 dotmap_minus1_to_1_d3d(vec3 col) {\n"
" return vec3(sign1(col.r),sign1(col.g),sign1(col.b));\n"
"}\n"
"vec3 dotmap_minus1_to_1_gl(vec3 col) {\n"
" return vec3(sign2(col.r),sign2(col.g),sign2(col.b));\n"
"}\n"
"vec3 dotmap_minus1_to_1(vec3 col) {\n"
" return vec3(sign3(col.r),sign3(col.g),sign3(col.b));\n"
"}\n"
"vec3 dotmap_hilo_1(vec3 col) {\n"
" return col;\n" // FIXME
"}\n"
"vec3 dotmap_hilo_hemisphere_d3d(vec3 col) {\n"
" return col;\n" // FIXME
"}\n"
"vec3 dotmap_hilo_hemisphere_gl(vec3 col) {\n"
" return col;\n" // FIXME
"}\n"
"vec3 dotmap_hilo_hemisphere(vec3 col) {\n"
" return col;\n" // FIXME
"}\n"
);
/* Window Clipping */
QString *clip = qstring_new();
if (ps->state.window_clip_count != 0) {
@ -584,17 +643,19 @@ static QString* psh_convert(struct PixelShader *ps)
const char *sampler_type = NULL;
assert(ps->dot_map[i] < 8);
const char *dotmap_func = dotmap_funcs[ps->dot_map[i]];
if (ps->dot_map[i] > 3) {
NV2A_UNIMPLEMENTED("Dot Mapping mode %s", dotmap_func);
}
switch (ps->tex_modes[i]) {
case PS_TEXTUREMODES_NONE:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_NONE */\n",
i);
break;
case PS_TEXTUREMODES_PROJECT2D:
if (ps->state.rect_tex[i]) {
sampler_type = "sampler2DRect";
} else {
sampler_type = "sampler2D";
}
sampler_type = ps->state.rect_tex[i] ? "sampler2DRect" : "sampler2D";
qstring_append_fmt(vars, "vec4 t%d = textureProj(texSamp%d, pT%d.xyw);\n",
i, i, i);
break;
@ -623,6 +684,7 @@ static QString* psh_convert(struct PixelShader *ps)
break;
}
case PS_TEXTUREMODES_BUMPENVMAP:
assert(i >= 1);
assert(!ps->state.rect_tex[i]);
sampler_type = "sampler2D";
qstring_append_fmt(preflight, "uniform mat2 bumpMat%d;\n", i);
@ -631,6 +693,7 @@ static QString* psh_convert(struct PixelShader *ps)
i, i, i, ps->input_tex[i], i, i);
break;
case PS_TEXTUREMODES_BUMPENVMAP_LUM:
assert(i >= 1);
qstring_append_fmt(preflight, "uniform float bumpScale%d;\n", i);
qstring_append_fmt(preflight, "uniform float bumpOffset%d;\n", i);
qstring_append_fmt(ps->code, "/* BUMPENVMAP_LUM for stage %d */\n", i);
@ -645,55 +708,80 @@ static QString* psh_convert(struct PixelShader *ps)
i, i, i, ps->input_tex[i], i, i);
break;
case PS_TEXTUREMODES_BRDF:
assert(i >= 2);
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_BRDF */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_BRDF");
break;
case PS_TEXTUREMODES_DOT_ST:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_ST */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_ST");
assert(i >= 2);
sampler_type = ps->state.rect_tex[i] ? "sampler2DRect" : "sampler2D";
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_ST */\n");
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, vec2(t%d.r, dot(pT%d.xyz, %s(t%d.rgb))) );\n",
i, i, i-1, i, dotmap_func, ps->input_tex[i]);
break;
case PS_TEXTUREMODES_DOT_ZW:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_ZW */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_ZW");
assert(i >= 2);
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_ZW */\n");
qstring_append_fmt(vars, "vec3 t%d = vec3(t%d.x / dot(pT%d.rgb, %s(t%d.rgb))); \n",
i, i-1, i, dotmap_func, ps->input_tex[i]);
// FIXME: qstring_append_fmt(vars, "gl_FragDepth = t%d.x;\n", i);
break;
case PS_TEXTUREMODES_DOT_RFLCT_DIFF:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_RFLCT_DIFF */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_RFLCT_DIFF");
assert(i == 2);
sampler_type = "samplerCube";
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_RFLCT_DIFF */\n");
qstring_append_fmt(vars, "vec3 n_%d = vec3(t%d.x, dot(pT%d.xyz, %s(t%d.rgb)), t%d.x);\n",
i, i-1, i, dotmap_funcs[i], ps->input_tex[i], i-1);
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, n_%d);\n",
i, i, i);
break;
case PS_TEXTUREMODES_DOT_RFLCT_SPEC:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_RFLCT_SPEC */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_RFLCT_SPEC");
assert(i == 3);
sampler_type = "samplerCube";
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_RFLCT_SPEC */\n");
qstring_append_fmt(vars, "vec3 n_%d = vec3(t%d.x, t%d.x, dot(pT%d.xyz, %s(t%d.rgb))); \n",
i, i-2, i-1, i, dotmap_func, ps->input_tex[i]);
qstring_append_fmt(vars, "vec3 e_%d = vec3(pT%d.w, pT%d.w, pT%d.w);\n",
i, i-2, i-1, i);
qstring_append_fmt(vars, "vec3 rv_%d = 2*n_%d*dot(n_%d,e_%d)/dot(n_%d,n_%d) - e_%d;\n",
i, i, i, i, i, i, i);
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, rv_%d);\n",
i, i, i);
break;
case PS_TEXTUREMODES_DOT_STR_3D:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_STR_3D */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_STR_3D");
assert(i == 3);
sampler_type = "sampler3D";
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_STR_3D */\n");
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, vec3(t%d.x, t%d.x, dot(pT%d.xyz, %s(t%d.rgb))));\n",
i, i, i-2, i-1, i, dotmap_func, ps->input_tex[i]);
break;
case PS_TEXTUREMODES_DOT_STR_CUBE:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_STR_CUBE */\n",
i);
NV2A_UNIMPLEMENTED("PS_TEXTUREMODES_DOT_STR_CUBE");
assert(i == 3);
sampler_type = "samplerCube";
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOT_STR_CUBE */\n");
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, vec3(t%d.x, t%d.x, dot(pT%d.xyz, %s(t%d.rgb))));\n",
i, i, i-2, i-1, i, dotmap_func, ps->input_tex[i]);
break;
case PS_TEXTUREMODES_DPNDNT_AR:
assert(i >= 1);
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(i >= 1);
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]);
break;
case PS_TEXTUREMODES_DOTPRODUCT:
qstring_append_fmt(vars, "vec4 t%d = vec4(dot(pT%d.xyz, t%d.rgb));\n",
i, i, ps->input_tex[i]);
assert(i == 1 || i == 2);
qstring_append_fmt(vars, "/* PS_TEXTUREMODES_DOTPRODUCT */\n");
qstring_append_fmt(vars, "vec4 t%d = vec4(dot(pT%d.xyz, %s(t%d.rgb)));\n",
i, i, dotmap_func, ps->input_tex[i]);
break;
case PS_TEXTUREMODES_DOT_RFLCT_SPEC_CONST:
qstring_append_fmt(vars, "vec4 t%d = vec4(0.0); /* PS_TEXTUREMODES_DOT_RFLCT_SPEC_CONST */\n",
@ -829,6 +917,11 @@ QString *psh_translate(const PshState state)
ps.tex_modes[i] = (state.shader_stage_program >> (i * 5)) & 0x1F;
}
ps.dot_map[0] = 0;
ps.dot_map[1] = (state.other_stage_input >> 0) & 0xf;
ps.dot_map[2] = (state.other_stage_input >> 4) & 0xf;
ps.dot_map[3] = (state.other_stage_input >> 8) & 0xf;
ps.input_tex[0] = -1;
ps.input_tex[1] = 0;
ps.input_tex[2] = (state.other_stage_input >> 16) & 0xF;

View File

@ -843,7 +843,7 @@ static GLuint create_gl_shader(GLenum gl_shader_type,
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
log = g_malloc(log_length * sizeof(GLchar));
glGetShaderInfoLog(shader, log_length, NULL, log);
fprintf(stderr, "nv2a: %s compilation failed: %s\n", name, log);
fprintf(stderr, "%s\n\n" "nv2a: %s compilation failed: %s\n", code, name, log);
g_free(log);
NV2A_GL_DGROUP_END();