diff --git a/hw/xbox/nv2a/nv2a_pgraph.c b/hw/xbox/nv2a/nv2a_pgraph.c index c3c20889b6..4fdc7a1244 100644 --- a/hw/xbox/nv2a/nv2a_pgraph.c +++ b/hw/xbox/nv2a/nv2a_pgraph.c @@ -741,16 +741,21 @@ void pgraph_method(NV2AState *d, GET_MASK(parameter, NV097_SET_SURFACE_PITCH_COLOR); pg->surface_zeta.pitch = GET_MASK(parameter, NV097_SET_SURFACE_PITCH_ZETA); + + pg->surface_color.buffer_dirty = true; + pg->surface_zeta.buffer_dirty = true; break; case NV097_SET_SURFACE_COLOR_OFFSET: pgraph_update_surface(d, false, true, true); pg->surface_color.offset = parameter; + pg->surface_color.buffer_dirty = true; break; case NV097_SET_SURFACE_ZETA_OFFSET: pgraph_update_surface(d, false, true, true); pg->surface_zeta.offset = parameter; + pg->surface_zeta.buffer_dirty = true; break; case NV097_SET_COMBINER_ALPHA_ICW ... @@ -2742,7 +2747,7 @@ static void pgraph_shader_update_constants(PGRAPHState *pg, int i, j; /* update combiner constants */ - for (i = 0; i<= 8; i++) { + for (i = 0; i < 9; i++) { uint32_t constant[2]; if (i == 8) { /* final combiner */ @@ -3370,9 +3375,9 @@ static void pgraph_update_surface_part(NV2AState *d, bool upload, bool color) { } surface->buffer_dirty = false; -#ifdef DEBUG_NV2A + uint8_t *out = data + surface->offset + 64; - NV2A_DPRINTF("upload_surface %s 0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " + NV2A_GL_DPRINTF(true, "upload_surface %s 0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " "(0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " "%d %d, %d %d, %d) - %x %x %x %x\n", color ? "color" : "zeta", @@ -3384,7 +3389,7 @@ static void pgraph_update_surface_part(NV2AState *d, bool upload, bool color) { pg->surface_shape.clip_height, surface->pitch, out[0], out[1], out[2], out[3]); -#endif + } if (!upload && surface->draw_dirty) { @@ -3416,9 +3421,8 @@ static void pgraph_update_surface_part(NV2AState *d, bool upload, bool color) { surface->draw_dirty = false; surface->write_enabled_cache = false; -#ifdef DEBUG_NV2A uint8_t *out = data + surface->offset + 64; - NV2A_DPRINTF("read_surface %s 0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " + NV2A_GL_DPRINTF(true, "read_surface %s 0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " "(0x%" HWADDR_PRIx " - 0x%" HWADDR_PRIx ", " "%d %d, %d %d, %d) - %x %x %x %x\n", color ? "color" : "zeta", @@ -3429,7 +3433,6 @@ static void pgraph_update_surface_part(NV2AState *d, bool upload, bool color) { pg->surface_shape.clip_width, pg->surface_shape.clip_height, surface->pitch, out[0], out[1], out[2], out[3]); -#endif } if (swizzle) { diff --git a/hw/xbox/nv2a/nv2a_psh.c b/hw/xbox/nv2a/nv2a_psh.c index e31533d1b1..918cd6e4fe 100644 --- a/hw/xbox/nv2a/nv2a_psh.c +++ b/hw/xbox/nv2a/nv2a_psh.c @@ -167,7 +167,6 @@ enum PS_FINALCOMBINERSETTING struct InputInfo { int reg, mod, chan; - bool invert; }; struct InputVarInfo { @@ -176,9 +175,6 @@ struct InputVarInfo { struct FCInputInfo { struct InputInfo a, b, c, d, e, f, g; - int c0, c1; - //uint32_t c0_value, c1_value; - bool c0_used, c1_used; bool v1r0_sum, clamp_sum, inv_v1, inv_r0, enabled; }; @@ -191,8 +187,6 @@ struct PSStageInfo { struct InputVarInfo rgb_input, alpha_input; struct OutputInfo rgb_output, alpha_output; int c0, c1; - //uint32_t c0_value, c1_value; - bool c0_used, c1_used; }; struct PixelShader { @@ -215,6 +209,8 @@ struct PixelShader { char const_refs[32][32]; }; + static QString* get_input_var(struct PixelShader *ps, struct InputInfo in, bool is_alpha); + static void add_var_ref(struct PixelShader *ps, const char *var) { int i; @@ -234,47 +230,27 @@ static void add_const_ref(struct PixelShader *ps, const char *var) } // Get the code for a variable used in the program -static QString* get_var(struct PixelShader *ps, int reg, bool is_dest) +static QString* get_var(struct PixelShader *ps, int reg) { switch (reg) { - case PS_REGISTER_DISCARD: - if (is_dest) { - return qstring_from_str(""); - } else { - return qstring_from_str("0.0"); - } - break; case PS_REGISTER_C0: - /* TODO: should the final stage really always be unique? */ if (ps->flags & PS_COMBINERCOUNT_UNIQUE_C0 || ps->cur_stage == 8) { - QString *reg = qstring_from_fmt("c_%d_%d", ps->cur_stage, 0); + QString *reg = qstring_from_fmt("c0_%d", ps->cur_stage); add_const_ref(ps, qstring_get_str(reg)); - if (ps->cur_stage == 8) { - ps->final_input.c0_used = true; - } else { - ps->stage[ps->cur_stage].c0_used = true; - } return reg; } else { // Same c0 - add_const_ref(ps, "c_0_0"); - ps->stage[0].c0_used = true; - return qstring_from_str("c_0_0"); + add_const_ref(ps, "c0_0"); + return qstring_from_str("c0_0"); } break; case PS_REGISTER_C1: if (ps->flags & PS_COMBINERCOUNT_UNIQUE_C1 || ps->cur_stage == 8) { - QString *reg = qstring_from_fmt("c_%d_%d", ps->cur_stage, 1); + QString *reg = qstring_from_fmt("c1_%d", ps->cur_stage); add_const_ref(ps, qstring_get_str(reg)); - if (ps->cur_stage == 8) { - ps->final_input.c1_used = true; - } else { - ps->stage[ps->cur_stage].c1_used = true; - } return reg; } else { // Same c1 - add_const_ref(ps, "c_0_1"); - ps->stage[0].c1_used = true; - return qstring_from_str("c_0_1"); + add_const_ref(ps, "c1_0"); + return qstring_from_str("c1_0"); } break; case PS_REGISTER_FOG: @@ -299,7 +275,35 @@ static QString* get_var(struct PixelShader *ps, int reg, bool is_dest) return qstring_from_str("r1"); case PS_REGISTER_V1R0_SUM: add_var_ref(ps, "r0"); - return qstring_from_str("(v1 + r0)"); + + struct InputInfo v1_info; + v1_info.reg = PS_REGISTER_V1; + if (ps->final_input.inv_v1) { + v1_info.mod = PS_INPUTMAPPING_UNSIGNED_INVERT; + } else { + v1_info.mod = PS_INPUTMAPPING_UNSIGNED_IDENTITY; + } + v1_info.chan = PS_CHANNEL_RGB; + QString *v1 = get_input_var(ps, v1_info, false); + + struct InputInfo r0_info; + r0_info.reg = PS_REGISTER_R0; + if (ps->final_input.inv_r0) { + r0_info.mod = PS_INPUTMAPPING_UNSIGNED_INVERT; + } else { + r0_info.mod = PS_INPUTMAPPING_UNSIGNED_IDENTITY; + } + r0_info.chan = PS_CHANNEL_RGB; + QString *r0 = get_input_var(ps, r0_info, false); + + QString *reg = qstring_from_fmt(ps->final_input.clamp_sum ? + "vec4(clamp(%s + %s, 0.0, 1.0), 0.0)" : + "vec4(%s + %s, 0.0)", + qstring_get_str(v1), + qstring_get_str(r0)); + QDECREF(v1); + QDECREF(r0); + return reg; case PS_REGISTER_EF_PROD: return qstring_from_fmt("(%s * %s)", qstring_get_str(ps->varE), qstring_get_str(ps->varF)); @@ -312,11 +316,17 @@ static QString* get_var(struct PixelShader *ps, int reg, bool is_dest) // Get input variable code static QString* get_input_var(struct PixelShader *ps, struct InputInfo in, bool is_alpha) { - QString *reg = get_var(ps, in.reg, false); - if (strcmp(qstring_get_str(reg), "0.0") != 0 - && (in.reg != PS_REGISTER_EF_PROD - || strstr(qstring_get_str(reg), ".a") == NULL)) { + QString *reg; + if (in.reg == PS_REGISTER_ZERO) { + if (is_alpha) { + reg = qstring_from_str("0.0"); + } else { + reg = qstring_from_str("vec3(0.0)"); + } + } else { + reg = get_var(ps, in.reg); + switch (in.chan) { case PS_CHANNEL_RGB: if (is_alpha) { @@ -326,7 +336,11 @@ static QString* get_input_var(struct PixelShader *ps, struct InputInfo in, bool } break; case PS_CHANNEL_ALPHA: - qstring_append(reg, ".a"); + if (is_alpha) { + qstring_append(reg, ".a"); + } else { + qstring_append(reg, ".aaa"); + } break; default: assert(false); @@ -336,25 +350,27 @@ static QString* get_input_var(struct PixelShader *ps, struct InputInfo in, bool QString *res; switch (in.mod) { - case PS_INPUTMAPPING_SIGNED_IDENTITY: case PS_INPUTMAPPING_UNSIGNED_IDENTITY: - QINCREF(reg); - res = reg; + res = qstring_from_fmt("max(%s, 0.0)", qstring_get_str(reg)); break; case PS_INPUTMAPPING_UNSIGNED_INVERT: - res = qstring_from_fmt("(1.0 - %s)", qstring_get_str(reg)); + res = qstring_from_fmt("(1.0 - clamp(%s, 0.0, 1.0))", qstring_get_str(reg)); break; - case PS_INPUTMAPPING_EXPAND_NORMAL: // TODO: Change to max(0, x)?? - res = qstring_from_fmt("(2.0 * %s - 1.0)", qstring_get_str(reg)); + case PS_INPUTMAPPING_EXPAND_NORMAL: + res = qstring_from_fmt("(2.0 * max(%s, 0.0) - 1.0)", qstring_get_str(reg)); break; case PS_INPUTMAPPING_EXPAND_NEGATE: - res = qstring_from_fmt("(1.0 - 2.0 * %s)", qstring_get_str(reg)); + res = qstring_from_fmt("(-2.0 * max(%s, 0.0) + 1.0)", qstring_get_str(reg)); break; case PS_INPUTMAPPING_HALFBIAS_NORMAL: - res = qstring_from_fmt("(%s - 0.5)", qstring_get_str(reg)); + res = qstring_from_fmt("(max(%s, 0.0) - 0.5)", qstring_get_str(reg)); break; case PS_INPUTMAPPING_HALFBIAS_NEGATE: - res = qstring_from_fmt("(0.5 - %s)", qstring_get_str(reg)); + res = qstring_from_fmt("(-max(%s, 0.0) + 0.5)", qstring_get_str(reg)); + break; + case PS_INPUTMAPPING_SIGNED_IDENTITY: + QINCREF(reg); + res = reg; break; case PS_INPUTMAPPING_SIGNED_NEGATE: res = qstring_from_fmt("-%s", qstring_get_str(reg)); @@ -399,99 +415,124 @@ static QString* get_output(QString *reg, int mapping) return res; } -// Add the HLSL code for a stage +// Add the GLSL code for a stage which does operation static void add_stage_code(struct PixelShader *ps, struct InputVarInfo input, struct OutputInfo output, - const char *write_mask, bool is_alpha) + bool is_alpha) { + const char *write_mask = is_alpha ? "a" : "rgb"; + QString *a = get_input_var(ps, input.a, is_alpha); QString *b = get_input_var(ps, input.b, is_alpha); QString *c = get_input_var(ps, input.c, is_alpha); QString *d = get_input_var(ps, input.d, is_alpha); - const char *caster = ""; - if (strlen(write_mask) == 3) { - caster = "vec3"; - } - QString *ab; if (output.ab_op == PS_COMBINEROUTPUT_AB_DOT_PRODUCT) { - ab = qstring_from_fmt("dot(%s, %s)", - qstring_get_str(a), qstring_get_str(b)); + assert(!is_alpha); + qstring_append_fmt(ps->code, "ab_in.%s = vec3(dot(%s, %s));\n", + write_mask, qstring_get_str(a), qstring_get_str(b)); } else { - ab = qstring_from_fmt("(%s * %s)", - qstring_get_str(a), qstring_get_str(b)); + qstring_append_fmt(ps->code, "ab_in.%s = (%s * %s);\n", + write_mask, qstring_get_str(a), qstring_get_str(b)); } - QString *cd; if (output.cd_op == PS_COMBINEROUTPUT_CD_DOT_PRODUCT) { - cd = qstring_from_fmt("dot(%s, %s)", - qstring_get_str(c), qstring_get_str(d)); + assert(!is_alpha); + qstring_append_fmt(ps->code, "cd_in.%s = vec3(dot(%s, %s));\n", + write_mask, qstring_get_str(c), qstring_get_str(d)); } else { - cd = qstring_from_fmt("(%s * %s)", - qstring_get_str(c), qstring_get_str(d)); + qstring_append_fmt(ps->code, "cd_in.%s = (%s * %s);\n", + write_mask, qstring_get_str(c), qstring_get_str(d)); } - QString *ab_mapping = get_output(ab, output.mapping); - QString *cd_mapping = get_output(cd, output.mapping); - QString *ab_dest = get_var(ps, output.ab, true); - QString *cd_dest = get_var(ps, output.cd, true); - QString *sum_dest = get_var(ps, output.muxsum, true); + if (output.ab != PS_REGISTER_DISCARD) { + QString* ab_reg = qstring_from_fmt("ab_in.%s", write_mask); + QString *ab_mapping = get_output(ab_reg, output.mapping); - if (qstring_get_length(ab_dest)) { - qstring_append_fmt(ps->code, "%s.%s = %s(%s);\n", - qstring_get_str(ab_dest), write_mask, caster, qstring_get_str(ab_mapping)); - } else { - QDECREF(ab_dest); - QINCREF(ab_mapping); - ab_dest = ab_mapping; - } + qstring_append_fmt(ps->code, "ab_out.%s = clamp(%s, -1.0, 1.0);\n", + write_mask, qstring_get_str(ab_mapping)); - if (qstring_get_length(cd_dest)) { - qstring_append_fmt(ps->code, "%s.%s = %s(%s);\n", - qstring_get_str(cd_dest), write_mask, caster, qstring_get_str(cd_mapping)); - } else { - QDECREF(cd_dest); - QINCREF(cd_mapping); - cd_dest = cd_mapping; - } + /* FIXME: Will these still write rgb? */ + if (!is_alpha && output.flags & PS_COMBINEROUTPUT_AB_BLUE_TO_ALPHA) { + qstring_append_fmt(ps->code, "ab_out.a = ab_out.b;\n"); + } - if (!is_alpha && output.flags & PS_COMBINEROUTPUT_AB_BLUE_TO_ALPHA) { - qstring_append_fmt(ps->code, "%s.a = %s.b;\n", - qstring_get_str(ab_dest), qstring_get_str(ab_dest)); - } - if (!is_alpha && output.flags & PS_COMBINEROUTPUT_CD_BLUE_TO_ALPHA) { - qstring_append_fmt(ps->code, "%s.a = %s.b;\n", - qstring_get_str(cd_dest), qstring_get_str(cd_dest)); + QDECREF(ab_mapping); + QDECREF(ab_reg); } - QString *sum; - 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)); + if (output.cd != PS_REGISTER_DISCARD) { + QString* cd_reg = qstring_from_fmt("cd_in.%s", write_mask); + QString *cd_mapping = get_output(cd_reg, output.mapping); + + qstring_append_fmt(ps->code, "cd_out.%s = clamp(%s, -1.0, 1.0);\n", + write_mask, qstring_get_str(cd_mapping)); + + /* FIXME: Will these still write rgb? */ + if (!is_alpha && output.flags & PS_COMBINEROUTPUT_CD_BLUE_TO_ALPHA) { + qstring_append_fmt(ps->code, "cd_out.a = cd_out.b;\n"); + } + + QDECREF(cd_mapping); + QDECREF(cd_reg); } - QString *sum_mapping = get_output(sum, output.mapping); - if (qstring_get_length(sum_dest)) { - qstring_append_fmt(ps->code, "%s.%s = %s(%s);\n", - qstring_get_str(sum_dest), write_mask, caster, qstring_get_str(sum_mapping)); + if (output.muxsum != PS_REGISTER_DISCARD) { + + assert(output.ab_op != PS_COMBINEROUTPUT_AB_DOT_PRODUCT); + assert(output.cd_op != PS_COMBINEROUTPUT_CD_DOT_PRODUCT); + + if (output.muxsum_op == PS_COMBINEROUTPUT_AB_CD_SUM) { + qstring_append_fmt(ps->code, "sum_in.%s = (ab_in.%s + cd_in.%s);\n", + write_mask, write_mask, write_mask); + } else { + assert(ps->flags & PS_COMBINERCOUNT_MUX_MSB); + qstring_append_fmt(ps->code, "sum_in.%s = mix(ab_in.%s, cd_in.%s, %s(r0.a < 0.5));\n", + write_mask, write_mask, write_mask, + is_alpha ? "bool" : "bvec3"); + } + + QString* sum_reg = qstring_from_fmt("sum_in.%s", write_mask); + QString *sum_mapping = get_output(sum_reg, output.mapping); + + qstring_append_fmt(ps->code, "sum_out.%s = clamp(%s, -1.0, 1.0);\n", + write_mask, qstring_get_str(sum_mapping)); + + QDECREF(sum_mapping); + QDECREF(sum_reg); } QDECREF(a); QDECREF(b); QDECREF(c); QDECREF(d); - QDECREF(ab); - QDECREF(cd); - QDECREF(ab_mapping); - QDECREF(cd_mapping); - QDECREF(ab_dest); - QDECREF(cd_dest); - QDECREF(sum_dest); - QDECREF(sum); - QDECREF(sum_mapping); +} + +// Add the GLSL code for a stage which does writeback +static void add_stage_code_writeback(struct PixelShader *ps, + struct OutputInfo output, + bool is_alpha) +{ + const char *write_mask = is_alpha ? "a" : "rgb"; + + if (output.ab != PS_REGISTER_DISCARD) { + QString *ab_dest = get_var(ps, output.ab); + qstring_append_fmt(ps->code, "%s.%s = ab_out.%s;\n", qstring_get_str(ab_dest), write_mask, write_mask); + QDECREF(ab_dest); + } + + if (output.cd != PS_REGISTER_DISCARD) { + QString *cd_dest = get_var(ps, output.cd); + qstring_append_fmt(ps->code, "%s.%s = cd_out.%s;\n", qstring_get_str(cd_dest), write_mask, write_mask); + QDECREF(cd_dest); + } + + if (output.muxsum != PS_REGISTER_DISCARD) { + QString *sum_dest = get_var(ps, output.muxsum); + qstring_append_fmt(ps->code, "%s.%s = sum_out.%s;\n", qstring_get_str(sum_dest), write_mask, write_mask); + QDECREF(sum_dest); + } } // Add code for the final combiner stage @@ -504,14 +545,12 @@ static void add_final_stage_code(struct PixelShader *ps, struct FCInputInfo fina QString *b = get_input_var(ps, final.b, false); QString *c = get_input_var(ps, final.c, false); QString *d = get_input_var(ps, final.d, false); - QString *g = get_input_var(ps, final.g, false); + QString *g = get_input_var(ps, final.g, true); - add_var_ref(ps, "r0"); - qstring_append_fmt(ps->code, "r0.rgb = %s + mix(vec3(%s), vec3(%s), vec3(%s));\n", + qstring_append_fmt(ps->code, "fragColor.rgb = %s + mix(%s, %s, %s);\n", qstring_get_str(d), qstring_get_str(c), qstring_get_str(b), qstring_get_str(a)); - /* FIXME: Is .x correctly here? */ - qstring_append_fmt(ps->code, "r0.a = vec3(%s).x;\n", qstring_get_str(g)); + qstring_append_fmt(ps->code, "fragColor.a = %s;\n", qstring_get_str(g)); QDECREF(a); QDECREF(b); @@ -589,6 +628,14 @@ static QString* psh_convert(struct PixelShader *ps) qstring_append(vars, "\n"); qstring_append(vars, "vec4 v0 = pD0;\n"); qstring_append(vars, "vec4 v1 = pD1;\n"); + qstring_append(vars, "\n"); + qstring_append(vars, "vec4 ab_in;\n"); + qstring_append(vars, "vec4 ab_out;\n"); + qstring_append(vars, "vec4 cd_in;\n"); + qstring_append(vars, "vec4 cd_out;\n"); + qstring_append(vars, "vec4 sum_in;\n"); + qstring_append(vars, "vec4 sum_out;\n"); + ps->code = qstring_new(); @@ -732,28 +779,17 @@ static QString* psh_convert(struct PixelShader *ps) for (i = 0; i < ps->num_stages; i++) { ps->cur_stage = i; qstring_append_fmt(ps->code, "// Stage %d\n", i); - add_stage_code(ps, ps->stage[i].rgb_input, ps->stage[i].rgb_output, "rgb", false); - add_stage_code(ps, ps->stage[i].alpha_input, ps->stage[i].alpha_output, "a", true); + add_stage_code(ps, ps->stage[i].rgb_input, ps->stage[i].rgb_output, false); + add_stage_code(ps, ps->stage[i].alpha_input, ps->stage[i].alpha_output, true); + add_stage_code_writeback(ps, ps->stage[i].rgb_output, false); + add_stage_code_writeback(ps, ps->stage[i].alpha_output, true); } if (ps->final_input.enabled) { ps->cur_stage = 8; qstring_append(ps->code, "// Final Combiner\n"); add_final_stage_code(ps, ps->final_input); - } - - for (i = 0; i < ps->num_var_refs; i++) { - qstring_append_fmt(vars, "vec4 %s;\n", ps->var_refs[i]); - if (strcmp(ps->var_refs[i], "r0") == 0) { - if (ps->tex_modes[0] != PS_TEXTUREMODES_NONE) { - qstring_append(vars, "r0.a = t0.a;\n"); - } else { - qstring_append(vars, "r0.a = 1.0;\n"); - } - } - } - for (i = 0; i < ps->num_const_refs; i++) { - qstring_append_fmt(preflight, "uniform vec4 %s;\n", ps->const_refs[i]); +// qstring_append(ps->code, "fragColor.rgba = vec4(pFog.aaa,1.0);\n"); } if (ps->state.alpha_test && ps->state.alpha_func != ALPHA_FUNC_ALWAYS) { @@ -773,11 +809,26 @@ static QString* psh_convert(struct PixelShader *ps) assert(false); break; } - qstring_append_fmt(ps->code, "if (!(r0.a %s alphaRef)) discard;\n", + qstring_append_fmt(ps->code, "if (!(fragColor.a %s alphaRef)) discard;\n", alpha_op); } } + for (i = 0; i < ps->num_const_refs; i++) { + qstring_append_fmt(preflight, "uniform vec4 %s;\n", ps->const_refs[i]); + } + + for (i = 0; i < ps->num_var_refs; i++) { + qstring_append_fmt(vars, "vec4 %s;\n", ps->var_refs[i]); + if (strcmp(ps->var_refs[i], "r0") == 0) { + if (ps->tex_modes[0] != PS_TEXTUREMODES_NONE) { + qstring_append(vars, "r0.a = t0.a;\n"); + } else { + qstring_append(vars, "r0.a = 1.0;\n"); + } + } + } + QString *final = qstring_new(); qstring_append(final, "#version 330\n\n"); qstring_append(final, qstring_get_str(preflight)); @@ -785,7 +836,6 @@ static QString* psh_convert(struct PixelShader *ps) qstring_append(final, qstring_get_str(clip)); qstring_append(final, qstring_get_str(vars)); qstring_append(final, qstring_get_str(ps->code)); - qstring_append(final, "fragColor = r0;\n"); qstring_append(final, "}\n"); QDECREF(preflight); @@ -855,10 +905,6 @@ QString *psh_translate(const PshState state) 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]; - //ps.stage[i].c1_value = constant_1[i]; } struct InputInfo blank; @@ -874,10 +920,6 @@ QString *psh_translate(const PshState state) 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; - //ps.final_input.c0 = (pDef->PSFinalCombinerConstants >> 0) & 0xF; - //ps.final_input.c1 = (pDef->PSFinalCombinerConstants >> 4) & 0xF; - //ps.final_input.c0_value = final_constant_0; - //ps.final_input.c1_value = final_constant_1; } diff --git a/hw/xbox/nv2a/nv2a_shaders.c b/hw/xbox/nv2a/nv2a_shaders.c index e0e4f26466..a8afb4a4e1 100644 --- a/hw/xbox/nv2a/nv2a_shaders.c +++ b/hw/xbox/nv2a/nv2a_shaders.c @@ -715,8 +715,13 @@ STRUCT_VERTEX_DATA); qstring_append(body, " float fogDistance = oFog.x;\n"); } + /* FIXME: Microsoft just decided to use 13 bits, but hardware should have 14?! */ + qstring_append(body, " if (isnan(fogDistance)) { fogDistance = 8192.0; }\n"); + /* FIXME: Do this per pixel? */ + qstring_append(body, " fogDistance = clamp(fogDistance, 0.0, 8192.0);\n"); + switch (state.fog_mode) { case FOG_MODE_LINEAR: case FOG_MODE_LINEAR_ABS: @@ -934,9 +939,9 @@ ShaderBinding* generate_shaders(const ShaderState state) ret->gl_primitive_mode = gl_primitive_mode; /* lookup fragment shader uniforms */ - for (i=0; i<=8; i++) { - for (j=0; j<2; j++) { - snprintf(tmp, sizeof(tmp), "c_%d_%d", i, j); + for (i = 0; i < 9; i++) { + for (j = 0; j < 2; j++) { + snprintf(tmp, sizeof(tmp), "c%d_%d", j, i); ret->psh_constant_loc[i][j] = glGetUniformLocation(program, tmp); } }