mirror of https://github.com/xemu-project/xemu.git
not even necessary
This commit is contained in:
parent
04eba3b3a2
commit
c31498a236
309
hw/xbox/nv2a.c
309
hw/xbox/nv2a.c
|
@ -832,7 +832,7 @@ static const GLenum kelvin_primitive_map[] = {
|
|||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_QUADS,
|
||||
GL_LINES_ADJACENCY, // GL_QUADS,
|
||||
// GL_QUAD_STRIP,
|
||||
// GL_POLYGON,
|
||||
};
|
||||
|
@ -1137,9 +1137,13 @@ typedef struct ShaderState {
|
|||
|
||||
bool fixed_function;
|
||||
|
||||
/* vertex program */
|
||||
bool vertex_program;
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
int program_length;
|
||||
|
||||
/* primitive format for geomotry shader */
|
||||
unsigned int primitive_mode;
|
||||
} ShaderState;
|
||||
|
||||
typedef struct ShaderBinding {
|
||||
|
@ -1277,7 +1281,6 @@ typedef struct PGRAPHState {
|
|||
bool texture_dirty[NV2A_MAX_TEXTURES];
|
||||
TextureBinding *texture_binding[NV2A_MAX_TEXTURES];
|
||||
|
||||
bool shaders_dirty;
|
||||
GHashTable *shader_cache;
|
||||
ShaderBinding *shader_binding;
|
||||
|
||||
|
@ -1292,6 +1295,7 @@ typedef struct PGRAPHState {
|
|||
|
||||
hwaddr dma_vertex_a, dma_vertex_b;
|
||||
|
||||
unsigned int primitive_mode;
|
||||
GLenum gl_primitive_mode;
|
||||
|
||||
bool enable_vertex_program_write;
|
||||
|
@ -2098,6 +2102,79 @@ static gboolean shader_equal(gconstpointer a, gconstpointer b)
|
|||
return memcmp(as, bs, sizeof(ShaderState)) == 0;
|
||||
}
|
||||
|
||||
static QString* generate_geometry_shader(unsigned int primitive_mode)
|
||||
{
|
||||
int in_verticies, out_verticies;
|
||||
switch (primitive_mode) {
|
||||
case NV097_SET_BEGIN_END_OP_QUADS:
|
||||
in_verticies = 4;
|
||||
out_verticies = 6;
|
||||
break;
|
||||
default:
|
||||
in_verticies = 3;
|
||||
out_verticies = 3;
|
||||
break;
|
||||
}
|
||||
QString* s = qstring_new();
|
||||
qstring_append(s, "#version 330\n");
|
||||
qstring_append(s, "\n");
|
||||
if (primitive_mode == NV097_SET_BEGIN_END_OP_QUADS) {
|
||||
qstring_append(s, "layout(lines_adjacency) in;\n");
|
||||
qstring_append(s, "layout(triangle_strip, max_vertices = 6) out;\n");
|
||||
} else {
|
||||
qstring_append(s, "layout(triangles) in;\n");
|
||||
qstring_append(s, "layout(triangle_strip, max_vertices = 3) out;\n");
|
||||
}
|
||||
qstring_append(s, "\n");
|
||||
qstring_append_fmt(s, "noperspective in vec4 oD0[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oD1[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oB0[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oB1[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oFog[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oT0[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oT1[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oT2[%d];\n", in_verticies);
|
||||
qstring_append_fmt(s, "noperspective in vec4 oT3[%d];\n", in_verticies);
|
||||
qstring_append(s, "\n");
|
||||
qstring_append_fmt(s, "noperspective in float oPos_w[%d];\n", in_verticies);
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, "noperspective out vec4 gD0;\n");
|
||||
qstring_append(s, "noperspective out vec4 gD1;\n");
|
||||
qstring_append(s, "noperspective out vec4 gB0;\n");
|
||||
qstring_append(s, "noperspective out vec4 gB1;\n");
|
||||
qstring_append(s, "noperspective out vec4 gFog;\n");
|
||||
qstring_append(s, "noperspective out vec4 gT0;\n");
|
||||
qstring_append(s, "noperspective out vec4 gT1;\n");
|
||||
qstring_append(s, "noperspective out vec4 gT2;\n");
|
||||
qstring_append(s, "noperspective out vec4 gT3;\n");
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, "noperspective out vec3 gCor;\n");
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, "void main() {\n");
|
||||
qstring_append(s, " for (int i = 0; i < 3; i++) {\n");
|
||||
qstring_append(s, " gD0 = oD0[i];\n");
|
||||
qstring_append(s, " gD1 = oD1[i];\n");
|
||||
qstring_append(s, " gB0 = oB0[i];\n");
|
||||
qstring_append(s, " gB1 = oB1[i];\n");
|
||||
qstring_append(s, " gFog = oFog[i];\n");
|
||||
qstring_append(s, " gT0 = oT0[i];\n");
|
||||
qstring_append(s, " gT1 = oT1[i];\n");
|
||||
qstring_append(s, " gT2 = oT2[i];\n");
|
||||
qstring_append(s, " gT3 = oT3[i];\n");
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, " gCor = vec3(0.0);\n");
|
||||
qstring_append(s, " gCor[i] = oPos_w[i];\n");
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, " gl_Position = gl_in[i].gl_Position;\n");
|
||||
qstring_append(s, " EmitVertex();\n");
|
||||
qstring_append(s, " }\n");
|
||||
qstring_append(s, "\n");
|
||||
qstring_append(s, " EndPrimitive();\n");
|
||||
qstring_append(s, "}\n");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static ShaderBinding* generate_shaders(const ShaderState state)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -2123,16 +2200,18 @@ static ShaderBinding* generate_shaders(const ShaderState state)
|
|||
"in vec4 multiTexCoord2;\n"
|
||||
"in vec4 multiTexCoord3;\n"
|
||||
"\n"
|
||||
"out vec4 oD0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oD1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oB0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oB1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oFog = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT2 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT3 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
|
||||
"noperspective out vec4 oD0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oD1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oB0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oB1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oFog = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT2 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT3 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"\n"
|
||||
"noperspective out float oPos_w;\n"
|
||||
"\n"
|
||||
"uniform mat4 composite;\n"
|
||||
"uniform mat4 invViewport;\n"
|
||||
"void main() {\n"
|
||||
|
@ -2142,6 +2221,7 @@ static ShaderBinding* generate_shaders(const ShaderState state)
|
|||
//" gl_Position.x = (gl_Position.x - 320.0) / 320.0;\n"
|
||||
//" gl_Position.y = -(gl_Position.y - 240.0) / 240.0;\n"
|
||||
" gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"
|
||||
" oPos_w = gl_Position.w;\n"
|
||||
" oD0 = diffuse;\n"
|
||||
" oT0 = multiTexCoord0;\n"
|
||||
" oT1 = multiTexCoord1;\n"
|
||||
|
@ -2238,13 +2318,39 @@ static ShaderBinding* generate_shaders(const ShaderState state)
|
|||
|
||||
|
||||
|
||||
// GLuint geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
// glAttachShader(program, geometry_shader);
|
||||
|
||||
// QString* geometry_shader_code =
|
||||
// generate_geometry_shader(state.primitive_mode);
|
||||
// const char* geometry_shader_code_str =
|
||||
// qstring_get_str(geometry_shader_code);
|
||||
|
||||
// NV2A_DPRINTF("bind geometry shader, code:\n%s\n", geometry_shader_code_str);
|
||||
|
||||
// glShaderSource(geometry_shader, 1, &geometry_shader_code_str, 0);
|
||||
// glCompileShader(geometry_shader);
|
||||
|
||||
// /* Check it compiled */
|
||||
// compiled = 0;
|
||||
// glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &compiled);
|
||||
// if (!compiled) {
|
||||
// GLchar log[2048];
|
||||
// glGetShaderInfoLog(geometry_shader, 2048, NULL, log);
|
||||
// fprintf(stderr, "nv2a: geometry shader compilation failed: %s\n", log);
|
||||
// abort();
|
||||
// }
|
||||
|
||||
// QDECREF(geometry_shader_code);
|
||||
|
||||
|
||||
/* link the program */
|
||||
glLinkProgram(program);
|
||||
GLint linked = 0;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||
if(!linked) {
|
||||
GLchar log[1024];
|
||||
glGetProgramInfoLog(program, 1024, NULL, log);
|
||||
GLchar log[2048];
|
||||
glGetProgramInfoLog(program, 2048, NULL, log);
|
||||
fprintf(stderr, "nv2a: shader linking failed: %s\n", log);
|
||||
abort();
|
||||
}
|
||||
|
@ -2311,85 +2417,84 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
|
|||
ShaderBinding* old_binding = pg->shader_binding;
|
||||
bool binding_changed = false;
|
||||
|
||||
if (pg->shaders_dirty) {
|
||||
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],
|
||||
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],
|
||||
|
||||
.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),
|
||||
|
||||
/* fixed function stuff */
|
||||
.fixed_function = fixed_function,
|
||||
/* fixed function stuff */
|
||||
.fixed_function = fixed_function,
|
||||
|
||||
/* vertex program stuff */
|
||||
.vertex_program = vertex_program,
|
||||
};
|
||||
/* vertex program stuff */
|
||||
.vertex_program = vertex_program,
|
||||
|
||||
state.program_length = 0;
|
||||
memset(state.program_data, 0, sizeof(state.program_data));
|
||||
/* geometry shader stuff */
|
||||
.primitive_mode = pg->primitive_mode,
|
||||
};
|
||||
|
||||
if (vertex_program) {
|
||||
// copy in vertex program tokens
|
||||
for (i = program_start;
|
||||
i < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH;
|
||||
i++) {
|
||||
uint32_t *cur_token = (uint32_t*)&pg->program_data[i];
|
||||
memcpy(&state.program_data[state.program_length],
|
||||
cur_token,
|
||||
VSH_TOKEN_SIZE * sizeof(uint32_t));
|
||||
state.program_length++;
|
||||
state.program_length = 0;
|
||||
memset(state.program_data, 0, sizeof(state.program_data));
|
||||
|
||||
if (vsh_get_field(cur_token, FLD_FINAL)) {
|
||||
break;
|
||||
}
|
||||
if (vertex_program) {
|
||||
// copy in vertex program tokens
|
||||
for (i = program_start; i < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH; i++) {
|
||||
uint32_t *cur_token = (uint32_t*)&pg->program_data[i];
|
||||
memcpy(&state.program_data[state.program_length],
|
||||
cur_token,
|
||||
VSH_TOKEN_SIZE * sizeof(uint32_t));
|
||||
state.program_length++;
|
||||
|
||||
if (vsh_get_field(cur_token, FLD_FINAL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
//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;
|
||||
bool enabled = GET_MASK(pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4],
|
||||
NV_PGRAPH_TEXCTL0_0_ENABLE);
|
||||
unsigned int color_format =
|
||||
GET_MASK(pg->regs[NV_PGRAPH_TEXFMT0 + i*4],
|
||||
NV_PGRAPH_TEXFMT0_COLOR);
|
||||
|
||||
if (enabled && kelvin_color_format_map[color_format].linear) {
|
||||
state.rect_tex[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderBinding* cached_shader = g_hash_table_lookup(pg->shader_cache, &state);
|
||||
if (cached_shader) {
|
||||
pg->shader_binding = cached_shader;
|
||||
} else {
|
||||
pg->shader_binding = generate_shaders(state);
|
||||
|
||||
/* cache it */
|
||||
ShaderState *cache_state = g_malloc(sizeof(*cache_state));
|
||||
memcpy(cache_state, &state, sizeof(*cache_state));
|
||||
g_hash_table_insert(pg->shader_cache, cache_state,
|
||||
(gpointer)pg->shader_binding);
|
||||
}
|
||||
|
||||
binding_changed = (pg->shader_binding != old_binding);
|
||||
}
|
||||
|
||||
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];
|
||||
//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;
|
||||
bool enabled = GET_MASK(pg->regs[NV_PGRAPH_TEXCTL0_0 + i*4],
|
||||
NV_PGRAPH_TEXCTL0_0_ENABLE);
|
||||
unsigned int color_format =
|
||||
GET_MASK(pg->regs[NV_PGRAPH_TEXFMT0 + i*4],
|
||||
NV_PGRAPH_TEXFMT0_COLOR);
|
||||
|
||||
if (enabled && kelvin_color_format_map[color_format].linear) {
|
||||
state.rect_tex[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderBinding* cached_shader = g_hash_table_lookup(pg->shader_cache, &state);
|
||||
if (cached_shader) {
|
||||
pg->shader_binding = cached_shader;
|
||||
} else {
|
||||
pg->shader_binding = generate_shaders(state);
|
||||
|
||||
/* cache it */
|
||||
ShaderState *cache_state = g_malloc(sizeof(*cache_state));
|
||||
memcpy(cache_state, &state, sizeof(*cache_state));
|
||||
g_hash_table_insert(pg->shader_cache, cache_state,
|
||||
(gpointer)pg->shader_binding);
|
||||
}
|
||||
|
||||
binding_changed = (pg->shader_binding != old_binding);
|
||||
|
||||
glUseProgram(pg->shader_binding->gl_program);
|
||||
|
||||
|
||||
|
@ -2486,7 +2591,6 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
|
|||
}
|
||||
}
|
||||
|
||||
pg->shaders_dirty = false;
|
||||
}
|
||||
|
||||
static void pgraph_get_surface_dimensions(NV2AState *d,
|
||||
|
@ -2922,8 +3026,6 @@ static void pgraph_init(PGRAPHState *pg)
|
|||
|
||||
//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
|
||||
pg->shaders_dirty = true;
|
||||
|
||||
pg->texture_cache = g_lru_cache_new(
|
||||
texture_key_hash, texture_key_equal,
|
||||
NULL, texture_key_retrieve,
|
||||
|
@ -3304,17 +3406,14 @@ static void pgraph_method(NV2AState *d,
|
|||
NV097_SET_COMBINER_ALPHA_ICW + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_ALPHA_ICW) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINEALPHAI0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_SPECULAR_FOG_CW0:
|
||||
pg->regs[NV_PGRAPH_COMBINESPECFOG0] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_SPECULAR_FOG_CW1:
|
||||
pg->regs[NV_PGRAPH_COMBINESPECFOG1] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_CONTROL0: {
|
||||
|
@ -3334,7 +3433,6 @@ static void pgraph_method(NV2AState *d,
|
|||
case NV097_SET_ALPHA_TEST_ENABLE:
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
|
||||
NV_PGRAPH_CONTROL_0_ALPHATESTENABLE, parameter);
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
case NV097_SET_BLEND_ENABLE:
|
||||
SET_MASK(pg->regs[NV_PGRAPH_BLEND], NV_PGRAPH_BLEND_EN, parameter);
|
||||
|
@ -3351,7 +3449,6 @@ static void pgraph_method(NV2AState *d,
|
|||
case NV097_SET_ALPHA_FUNC:
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
|
||||
NV_PGRAPH_CONTROL_0_ALPHAFUNC, parameter & 0xF);
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
case NV097_SET_ALPHA_REF:
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
|
||||
|
@ -3554,28 +3651,24 @@ static void pgraph_method(NV2AState *d,
|
|||
NV097_SET_COMBINER_FACTOR0 + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_FACTOR0) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINEFACTOR0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_FACTOR1 ...
|
||||
NV097_SET_COMBINER_FACTOR1 + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_FACTOR1) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINEFACTOR1 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_ALPHA_OCW ...
|
||||
NV097_SET_COMBINER_ALPHA_OCW + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_ALPHA_OCW) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINEALPHAO0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_COLOR_ICW ...
|
||||
NV097_SET_COMBINER_COLOR_ICW + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_COLOR_ICW) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINECOLORI0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_VIEWPORT_SCALE ...
|
||||
|
@ -3598,7 +3691,6 @@ static void pgraph_method(NV2AState *d,
|
|||
|
||||
assert(program_load < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
pg->program_data[program_load][slot%4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
|
||||
if (slot % 4 == 3) {
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CHEOPS_OFFSET],
|
||||
|
@ -3758,7 +3850,6 @@ static void pgraph_method(NV2AState *d,
|
|||
& NV_PGRAPH_CONTROL_1_STENCIL_TEST_ENABLE;
|
||||
|
||||
if (parameter == NV097_SET_BEGIN_END_OP_END) {
|
||||
if (pg->gl_primitive_mode == GL_QUADS) break;
|
||||
if (pg->inline_buffer_length) {
|
||||
|
||||
// pgraph_bind_vertex_attributes(...)
|
||||
|
@ -3826,6 +3917,10 @@ static void pgraph_method(NV2AState *d,
|
|||
|
||||
pgraph_update_surface(d, true, true, depth_test || stencil_test);
|
||||
|
||||
assert(parameter < ARRAYSIZE(kelvin_primitive_map));
|
||||
pg->primitive_mode = parameter;
|
||||
pg->gl_primitive_mode = kelvin_primitive_map[parameter];
|
||||
|
||||
uint32_t control_0 = pg->regs[NV_PGRAPH_CONTROL_0];
|
||||
|
||||
bool alpha = control_0 & NV_PGRAPH_CONTROL_0_ALPHA_WRITE_ENABLE;
|
||||
|
@ -3909,18 +4004,16 @@ static void pgraph_method(NV2AState *d,
|
|||
}
|
||||
|
||||
pgraph_bind_shaders(pg);
|
||||
|
||||
pgraph_bind_textures(d);
|
||||
|
||||
//glDisableVertexAttribArray(NV2A_VERTEX_ATTR_DIFFUSE);
|
||||
//glVertexAttrib4f(NV2A_VERTEX_ATTR_DIFFUSE, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
|
||||
unsigned int width, height;
|
||||
pgraph_get_surface_dimensions(d, &width, &height);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
assert(parameter < ARRAYSIZE(kelvin_primitive_map));
|
||||
pg->gl_primitive_mode = kelvin_primitive_map[parameter];
|
||||
if (pg->gl_primitive_mode == GL_QUADS) break;
|
||||
|
||||
pg->inline_elements_length = 0;
|
||||
pg->inline_array_length = 0;
|
||||
pg->inline_buffer_length = 0;
|
||||
|
@ -3959,13 +4052,11 @@ static void pgraph_method(NV2AState *d,
|
|||
SET_MASK(*reg, NV_PGRAPH_TEXFMT0_BASE_SIZE_V, log_height);
|
||||
|
||||
pg->texture_dirty[slot] = true;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
}
|
||||
CASE_4(NV097_SET_TEXTURE_CONTROL0, 64):
|
||||
slot = (class_method - NV097_SET_TEXTURE_CONTROL0) / 64;
|
||||
pg->regs[NV_PGRAPH_TEXCTL0_0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
CASE_4(NV097_SET_TEXTURE_CONTROL1, 64):
|
||||
slot = (class_method - NV097_SET_TEXTURE_CONTROL1) / 64;
|
||||
|
@ -3997,8 +4088,6 @@ static void pgraph_method(NV2AState *d,
|
|||
unsigned int start = GET_MASK(parameter, NV097_DRAW_ARRAYS_START_INDEX);
|
||||
unsigned int count = GET_MASK(parameter, NV097_DRAW_ARRAYS_COUNT)+1;
|
||||
|
||||
if (pg->gl_primitive_mode == GL_QUADS) break;
|
||||
|
||||
pgraph_bind_vertex_attributes(d, start + count, false, 0);
|
||||
glDrawArrays(pg->gl_primitive_mode, start, count);
|
||||
|
||||
|
@ -4109,29 +4198,24 @@ static void pgraph_method(NV2AState *d,
|
|||
NV097_SET_SPECULAR_FOG_FACTOR + 4:
|
||||
slot = (class_method - NV097_SET_SPECULAR_FOG_FACTOR) / 4;
|
||||
pg->regs[NV_PGRAPH_SPECFOGFACTOR0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_COLOR_OCW ...
|
||||
NV097_SET_COMBINER_COLOR_OCW + 28:
|
||||
slot = (class_method - NV097_SET_COMBINER_COLOR_OCW) / 4;
|
||||
pg->regs[NV_PGRAPH_COMBINECOLORO0 + slot*4] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_COMBINER_CONTROL:
|
||||
pg->regs[NV_PGRAPH_COMBINECTL] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_SHADER_STAGE_PROGRAM:
|
||||
pg->regs[NV_PGRAPH_SHADERPROG] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_SHADER_OTHER_STAGE_INPUT:
|
||||
pg->regs[NV_PGRAPH_SHADERCTL] = parameter;
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
|
||||
case NV097_SET_TRANSFORM_EXECUTION_MODE:
|
||||
|
@ -4152,7 +4236,6 @@ static void pgraph_method(NV2AState *d,
|
|||
assert(parameter < NV2A_MAX_TRANSFORM_PROGRAM_LENGTH);
|
||||
SET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
|
||||
NV_PGRAPH_CSV0_C_CHEOPS_PROGRAM_START, parameter);
|
||||
pg->shaders_dirty = true;
|
||||
break;
|
||||
case NV097_SET_TRANSFORM_CONSTANT_LOAD:
|
||||
assert(parameter < NV2A_VERTEXSHADER_CONSTANTS);
|
||||
|
@ -5595,7 +5678,7 @@ static const char* nv2a_method_names[] = {};
|
|||
static void reg_log_read(int block, hwaddr addr, uint64_t val) {
|
||||
if (blocktable[block].name) {
|
||||
hwaddr naddr = blocktable[block].offset + addr;
|
||||
if (naddr < ARARYSIZE(nv2a_reg_names) && nv2a_reg_names[naddr]) {
|
||||
if (naddr < ARRAY_SIZE(nv2a_reg_names) && nv2a_reg_names[naddr]) {
|
||||
NV2A_DPRINTF("%s: read [%s] -> 0x%" PRIx64 "\n",
|
||||
blocktable[block].name, nv2a_reg_names[naddr], val);
|
||||
} else {
|
||||
|
|
|
@ -529,20 +529,35 @@ static QString* psh_convert(struct PixelShader *ps)
|
|||
int i;
|
||||
|
||||
QString *preflight = qstring_new();
|
||||
qstring_append(preflight, "in vec4 oD0;\n");
|
||||
qstring_append(preflight, "in vec4 oD1;\n");
|
||||
qstring_append(preflight, "in vec4 oB0;\n");
|
||||
qstring_append(preflight, "in vec4 oB1;\n");
|
||||
qstring_append(preflight, "in vec4 oFog;\n");
|
||||
qstring_append(preflight, "in vec4 oT0;\n");
|
||||
qstring_append(preflight, "in vec4 oT1;\n");
|
||||
qstring_append(preflight, "in vec4 oT2;\n");
|
||||
qstring_append(preflight, "in vec4 oT3;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oD0;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oD1;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oB0;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oB1;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oFog;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oT0;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oT1;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oT2;\n");
|
||||
qstring_append(preflight, "noperspective in vec4 oT3;\n");
|
||||
qstring_append(preflight, "\n");
|
||||
qstring_append(preflight, "noperspective in float oPos_w;\n");
|
||||
// qstring_append(preflight, "noperspective in vec3 gCor;\n");
|
||||
qstring_append(preflight, "\n");
|
||||
qstring_append(preflight, "out vec4 fragColor;\n");
|
||||
qstring_append(preflight, "\n");
|
||||
|
||||
QString *vars = qstring_new();
|
||||
// qstring_append(vars, "float pFactor = gCor[0]+gCor[1]+gCor[2];\n");
|
||||
qstring_append(vars, "float pFactor = oPos_w;\n");
|
||||
qstring_append(vars, "vec4 pD0 = oD0 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pD1 = oD1 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pB0 = oB0 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pB1 = oB1 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pFog = oFog / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pT0 = oT0 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pT1 = oT1 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pT2 = oT2 / pFactor;\n");
|
||||
qstring_append(vars, "vec4 pT3 = oT3 / pFactor;\n");
|
||||
qstring_append(vars, "\n");
|
||||
qstring_append(vars, "vec4 v0 = oD0;\n");
|
||||
qstring_append(vars, "vec4 v1 = oD1;\n");
|
||||
qstring_append(vars, "float fog = oFog.x;\n");
|
||||
|
@ -559,22 +574,22 @@ static QString* psh_convert(struct PixelShader *ps)
|
|||
} else {
|
||||
sampler_type = "sampler2D";
|
||||
}
|
||||
qstring_append_fmt(vars, "vec4 t%d = textureProj(texSamp%d, oT%d.xyw);\n",
|
||||
qstring_append_fmt(vars, "vec4 t%d = textureProj(texSamp%d, pT%d.xyw);\n",
|
||||
i, i, i);
|
||||
break;
|
||||
case PS_TEXTUREMODES_PROJECT3D:
|
||||
sampler_type = "sampler3D";
|
||||
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, oT%d.xyz);\n",
|
||||
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, pT%d.xyz);\n",
|
||||
i, i, i);
|
||||
break;
|
||||
case PS_TEXTUREMODES_CUBEMAP:
|
||||
sampler_type = "samplerCube";
|
||||
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, oT%d.xyz);\n",
|
||||
qstring_append_fmt(vars, "vec4 t%d = texture(texSamp%d, pT%d.xyz);\n",
|
||||
i, i, i);
|
||||
break;
|
||||
case PS_TEXTUREMODES_PASSTHRU:
|
||||
assert(false);
|
||||
qstring_append_fmt(vars, "vec4 t%d = oT%d;\n", i, i);
|
||||
qstring_append_fmt(vars, "vec4 t%d = pT%d;\n", i, i);
|
||||
break;
|
||||
default:
|
||||
printf("%x\n", ps->tex_modes[i]);
|
||||
|
|
|
@ -563,16 +563,18 @@ static const char* vsh_header =
|
|||
"vec4 R12 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"\n"
|
||||
"#define oPos R12\n" /* opos is a mirror of R12 */
|
||||
"out vec4 oD0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oD1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oB0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oB1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oD0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oD1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oB0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oB1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"vec4 oPts = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oFog = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT2 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"out vec4 oT3 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oFog = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT0 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT1 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT2 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"noperspective out vec4 oT3 = vec4(0.0,0.0,0.0,1.0);\n"
|
||||
"\n"
|
||||
"noperspective out float oPos_w;\n"
|
||||
"\n"
|
||||
|
||||
/* All constants in 1 array declaration */
|
||||
|
@ -776,6 +778,19 @@ QString* vsh_translate(uint16_t version,
|
|||
* but they're not necessarily present...
|
||||
*/
|
||||
|
||||
"oPos_w = 1.0/oPos.w;\n"
|
||||
"oD0 /= oPos.w;\n"
|
||||
"oD1 /= oPos.w;\n"
|
||||
"oB0 /= oPos.w;\n"
|
||||
"oB1 /= oPos.w;\n"
|
||||
"oFog /= oPos.w;\n"
|
||||
"oT0 /= oPos.w;\n"
|
||||
"oT1 /= oPos.w;\n"
|
||||
"oT2 /= oPos.w;\n"
|
||||
"oT3 /= oPos.w;\n"
|
||||
"\n"
|
||||
|
||||
|
||||
" /* Un-screenspace transform */\n"
|
||||
"oPos.x = (oPos.x - viewportOffset.x) / viewportScale.x;\n"
|
||||
"oPos.y = (oPos.y - viewportOffset.y) / viewportScale.y;\n"
|
||||
|
|
Loading…
Reference in New Issue