diff options
Diffstat (limited to 'src/mesa')
49 files changed, 777 insertions, 909 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index e48e10d7c0..da81ec9de5 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -167,11 +167,12 @@ static int driBindContext(__DRIcontext *pcp, __DRIdrawable *pdp, __DRIdrawable *prp) { - __DRIscreenPrivate *psp = pcp->driScreenPriv; + __DRIscreenPrivate *psp; /* Bind the drawable to the context */ if (pcp) { + psp = pcp->driScreenPriv; pcp->driDrawablePriv = pdp; pcp->driReadablePriv = prp; if (pdp) { @@ -498,11 +499,11 @@ static void dri_put_drawable(__DRIdrawable *pdp) { __DRIscreenPrivate *psp; - pdp->refcount--; - if (pdp->refcount) - return; - if (pdp) { + pdp->refcount--; + if (pdp->refcount) + return; + psp = pdp->driScreenPriv; (*psp->DriverAPI.DestroyBuffer)(pdp); if (pdp->pClipRects) { diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 082d614442..25418d5f7a 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -39,6 +39,7 @@ #define I915_FALLBACK_LOGICOP 0x20000 #define I915_FALLBACK_POLYGON_SMOOTH 0x40000 #define I915_FALLBACK_POINT_SMOOTH 0x80000 +#define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN 0x100000 #define I915_UPLOAD_CTX 0x1 #define I915_UPLOAD_BUFFERS 0x2 diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index b60efea75b..cc98d125db 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -585,7 +585,7 @@ i915PointSize(GLcontext * ctx, GLfloat size) { struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int) size; + GLint point_size = (int) round(size); DBG("%s\n", __FUNCTION__); @@ -599,6 +599,24 @@ i915PointSize(GLcontext * ctx, GLfloat size) } +static void +i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_POINT_SPRITE_COORD_ORIGIN: + /* This could be supported, but it would require modifying the fragment + * program to invert the y component of the texture coordinate by + * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction. + */ + FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN, + (params[0] != GL_UPPER_LEFT)); + break; + } +} + + /* ============================================================= * Color masks */ @@ -939,6 +957,17 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) case GL_POLYGON_SMOOTH: break; + case GL_POINT_SPRITE: + /* This state change is handled in i915_reduced_primitive_state because + * the hardware bit should only be set when rendering points. + */ + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE; + break; + case GL_POINT_SMOOTH: break; @@ -1108,6 +1137,7 @@ i915InitStateFunctions(struct dd_function_table *functions) functions->LineWidth = i915LineWidth; functions->LogicOpcode = i915LogicOp; functions->PointSize = i915PointSize; + functions->PointParameterfv = i915PointParameterfv; functions->PolygonStipple = i915PolygonStipple; functions->Scissor = i915Scissor; functions->ShadeModel = i915ShadeModel; diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 48685c087b..8bdda60697 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -111,6 +111,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, ctx->Const.MaxTextureImageUnits); ctx->Const.MaxVertexTextureImageUnits = 0; /* no vertex shader textures */ + ctx->Const.MaxCombinedTextureImageUnits = 0; /* Mesa limits textures to 4kx4k; it would be nice to fix that someday */ diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 669becdab4..3b7015b5ad 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -268,6 +268,8 @@ intel_bufferobj_map(GLcontext * ctx, if (intel_obj->sys_buffer) { obj->Pointer = intel_obj->sys_buffer; + obj->Length = obj->Size; + obj->Offset = 0; return obj->Pointer; } diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 7de29e5bb8..25314eff56 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -111,6 +111,7 @@ static const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_crossbar", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, @@ -327,7 +328,6 @@ static void r600InitGLExtensions(GLcontext *ctx) ctx->Extensions.ARB_shader_objects = GL_TRUE; ctx->Extensions.ARB_vertex_shader = GL_TRUE; ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE; ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; ctx->Extensions.ATI_separate_stencil = GL_TRUE; diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 8e57396a0d..309c90fdd0 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -1038,7 +1038,8 @@ GLboolean checkop2(r700_AssemblerBase* pAsm) checkop_init(pAsm); - if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) ) @@ -1049,7 +1050,8 @@ GLboolean checkop2(r700_AssemblerBase* pAsm) { bSrcConst[0] = GL_FALSE; } - if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) ) @@ -1082,7 +1084,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) checkop_init(pAsm); - if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[0].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) ) @@ -1093,7 +1096,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) { bSrcConst[0] = GL_FALSE; } - if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[1].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) ) @@ -1104,7 +1108,8 @@ GLboolean checkop3(r700_AssemblerBase* pAsm) { bSrcConst[1] = GL_FALSE; } - if( (pILInst->SrcReg[2].File == PROGRAM_CONSTANT) || + if( (pILInst->SrcReg[2].File == PROGRAM_UNIFORM) || + (pILInst->SrcReg[2].File == PROGRAM_CONSTANT) || (pILInst->SrcReg[2].File == PROGRAM_LOCAL_PARAM) || (pILInst->SrcReg[2].File == PROGRAM_ENV_PARAM) || (pILInst->SrcReg[2].File == PROGRAM_STATE_VAR) ) @@ -1218,7 +1223,7 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm, pAsm->S[fld].src.reg = pILInst->SrcReg[src].Index; break; case PROGRAM_INPUT: - setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE); + setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE); pAsm->S[fld].src.rtype = SRC_REG_INPUT; switch (pAsm->currentShaderType) { @@ -1346,6 +1351,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm) else { switch (pILInst->SrcReg[0].File) { + case PROGRAM_UNIFORM: case PROGRAM_CONSTANT: case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: @@ -2117,7 +2123,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, if( is_gpr(sel) ) { if( GL_FALSE == cycle_for_vector_bank_swizzle(bank_swizzle, src, &cycle) ) - { + { return GL_FALSE; } @@ -2129,7 +2135,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, else { if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) ) - { + { return GL_FALSE; } } @@ -2141,7 +2147,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, if( is_cfile(sel) ) { if( GL_FALSE == reserve_cfile(pAsm, sel, chan) ) - { + { return GL_FALSE; } } @@ -2244,7 +2250,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) current_source_index, pcurrent_source, scalar_channel_index) ) - { + { return GL_FALSE; } @@ -2258,7 +2264,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) current_source_index, pcurrent_source, scalar_channel_index) ) - { + { return GL_FALSE; } } @@ -2287,7 +2293,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) alu_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg; } else - { + { radeon_error("Only temp destination registers supported for ALU dest regs.\n"); return GL_FALSE; } @@ -2401,7 +2407,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) } if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) ) - { + { return GL_FALSE; } @@ -2412,15 +2418,15 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) if (is_single_scalar_operation) { if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) ) - { + { return GL_FALSE; } } else { if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) ) - { - return 1; + { + return GL_FALSE; } } @@ -2667,7 +2673,7 @@ GLboolean assemble_alu_instruction2(r700_AssemblerBase *pAsm) { if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) ) { - return 1; + return GL_FALSE; } } @@ -3642,6 +3648,7 @@ GLboolean assemble_LRP(r700_AssemblerBase *pAsm) { return GL_FALSE; } + if( GL_FALSE == assemble_src(pAsm, 2, -1) ) { return GL_FALSE; @@ -4598,6 +4605,7 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) switch (pAsm->pILInst[pAsm->uiCurInst].SrcReg[0].File) { + case PROGRAM_UNIFORM: case PROGRAM_CONSTANT: case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: @@ -5663,6 +5671,8 @@ GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) pAsm->D2.dst2.literal = 1; pAsm->D2.dst2.SaturateMode = SATURATE_OFF; pAsm->D.dst.predicated = 0; + /* in reloc where dislink flag init inst, only one slot alu inst is handled. */ + pAsm->D.dst.math = 1; /* TODO : not math really, but one channel op, more generic alu assembler needed */ #if 0 pAsm->S[0].src.rtype = SRC_REC_LITERAL; //pAsm->S[0].src.reg = 0; @@ -6457,6 +6467,7 @@ GLboolean AssembleInstr(GLuint uiFirstInst, GLboolean InitShaderProgram(r700_AssemblerBase * pAsm) { setRetInLoopFlag(pAsm, SQ_SEL_0); + pAsm->alu_x_opcode = SQ_CF_INST_ALU; return GL_TRUE; } @@ -6482,7 +6493,7 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm) if(SIT_CF_ALU == pInst->m_ShaderInstType) { pCF_ALU = (R700ControlFlowALUClause *)pInst; - if(1 == pCF_ALU->m_Word1.f.count) + if(0 == pCF_ALU->m_Word1.f.count) { pCF_ALU->m_Word1.f.cf_inst = SQ_CF_INST_NOP; } @@ -6503,14 +6514,14 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm) }; } - if(0 == pAsm->unSubArrayPointer) + if(pAsm->CALLSTACK[0].max > 0) { - return GL_TRUE; + pAsm->pR700Shader->uStackSize = ((pAsm->CALLSTACK[0].max + 3)>>2) + 2; } - if(pAsm->CALLSTACK[0].max > 0) + if(0 == pAsm->unSubArrayPointer) { - pAsm->pR700Shader->uStackSize = ((pAsm->CALLSTACK[0].max + 3)>>2) + 2; + return GL_TRUE; } unCFoffset = plstCFmain->uNumOfNode; @@ -6864,7 +6875,7 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode, export_starting_index++; } } - + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) { unBit = 1 << i; @@ -6876,7 +6887,7 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode, 1, pR700AsmCode->ucVP_OutputMap[i], GL_FALSE) ) - { + { return GL_FALSE; } diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c index 21ac46e7b8..e9ef6c8695 100644 --- a/src/mesa/drivers/dri/r600/r700_fragprog.c +++ b/src/mesa/drivers/dri/r600/r700_fragprog.c @@ -44,12 +44,18 @@ //TODO : Validate FP input with VP output. void Map_Fragment_Program(r700_AssemblerBase *pAsm, - struct gl_fragment_program *mesa_fp) + struct gl_fragment_program *mesa_fp, + GLcontext *ctx) { unsigned int unBit; unsigned int i; GLuint ui; + /* match fp inputs with vp exports. */ + struct r700_vertex_program_cont *vpc = + (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; + GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten; + pAsm->number_used_registers = 0; //Input mapping : mesa_fp->Base.InputsRead set the flag, set in @@ -61,41 +67,41 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm, pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_COL0; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL0; + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_COL1; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL1; + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1] = pAsm->number_used_registers++; } - unBit = 1 << FRAG_ATTRIB_FOGC; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_FOGC; + if(OutputsWritten & unBit) { - pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++; + pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++; } for(i=0; i<8; i++) { - unBit = 1 << (FRAG_ATTRIB_TEX0 + i); - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << (VERT_RESULT_TEX0 + i); + if(OutputsWritten & unBit) { pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i] = pAsm->number_used_registers++; } } -/* order has been taken care of */ +/* order has been taken care of */ #if 1 - for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++) - { + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) + { unBit = 1 << i; - if(mesa_fp->Base.InputsRead & unBit) + if(OutputsWritten & unBit) { - pAsm->uiFP_AttributeMap[i] = pAsm->number_used_registers++; + pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0] = pAsm->number_used_registers++; } } #else @@ -291,7 +297,8 @@ GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp, } GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, - struct gl_fragment_program *mesa_fp) + struct gl_fragment_program *mesa_fp, + GLcontext *ctx) { GLuint number_of_colors_exported; GLboolean z_enabled = GL_FALSE; @@ -299,7 +306,7 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, //Init_Program Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) ); - Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp); + Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); if( GL_FALSE == Find_Instruction_Dependencies_fp(fp, mesa_fp) ) { @@ -366,7 +373,7 @@ void r700SelectFragmentShader(GLcontext *ctx) } if (GL_FALSE == fp->translated) - r700TranslateFragmentShader(fp, &(fp->mesa_program)); + r700TranslateFragmentShader(fp, &(fp->mesa_program), ctx); } void * r700GetActiveFpShaderBo(GLcontext * ctx) @@ -460,6 +467,9 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) EXPORT_MODE_shift, EXPORT_MODE_mask); // emit ps input map + struct r700_vertex_program_cont *vpc = + (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; + GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten; unBit = 1 << FRAG_ATTRIB_WPOS; if(mesa_fp->Base.InputsRead & unBit) { @@ -473,8 +483,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_COL0; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL0; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -486,8 +496,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_COL1; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_COL1; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -499,8 +509,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); } - unBit = 1 << FRAG_ATTRIB_FOGC; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << VERT_RESULT_FOGC; + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -514,8 +524,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) for(i=0; i<8; i++) { - unBit = 1 << (FRAG_ATTRIB_TEX0 + i); - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << (VERT_RESULT_TEX0 + i); + if(OutputsWritten & unBit) { ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); @@ -525,12 +535,12 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) } } - for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++) + for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++) { - unBit = 1 << i; - if(mesa_fp->Base.InputsRead & unBit) + unBit = 1 << i; + if(OutputsWritten & unBit) { - ui = pAsm->uiFP_AttributeMap[i]; + ui = pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0]; SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit); SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui, SEMANTIC_shift, SEMANTIC_mask); @@ -538,8 +548,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); else CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit); - } - } + } + } exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift); if (r700->CB_SHADER_CONTROL.u32All != ((1 << exportCount) - 1)) @@ -551,7 +561,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) /* sent out shader constants. */ paramList = fp->mesa_program.Base.Parameters; - if(NULL != paramList) { + if(NULL != paramList) + { _mesa_load_state_parameters(ctx, paramList); if (paramList->NumParameters > R700_MAX_DX9_CONSTS) @@ -564,10 +575,10 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx) unNumParamData = paramList->NumParameters; for(ui=0; ui<unNumParamData; ui++) { - r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; - r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; - r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; - r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; + r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; + r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; + r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; } } else r700->ps.num_consts = 0; diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h index cbb108d212..e562bfa478 100644 --- a/src/mesa/drivers/dri/r600/r700_fragprog.h +++ b/src/mesa/drivers/dri/r600/r700_fragprog.h @@ -49,12 +49,14 @@ struct r700_fragment_program /* Internal */ void Map_Fragment_Program(r700_AssemblerBase *pAsm, - struct gl_fragment_program *mesa_fp); + struct gl_fragment_program *mesa_fp, + GLcontext *ctx); GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp, struct gl_fragment_program *mesa_fp); GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp, - struct gl_fragment_program *mesa_vp); + struct gl_fragment_program *mesa_vp, + GLcontext *ctx); /* Interface */ extern void r700SelectFragmentShader(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index c8f72d588b..d3d1da7959 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -631,6 +631,12 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) paramList = vp->mesa_program->Base.Parameters; if(NULL != paramList) { + /* vp->mesa_program was cloned, not updated by glsl shader api. */ + /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */ + /* so, use ctx->VertexProgem._Current */ + struct gl_program_parameter_list *paramListOrginal = + paramListOrginal = ctx->VertexProgram._Current->Base.Parameters; + _mesa_load_state_parameters(ctx, paramList); if (paramList->NumParameters > R700_MAX_DX9_CONSTS) @@ -643,10 +649,20 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) unNumParamData = paramList->NumParameters; for(ui=0; ui<unNumParamData; ui++) { - r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; - r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; - r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; - r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM) + { + r700->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0]; + r700->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1]; + r700->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2]; + r700->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3]; + } + else + { + r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0]; + r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1]; + r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2]; + r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3]; + } } } else r700->vs.num_consts = 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 89a99974e2..b8c65f4ce6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -205,6 +205,7 @@ again_alloc: counter on unused buffers for later freeing them from begin of list */ dma_bo = last_elem(&rmesa->dma.free); + assert(dma_bo->bo->cref == 1); remove_from_list(dma_bo); insert_at_head(&rmesa->dma.reserved, dma_bo); } @@ -301,10 +302,6 @@ static int radeon_bo_is_idle(struct radeon_bo* bo) WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n" "This may cause small performance drop for you.\n"); } - /* Protect against bug in legacy bo handling that causes bos stay - * referenced even after they should be freed */ - if (bo->cref != 1) - return 0; return ret != -EBUSY; } @@ -341,9 +338,7 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa) foreach_s(dma_bo, temp, &rmesa->dma.wait) { if (dma_bo->expire_counter == time) { WARN_ONCE("Leaking dma buffer object!\n"); - /* force free of buffer so we don't realy start - * leaking stuff now*/ - while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {} + radeon_bo_unref(dma_bo->bo); remove_from_list(dma_bo); FREE(dma_bo); continue; diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 02de8e5fd1..7ad781ba61 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -62,8 +62,6 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) __DRIdrawablePrivate *const readable = radeon_get_readable(rmesa); __DRIscreenPrivate *sPriv = rmesa->dri.screen; - assert(drawable != NULL); - drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); /* The window might have moved, so we might need to get new clip @@ -74,12 +72,13 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); - if (drawable != readable) { + if (drawable) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (readable && drawable != readable) { DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); } - if (rmesa->lastStamp != drawable->lastStamp) { + if (drawable && (rmesa->lastStamp != drawable->lastStamp)) { radeon_window_moved(rmesa); rmesa->lastStamp = drawable->lastStamp; } diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 46603de2e7..bdbb9460bf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -68,6 +68,19 @@ static unsigned get_compressed_image_size( return rowStride * ((height + blockHeight - 1) / blockHeight); } +static int find_next_power_of_two(GLuint value) +{ + int i, tmp; + + i = 0; + tmp = value - 1; + while (tmp) { + tmp >>= 1; + i++; + } + return (1 << i); +} + /** * Compute sizes and fill in offset and blit information for the given * image (determined by \p face and \p level). @@ -80,25 +93,28 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree { radeon_mipmap_level *lvl = &mt->levels[level]; uint32_t row_align; + GLuint height; + + height = find_next_power_of_two(lvl->height); /* Find image size in bytes */ if (_mesa_is_format_compressed(mt->mesaFormat)) { lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align); - lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, lvl->height); + lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height); } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { row_align = rmesa->texture_rect_row_align - 1; lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height; + lvl->size = lvl->rowstride * height; } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) { /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, * though the actual offset may be different (if texture is less than * 32 bytes width) to the untiled case */ lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31; - lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; + lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth; } else { row_align = rmesa->texture_row_align - 1; lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height * lvl->depth; + lvl->size = lvl->rowstride * height * lvl->depth; } assert(lvl->size > 0); @@ -110,7 +126,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree if (RADEON_DEBUG & RADEON_TEXTURE) fprintf(stderr, "level %d, face %d: rs:%d %dx%d at %d\n", - level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset); + level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset); } static GLuint minify(GLuint size, GLuint levels) @@ -124,20 +140,19 @@ static GLuint minify(GLuint size, GLuint levels) static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint i; - GLuint face; + GLuint curOffset, i, face, level; assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; for(face = 0; face < mt->faces; face++) { - for(i = 0; i < mt->numLevels; i++) { - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } } @@ -147,21 +162,21 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint i; + GLuint curOffset, i, level; assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; - for(i = 0; i < mt->numLevels; i++) { + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { GLuint face; - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); for(face = 0; face < mt->faces; face++) - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } /* Note the required size in memory */ @@ -277,18 +292,19 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj, * given face and level. */ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint mtLevel) + struct gl_texture_image *texImage, GLuint face, GLuint level) { radeon_mipmap_level *lvl; - if (face >= mt->faces || mtLevel > mt->numLevels) + if (face >= mt->faces) return GL_FALSE; if (texImage->TexFormat != mt->mesaFormat) return GL_FALSE; - lvl = &mt->levels[mtLevel]; - if (lvl->width != texImage->Width || + lvl = &mt->levels[level]; + if (!lvl->valid || + lvl->width != texImage->Width || lvl->height != texImage->Height || lvl->depth != texImage->Depth) return GL_FALSE; @@ -394,38 +410,17 @@ radeon_miptree_image_offset(radeon_mipmap_tree *mt, } /** - * Convert radeon miptree texture level to GL texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level radeon miptree texture level - * @return GL texture level - */ -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level) -{ - return level + tObj->BaseLevel; -} - -/** - * Convert GL texture level to radeon miptree texture level - * @param[in] tObj texture object whom level is to be converted - * @param[in] level GL texture level - * @return radeon miptree texture level - */ -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level) -{ - return level - tObj->BaseLevel; -} - -/** * Ensure that the given image is stored in the given miptree from now on. */ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, - int face, int mtLevel) + int face, int level) { - radeon_mipmap_level *dstlvl = &mt->levels[mtLevel]; + radeon_mipmap_level *dstlvl = &mt->levels[level]; unsigned char *dest; assert(image->mt != mt); + assert(dstlvl->valid); assert(dstlvl->width == image->base.Width); assert(dstlvl->height == image->base.Height); assert(dstlvl->depth == image->base.Depth); @@ -442,6 +437,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + assert(image->mtlevel == level); assert(srclvl->size == dstlvl->size); assert(srclvl->rowstride == dstlvl->rowstride); @@ -479,7 +475,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_miptree_reference(mt, &image->mt); image->mtface = face; - image->mtlevel = mtLevel; + image->mtlevel = level; } /** @@ -506,7 +502,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, if (!img) break; - if (!img->mt || !radeon_miptree_matches_texture(img->mt, &texObj->base)) + if (!img->mt) continue; for (int i = 0; i < mtCount; ++i) { @@ -517,8 +513,8 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, } } - if (!found) { - mtSizes[mtCount] += img->mt->levels[img->mtlevel].size; + if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) { + mtSizes[mtCount] = img->mt->levels[img->mtlevel].size; mts[mtCount] = img->mt; mtCount++; } @@ -576,6 +572,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); dst_miptree = t->mt; + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt); + } + } else if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt); } const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; @@ -594,7 +595,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t if (RADEON_DEBUG & RADEON_TEXTURE) { fprintf(stderr, "MIGRATING\n"); } - migrate_image_to_miptree(dst_miptree, img, face, radeon_gl_level_to_miptree_level(texObj, level)); + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; + if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + migrate_image_to_miptree(dst_miptree, img, face, level); } else if (RADEON_DEBUG & RADEON_TEXTURE) { fprintf(stderr, "OK\n"); } diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 28b8485095..a10649b5ae 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -44,6 +44,7 @@ struct _radeon_mipmap_level { GLuint depth; GLuint size; /** Size of each image, in bytes */ GLuint rowstride; /** in bytes */ + GLuint valid; radeon_mipmap_image faces[6]; }; @@ -70,9 +71,9 @@ struct _radeon_mipmap_tree { GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */ GLuint numLevels; /** Number of mip levels stored in this mipmap tree */ - GLuint width0; /** Width of firstLevel image */ - GLuint height0; /** Height of firstLevel image */ - GLuint depth0; /** Depth of firstLevel image */ + GLuint width0; /** Width of baseLevel image */ + GLuint height0; /** Height of baseLevel image */ + GLuint depth0; /** Depth of baseLevel image */ GLuint tilebits; /** RADEON_TXO_xxx_TILE */ @@ -89,8 +90,5 @@ GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); -unsigned radeon_miptree_level_to_gl_level(struct gl_texture_object *tObj, unsigned level); -unsigned radeon_gl_level_to_miptree_level(struct gl_texture_object *tObj, unsigned level); - uint32_t get_base_teximage_offset(radeonTexObj *texObj); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 1ee9e2792a..0390d376ba 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -509,6 +509,27 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, return MESA_FORMAT_NONE; /* never get here */ } +/** Check if given image is valid within current texture object. + */ +static int image_matches_texture_obj(struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned level) +{ + const struct gl_texture_image *baseImage = texObj->Image[0][level]; + + if (level < texObj->BaseLevel || level > texObj->MaxLevel) + return 0; + + const unsigned levelDiff = level - texObj->BaseLevel; + const unsigned refWidth = baseImage->Width >> levelDiff; + const unsigned refHeight = baseImage->Height >> levelDiff; + const unsigned refDepth = baseImage->Depth >> levelDiff; + + return (texImage->Width == refWidth && + texImage->Height == refHeight && + texImage->Depth == refDepth); +} + static void teximage_assign_miptree(radeonContextPtr rmesa, struct gl_texture_object *texObj, struct gl_texture_image *texImage, @@ -518,18 +539,28 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); + /* Since miptree holds only images for levels <BaseLevel..MaxLevel> + * don't allocate the miptree if the teximage won't fit. + */ + if (!image_matches_texture_obj(texObj, texImage, level)) + return; + /* Try using current miptree, or create new if there isn't any */ - if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, - radeon_gl_level_to_miptree_level(texObj, level))) { + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " + "texObj miptree doesn't match, allocated new miptree %p\n", + __FUNCTION__, texObj, texImage, face, level, t->mt); + } } /* Miptree alocation may have failed, * when there was no image for baselevel specified */ if (t->mt) { image->mtface = face; - image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level); + image->mtlevel = level; radeon_miptree_reference(t->mt, &image->mt); } } @@ -585,6 +616,8 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); } + assert(dstRowStride); + if (dims == 3) { unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); @@ -670,6 +703,11 @@ static void radeon_teximage( } } + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, face, level); + } + t->validated = GL_FALSE; if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { @@ -694,12 +732,17 @@ static void radeon_teximage( if (!t->bo) { teximage_assign_miptree(rmesa, texObj, texImage, face, level); - if (!t->mt) { + if (!image->mt) { int size = _mesa_format_image_size(texImage->TexFormat, texImage->Width, texImage->Height, texImage->Depth); texImage->Data = _mesa_alloc_texmemory(size); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " + " no miptree assigned, using local memory %p\n", + dims, texObj, texImage, texImage->Data); + } } } @@ -801,6 +844,11 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve } } + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, radeon_face_for_target(target), level); + } + t->validated = GL_FALSE; if (compressed) { pixels = _mesa_validate_pbo_compressed_teximage( diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c index 2d3c25dcbe..f8e503463f 100644 --- a/src/mesa/drivers/dri/swrast/swrast_span.c +++ b/src/mesa/drivers/dri/swrast/swrast_span.c @@ -63,56 +63,42 @@ static const GLubyte kernel[16] = { /* 32-bit BGRA */ #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = VALUE[ACOMP]; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \ - DST[ACOMP] = SRC[3]; \ - DST[RCOMP] = SRC[2]; \ - DST[GCOMP] = SRC[1]; \ - DST[BCOMP] = SRC[0] + DST[ACOMP] = *SRC >> 24; \ + DST[RCOMP] = (*SRC >> 16) & 0xff; \ + DST[GCOMP] = (*SRC >> 8) & 0xff; \ + DST[BCOMP] = *SRC & 0xff /* 32-bit BGRX */ #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \ - DST[3] = 0xff; \ - DST[2] = VALUE[RCOMP]; \ - DST[1] = VALUE[GCOMP]; \ - DST[0] = VALUE[BCOMP] + *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP] #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \ - DST[ACOMP] = 0xff; \ - DST[RCOMP] = SRC[2]; \ - DST[GCOMP] = SRC[1]; \ - DST[BCOMP] = SRC[0] + DST[ACOMP] = 0xff; \ + DST[RCOMP] = (*SRC >> 16) & 0xff; \ + DST[GCOMP] = (*SRC >> 8) & 0xff; \ + DST[BCOMP] = *SRC & 0xff /* 16-bit BGR */ #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \ do { \ int d = DITHER_COMP(X, Y) >> 6; \ - GLushort *p = (GLushort *)DST; \ - *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \ - ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \ - ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \ + *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \ + ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \ + ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \ } while(0) #define FETCH_PIXEL_R5G6B5(DST, SRC) \ do { \ - GLushort p = *(GLushort *)SRC; \ DST[ACOMP] = 0xff; \ - DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ - DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ - DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \ + DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \ + DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \ } while(0) @@ -145,8 +131,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X) +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -163,8 +149,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X); +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -181,8 +167,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2; -#define INC_PIXEL_PTR(P) P += 2 + GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X); +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) #define FETCH_PIXEL(DST, SRC) \ @@ -234,8 +220,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)row; +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -252,8 +238,8 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; -#define INC_PIXEL_PTR(P) P += 4 + GLuint *P = (GLuint *)row; +#define INC_PIXEL_PTR(P) P++ #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ @@ -270,7 +256,7 @@ static const GLubyte kernel[16] = { #define SPAN_VARS \ struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = (GLubyte *)row; + GLushort *P = (GLushort *)row; #define INC_PIXEL_PTR(P) P += 2 #define STORE_PIXEL(DST, X, Y, VALUE) \ STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index 380663ec97..87c3b2e562 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -234,7 +234,12 @@ extern "C" { #elif defined(__APPLE__) #include <CoreFoundation/CFByteOrder.h> #define CPU_TO_LE32( x ) CFSwapInt32HostToLittle( x ) -#else /*__linux__ __APPLE__*/ +#elif defined(_AIX) +#define CPU_TO_LE32( x ) x = ((x & 0x000000ff) << 24) | \ + ((x & 0x0000ff00) << 8) | \ + ((x & 0x00ff0000) >> 8) | \ + ((x & 0xff000000) >> 24); +#else /*__linux__ */ #include <sys/endian.h> #define CPU_TO_LE32( x ) bswap32( x ) #endif /*__linux__*/ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b5bf46718f..03fc57e665 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -575,6 +575,7 @@ _mesa_init_constants(GLcontext *ctx) #if FEATURE_ARB_vertex_shader ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVarying = MAX_VARYING; #endif diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 6c5ce02913..e8932f83b6 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1876,7 +1876,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetBooleanv"); @@ -3711,7 +3711,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = (GLfloat)(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetFloatv"); @@ -5546,7 +5546,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS; + params[0] = ctx->Const.MaxCombinedTextureImageUnits; break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetIntegerv"); @@ -7382,7 +7382,7 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetInteger64v"); - params[0] = (GLint64)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); + params[0] = (GLint64)(ctx->Const.MaxCombinedTextureImageUnits); break; case GL_CURRENT_PROGRAM: CHECK_EXT1(ARB_shader_objects, "GetInteger64v"); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 930c3362fa..a29962d334 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -1006,7 +1006,7 @@ StateVars = [ ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, - ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxCombinedTextureImageUnits"], "", ["ARB_vertex_shader"] ), # GL_ARB_shader_objects # Actually, this token isn't part of GL_ARB_shader_objects, but is diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 881d233ca3..5f01244827 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2319,6 +2319,7 @@ struct gl_constants GLuint MaxTextureCoordUnits; GLuint MaxTextureImageUnits; GLuint MaxVertexTextureImageUnits; + GLuint MaxCombinedTextureImageUnits; GLuint MaxTextureUnits; /**< = MIN(CoordUnits, ImageUnits) */ GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 4c8fc1f72e..b330544890 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -200,7 +200,12 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) } break; case GL_POINT_SPRITE_COORD_ORIGIN: - if (ctx->Extensions.ARB_point_sprite || ctx->Extensions.NV_point_sprite) { + /* This is not completely correct. GL_POINT_SPRITE_COORD_ORIGIN was + * added to point sprites when the extension was merged into OpenGL + * 2.0. It is expected that an implementation supporting OpenGL 1.4 + * and GL_ARB_point_sprite will generate an error here. + */ + if (ctx->Extensions.ARB_point_sprite) { GLenum value = (GLenum) params[0]; if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) { _mesa_error(ctx, GL_INVALID_VALUE, diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c index 6d86a4275c..4442fb8cf8 100644 --- a/src/mesa/main/texenv.c +++ b/src/mesa/main/texenv.c @@ -598,7 +598,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) void GLAPIENTRY _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) { - _mesa_TexEnvfv( target, pname, ¶m ); + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0; + _mesa_TexEnvfv( target, pname, p ); } diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c index 733e129fcf..5abb1ff0ab 100644 --- a/src/mesa/main/texgen.c +++ b/src/mesa/main/texgen.c @@ -211,14 +211,20 @@ _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) static void GLAPIENTRY _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) { - _mesa_TexGenfv(coord, pname, ¶m); + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0F; + _mesa_TexGenfv(coord, pname, p); } void GLAPIENTRY _mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) { - _mesa_TexGeniv( coord, pname, ¶m ); + GLint p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0; + _mesa_TexGeniv( coord, pname, p ); } diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index ab170cde35..310d594cd5 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -547,13 +547,20 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) case GL_DEPTH_TEXTURE_MODE_ARB: { /* convert float param to int */ - GLint p = (GLint) param; - need_update = set_tex_parameteri(ctx, texObj, pname, &p); + GLint p[4]; + p[0] = (GLint) param; + p[1] = p[2] = p[3] = 0; + need_update = set_tex_parameteri(ctx, texObj, pname, p); } break; default: - /* this will generate an error if pname is illegal */ - need_update = set_tex_parameterf(ctx, texObj, pname, ¶m); + { + /* this will generate an error if pname is illegal */ + GLfloat p[4]; + p[0] = param; + p[1] = p[2] = p[3] = 0.0F; + need_update = set_tex_parameterf(ctx, texObj, pname, p); + } } if (ctx->Driver.TexParameter && need_update) { diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 0e89a624c4..73df44d198 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -46,7 +46,8 @@ static const struct st_tracked_state *atoms[] = &st_update_clip, &st_finalize_textures, - &st_update_shader, + &st_update_fp, + &st_update_vp, &st_update_rasterizer, &st_update_polygon_stipple, diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index c7cffd85c8..f34b49203b 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -47,7 +47,8 @@ void st_validate_state( struct st_context *st ); extern const struct st_tracked_state st_update_framebuffer; extern const struct st_tracked_state st_update_clip; extern const struct st_tracked_state st_update_depth_stencil_alpha; -extern const struct st_tracked_state st_update_shader; +extern const struct st_tracked_state st_update_fp; +extern const struct st_tracked_state st_update_vp; extern const struct st_tracked_state st_update_rasterizer; extern const struct st_tracked_state st_update_polygon_stipple; extern const struct st_tracked_state st_update_viewport; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index e18c0f6e0a..8ca4335e33 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -40,6 +40,7 @@ #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_rect.h" +#include "util/u_math.h" @@ -64,8 +65,8 @@ update_renderbuffer_surface(struct st_context *st, GLuint level; /* find matching mipmap level size */ for (level = 0; level <= texture->last_level; level++) { - if (texture->width[level] == rtt_width && - texture->height[level] == rtt_height) { + if (u_minify(texture->width0, level) == rtt_width && + u_minify(texture->height0, level) == rtt_height) { pipe_surface_reference(&strb->surface, NULL); diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index babfcc87b4..4b35f59cc2 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -145,7 +145,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) const GLuint gSize = ctx->PixelMaps.GtoG.Size; const GLuint bSize = ctx->PixelMaps.BtoB.Size; const GLuint aSize = ctx->PixelMaps.AtoA.Size; - const uint texSize = pt->width[0]; + const uint texSize = pt->width0; uint *dest; uint i, j; diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 6611956ae8..d6e3a3e561 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -229,14 +229,23 @@ update_samplers(struct st_context *st) /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, sampler); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, sampler); + } } else { /*printf("%s su=%u null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, NULL); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, NULL); + } } } cso_single_sampler_done(st->cso_context); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_single_vertex_sampler_done(st->cso_context); + } } diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 6e311e537e..09baff875b 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -56,82 +56,18 @@ #include "st_mesa_to_tgsi.h" -/** - * This represents a vertex program, especially translated to match - * the inputs of a particular fragment shader. - */ -struct translated_vertex_program -{ - struct st_vertex_program *master; - - /** The fragment shader "signature" this vertex shader is meant for: */ - GLbitfield frag_inputs; - /** Compared against master vertex program's serialNo: */ - GLuint serialNo; - /** Maps VERT_RESULT_x to slot */ - GLuint output_to_slot[VERT_RESULT_MAX]; - ubyte output_to_semantic_name[VERT_RESULT_MAX]; - ubyte output_to_semantic_index[VERT_RESULT_MAX]; - - /** Pointer to the translated vertex program */ - struct st_vertex_program *vp; - - struct translated_vertex_program *next; /**< next in linked list */ -}; - - -/** - * Given a vertex program output attribute, return the corresponding - * fragment program input attribute. - * \return -1 for vertex outputs that have no corresponding fragment input +/* + * Translate fragment program if needed. */ -static GLint -vp_out_to_fp_in(GLuint vertResult) -{ - if (vertResult >= VERT_RESULT_TEX0 && - vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS) - return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0); - - if (vertResult >= VERT_RESULT_VAR0 && - vertResult < VERT_RESULT_VAR0 + MAX_VARYING) - return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0); - - switch (vertResult) { - case VERT_RESULT_HPOS: - return FRAG_ATTRIB_WPOS; - case VERT_RESULT_COL0: - return FRAG_ATTRIB_COL0; - case VERT_RESULT_COL1: - return FRAG_ATTRIB_COL1; - case VERT_RESULT_FOGC: - return FRAG_ATTRIB_FOGC; - default: - /* Back-face colors, edge flags, etc */ - return -1; - } -} - - -/** - * Find a translated vertex program that corresponds to stvp and - * has outputs matched to stfp's inputs. - * This performs vertex and fragment translation (to TGSI) when needed. - */ -static struct translated_vertex_program * -find_translated_vp(struct st_context *st, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp) +static void +translate_fp(struct st_context *st, + struct st_fragment_program *stfp) { - static const GLuint UNUSED = ~0; - struct translated_vertex_program *xvp; const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - /* - * Translate fragment program if needed. - */ if (!stfp->state.tokens) { GLuint inAttr, numIn = 0; @@ -141,7 +77,7 @@ find_translated_vp(struct st_context *st, numIn++; } else { - stfp->input_to_slot[inAttr] = UNUSED; + stfp->input_to_slot[inAttr] = -1; } } @@ -151,170 +87,63 @@ find_translated_vp(struct st_context *st, st_translate_fragment_program(st, stfp, stfp->input_to_slot); } +} - /* See if we've got a translated vertex program whose outputs match - * the fragment program's inputs. - * XXX This could be a hash lookup, using InputsRead as the key. - */ - for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) { - if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) { - break; - } - } - /* No? Allocate translated vp object now */ - if (!xvp) { - xvp = ST_CALLOC_STRUCT(translated_vertex_program); - xvp->frag_inputs = fragInputsRead; - xvp->master = stvp; +/** + * Find a translated vertex program that corresponds to stvp and + * has outputs matched to stfp's inputs. + * This performs vertex and fragment translation (to TGSI) when needed. + */ +static struct st_vp_varient * +find_translated_vp(struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + struct st_vp_varient_key key; - xvp->next = stfp->vertex_programs; - stfp->vertex_programs = xvp; - } + /* Nothing in our key yet. This will change: + */ + memset(&key, 0, sizeof key); + key.dummy = 0; - /* See if we need to translate vertex program to TGSI form */ - if (xvp->serialNo != stvp->serialNo) { - GLuint outAttr; - const GLbitfield64 outputsWritten = stvp->Base.Base.OutputsWritten; - GLuint numVpOuts = 0; - GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE; - GLbitfield usedGenerics = 0x0; - GLbitfield usedOutputSlots = 0x0; - - /* Compute mapping of vertex program outputs to slots, which depends - * on the fragment program's input->slot mapping. + /* Do we need to throw away old translations after a change in the + * GL program string? + */ + if (stvp->serialNo != stvp->lastSerialNo) { + /* These may have changed if the program string changed. */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - /* set defaults: */ - xvp->output_to_slot[outAttr] = UNUSED; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT; - xvp->output_to_semantic_index[outAttr] = 99; - - if (outAttr == VERT_RESULT_HPOS) { - /* always put xformed position into slot zero */ - GLuint slot = 0; - xvp->output_to_slot[VERT_RESULT_HPOS] = slot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION; - xvp->output_to_semantic_index[outAttr] = 0; - numVpOuts++; - usedOutputSlots |= (1 << slot); - } - else if (outputsWritten & (1 << outAttr)) { - /* see if the frag prog wants this vert output */ - GLint fpInAttrib = vp_out_to_fp_in(outAttr); - if (fpInAttrib >= 0) { - GLuint fpInSlot = stfp->input_to_slot[fpInAttrib]; - if (fpInSlot != ~0) { - /* match this vp output to the fp input */ - GLuint vpOutSlot = stfp->input_map[fpInSlot]; - xvp->output_to_slot[outAttr] = vpOutSlot; - xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot]; - xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot]; - numVpOuts++; - usedOutputSlots |= (1 << vpOutSlot); - } - else { -#if 0 /*debug*/ - printf("VP output %d not used by FP\n", outAttr); -#endif - } - } - else if (outAttr == VERT_RESULT_PSIZ) - emitPntSize = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC0) - emitBFC0 = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC1) - emitBFC1 = GL_TRUE; - } -#if 0 /*debug*/ - printf("assign vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif - } - - /* must do these last */ - if (emitPntSize) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_PSIZ] = slot; - xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE; - xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC0) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC0] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC1) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC1] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1; - usedOutputSlots |= (1 << slot); - } - - /* build usedGenerics mask */ - usedGenerics = 0x0; - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) { - usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]); - } - } + st_prepare_vertex_program( st, stvp ); - /* For each vertex program output that doesn't match up to a fragment - * program input, map the vertex program output to a free slot and - * free generic attribute. + /* We are now up-to-date: */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (outputsWritten & (1 << outAttr)) { - if (xvp->output_to_slot[outAttr] == UNUSED) { - GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1; - GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1; - usedGenerics |= (1 << freeGeneric); - usedOutputSlots |= (1 << freeSlot); - xvp->output_to_slot[outAttr] = freeSlot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC; - xvp->output_to_semantic_index[outAttr] = freeGeneric; - } - } - -#if 0 /*debug*/ - printf("vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif + stvp->lastSerialNo = stvp->serialNo; + } + + /* See if we've got a translated vertex program whose outputs match + * the fragment program's inputs. + */ + for (vpv = stvp->varients; vpv; vpv = vpv->next) { + if (memcmp(&vpv->key, &key, sizeof key) == 0) { + break; } + } - assert(stvp->Base.Base.NumInstructions > 1); - - st_translate_vertex_program(st, stvp, xvp->output_to_slot, - xvp->output_to_semantic_name, - xvp->output_to_semantic_index); - - xvp->vp = stvp; - - /* translated VP is up to date now */ - xvp->serialNo = stvp->serialNo; + /* No? Perform new translation here. */ + if (!vpv) { + vpv = st_translate_vertex_program(st, stvp, &key); + if (!vpv) + return NULL; + + vpv->next = stvp->varients; + stvp->varients = vpv; } - return xvp; + return vpv; } -void -st_free_translated_vertex_programs(struct st_context *st, - struct translated_vertex_program *xvp) -{ - struct translated_vertex_program *next; - - while (xvp) { - next = xvp->next; - _mesa_free(xvp); - xvp = next; - } -} static void * @@ -328,32 +157,19 @@ get_passthrough_fs(struct st_context *st) return st->passthrough_fs; } - static void -update_linkage( struct st_context *st ) +update_fp( struct st_context *st ) { - struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct translated_vertex_program *xvp; - - /* find active shader and params -- Should be covered by - * ST_NEW_VERTEX_PROGRAM - */ - assert(st->ctx->VertexProgram._Current); - stvp = st_vertex_program(st->ctx->VertexProgram._Current); - assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); assert(st->ctx->FragmentProgram._Current); stfp = st_fragment_program(st->ctx->FragmentProgram._Current); assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); - xvp = find_translated_vp(st, stvp, stfp); + translate_fp(st, stfp); - st_reference_vertprog(st, &st->vp, stvp); st_reference_fragprog(st, &st->fp, stfp); - cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); - if (st->missing_textures) { /* use a pass-through frag shader that uses no textures */ void *fs = get_passthrough_fs(st); @@ -362,16 +178,48 @@ update_linkage( struct st_context *st ) else { cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); } +} + +const struct st_tracked_state st_update_fp = { + "st_update_fp", /* name */ + { /* dirty */ + 0, /* mesa */ + ST_NEW_FRAGMENT_PROGRAM /* st */ + }, + update_fp /* update */ +}; + + + + +static void +update_vp( struct st_context *st ) +{ + struct st_vertex_program *stvp; + + /* find active shader and params -- Should be covered by + * ST_NEW_VERTEX_PROGRAM + */ + assert(st->ctx->VertexProgram._Current); + stvp = st_vertex_program(st->ctx->VertexProgram._Current); + assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); + + st->vp_varient = find_translated_vp(st, stvp); + + st_reference_vertprog(st, &st->vp, stvp); + + cso_set_vertex_shader_handle(st->cso_context, + st->vp_varient->driver_shader); - st->vertex_result_to_slot = xvp->output_to_slot; + st->vertex_result_to_slot = stvp->result_to_output; } -const struct st_tracked_state st_update_shader = { - "st_update_shader", /* name */ +const struct st_tracked_state st_update_vp = { + "st_update_vp", /* name */ { /* dirty */ 0, /* mesa */ - ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM /* st */ + ST_NEW_VERTEX_PROGRAM /* st */ }, - update_linkage /* update */ + update_vp /* update */ }; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 4d4f97da7e..0b68447d21 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -32,6 +32,8 @@ */ +#include "main/macros.h" + #include "st_context.h" #include "st_atom.h" #include "st_texture.h" @@ -99,6 +101,12 @@ update_textures(struct st_context *st) cso_set_sampler_textures(st->cso_context, st->state.num_textures, st->state.sampler_texture); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_set_vertex_sampler_textures(st->cso_context, + MIN2(st->state.num_textures, + st->ctx->Const.MaxVertexTextureImageUnits), + st->state.sampler_texture); + } } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 1960d171bf..1bdeaccda3 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -169,11 +169,6 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex) stfp = (struct st_fragment_program *) p; stfp->Base.UsesKill = GL_TRUE; - /* No need to send this incomplete program down to hardware: - * - * st_translate_fragment_program(ctx->st, stfp, NULL); - */ - return stfp; } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 1d33e81c2c..03617b7a93 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -60,6 +60,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "tgsi/tgsi_ureg.h" #include "util/u_tile.h" #include "util/u_draw_quad.h" #include "util/u_math.h" @@ -236,78 +237,41 @@ make_fragment_shader_z(struct st_context *st) * Create a simple vertex shader that just passes through the * vertex position and texcoord (and optionally, color). */ -static struct st_vertex_program * -st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor) +static void * +st_make_passthrough_vertex_shader(struct st_context *st, + GLboolean passColor) { - GLcontext *ctx = st->ctx; - struct st_vertex_program *stvp; - struct gl_program *p; - GLuint ic = 0; - - if (st->drawpix.vert_shaders[passColor]) - return st->drawpix.vert_shaders[passColor]; - - /* - * Create shader now - */ - p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); - if (!p) - return NULL; - - if (passColor) - p->NumInstructions = 4; - else - p->NumInstructions = 3; - - p->Instructions = _mesa_alloc_instructions(p->NumInstructions); - if (!p->Instructions) { - ctx->Driver.DeleteProgram(ctx, p); - return NULL; - } - _mesa_init_instructions(p->Instructions, p->NumInstructions); - /* MOV result.pos, vertex.pos; */ - p->Instructions[0].Opcode = OPCODE_MOV; - p->Instructions[0].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS; - p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS; - /* MOV result.texcoord0, vertex.texcoord0; */ - p->Instructions[1].Opcode = OPCODE_MOV; - p->Instructions[1].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[1].DstReg.Index = VERT_RESULT_TEX0; - p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_TEX0; - ic = 2; - if (passColor) { - /* MOV result.color0, vertex.color0; */ - p->Instructions[ic].Opcode = OPCODE_MOV; - p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[ic].DstReg.Index = VERT_RESULT_COL0; - p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[ic].SrcReg[0].Index = VERT_ATTRIB_COLOR0; - ic++; - } - - /* END; */ - p->Instructions[ic].Opcode = OPCODE_END; - ic++; - - assert(ic == p->NumInstructions); + if (!st->drawpix.vert_shaders[passColor]) { + struct ureg_program *ureg = + ureg_create( TGSI_PROCESSOR_VERTEX ); + + if (ureg == NULL) + return NULL; + + /* MOV result.pos, vertex.pos; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), + ureg_DECL_vs_input( ureg, 0 )); + + /* MOV result.texcoord0, vertex.texcoord0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), + ureg_DECL_vs_input( ureg, 1 )); + + if (passColor) { + /* MOV result.color0, vertex.color0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), + ureg_DECL_vs_input( ureg, 2 )); + } - p->InputsRead = VERT_BIT_POS | VERT_BIT_TEX0; - p->OutputsWritten = ((1 << VERT_RESULT_TEX0) | - (1 << VERT_RESULT_HPOS)); - if (passColor) { - p->InputsRead |= VERT_BIT_COLOR0; - p->OutputsWritten |= (1 << VERT_RESULT_COL0); + ureg_END( ureg ); + + st->drawpix.vert_shaders[passColor] = + ureg_create_shader_and_destroy( ureg, st->pipe ); } - stvp = (struct st_vertex_program *) p; - st_translate_vertex_program(st, stvp, NULL, NULL, NULL); - - st->drawpix.vert_shaders[passColor] = stvp; - - return stvp; + return st->drawpix.vert_shaders[passColor]; } @@ -539,8 +503,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, struct pipe_texture *pt, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp, + void *driver_vp, + void *driver_fp, const GLfloat *color, GLboolean invertTex) { @@ -575,10 +539,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - cso_set_fragment_shader_handle(cso, stfp->driver_shader); + cso_set_fragment_shader_handle(cso, driver_fp); /* vertex shader state: position + texcoord pass-through */ - cso_set_vertex_shader_handle(cso, stvp->driver_shader); + cso_set_vertex_shader_handle(cso, driver_vp); /* texture sampling state: */ @@ -621,10 +585,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, struct pipe_texture *textures[2]; textures[0] = pt; textures[1] = st->pixel_xfer.pixelmap_texture; - pipe->set_sampler_textures(pipe, 2, textures); + pipe->set_fragment_sampler_textures(pipe, 2, textures); } else { - pipe->set_sampler_textures(pipe, 1, &pt); + pipe->set_fragment_sampler_textures(pipe, 1, &pt); } /* Compute window coords (y=0=bottom) with pixel zoom. @@ -637,8 +601,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, y1 = y + height * ctx->Pixel.ZoomY; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - (GLfloat) width / pt->width[0], - (GLfloat) height / pt->height[0]); + (GLfloat) width / pt->width0, + (GLfloat) height / pt->height0); /* restore state */ cso_restore_rasterizer(cso); @@ -806,7 +770,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { struct st_fragment_program *stfp; - struct st_vertex_program *stvp; + void *driver_vp; struct st_context *st = st_context(ctx); struct pipe_surface *ps; const GLfloat *color; @@ -826,13 +790,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (format == GL_DEPTH_COMPONENT) { ps = st->state.framebuffer.zsbuf; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); color = ctx->Current.RasterColor; } else { ps = st->state.framebuffer.cbufs[0]; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); color = NULL; } @@ -843,7 +807,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (pt) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_FALSE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_FALSE); pipe_texture_reference(&pt, NULL); } } @@ -960,7 +927,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *rbRead; - struct st_vertex_program *stvp; + void *driver_vp; struct st_fragment_program *stfp; struct pipe_texture *pt; GLfloat *color; @@ -1009,14 +976,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); } else { assert(type == GL_DEPTH); rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); } srcFormat = rbRead->texture->format; @@ -1148,7 +1115,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_TRUE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_TRUE); pipe_texture_reference(&pt, NULL); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 65ce12ccd4..659a6c9193 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -128,9 +128,9 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, template.target = PIPE_TEXTURE_2D; template.format = format; pf_get_block(format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; template.last_level = 0; template.nr_samples = rb->NumSamples; if (pf_is_depth_stencil(format)) { @@ -376,7 +376,7 @@ st_render_texture(GLcontext *ctx, rb->_BaseFormat = texImage->_BaseFormat; /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ - /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/ + /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/ pipe_texture_reference( &strb->texture, pt ); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index b2d5c39a3a..8c276f8128 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -138,24 +138,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } + st_vp_release_varients( st, stvp ); } break; case GL_FRAGMENT_PROGRAM_ARB: @@ -177,8 +160,6 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) _mesa_reference_program(ctx, &prg, NULL); stfp->bitmap_program = NULL; } - - st_free_translated_vertex_programs(st, stfp->vertex_programs); } break; default: @@ -219,8 +200,6 @@ static void st_program_string_notify( GLcontext *ctx, stfp->state.tokens = NULL; } - stfp->param_state = stfp->Base.Base.Parameters->StateFlags; - if (st->fp == stfp) st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; } @@ -229,25 +208,7 @@ static void st_program_string_notify( GLcontext *ctx, stvp->serialNo++; - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - - stvp->param_state = stvp->Base.Base.Parameters->StateFlags; + st_vp_release_varients( st, stvp ); if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 772bb3bb69..103861d6f9 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -243,7 +243,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, GLint row, col, dy, dstStride; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - y = strb->texture->height[0] - y - height; + y = strb->texture->height0 - y - height; } trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index d4630a514f..3a2337802f 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -406,9 +406,9 @@ compress_with_blit(GLcontext * ctx, templ.target = PIPE_TEXTURE_2D; templ.format = st_mesa_format_to_pipe_format(mesa_format); pf_get_block(templ.format, &templ.block); - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; templ.last_level = 0; templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; src_tex = screen->texture_create(screen, &templ); @@ -1761,9 +1761,9 @@ st_finalize_texture(GLcontext *ctx, if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || stObj->pt->format != fmt || stObj->pt->last_level < stObj->lastLevel || - stObj->pt->width[0] != firstImage->base.Width2 || - stObj->pt->height[0] != firstImage->base.Height2 || - stObj->pt->depth[0] != firstImage->base.Depth2 || + stObj->pt->width0 != firstImage->base.Width2 || + stObj->pt->height0 != firstImage->base.Height2 || + stObj->pt->depth0 != firstImage->base.Depth2 || stObj->pt->block.size != blockSize) { pipe_texture_reference(&stObj->pt, NULL); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 18adb35e87..b760728658 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -127,6 +127,8 @@ struct st_context struct st_vertex_program *vp; /**< Currently bound vertex program */ struct st_fragment_program *fp; /**< Currently bound fragment program */ + struct st_vp_varient *vp_varient; + struct gl_texture_object *default_texture; struct { diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index 3009cde9d5..6e699ca552 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -86,7 +86,8 @@ st_print_current(void) } #endif - tgsi_dump( st->vp->state.tokens, 0 ); + if (st->vp->varients) + tgsi_dump( st->vp->varients[0].state.tokens, 0 ); if (st->vp->Base.Base.Parameters) _mesa_print_parameter_list(st->vp->Base.Base.Parameters); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 68bc76b572..e13ae57a0e 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -573,7 +573,7 @@ st_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &ctx->st->vp->state; + vs = &ctx->st->vp_varient->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index b2d682ef64..d793f820bc 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -120,10 +120,10 @@ st_feedback_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &st->vp->state; + vs = &st->vp_varient->state; - if (!st->vp->draw_shader) { - st->vp->draw_shader = draw_create_vertex_shader(draw, vs); + if (!st->vp_varient->draw_shader) { + st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs); } /* @@ -136,7 +136,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_viewport_state(draw, &st->state.viewport); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer); - draw_bind_vertex_shader(draw, st->vp->draw_shader); + draw_bind_vertex_shader(draw, st->vp_varient->draw_shader); set_feedback_vertex_format(ctx); /* loop over TGSI shader inputs to determine vertex buffer diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 57fe72d76a..ef3cbc53ee 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -92,6 +92,10 @@ void st_init_limits(struct st_context *st) = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), MAX_VERTEX_TEXTURE_IMAGE_UNITS); + c->MaxCombinedTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS), + MAX_COMBINED_TEXTURE_IMAGE_UNITS); + c->MaxTextureCoordUnits = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 16ca2771b0..f8068fa12b 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -38,6 +38,7 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "util/u_gen_mipmap.h" +#include "util/u_math.h" #include "cso_cache/cso_cache.h" #include "cso_cache/cso_context.h" @@ -133,14 +134,14 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcData = (ubyte *) screen->transfer_map(screen, srcTrans); dstData = (ubyte *) screen->transfer_map(screen, dstTrans); @@ -149,13 +150,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, dstStride = dstTrans->stride / dstTrans->block.size; _mesa_generate_mipmap_level(target, datatype, comps, - 0 /*border*/, - pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], - srcData, - srcStride, /* stride in texels */ - pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], - dstData, - dstStride); /* stride in texels */ + 0 /*border*/, + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel), + u_minify(pt->depth0, srcLevel), + srcData, + srcStride, /* stride in texels */ + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel), + u_minify(pt->depth0, dstLevel), + dstData, + dstStride); /* stride in texels */ screen->transfer_unmap(screen, srcTrans); screen->transfer_unmap(screen, dstTrans); @@ -232,9 +237,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, oldTex->target, oldTex->format, lastLevel, - oldTex->width[0], - oldTex->height[0], - oldTex->depth[0], + oldTex->width0, + oldTex->height0, + oldTex->depth0, oldTex->tex_usage); /* The texture isn't in a "complete" state yet so set the expected @@ -269,9 +274,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, = _mesa_get_tex_image(ctx, texObj, target, srcLevel); struct gl_texture_image *dstImage; struct st_texture_image *stImage; - uint dstWidth = pt->width[dstLevel]; - uint dstHeight = pt->height[dstLevel]; - uint dstDepth = pt->depth[dstLevel]; + uint dstWidth = u_minify(pt->width0, dstLevel); + uint dstHeight = u_minify(pt->height0, dstLevel); + uint dstDepth = u_minify(pt->depth0, dstLevel); uint border = srcImage->Border; dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 3d6c215819..5e8e61135e 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -676,6 +676,31 @@ emit_inverted_wpos( struct st_translate *t, /** + * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. + * TGSI uses +1 for front, -1 for back. + * This function converts the TGSI value to the GL value. Simply clamping/ + * saturating the value to [0,1] does the job. + */ +static void +emit_face_var( struct st_translate *t, + const struct gl_program *program ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst face_temp = ureg_DECL_temporary( ureg ); + struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; + + /* MOV_SAT face_temp, input[face] + */ + face_temp = ureg_saturate( face_temp ); + ureg_MOV( ureg, face_temp, face_input ); + + /* Use face_temp as face input from here on: + */ + t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); +} + + +/** * Translate Mesa program to TGSI format. * \param program the program to translate * \param numInputs number of input registers used @@ -704,12 +729,10 @@ st_translate_mesa_program( const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ) + const ubyte outputSemanticIndex[] ) { struct st_translate translate, *t; struct ureg_program *ureg; @@ -748,6 +771,10 @@ st_translate_mesa_program( emit_inverted_wpos( t, program ); } + if (program->InputsRead & FRAG_BIT_FACE) { + emit_face_var( t, program ); + } + /* * Declare output attributes. */ diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index c0d1ff59e1..dc0362fe79 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -49,12 +49,10 @@ st_translate_mesa_program( const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], - const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ); + const ubyte outputSemanticIndex[] ); void st_free_tokens(const struct tgsi_token *tokens); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 190b6a5526..d66f45d13e 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -49,6 +49,36 @@ #include "st_mesa_to_tgsi.h" #include "cso_cache/cso_context.h" + /* Clean out any old compilations: + */ +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + + for (vpv = stvp->varients; vpv; ) { + struct st_vp_varient *next = vpv->next; + + if (vpv->driver_shader) + cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); + + if (vpv->draw_shader) + draw_delete_vertex_shader( st->draw, vpv->draw_shader ); + + if (vpv->state.tokens) + st_free_tokens(vpv->state.tokens); + + FREE( vpv ); + + vpv = next; + } + + stvp->varients = NULL; +} + + + /** * Translate a Mesa vertex shader into a TGSI shader. @@ -58,31 +88,13 @@ * \return pointer to cached pipe_shader object. */ void -st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *stvp, - const GLuint outputMapping[], - const ubyte *outputSemanticName, - const ubyte *outputSemanticIndex) +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp) { - struct pipe_context *pipe = st->pipe; - GLuint defaultOutputMapping[VERT_RESULT_MAX]; - GLuint attr, i; - GLuint num_generic = 0; - - ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; - ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - uint vs_num_inputs = 0; - - ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; - ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - uint vs_num_outputs = 0; - - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; + GLuint attr; - /*memset(&vs, 0, sizeof(vs));*/ - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); + stvp->num_inputs = 0; + stvp->num_outputs = 0; if (stvp->Base.IsPositionInvariant) _mesa_insert_mvp_code(st->ctx, &stvp->Base); @@ -93,162 +105,56 @@ st_translate_vertex_program(struct st_context *st, */ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { if (stvp->Base.Base.InputsRead & (1 << attr)) { - const GLuint slot = vs_num_inputs; - - vs_num_inputs++; - - stvp->input_to_index[attr] = slot; - stvp->index_to_input[slot] = attr; - - switch (attr) { - case VERT_ATTRIB_POS: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_WEIGHT: - /* fall-through */ - case VERT_ATTRIB_NORMAL: - /* just label as a generic */ - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR0: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR1: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 1; - break; - case VERT_ATTRIB_FOG: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_POINT_SIZE: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_TEX0: - case VERT_ATTRIB_TEX1: - case VERT_ATTRIB_TEX2: - case VERT_ATTRIB_TEX3: - case VERT_ATTRIB_TEX4: - case VERT_ATTRIB_TEX5: - case VERT_ATTRIB_TEX6: - case VERT_ATTRIB_TEX7: - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - case VERT_ATTRIB_GENERIC0: - case VERT_ATTRIB_GENERIC1: - case VERT_ATTRIB_GENERIC2: - case VERT_ATTRIB_GENERIC3: - case VERT_ATTRIB_GENERIC4: - case VERT_ATTRIB_GENERIC5: - case VERT_ATTRIB_GENERIC6: - case VERT_ATTRIB_GENERIC7: - case VERT_ATTRIB_GENERIC8: - case VERT_ATTRIB_GENERIC9: - case VERT_ATTRIB_GENERIC10: - case VERT_ATTRIB_GENERIC11: - case VERT_ATTRIB_GENERIC12: - case VERT_ATTRIB_GENERIC13: - case VERT_ATTRIB_GENERIC14: - case VERT_ATTRIB_GENERIC15: - assert(attr < VERT_ATTRIB_MAX); - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - default: - assert(0); - } - - input_flags[slot] = stvp->Base.Base.InputFlags[attr]; + stvp->input_to_index[attr] = stvp->num_inputs; + stvp->index_to_input[stvp->num_inputs] = attr; + stvp->num_inputs++; } } -#if 0 - if (outputMapping && outputSemanticName) { - printf("VERT_RESULT written out_slot semantic_name semantic_index\n"); - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - printf(" %-2d %c %3d %2d %2d\n", - attr, - ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '), - outputMapping[attr], - outputSemanticName[attr], - outputSemanticIndex[attr]); - } - } -#endif - - /* initialize output semantics to defaults */ - for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { - assert(i < Elements(vs_output_semantic_name)); - vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[i] = 0; - output_flags[i] = 0x0; - } - - num_generic = 0; - /* - * Determine number of outputs, the (default) output register - * mapping and the semantic information for each output. + /* Compute mapping of vertex program outputs to slots. */ for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (stvp->Base.Base.OutputsWritten & (1 << attr)) { - GLuint slot; - - /* XXX - * Pass in the fragment program's input's semantic info. - * Use the generic semantic indexes from there, instead of - * guessing below. - */ - - if (outputMapping) { - slot = outputMapping[attr]; - assert(slot != ~0); - } - else { - slot = vs_num_outputs; - vs_num_outputs++; - defaultOutputMapping[attr] = slot; - } + if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) { + stvp->result_to_output[attr] = ~0; + } + else { + unsigned slot = stvp->num_outputs++; + + stvp->result_to_output[attr] = slot; switch (attr) { case VERT_RESULT_HPOS: - assert(slot == 0); - vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_BFC0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_BFC1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_FOGC: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_PSIZ: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_EDGE: assert(0); break; + case VERT_RESULT_TEX0: case VERT_RESULT_TEX1: case VERT_RESULT_TEX2: @@ -257,92 +163,50 @@ st_translate_vertex_program(struct st_context *st, case VERT_RESULT_TEX5: case VERT_RESULT_TEX6: case VERT_RESULT_TEX7: - /* fall-through */ + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0; + break; + case VERT_RESULT_VAR0: - /* fall-through */ default: - assert(slot < Elements(vs_output_semantic_name)); - if (outputSemanticName) { - /* use provided semantic into */ - assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT); - vs_output_semantic_name[slot] = outputSemanticName[attr]; - vs_output_semantic_index[slot] = outputSemanticIndex[attr]; - } - else { - /* use default semantic info */ - vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[slot] = num_generic++; - } + assert(attr < VERT_RESULT_MAX); + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 - + FRAG_ATTRIB_TEX0 + + attr - + VERT_RESULT_VAR0); + break; } - - assert(slot < Elements(output_flags)); - output_flags[slot] = stvp->Base.Base.OutputFlags[attr]; } } +} - if (outputMapping) { - /* find max output slot referenced to compute vs_num_outputs */ - GLuint maxSlot = 0; - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) - maxSlot = outputMapping[attr]; - } - vs_num_outputs = maxSlot + 1; - } - else { - outputMapping = defaultOutputMapping; - } - -#if 0 /* debug */ - { - GLuint i; - printf("outputMapping? %d\n", outputMapping ? 1 : 0); - if (outputMapping) { - printf("attr -> slot\n"); - for (i = 0; i < 16; i++) { - printf(" %2d %3d\n", i, outputMapping[i]); - } - } - printf("slot sem_name sem_index\n"); - for (i = 0; i < vs_num_outputs; i++) { - printf(" %2d %d %d\n", - i, - vs_output_semantic_name[i], - vs_output_semantic_index[i]); - } - } -#endif - /* free old shader state, if any */ - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } +struct st_vp_varient * +st_translate_vertex_program(struct st_context *st, + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key) +{ + struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient); + struct pipe_context *pipe = st->pipe; - stvp->state.tokens = + vpv->state.tokens = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_VERTEX, &stvp->Base.Base, /* inputs */ - vs_num_inputs, + stvp->num_inputs, stvp->input_to_index, - vs_input_semantic_name, - vs_input_semantic_index, + NULL, /* input semantic name */ + NULL, /* input semantic index */ NULL, - input_flags, /* outputs */ - vs_num_outputs, - outputMapping, - vs_output_semantic_name, - vs_output_semantic_index, - output_flags ); + stvp->num_outputs, + stvp->result_to_output, + stvp->output_semantic_name, + stvp->output_semantic_index ); - stvp->num_inputs = vs_num_inputs; - stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state); + vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { _mesa_print_program(&stvp->Base.Base); @@ -350,9 +214,11 @@ st_translate_vertex_program(struct st_context *st, } if (ST_DEBUG & DEBUG_TGSI) { - tgsi_dump( stvp->state.tokens, 0 ); + tgsi_dump( vpv->state.tokens, 0 ); debug_printf("\n"); } + + return vpv; } @@ -375,7 +241,6 @@ st_translate_fragment_program(struct st_context *st, GLuint attr; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; GLuint vslot = 0; - GLuint num_generic = 0; uint fs_num_inputs = 0; @@ -383,13 +248,6 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; - - /*memset(&fs, 0, sizeof(fs));*/ - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); - /* which vertex output goes to the first fragment input: */ if (inputsRead & FRAG_BIT_WPOS) vslot = 0; @@ -432,14 +290,25 @@ st_translate_fragment_program(struct st_context *st, break; case FRAG_ATTRIB_FACE: stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE; - stfp->input_semantic_index[slot] = num_generic++; + stfp->input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; - case FRAG_ATTRIB_PNTC: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + + /* In most cases, there is nothing special about these + * inputs, so adopt a convention to use the generic + * semantic name and the mesa FRAG_ATTRIB_ number as the + * index. + * + * All that is required is that the vertex shader labels + * its own outputs similarly, and that the vertex shader + * generates at least every output required by the + * fragment shader plus fixed-function hardware (such as + * BFC). + * + * There is no requirement that semantic indexes start at + * zero or be restricted to a particular range -- nobody + * should be building tables based on semantic index. + */ case FRAG_ATTRIB_TEX0: case FRAG_ATTRIB_TEX1: case FRAG_ATTRIB_TEX2: @@ -448,19 +317,18 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + case FRAG_ATTRIB_PNTC: case FRAG_ATTRIB_VAR0: - /* fall-through */ default: + /* Actually, let's try and zero-base this just for + * readability of the generated TGSI. + */ + assert(attr >= FRAG_ATTRIB_TEX0); + stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + break; } - - input_flags[slot] = stfp->Base.Base.InputFlags[attr]; } } @@ -498,8 +366,6 @@ st_translate_fragment_program(struct st_context *st, break; } - output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr]; - fs_num_outputs++; } } @@ -518,13 +384,11 @@ st_translate_fragment_program(struct st_context *st, stfp->input_semantic_name, stfp->input_semantic_index, interpMode, - input_flags, /* outputs */ fs_num_outputs, outputMapping, fs_output_semantic_name, - fs_output_semantic_index, - output_flags ); + fs_output_semantic_index ); stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index e2e5eddef2..88aadbd751 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -64,41 +64,70 @@ struct st_fragment_program struct pipe_shader_state state; void *driver_shader; - GLuint param_state; - - /** List of vertex programs which have been translated such that their - * outputs match this fragment program's inputs. - */ - struct translated_vertex_program *vertex_programs; - /** Program prefixed with glBitmap prologue */ struct st_fragment_program *bitmap_program; uint bitmap_sampler; }; + +struct st_vp_varient_key +{ + char dummy; /* currently unused */ +}; + + +/** + * This represents a vertex program, especially translated to match + * the inputs of a particular fragment shader. + */ +struct st_vp_varient +{ + /* Parameters which generated this translated version of a vertex + * shader: + */ + struct st_vp_varient_key key; + + /** TGSI tokens -- why? + */ + struct pipe_shader_state state; + + /** Driver's compiled shader */ + void *driver_shader; + + /** For using our private draw module (glRasterPos) */ + struct draw_vertex_shader *draw_shader; + + /** Next in linked list */ + struct st_vp_varient *next; +}; + + + + /** * Derived from Mesa gl_fragment_program: */ struct st_vertex_program { struct gl_vertex_program Base; /**< The Mesa vertex program */ - GLuint serialNo; + GLuint serialNo, lastSerialNo; /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */ GLuint input_to_index[VERT_ATTRIB_MAX]; /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */ GLuint index_to_input[PIPE_MAX_SHADER_INPUTS]; - GLuint num_inputs; - struct pipe_shader_state state; - void *driver_shader; + /** Maps VERT_RESULT_x to slot */ + GLuint result_to_output[VERT_RESULT_MAX]; + ubyte output_semantic_name[VERT_RESULT_MAX]; + ubyte output_semantic_index[VERT_RESULT_MAX]; + GLuint num_outputs; - /** For using our private draw module (glRasterPos) */ - struct draw_vertex_shader *draw_shader; - - GLuint param_state; + /** List of translated varients of this vertex program. + */ + struct st_vp_varient *varients; }; @@ -143,13 +172,21 @@ st_translate_fragment_program(struct st_context *st, const GLuint inputMapping[]); +/* Called after program string change, discard all previous + * compilation results. + */ extern void +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp); + +extern struct st_vp_varient * st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *vp, - const GLuint vert_output_to_slot[], - const ubyte *fs_input_semantic_name, - const ubyte *fs_input_semantic_index); + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key); +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ); extern void st_print_shaders(GLcontext *ctx); diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 10f1351283..dbccee86c1 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -44,6 +44,7 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "util/u_rect.h" +#include "util/u_math.h" #define DBG if(0) printf @@ -100,9 +101,9 @@ st_texture_create(struct st_context *st, pt.target = target; pt.format = format; pt.last_level = last_level; - pt.width[0] = width0; - pt.height[0] = height0; - pt.depth[0] = depth0; + pt.width0 = width0; + pt.height0 = height0; + pt.depth0 = depth0; pf_get_block(format, &pt.block); pt.tex_usage = usage; @@ -135,9 +136,9 @@ st_texture_match_image(const struct pipe_texture *pt, /* Test if this image's size matches what's expected in the * established texture. */ - if (image->Width != pt->width[level] || - image->Height != pt->height[level] || - image->Depth != pt->depth[level]) + if (image->Width != u_minify(pt->width0, level) || + image->Height != u_minify(pt->height0, level) || + image->Depth != u_minify(pt->depth0, level)) return GL_FALSE; return GL_TRUE; @@ -265,7 +266,7 @@ st_texture_image_data(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - GLuint depth = dst->depth[level]; + GLuint depth = u_minify(dst->depth0, level); GLuint i; const GLubyte *srcUB = src; struct pipe_transfer *dst_transfer; @@ -275,15 +276,16 @@ st_texture_image_data(struct st_context *st, for (i = 0; i < depth; i++) { dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, - dst->width[level], - dst->height[level]); + u_minify(dst->width0, level), + u_minify(dst->height0, level)); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ - dst->width[level], dst->height[level]); /* width, height */ + u_minify(dst->width0, level), + u_minify(dst->height0, level)); /* width, height */ screen->tex_transfer_destroy(dst_transfer); @@ -301,9 +303,9 @@ st_texture_image_copy(struct pipe_context *pipe, GLuint face) { struct pipe_screen *screen = pipe->screen; - GLuint width = dst->width[dstLevel]; - GLuint height = dst->height[dstLevel]; - GLuint depth = dst->depth[dstLevel]; + GLuint width = u_minify(dst->width0, dstLevel); + GLuint height = u_minify(dst->height0, dstLevel); + GLuint depth = u_minify(dst->depth0, dstLevel); struct pipe_surface *src_surface; struct pipe_surface *dst_surface; GLuint i; @@ -313,13 +315,13 @@ st_texture_image_copy(struct pipe_context *pipe, /* find src texture level of needed size */ for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) { - if (src->width[srcLevel] == width && - src->height[srcLevel] == height) { + if (u_minify(src->width0, srcLevel) == width && + u_minify(src->height0, srcLevel) == height) { break; } } - assert(src->width[srcLevel] == width); - assert(src->height[srcLevel] == height); + assert(u_minify(src->width0, srcLevel) == width); + assert(u_minify(src->height0, srcLevel) == height); #if 0 { |