static void check_wpos( struct i915_fragment_program *p ) { GLuint inputs = p->FragProg.InputsRead; GLint i; p->wpos_tex = -1; for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { if (inputs & FRAG_BIT_TEX(i)) continue; else if (inputs & FRAG_BIT_WPOS) { p->wpos_tex = i; inputs &= ~FRAG_BIT_WPOS; } } if (inputs & FRAG_BIT_WPOS) { i915_program_error(p, "No free texcoord for wpos value"); } }
void i915_update_sprite_point_enable(struct gl_context *ctx) { struct intel_context *intel = intel_context(ctx); /* _NEW_PROGRAM */ struct i915_fragment_program *p = (struct i915_fragment_program *) ctx->FragmentProgram._Current; const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead; struct i915_context *i915 = i915_context(ctx); GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; int i; GLuint coord_replace_bits = 0x0; GLuint tex_coord_unit_bits = 0x0; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { /* _NEW_POINT */ if (ctx->Point.CoordReplace[i] && ctx->Point.PointSprite) coord_replace_bits |= (1 << i); if (inputsRead & FRAG_BIT_TEX(i)) tex_coord_unit_bits |= (1 << i); } /* * Here we can't enable the SPRITE_POINT_ENABLE bit when the mis-match * of tex_coord_unit_bits and coord_replace_bits, or this will make all * the other non-point-sprite coords(like varying inputs, as we now use * tex coord to implement varying inputs) be replaced to value (0, 0)-(1, 1). * * Thus, do fallback when needed. */ FALLBACK(intel, I915_FALLBACK_COORD_REPLACE, coord_replace_bits && coord_replace_bits != tex_coord_unit_bits); s4 &= ~S4_SPRITE_POINT_ENABLE; s4 |= (coord_replace_bits && coord_replace_bits == tex_coord_unit_bits) ? S4_SPRITE_POINT_ENABLE : 0; if (s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { i915->state.Ctx[I915_CTXREG_LIS4] = s4; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } }
void i915ValidateFragmentProgram(struct i915_context *i915) { GLcontext *ctx = &i915->intel.ctx; struct intel_context *intel = intel_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; struct i915_fragment_program *p = (struct i915_fragment_program *) ctx->FragmentProgram._Current; const GLuint inputsRead = p->FragProg.Base.InputsRead; GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; GLuint s2 = S2_TEXCOORD_NONE; int i, offset = 0; if (i915->current_program != p) { if (i915->current_program) { i915->current_program->on_hardware = 0; i915->current_program->params_uptodate = 0; } i915->current_program = p; } /* Important: */ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; if (!p->translated) translate_program(p); intel->vertex_attr_count = 0; intel->wpos_offset = 0; intel->wpos_size = 0; intel->coloroffset = 0; intel->specoffset = 0; if (inputsRead & FRAG_BITS_TEX_ANY) { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); } else { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); } if (inputsRead & FRAG_BIT_COL0) { intel->coloroffset = offset / 4; EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); } if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || i915->vertex_fog != I915_FOG_NONE) { if (inputsRead & FRAG_BIT_COL1) { intel->specoffset = offset / 4; EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); } else EMIT_PAD(3); if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); else EMIT_PAD(1); } /* XXX this was disabled, but enabling this code helped fix the Glean * tfragprog1 fog tests. */ #if 1 if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); } #endif for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { if (inputsRead & FRAG_BIT_TEX(i)) { int sz = VB->TexCoordPtr[i]->size; s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); } else if (i == p->wpos_tex) { /* If WPOS is required, duplicate the XYZ position data in an * unused texture coordinate: */ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); intel->wpos_offset = offset; intel->wpos_size = 3 * sizeof(GLuint); EMIT_PAD(intel->wpos_size); } } if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { int k; I915_STATECHANGE(i915, I915_UPLOAD_CTX); /* Must do this *after* statechange, so as not to affect * buffered vertices reliant on the old state: */ intel->vertex_size = _tnl_install_attrs(&intel->ctx, intel->vertex_attrs, intel->vertex_attr_count, intel->ViewportMatrix.m, 0); intel->vertex_size >>= 2; i915->state.Ctx[I915_CTXREG_LIS2] = s2; i915->state.Ctx[I915_CTXREG_LIS4] = s4; k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); assert(k); }
void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_OutputsWritten) { r300ContextPtr rmesa = R300_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; int first_free_tex = 0; GLuint InputsRead = 0; GLuint OutputsWritten = 0; int num_attrs = 0; GLuint fp_reads = rmesa->selected_fp->InputsRead; struct vertex_attribute *attrs = rmesa->vbuf.attribs; radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__); rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0; rmesa->radeon.swtcl.vertex_attr_count = 0; if (RADEON_DEBUG & RADEON_VERTS) fprintf(stderr, "%s\n", __func__); /* We always want non Ndc coords format */ VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; /* Always write position vector */ InputsRead |= 1 << VERT_ATTRIB_POS; OutputsWritten |= 1 << VERT_RESULT_HPOS; EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW, 0); rmesa->swtcl.coloroffset = 4; if (fp_reads & FRAG_BIT_COL0) { InputsRead |= 1 << VERT_ATTRIB_COLOR0; OutputsWritten |= 1 << VERT_RESULT_COL0; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA ); ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR ); ADD_ATTR(VERT_ATTRIB_COLOR0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW, 1); #endif } if (fp_reads & FRAG_BIT_COL1) { GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); InputsRead |= 1 << VERT_ATTRIB_COLOR1; OutputsWritten |= 1 << VERT_RESULT_COL1; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA ); ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR ); ADD_ATTR(VERT_ATTRIB_COLOR1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR1, swiz, MASK_XYZW, 1); #endif rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1; } if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->ColorPtr[1]; OutputsWritten |= 1 << VERT_RESULT_BFC0; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA ); ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_ABGR ); ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1); #endif if (fp_reads & FRAG_BIT_COL1) { VB->AttribPtr[VERT_ATTRIB_GENERIC1] = VB->SecondaryColorPtr[1]; GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); OutputsWritten |= 1 << VERT_RESULT_BFC1; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_RGBA ); ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1); #else EMIT_ATTR( _TNL_ATTRIB_GENERIC1, EMIT_4UB_4F_ABGR ); ADD_ATTR(VERT_ATTRIB_GENERIC1, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR3, swiz, MASK_XYZW, 1); #endif } } if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) { GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE; OutputsWritten |= 1 << VERT_RESULT_PSIZ; EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F ); ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0); } if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) { int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0; VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS]; VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS]; RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); } if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) { int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0; VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG]; VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG]; RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); } /** * Sending only one texcoord component may lead to lock up, * so for all textures always output 4 texcoord components to RS. */ { int i; GLuint swiz, format, hw_format; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (fp_reads & FRAG_BIT_TEX(i)) { switch (VB->TexCoordPtr[i]->size) { case 1: format = EMIT_1F; hw_format = R300_DATA_TYPE_FLOAT_1; swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE); break; case 2: format = EMIT_2F; hw_format = R300_DATA_TYPE_FLOAT_2; swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE); break; case 3: format = EMIT_3F; hw_format = R300_DATA_TYPE_FLOAT_3; swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); break; case 4: format = EMIT_4F; hw_format = R300_DATA_TYPE_FLOAT_4; swiz = SWIZZLE_XYZW; break; default: continue; } InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i); OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); EMIT_ATTR(_TNL_ATTRIB_TEX(i), format); ADD_ATTR(VERT_ATTRIB_TEX0 + i, hw_format, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0); ++first_free_tex; } } } if (first_free_tex >= ctx->Const.MaxTextureUnits) { fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); _mesa_exit(-1); } R300_NEWPRIM(rmesa); rmesa->vbuf.num_attribs = num_attrs; *_InputsRead = InputsRead; *_OutputsWritten = OutputsWritten; RENDERINPUTS_COPY(rmesa->render_inputs_bitset, tnl->render_inputs_bitset); }
static void build_texture_transform( struct tnl_program *p ) { GLuint i, j; for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) continue; if (p->state->unit[i].texgen_enabled || p->state->unit[i].texmat_enabled) { GLuint texmat_enabled = p->state->unit[i].texmat_enabled; struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); struct ureg out_texgen = undef; if (p->state->unit[i].texgen_enabled) { GLuint copy_mask = 0; GLuint sphere_mask = 0; GLuint reflect_mask = 0; GLuint normal_mask = 0; GLuint modes[4]; if (texmat_enabled) out_texgen = get_temp(p); else out_texgen = out; modes[0] = p->state->unit[i].texgen_mode0; modes[1] = p->state->unit[i].texgen_mode1; modes[2] = p->state->unit[i].texgen_mode2; modes[3] = p->state->unit[i].texgen_mode3; for (j = 0; j < 4; j++) { switch (modes[j]) { case TXG_OBJ_LINEAR: { struct ureg obj = register_input(p, VERT_ATTRIB_POS); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, obj, plane ); break; } case TXG_EYE_LINEAR: { struct ureg eye = get_eye_position(p); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_EYE_S + j); emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, eye, plane ); break; } case TXG_SPHERE_MAP: sphere_mask |= WRITEMASK_X << j; break; case TXG_REFLECTION_MAP: reflect_mask |= WRITEMASK_X << j; break; case TXG_NORMAL_MAP: normal_mask |= WRITEMASK_X << j; break; case TXG_NONE: copy_mask |= WRITEMASK_X << j; } } if (sphere_mask) { build_sphere_texgen(p, out_texgen, sphere_mask); } if (reflect_mask) { build_reflect_texgen(p, out_texgen, reflect_mask); } if (normal_mask) { struct ureg normal = get_transformed_normal(p); emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); } if (copy_mask) { struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); } } if (texmat_enabled) { struct ureg texmat[4]; struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); } else { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); emit_transpose_matrix_transform_vec4( p, out, texmat, in ); } } release_temps(p); } else { emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } } }
void _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) { TNLcontext *tnl = TNL_CONTEXT(ctx); const struct gl_vertex_program *vp = ctx->VertexProgram._Current; const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; if (new_state & (_NEW_HINT | _NEW_PROGRAM)) { ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog); tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) || !tnl->AllowPixelFog) && !fp; } tnl->pipeline.new_state |= new_state; /* Calculate tnl->render_inputs. This bitmask indicates which vertex * attributes need to be emitted to the rasterizer. */ if (ctx->Visual.rgbMode) { GLuint i; RENDERINPUTS_ZERO( tnl->render_inputs_bitset ); RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); if (!fp || (fp->Base.InputsRead & FRAG_BIT_COL0)) { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 ); } if (NEED_SECONDARY_COLOR(ctx)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 ); for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture._EnabledCoordUnits & (1 << i) || (fp && fp->Base.InputsRead & FRAG_BIT_TEX(i))) { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) ); } } } else { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR_INDEX ); } if (ctx->Fog.Enabled) { /* fixed-function fog */ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); } else if (fp) { if (fp->FogOption != GL_NONE || (fp->Base.InputsRead & FRAG_BIT_FOGC)) { /* fragment program needs fog coord */ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); } } if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_EDGEFLAG ); if (ctx->RenderMode == GL_FEEDBACK) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 ); if (ctx->Point._Attenuated || (ctx->VertexProgram._Enabled && ctx->VertexProgram.PointSizeEnabled)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE ); /* check for varying vars which are written by the vertex program */ if (vp) { GLuint i; for (i = 0; i < MAX_VARYING; i++) { if (vp->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_VAR0 + i)) { RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_GENERIC(i)); } } } }