avoid sign extending PT_ALPHA_REF value when storing on ta_surface

add PT_ALPHA_REF to saved trace state
This commit is contained in:
Anthony Pesch 2017-10-22 23:56:46 -04:00
parent 75aceb847f
commit f08db8afd3
10 changed files with 50 additions and 34 deletions

View File

@ -21,6 +21,7 @@ void trace_writer_render_context(struct trace_writer *writer,
cmd.context.palette_fmt = ctx->palette_fmt;
cmd.context.video_width = ctx->video_width;
cmd.context.video_height = ctx->video_height;
cmd.context.alpha_ref = ctx->alpha_ref;
cmd.context.bg_isp = ctx->bg_isp;
cmd.context.bg_tsp = ctx->bg_tsp;
cmd.context.bg_tcw = ctx->bg_tcw;
@ -166,12 +167,13 @@ void trace_copy_context(const struct trace_cmd *cmd, struct ta_context *ctx) {
ctx->autosort = cmd->context.autosort;
ctx->stride = cmd->context.stride;
ctx->palette_fmt = cmd->context.palette_fmt;
ctx->video_width = cmd->context.video_width;
ctx->video_height = cmd->context.video_height;
ctx->alpha_ref = cmd->context.alpha_ref;
ctx->bg_isp = cmd->context.bg_isp;
ctx->bg_tsp = cmd->context.bg_tsp;
ctx->bg_tcw = cmd->context.bg_tcw;
ctx->bg_depth = cmd->context.bg_depth;
ctx->video_width = cmd->context.video_width;
ctx->video_height = cmd->context.video_height;
memcpy(ctx->bg_vertices, cmd->context.bg_vertices,
cmd->context.bg_vertices_size);
memcpy(ctx->params, cmd->context.params, cmd->context.params_size);

View File

@ -25,9 +25,9 @@ struct trace_cmd {
union tsp tsp;
union tcw tcw;
uint32_t frame;
uint32_t palette_size;
int32_t palette_size;
const uint8_t *palette;
uint32_t texture_size;
int32_t texture_size;
const uint8_t *texture;
} texture;
@ -35,18 +35,19 @@ struct trace_cmd {
sync */
struct {
uint32_t frame;
int8_t autosort;
uint32_t stride;
uint32_t palette_fmt;
uint32_t video_width;
uint32_t video_height;
int32_t autosort;
int32_t stride;
int32_t palette_fmt;
int32_t video_width;
int32_t video_height;
int32_t alpha_ref;
union isp bg_isp;
union tsp bg_tsp;
union tcw bg_tcw;
float bg_depth;
uint32_t bg_vertices_size;
int32_t bg_vertices_size;
const uint8_t *bg_vertices;
uint32_t params_size;
int32_t params_size;
const uint8_t *params;
} context;
};

View File

@ -51,7 +51,7 @@ PVR_REG(0x005f810c, SPG_STATUS, 0x00000000, union spg_status)
PVR_REG(0x005f8110, FB_BURSTCTRL, 0x00090639, uint32_t)
PVR_REG(0x005f8114, FB_C_SOF, 0x00000000, uint32_t)
PVR_REG(0x005f8118, Y_COEFF, 0x00000000, uint32_t)
PVR_REG(0x005f811c, PT_ALPHA_REF, 0x000000ff, uint32_t)
PVR_REG(0x005f811c, PT_ALPHA_REF, 0x000000ff, union pt_alpha_ref)
PVR_REG(0x005f8124, TA_OL_BASE, 0x00000000, uint32_t)
PVR_REG(0x005f8128, TA_ISP_BASE, 0x00000000, union ta_isp_base)
PVR_REG(0x005f812c, TA_OL_LIMIT, 0x00000000, uint32_t)

View File

@ -216,6 +216,14 @@ union spg_status {
};
};
union pt_alpha_ref {
uint32_t full;
struct {
uint32_t alpha_ref : 8;
uint32_t : 24;
};
};
union ta_isp_base {
uint32_t full;
struct {

View File

@ -502,6 +502,9 @@ static void ta_save_state(struct ta *ta, struct ta_context *ctx) {
/* save video resolution in order to unproject the screen space coordinates */
pvr_video_size(pvr, &ctx->video_width, &ctx->video_height);
/* get the punch through polygon alpha test value */
ctx->alpha_ref = pvr->PT_ALPHA_REF->alpha_ref;
/* according to the hardware docs, this is the correct calculation of the
background ISP address. however, in practice, the second TA buffer's ISP
address comes out to be 0x800000 when booting the bios and the vram is
@ -521,9 +524,6 @@ static void ta_save_state(struct ta *ta, struct ta_context *ctx) {
/* get the background depth */
ctx->bg_depth = *(float *)pvr->ISP_BACKGND_D;
/* get the punch through polygon alpha test value */
ctx->pt_alpha_ref = *pvr->PT_ALPHA_REF;
/* get the byte size for each vertex. normally, the byte size is
ISP_BACKGND_T.skip + 3, but if parameter selection volume mode is in
effect and the shadow bit is 1, then the byte size is

View File

@ -427,11 +427,11 @@ struct ta_context {
int palette_fmt;
int video_width;
int video_height;
int alpha_ref;
union isp bg_isp;
union tsp bg_tsp;
union tcw bg_tcw;
float bg_depth;
uint32_t pt_alpha_ref;
uint8_t bg_vertices[TA_BG_VERTEX_SIZE];
/* parameter buffer */

View File

@ -463,8 +463,8 @@ static void tr_parse_poly_param(struct tr *tr, const struct ta_context *ctx,
surf->params.ignore_alpha = !param->type0.tsp.use_alpha;
surf->params.ignore_texture_alpha = param->type0.tsp.ignore_tex_alpha;
surf->params.offset_color = param->type0.pcw.offset;
surf->params.pt_alpha_test = tr->list_type == TA_LIST_PUNCH_THROUGH;
surf->params.pt_alpha_ref = ctx->pt_alpha_ref;
surf->params.alpha_test = tr->list_type == TA_LIST_PUNCH_THROUGH;
surf->params.alpha_ref = ctx->alpha_ref;
/* override a few surface parameters based on the list type */
if (tr->list_type != TA_LIST_TRANSLUCENT &&

View File

@ -11,12 +11,12 @@ enum uniform_attr {
UNIFORM_PROJ,
UNIFORM_DIFFUSE,
UNIFORM_VIDEO_SCALE,
UNIFORM_PT_ALPHA_REF,
UNIFORM_ALPHA_REF,
UNIFORM_NUM_UNIFORMS,
};
static const char *uniform_names[] = {
"u_proj", "u_diffuse", "u_video_scale", "u_pt_alpha_ref",
"u_proj", "u_diffuse", "u_video_scale", "u_alpha_ref",
};
enum shader_attr {
@ -31,7 +31,7 @@ enum shader_attr {
ATTR_IGNORE_ALPHA = 0x8,
ATTR_IGNORE_TEXTURE_ALPHA = 0x10,
ATTR_OFFSET_COLOR = 0x20,
ATTR_PT_ALPHA_TEST = 0x40,
ATTR_ALPHA_TEST = 0x40,
ATTR_DEBUG_DEPTH_BUFFER = 0x80,
ATTR_COUNT = 0x100
};
@ -452,8 +452,8 @@ static struct shader_program *r_get_ta_program(struct render_backend *r,
if (surf->params.offset_color) {
idx |= ATTR_OFFSET_COLOR;
}
if (surf->params.pt_alpha_test) {
idx |= ATTR_PT_ALPHA_TEST;
if (surf->params.alpha_test) {
idx |= ATTR_ALPHA_TEST;
}
if (surf->params.debug_depth) {
idx |= ATTR_DEBUG_DEPTH_BUFFER;
@ -489,8 +489,8 @@ static struct shader_program *r_get_ta_program(struct render_backend *r,
if (idx & ATTR_OFFSET_COLOR) {
strcat(header, "#define OFFSET_COLOR\n");
}
if (idx & ATTR_PT_ALPHA_TEST) {
strcat(header, "#define PT_ALPHA_TEST\n");
if (idx & ATTR_ALPHA_TEST) {
strcat(header, "#define ALPHA_TEST\n");
}
if (idx & ATTR_DEBUG_DEPTH_BUFFER) {
strcat(header, "#define DEBUG_DEPTH_BUFFER\n");
@ -631,8 +631,8 @@ void r_draw_ta_surface(struct render_backend *r,
}
/* bind non-global uniforms every time */
float alpha_ref = surf->params.pt_alpha_ref / 255.0f;
glUniform1f(program->loc[UNIFORM_PT_ALPHA_REF], alpha_ref);
float alpha_ref = surf->params.alpha_ref / 255.0f;
glUniform1f(program->loc[UNIFORM_ALPHA_REF], alpha_ref);
if (surf->params.texture) {
struct texture *tex = &r->textures[surf->params.texture];

View File

@ -96,10 +96,11 @@ struct ta_surface {
int ignore_alpha : 1;
int ignore_texture_alpha : 1;
int offset_color : 1;
int pt_alpha_test : 1;
int pt_alpha_ref : 8;
int alpha_test : 1;
/* give an extra bit to avoid sign extension / unsigned type */
int alpha_ref : 9;
int debug_depth : 1;
int : 20;
int : 19;
};
} params;

View File

@ -30,7 +30,7 @@ static const char *ta_vp =
static const char *ta_fp =
"uniform sampler2D u_diffuse;\n"
"uniform mediump float u_pt_alpha_ref;\n"
"uniform mediump float u_alpha_ref;\n"
"in mediump vec4 var_color;\n"
"in mediump vec4 var_offset_color;\n"
@ -48,10 +48,9 @@ static const char *ta_fp =
" #ifdef IGNORE_TEXTURE_ALPHA\n"
" tex.a = 1.0;\n"
" #endif\n"
" #ifdef PT_ALPHA_TEST\n"
" if(tex.a < u_pt_alpha_ref)\n"
" #ifdef ALPHA_TEST\n"
" if (tex.a < u_alpha_ref)\n"
" discard;\n"
" fragcolor.a = 1.0f;\n"
" #endif\n"
" #ifdef SHADE_DECAL\n"
" fragcolor = tex;\n"
@ -74,6 +73,11 @@ static const char *ta_fp =
" fragcolor.rgb += var_offset_color.rgb;\n"
" #endif\n"
" #ifdef ALPHA_TEST\n"
" // punch through polys are always drawn with an alpha value of 1.0\n"
" fragcolor.a = 1.0f;\n"
" #endif\n"
" // gl_FragCoord.w is 1/clip.w aka the original 1/w passed to the TA,\n"
" // interpolated in screen space. this value is normally between [0,1],\n"
" // however, values very close to the near plane often raise to 10-100000\n"