X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fstate_tracker%2Fst_mesa_to_tgsi.c;h=5c68fd78c30fe946cb2dd48f14f202406597a2e5;hb=f29606598e7703d830440a878673d98e7ce13218;hp=582ca6f1733b49ed403bb74de24e4746fefcc9d0;hpb=ef8bb7ada98f1ddc8e2554a7336af5d669cb1290;p=mesa.git diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 582ca6f1733..5c68fd78c30 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -72,6 +72,7 @@ struct st_translate { struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; struct ureg_dst address[1]; struct ureg_src samplers[PIPE_MAX_SAMPLERS]; + struct ureg_src systemValues[SYSTEM_VALUE_MAX]; /* Extra info for handling point size clamping in vertex shader */ struct ureg_dst pointSizeResult; /**< Actual point size output register */ @@ -104,6 +105,13 @@ struct st_translate { }; +/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ +static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { + TGSI_SEMANTIC_FACE, + TGSI_SEMANTIC_INSTANCEID +}; + + /** * Make note of a branch to a label in the TGSI code. * After we've emitted all instructions, we'll go over the list @@ -245,6 +253,10 @@ src_register( struct st_translate *t, case PROGRAM_ADDRESS: return ureg_src(t->address[index]); + case PROGRAM_SYSTEM_VALUE: + assert(index < Elements(t->systemValues)); + return t->systemValues[index]; + default: debug_assert( 0 ); return ureg_src_undef(); @@ -274,6 +286,8 @@ translate_texture_target( GLuint textarget, case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D; case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE; case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT; + case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_1D_ARRAY; + case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY; default: debug_assert( 0 ); return TGSI_TEXTURE_1D; @@ -739,10 +753,12 @@ compile_instruction( /** * Emit the TGSI instructions to adjust the WPOS pixel center convention + * Basically, add (adjX, adjY) to the fragment position. */ static void emit_adjusted_wpos( struct st_translate *t, - const struct gl_program *program, GLfloat value) + const struct gl_program *program, + GLfloat adjX, GLfloat adjY) { struct ureg_program *ureg = t->ureg; struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); @@ -752,7 +768,7 @@ emit_adjusted_wpos( struct st_translate *t, * The shader might also use gl_FragCoord.w and .z. */ ureg_ADD(ureg, wpos_temp, wpos_input, - ureg_imm4f(ureg, value, value, 0.0f, 0.0f)); + ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f)); t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); } @@ -760,10 +776,13 @@ emit_adjusted_wpos( struct st_translate *t, /** * Emit the TGSI instructions for inverting the WPOS y coordinate. + * This code is unavoidable because it also depends on whether + * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). */ static void -emit_inverted_wpos( struct st_translate *t, - const struct gl_program *program ) +emit_wpos_inversion( struct st_translate *t, + const struct gl_program *program, + boolean invert) { struct ureg_program *ureg = t->ureg; @@ -771,17 +790,17 @@ emit_inverted_wpos( struct st_translate *t, * Need to replace instances of INPUT[WPOS] with temp T * where T = INPUT[WPOS] by y is inverted. */ - static const gl_state_index winSizeState[STATE_LENGTH] - = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 }; + static const gl_state_index wposTransformState[STATE_LENGTH] + = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 }; /* XXX: note we are modifying the incoming shader here! Need to * do this before emitting the constant decls below, or this * will be missed: */ - unsigned winHeightConst = _mesa_add_state_reference(program->Parameters, - winSizeState); + unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, + wposTransformState); - struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst ); + struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); struct ureg_dst wpos_temp; struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; @@ -794,12 +813,23 @@ emit_inverted_wpos( struct st_translate *t, ureg_MOV( ureg, wpos_temp, wpos_input ); } - /* SUB wpos_temp.y, winsize_const, wpos_input - */ - ureg_SUB( ureg, - ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), - winsize, - wpos_input); + if (invert) { + /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy + */ + ureg_MAD( ureg, + ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), + wpos_input, + ureg_scalar(wpostrans, 0), + ureg_scalar(wpostrans, 1)); + } else { + /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww + */ + ureg_MAD( ureg, + ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), + wpos_input, + ureg_scalar(wpostrans, 2), + ureg_scalar(wpostrans, 3)); + } /* Use wpos_temp as position input from here on: */ @@ -822,9 +852,12 @@ emit_wpos(struct st_context *st, boolean invert = FALSE; if (fp->OriginUpperLeft) { + /* Fragment shader wants origin in upper-left */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { + /* the driver supports upper-left origin */ } else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { + /* the driver supports lower-left origin, need to invert Y */ ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); invert = TRUE; } @@ -832,28 +865,37 @@ emit_wpos(struct st_context *st, assert(0); } else { + /* Fragment shader wants origin in lower-left */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) + /* the driver supports lower-left origin */ ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) + /* the driver supports upper-left origin, need to invert Y */ invert = TRUE; else assert(0); } if (fp->PixelCenterInteger) { + /* Fragment shader wants pixel center integer */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) + /* the driver supports pixel center integer */ ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) - emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f); + /* the driver supports pixel center half integer, need to bias X,Y */ + emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f); else assert(0); } else { + /* Fragment shader wants pixel center half integer */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { + /* the driver supports pixel center half integer */ } else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { + /* the driver supports pixel center integer, need to bias X,Y */ ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f); + emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f); } else assert(0); @@ -861,8 +903,7 @@ emit_wpos(struct st_context *st, /* we invert after adjustment so that we avoid the MOV to temporary, * and reuse the adjustment ADD instead */ - if (invert) - emit_inverted_wpos(t, program); + emit_wpos_inversion(t, program, invert); } @@ -924,7 +965,7 @@ emit_edgeflags( struct st_translate *t, */ enum pipe_error st_translate_mesa_program( - GLcontext *ctx, + struct gl_context *ctx, uint procType, struct ureg_program *ureg, const struct gl_program *program, @@ -1076,6 +1117,21 @@ st_translate_mesa_program( t->address[0] = ureg_DECL_address( ureg ); } + /* Declare misc input registers + */ + { + GLbitfield sysInputs = program->SystemValuesRead; + unsigned numSys = 0; + for (i = 0; sysInputs; i++) { + if (sysInputs & (1 << i)) { + unsigned semName = mesa_sysval_to_semantic[i]; + t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); + numSys++; + sysInputs &= ~(1 << i); + } + } + } + if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) { /* If temps are accessed with indirect addressing, declare temporaries * in sequential order. Else, we declare them on demand elsewhere.