From 4176025d463e7733dac19788b45b6472b65d62d4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 8 Jun 2011 13:44:00 -0700 Subject: [PATCH] i965: Add support for GL_FIXED vertex attributes. This sadly requires work in the VS to rescale them, because the hardware doesn't support this format natively. Fixes arb_es2_compatibility-fixed-type and gtf/fixed_data_type. Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 5 +++++ src/mesa/drivers/dri/i965/brw_vs.c | 11 ++++++++++- src/mesa/drivers/dri/i965/brw_vs.h | 4 ++++ src/mesa/drivers/dri/i965/brw_vs_emit.c | 22 +++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 3cc33720486..c6e53951069 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -207,6 +207,10 @@ static GLuint get_surface_type( GLenum type, GLuint size, case GL_UNSIGNED_INT: return uint_types_scale[size]; case GL_UNSIGNED_SHORT: return ushort_types_scale[size]; case GL_UNSIGNED_BYTE: return ubyte_types_scale[size]; + /* This produces GL_FIXED inputs as values between INT32_MIN and + * INT32_MAX, which will be scaled down by 1/65536 by the VS. + */ + case GL_FIXED: return int_types_scale[size]; default: assert(0); return 0; } } @@ -225,6 +229,7 @@ static GLuint get_size( GLenum type ) case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_FIXED: return sizeof(GLuint); default: assert(0); return 0; } } diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index d6a53995531..80d5e78ed0b 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -145,6 +145,14 @@ static void brw_upload_vs_prog(struct brw_context *brw) } } + /* BRW_NEW_VERTICES */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (vp->program.Base.InputsRead & (1 << i) && + brw->vb.inputs[i].glarray->Type == GL_FIXED) { + key.gl_fixed_input_size[i] = brw->vb.inputs[i].glarray->Size; + } + } + /* Make an early check for the key. */ drm_intel_bo_unreference(brw->vs.prog_bo); @@ -164,7 +172,8 @@ const struct brw_tracked_state brw_vs_prog = { .dirty = { .mesa = (_NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT | _NEW_BUFFERS), - .brw = BRW_NEW_VERTEX_PROGRAM, + .brw = (BRW_NEW_VERTEX_PROGRAM | + BRW_NEW_VERTICES), .cache = 0 }, .prepare = brw_upload_vs_prog diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 7ca84a54b01..432994a8534 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -41,6 +41,10 @@ struct brw_vs_prog_key { GLuint program_string_id; + /** + * Number of channels of the vertex attribute that need GL_FIXED rescaling + */ + uint8_t gl_fixed_input_size[VERT_ATTRIB_MAX]; GLuint nr_userclip:4; GLuint copy_edgeflag:1; GLuint point_coord_replace:8; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 7d5eb353eee..b6c9e5a1ceb 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -1878,6 +1878,26 @@ get_predicate(const struct prog_instruction *inst) } } +static void +brw_vs_rescale_gl_fixed(struct brw_vs_compile *c) +{ + struct brw_compile *p = &c->func; + int i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (!(c->prog_data.inputs_read & (1 << i))) + continue; + + if (c->key.gl_fixed_input_size[i] != 0) { + struct brw_reg reg = c->regs[PROGRAM_INPUT][i]; + + brw_MUL(p, + brw_writemask(reg, (1 << c->key.gl_fixed_input_size[i]) - 1), + reg, brw_imm_f(1.0 / 65536.0)); + } + } +} + /* Emit the vertex program instructions here. */ void brw_vs_emit(struct brw_vs_compile *c ) @@ -1937,6 +1957,8 @@ void brw_vs_emit(struct brw_vs_compile *c ) */ brw_vs_alloc_regs(c); + brw_vs_rescale_gl_fixed(c); + if (c->needs_stack) brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); -- 2.30.2