From 28066ed012b51f2171866669a2972bc7ee293565 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 4 Jul 2009 12:56:31 +0200 Subject: r300: update state parameters only once per rendering operation --- src/mesa/drivers/dri/r300/r300_state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c0eda977db..67bd6ec33b 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1093,7 +1093,7 @@ r300FetchStateParameter(GLcontext * ctx, * Update R300's own internal state parameters. * For now just STATE_R300_WINDOW_DIMENSION */ -void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) +static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) { struct r300_fragment_program *fp; struct gl_program_parameter_list *paramList; @@ -1111,6 +1111,8 @@ void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) if (!paramList) return; + _mesa_load_state_parameters(ctx, paramList); + for (i = 0; i < paramList->NumParameters; i++) { if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { r300FetchStateParameter(ctx, @@ -2323,8 +2325,6 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) R300_STATECHANGE(r300, cb); } - r300UpdateStateParameters(ctx, new_state); - r300->radeon.NewGLState |= new_state; } -- cgit v1.2.3 From 7829b7a1b85dd8e6c31189e7f3dec91d71d134c3 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 4 Jul 2009 13:26:49 +0200 Subject: r300: cache translated fragment programs --- src/mesa/drivers/dri/r300/r300_context.h | 10 +- src/mesa/drivers/dri/r300/r300_fragprog_common.c | 169 ++++++++++++----------- src/mesa/drivers/dri/r300/r300_fragprog_common.h | 6 +- src/mesa/drivers/dri/r300/r300_shader.c | 51 ++++++- src/mesa/drivers/dri/r300/r300_state.c | 59 ++++---- src/mesa/drivers/dri/r300/r300_swtcl.c | 2 +- 6 files changed, 173 insertions(+), 124 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 026c33c67c..fc436e1100 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -546,7 +546,7 @@ struct r500_fragment_program_code { * to render with that program. */ struct r300_fragment_program { - struct gl_fragment_program Base; + struct gl_program *Base; GLboolean translated; GLboolean error; @@ -559,6 +559,13 @@ struct r300_fragment_program { GLboolean writes_depth; GLuint optimization; + + struct r300_fragment_program *next; +}; + +struct r300_fragment_program_cont { + struct gl_fragment_program Base; + struct r300_fragment_program *progs; }; struct r300_fragment_program_compiler { @@ -633,6 +640,7 @@ struct r300_context { struct r300_hw_state hw; struct r300_vertex_program *selected_vp; + struct r300_fragment_program *selected_fp; /* Vertex buffers */ diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index 1644e6f42a..b25cf24007 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -67,7 +67,7 @@ static void nqssadce_init(struct nqssadce_state* s) */ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) { - GLuint InputsRead = compiler->fp->Base.Base.InputsRead; + GLuint InputsRead = compiler->fp->Base->InputsRead; if (!(InputsRead & FRAG_BIT_WPOS)) return; @@ -168,7 +168,7 @@ static GLuint build_func(GLuint comparefunc) */ static void build_state( r300ContextPtr r300, - struct r300_fragment_program *fp, + struct gl_fragment_program *fp, struct r300_fragment_program_external_state *state) { int unit; @@ -176,7 +176,7 @@ static void build_state( _mesa_bzero(state, sizeof(*state)); for(unit = 0; unit < 16; ++unit) { - if (fp->Base.Base.ShadowSamplers & (1 << unit)) { + if (fp->Base.ShadowSamplers & (1 << unit)) { struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); @@ -185,96 +185,107 @@ static void build_state( } } -void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp) +void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp) { r300ContextPtr r300 = R300_CONTEXT(ctx); - struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp; - struct r300_fragment_program_external_state state; + struct r300_fragment_program_compiler compiler; + + compiler.r300 = r300; + compiler.fp = fp; + compiler.code = &fp->code; + compiler.program = fp->Base; + + if (RADEON_DEBUG & DEBUG_PIXEL) { + fflush(stdout); + _mesa_printf("Fragment Program: Initial program:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - build_state(r300, r300_fp, &state); - if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) { - /* TODO: cache compiled programs */ - r300_fp->translated = GL_FALSE; - _mesa_memcpy(&r300_fp->state, &state, sizeof(state)); + insert_WPOS_trailer(&compiler); + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_program_transformation transformations[] = { + { &r500_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformDeriv, 0 }, + { &radeonTransformTrigScale, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 4, transformations); + } else { + struct radeon_program_transformation transformations[] = { + { &r300_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformTrigSimple, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 3, transformations); } - if (!r300_fp->translated) { - struct r300_fragment_program_compiler compiler; + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Fragment Program: After native rewrite:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - compiler.r300 = r300; - compiler.fp = r300_fp; - compiler.code = &r300_fp->code; - compiler.program = _mesa_clone_program(ctx, &fp->Base); + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r500FPIsNativeSwizzle, + .BuildSwizzle = &r500FPBuildSwizzle, + .RewriteDepthOut = GL_TRUE + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } else { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r300FPIsNativeSwizzle, + .BuildSwizzle = &r300FPBuildSwizzle, + .RewriteDepthOut = GL_TRUE + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } - if (RADEON_DEBUG & DEBUG_PIXEL) { - fflush(stdout); - _mesa_printf("Fragment Program: Initial program:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); - } + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Compiler: after NqSSA-DCE:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - insert_WPOS_trailer(&compiler); - - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - struct radeon_program_transformation transformations[] = { - { &r500_transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformDeriv, 0 }, - { &radeonTransformTrigScale, 0 } - }; - radeonLocalTransform(ctx, compiler.program, 4, transformations); - } else { - struct radeon_program_transformation transformations[] = { - { &r300_transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformTrigSimple, 0 } - }; - radeonLocalTransform(ctx, compiler.program, 3, transformations); - } + if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler)) + fp->error = GL_TRUE; - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: After native rewrite:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); - } + fp->translated = GL_TRUE; - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r500FPIsNativeSwizzle, - .BuildSwizzle = &r500FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(ctx, compiler.program, &nqssadce); - } else { - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r300FPIsNativeSwizzle, - .BuildSwizzle = &r300FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(ctx, compiler.program, &nqssadce); - } + if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) + r300->vtbl.FragmentProgramDump(&fp->code); +} - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after NqSSA-DCE:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); - } +struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program_cont *fp_list; + struct r300_fragment_program *fp; + struct r300_fragment_program_external_state state; + + fp_list = (struct r300_fragment_program_cont *)ctx->FragmentProgram._Current; + build_state(r300, ctx->FragmentProgram._Current, &state); - if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler)) - r300_fp->error = GL_TRUE; + fp = fp_list->progs; + while (fp) { + if (_mesa_memcmp(&fp->state, &state, sizeof(state)) == 0) { + return r300->selected_fp = fp; + } + fp = fp->next; + } - /* Subtle: Rescue any parameters that have been added during transformations */ - _mesa_free_parameter_list(fp->Base.Parameters); - fp->Base.Parameters = compiler.program->Parameters; - compiler.program->Parameters = 0; + fp = _mesa_calloc(sizeof(struct r300_fragment_program)); - _mesa_reference_program(ctx, &compiler.program, NULL); + fp->state = state; + fp->translated = GL_FALSE; + fp->Base = _mesa_clone_program(ctx, &ctx->FragmentProgram._Current->Base); - r300_fp->translated = GL_TRUE; + fp->next = fp_list->progs; + fp_list->progs = fp; - if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) - r300->vtbl.FragmentProgramDump(&r300_fp->code); - } + return r300->selected_fp = fp; } diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.h b/src/mesa/drivers/dri/r300/r300_fragprog_common.h index 85ea86fecb..5e103ee408 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.h @@ -30,6 +30,10 @@ #include "main/mtypes.h" -extern void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp); +#include "r300_context.h" + +extern void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp); + +struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx); #endif diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 0133b83796..c9a429943a 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -32,11 +32,34 @@ #include "r300_context.h" #include "r300_fragprog_common.h" +static void freeFragProgCache(GLcontext *ctx, struct r300_fragment_program_cont *cache) +{ + struct r300_fragment_program *tmp, *fp = cache->progs; + + while (fp) { + tmp = fp->next; + _mesa_reference_program(ctx, &fp->Base, NULL); + _mesa_free(fp); + fp = tmp; + } +} + +static void freeVertProgCache(GLcontext *ctx, struct r300_vertex_program_cont *cache) +{ + struct r300_vertex_program *tmp, *vp = cache->progs; + + while (vp) { + tmp = vp->next; + _mesa_free(vp); + vp = tmp; + } +} + static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, GLuint id) { struct r300_vertex_program_cont *vp; - struct r300_fragment_program *fp; + struct r300_fragment_program_cont *fp; switch (target) { case GL_VERTEX_STATE_PROGRAM_NV: @@ -47,7 +70,7 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, case GL_FRAGMENT_PROGRAM_NV: case GL_FRAGMENT_PROGRAM_ARB: - fp = CALLOC_STRUCT(r300_fragment_program); + fp = CALLOC_STRUCT(r300_fragment_program_cont); return _mesa_init_fragment_program(ctx, &fp->Base, target, id); default: @@ -59,21 +82,35 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) { + struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; + struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + freeVertProgCache(ctx, vp); + break; + case GL_FRAGMENT_PROGRAM_ARB: + freeFragProgCache(ctx, fp); + break; + } + _mesa_delete_program(ctx, prog); } static void r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { - struct r300_vertex_program_cont *vp = (void *)prog; - struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog; + struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; + struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog; switch (target) { case GL_VERTEX_PROGRAM_ARB: + freeVertProgCache(ctx, vp); vp->progs = NULL; break; case GL_FRAGMENT_PROGRAM_ARB: - r300_fp->translated = GL_FALSE; + freeFragProgCache(ctx, fp); + fp->progs = NULL; break; } @@ -85,9 +122,9 @@ static GLboolean r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) { if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct r300_fragment_program *fp = (struct r300_fragment_program *)prog; + struct r300_fragment_program *fp = r300SelectFragmentShader(ctx); if (!fp->translated) - r300TranslateFragmentShader(ctx, &fp->Base); + r300TranslateFragmentShader(ctx, fp); return !fp->error; } else diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 67bd6ec33b..e0996383eb 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -452,9 +452,9 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state) static GLboolean current_fragment_program_writes_depth(GLcontext* ctx) { - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + r300ContextPtr r300 = R300_CONTEXT(ctx); - return (fp && fp->writes_depth); + return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth; } static void r300SetEarlyZState(GLcontext * ctx) @@ -1095,18 +1095,17 @@ r300FetchStateParameter(GLcontext * ctx, */ static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) { - struct r300_fragment_program *fp; + r300ContextPtr rmesa = R300_CONTEXT(ctx); struct gl_program_parameter_list *paramList; GLuint i; if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))) return; - fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current; - if (!fp) + if (!ctx->FragmentProgram._Current || !rmesa->selected_fp) return; - paramList = fp->Base.Base.Parameters; + paramList = rmesa->selected_fp->Base->Parameters; if (!paramList) return; @@ -1227,8 +1226,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - struct r300_fragment_program_code *code = &fp->code.r300; + struct r300_fragment_program_code *code = &r300->selected_fp->code.r300; R300_STATECHANGE(r300, fpt); @@ -1268,9 +1266,9 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { + r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - struct r500_fragment_program_code *code = &fp->code.r500; + struct r500_fragment_program_code *code = &r300->selected_fp->code.r500; /* find all the texture instructions and relocate the texture units */ for (i = 0; i < code->inst_end + 1; i++) { @@ -1318,8 +1316,6 @@ static void r300SetupTextures(GLcontext * ctx) int hw_tmu = 0; int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */ int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, }; - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; R300_STATECHANGE(r300, txe); R300_STATECHANGE(r300, tex.filter); @@ -1422,7 +1418,7 @@ static void r300SetupTextures(GLcontext * ctx) cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { - if (fp->Base.UsesKill && last_hw_tmu < 0) { + if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) { // The KILL operation requires the first texture unit // to be enabled. r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; @@ -1464,7 +1460,7 @@ static void r300SetupRSUnit(GLcontext * ctx) else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + InputsRead = r300->selected_fp->Base->InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -1581,7 +1577,7 @@ static void r500SetupRSUnit(GLcontext * ctx) else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + InputsRead = r300->selected_fp->Base->InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -2038,21 +2034,18 @@ static void r300ResetHwState(r300ContextPtr r300) void r300UpdateShaders(r300ContextPtr rmesa) { - GLcontext *ctx; + GLcontext *ctx = rmesa->radeon.glCtx; struct r300_fragment_program *fp; - int i; - - ctx = rmesa->radeon.glCtx; - fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; /* should only happenen once, just after context is created */ /* TODO: shouldn't we fallback to sw here? */ - if (!fp) { + if (!ctx->FragmentProgram._Current) { _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); return; } if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) { + int i; for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i]; @@ -2071,8 +2064,9 @@ void r300UpdateShaders(r300ContextPtr rmesa) r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error); } - if (!fp->translated || rmesa->radeon.NewGLState) - r300TranslateFragmentShader(ctx, ctx->FragmentProgram._Current); + fp = r300SelectFragmentShader(ctx); + if (!fp->translated) + r300TranslateFragmentShader(ctx, fp); r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); @@ -2104,7 +2098,7 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, static void r300SetupPixelShader(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r300_fragment_program *fp = rmesa->selected_fp; struct r300_fragment_program_code *code; int i, k; @@ -2150,8 +2144,7 @@ static void r300SetupPixelShader(GLcontext *ctx) R300_STATECHANGE(rmesa, fpp); rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); for (i = 0; i < code->const_nr; i++) { - const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->Base.Base, code->constant[i]); + const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]); @@ -2176,7 +2169,7 @@ static void r300SetupPixelShader(GLcontext *ctx) static void r500SetupPixelShader(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r300_fragment_program *fp = rmesa->selected_fp; int i; struct r500_fragment_program_code *code; @@ -2212,8 +2205,7 @@ static void r500SetupPixelShader(GLcontext *ctx) R300_STATECHANGE(rmesa, r500fp_const); for (i = 0; i < code->const_nr; i++) { - const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->Base.Base, code->constant[i]); + const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]); @@ -2276,20 +2268,17 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten) rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, rmesa->selected_fp->Base->InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, rmesa->selected_fp->Base->InputsRead); } void r300UpdateShaderStates(r300ContextPtr rmesa) { GLcontext *ctx; ctx = rmesa->radeon.glCtx; - struct r300_fragment_program *r300_fp; - - r300_fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; /* should only happenen once, just after context is created */ - if (!r300_fp) + if (!ctx->FragmentProgram._Current) return; r300SetEarlyZState(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index ce4179208e..db4ccce6f1 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -76,7 +76,7 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_ GLuint InputsRead = 0; GLuint OutputsWritten = 0; int num_attrs = 0; - GLuint fp_reads = ctx->FragmentProgram._Current->Base.InputsRead; + GLuint fp_reads = rmesa->selected_fp->Base->InputsRead; struct vertex_attribute *attrs = rmesa->vbuf.attribs; rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0; -- cgit v1.2.3 From 37c319f62f59d7750dd172034e43dfd489f572cc Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Fri, 3 Jul 2009 20:14:24 +0200 Subject: r300: implement proper IsProgramNative check for vertex programs --- src/mesa/drivers/dri/r300/r300_context.h | 1 - src/mesa/drivers/dri/r300/r300_shader.c | 9 +++++++-- src/mesa/drivers/dri/r300/r300_state.c | 8 ++++++-- src/mesa/drivers/dri/r300/r300_vertprog.c | 13 ++++++------- src/mesa/drivers/dri/r300/r300_vertprog.h | 4 ++++ 5 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 30b6e75039..44211a45b3 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -673,7 +673,6 @@ extern GLboolean r300CreateContext(const __GLcontextModes * glVisual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); -extern void r300SelectVertexShader(r300ContextPtr r300); extern void r300InitShaderFuncs(struct dd_function_table *functions); extern void r300InitShaderFunctions(r300ContextPtr r300); diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 7206379ea0..854eb5d80a 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -128,8 +128,13 @@ r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) r300TranslateFragmentShader(ctx, fp); return !fp->error; - } else - return GL_TRUE; + } else { + struct r300_vertex_program *vp = r300SelectVertexShader(ctx); + if (!vp->translated) + r300TranslateVertexShader(vp); + + return !vp->error; + } } void r300InitShaderFuncs(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e0996383eb..8c228ab5e7 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2045,6 +2045,7 @@ void r300UpdateShaders(r300ContextPtr rmesa) } if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) { + struct r300_vertex_program *vp; int i; for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { rmesa->temp_attrib[i] = @@ -2060,8 +2061,11 @@ void r300UpdateShaders(r300ContextPtr rmesa) rmesa->temp_attrib[i]; } - r300SelectVertexShader(rmesa); - r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error); + vp = r300SelectVertexShader(ctx); + if (!vp->translated) + r300TranslateVertexShader(vp); + + r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error); } fp = r300SelectFragmentShader(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 25c42814ec..326183bda4 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -1027,7 +1027,7 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) } } -static void r300TranslateVertexShader(struct r300_vertex_program *vp) +void r300TranslateVertexShader(struct r300_vertex_program *vp) { struct prog_instruction *vpi = vp->Base->Base.Instructions; int i; @@ -1524,7 +1524,6 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, assert(prog->NumInstructions); vp->num_temporaries = prog->NumTemporaries; - r300TranslateVertexShader(vp); return vp; } @@ -1538,9 +1537,9 @@ static void add_outputs(struct r300_vertex_program_key *key, GLint vert) key->OutputsAdded |= 1 << vert; } -void r300SelectVertexShader(r300ContextPtr r300) +struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx) { - GLcontext *ctx = ctx = r300->radeon.glCtx; + r300ContextPtr r300 = R300_CONTEXT(ctx); GLuint InputsRead; struct r300_vertex_program_key wanted_key = { 0 }; GLint i; @@ -1596,14 +1595,14 @@ void r300SelectVertexShader(r300ContextPtr r300) for (vp = vpc->progs; vp; vp = vp->next) if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { - r300->selected_vp = vp; - return; + return r300->selected_vp = vp; } vp = build_program(ctx, &wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; - r300->selected_vp = vp; + + return r300->selected_vp = vp; } #define bump_vpu_count(ptr, new_count) do { \ diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h index b552e3fb1b..2dab11c337 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.h +++ b/src/mesa/drivers/dri/r300/r300_vertprog.h @@ -34,4 +34,8 @@ void r300SetupVertexProgram(r300ContextPtr rmesa); +struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx); + +void r300TranslateVertexShader(struct r300_vertex_program *vp); + #endif -- cgit v1.2.3 From 7360f83364b407e949529eeca9f8c421d2da3ded Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 4 Jul 2009 13:17:35 +0200 Subject: r300: move fragment program selection before vertex program selection Prepare for wpos and fogc handling rewrite. --- src/mesa/drivers/dri/r300/r300_state.c | 44 +++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 8c228ab5e7..344f021acf 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2035,7 +2035,6 @@ static void r300ResetHwState(r300ContextPtr r300) void r300UpdateShaders(r300ContextPtr rmesa) { GLcontext *ctx = rmesa->radeon.glCtx; - struct r300_fragment_program *fp; /* should only happenen once, just after context is created */ /* TODO: shouldn't we fallback to sw here? */ @@ -2044,21 +2043,34 @@ void r300UpdateShaders(r300ContextPtr rmesa) return; } - if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) { + { + struct r300_fragment_program *fp; + + fp = r300SelectFragmentShader(ctx); + if (!fp->translated) + r300TranslateFragmentShader(ctx, fp); + + r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); + } + + if (rmesa->options.hw_tcl_enabled) { struct r300_vertex_program *vp; - int i; - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - rmesa->temp_attrib[i] = - TNL_CONTEXT(ctx)->vb.AttribPtr[i]; - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - &rmesa->dummy_attrib[i]; - } - _tnl_UpdateFixedFunctionProgram(ctx); + if (rmesa->radeon.NewGLState) { + int i; + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + rmesa->temp_attrib[i] = + TNL_CONTEXT(ctx)->vb.AttribPtr[i]; + TNL_CONTEXT(ctx)->vb.AttribPtr[i] = + &rmesa->dummy_attrib[i]; + } + + _tnl_UpdateFixedFunctionProgram(ctx); - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - rmesa->temp_attrib[i]; + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + TNL_CONTEXT(ctx)->vb.AttribPtr[i] = + rmesa->temp_attrib[i]; + } } vp = r300SelectVertexShader(ctx); @@ -2068,12 +2080,6 @@ void r300UpdateShaders(r300ContextPtr rmesa) r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error); } - fp = r300SelectFragmentShader(ctx); - if (!fp->translated) - r300TranslateFragmentShader(ctx, fp); - - r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); - r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); rmesa->radeon.NewGLState = 0; } -- cgit v1.2.3 From df5fe747fa08f63b949ba0fd6628060831b562ec Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 5 Jul 2009 02:03:32 +0200 Subject: r300: bind vertex program to fragment program --- src/mesa/drivers/dri/r300/r300_context.h | 4 +- src/mesa/drivers/dri/r300/r300_draw.c | 4 +- src/mesa/drivers/dri/r300/r300_state.c | 4 +- src/mesa/drivers/dri/r300/r300_vertprog.c | 205 ++++++++++++++---------------- 4 files changed, 103 insertions(+), 114 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 44211a45b3..6f99e49050 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -409,9 +409,7 @@ struct r300_vertex_program { struct r300_vertex_program *next; struct r300_vertex_program_key { - GLuint InputsRead; - GLuint OutputsWritten; - GLuint OutputsAdded; + GLuint FpReads; } key; struct r300_vertex_shader_hw_code { diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 4e8b62f186..5420293b91 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -332,7 +332,7 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar { int i, tmp; - tmp = r300->selected_vp->key.InputsRead; + tmp = r300->selected_vp->Base->Base.InputsRead; i = 0; vbuf->num_attribs = 0; while (tmp) { @@ -428,7 +428,7 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, if (r300->fallback) return GL_FALSE; - r300SetupVAP(ctx, r300->selected_vp->key.InputsRead, r300->selected_vp->key.OutputsWritten); + r300SetupVAP(ctx, r300->selected_vp->Base->Base.InputsRead, r300->selected_vp->Base->Base.OutputsWritten); r300UpdateShaderStates(r300); diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 344f021acf..0f3198e792 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1456,7 +1456,7 @@ static void r300SetupRSUnit(GLcontext * ctx) hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten; else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); @@ -1573,7 +1573,7 @@ static void r500SetupRSUnit(GLcontext * ctx) hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten; else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 326183bda4..0b04830350 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -961,10 +961,14 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) { int i; int cur_reg; + GLuint OutputsWritten, InputsRead; + + OutputsWritten = vp->Base->Base.OutputsWritten; + InputsRead = vp->Base->Base.InputsRead; cur_reg = -1; for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (vp->key.InputsRead & (1 << i)) + if (InputsRead & (1 << i)) vp->inputs[i] = ++cur_reg; else vp->inputs[i] = -1; @@ -974,13 +978,13 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) for (i = 0; i < VERT_RESULT_MAX; i++) vp->outputs[i] = -1; - assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)); + assert(OutputsWritten & (1 << VERT_RESULT_HPOS)); - if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) { + if (OutputsWritten & (1 << VERT_RESULT_HPOS)) { vp->outputs[VERT_RESULT_HPOS] = cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) { + if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) { vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; } @@ -990,39 +994,39 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) * pretend it does by skipping output index reg so the colors * get written into appropriate output vectors. */ - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) { + if (OutputsWritten & (1 << VERT_RESULT_COL0)) { vp->outputs[VERT_RESULT_COL0] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || - vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) || + OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) { + if (OutputsWritten & (1 << VERT_RESULT_COL1)) { vp->outputs[VERT_RESULT_COL1] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || - vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) || + OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + if (OutputsWritten & (1 << VERT_RESULT_BFC0)) { vp->outputs[VERT_RESULT_BFC0] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + if (OutputsWritten & (1 << VERT_RESULT_BFC1)) { vp->outputs[VERT_RESULT_BFC1] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0)) { cur_reg++; } for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) { - if (vp->key.OutputsWritten & (1 << i)) { + if (OutputsWritten & (1 << i)) { vp->outputs[i] = cur_reg++; } } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) { + if (OutputsWritten & (1 << VERT_RESULT_FOGC)) { vp->outputs[VERT_RESULT_FOGC] = cur_reg++; } } @@ -1255,6 +1259,8 @@ static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, ++vpi; vpi->Opcode = OPCODE_END; + + prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + vp->wpos_idx); } static void pos_as_texcoord(struct r300_vertex_program *vp, @@ -1448,6 +1454,63 @@ static void translateInsts(struct gl_program *prog) } } +#define ADD_OUTPUT(fp_attr, vp_result) \ + do { \ + if ((FpReads & (1 << (fp_attr))) && !(prog->OutputsWritten & (1 << (vp_result)))) { \ + OutputsAdded |= 1 << (vp_result); \ + count++; \ + } \ + } while (0) + +static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + GLuint OutputsAdded, FpReads; + int i, count; + + OutputsAdded = count = 0; + FpReads = r300->selected_fp->Base->InputsRead; + + ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0); + ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1); + + for (i = 0; i < 7; ++i) { + ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i); + } + + /* Some outputs may be artificially added, to match the inputs of the fragment program. + * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by + * vertex program are undefined, so just use MOV [vertex_result], CONST[0] + */ + if (count > 0) { + struct prog_instruction *inst; + + _mesa_insert_instructions(prog, prog->NumInstructions - 1, count); + inst = &prog->Instructions[prog->NumInstructions - 1 - count]; + + for (i = 0; i < VERT_RESULT_MAX; ++i) { + if (OutputsAdded & (1 << i)) { + inst->Opcode = OPCODE_MOV; + + inst->DstReg.File = PROGRAM_OUTPUT; + inst->DstReg.Index = i; + inst->DstReg.WriteMask = WRITEMASK_XYZW; + inst->DstReg.CondMask = COND_TR; + + inst->SrcReg[0].File = PROGRAM_CONSTANT; + inst->SrcReg[0].Index = 0; + inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + + ++inst; + } + } + + prog->OutputsWritten |= OutputsAdded; + } +} + +#undef ADD_OUTPUT + static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_key *wanted_key, const struct gl_vertex_program *mesa_vp, @@ -1477,42 +1540,7 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, pos_as_texcoord(vp, prog); } - /* Some outputs may be artificially added, to match the inputs of the fragment program. - * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by - * vertex program are undefined, so just use MOV [vertex_result], CONST[0] - */ - { - int i, count = 0; - for (i = 0; i < VERT_RESULT_MAX; ++i) { - if (vp->key.OutputsAdded & (1 << i)) { - ++count; - } - } - - if (count > 0) { - struct prog_instruction *inst; - - _mesa_insert_instructions(prog, prog->NumInstructions - 1, count); - inst = &prog->Instructions[prog->NumInstructions - 1 - count]; - - for (i = 0; i < VERT_RESULT_MAX; ++i) { - if (vp->key.OutputsAdded & (1 << i)) { - inst->Opcode = OPCODE_MOV; - - inst->DstReg.File = PROGRAM_OUTPUT; - inst->DstReg.Index = i; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->DstReg.CondMask = COND_TR; - - inst->SrcReg[0].File = PROGRAM_CONSTANT; - inst->SrcReg[0].Index = 0; - inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; - - ++inst; - } - } - } - } + addArtificialOutputs(ctx, prog); translateInsts(prog); @@ -1528,76 +1556,39 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, return vp; } -static void add_outputs(struct r300_vertex_program_key *key, GLint vert) -{ - if (key->OutputsWritten & (1 << vert)) - return; - - key->OutputsWritten |= 1 << vert; - key->OutputsAdded |= 1 << vert; -} - struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - GLuint InputsRead; struct r300_vertex_program_key wanted_key = { 0 }; - GLint i; struct r300_vertex_program_cont *vpc; struct r300_vertex_program *vp; GLint wpos_idx; vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; - wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; - wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - - wpos_idx = -1; - if (InputsRead & FRAG_BIT_WPOS) { - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (!(InputsRead & (FRAG_BIT_TEX0 << i))) - break; + wanted_key.FpReads = r300->selected_fp->Base->InputsRead; - if (i == ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tno free texcoord found\n"); - _mesa_exit(-1); + for (vp = vpc->progs; vp; vp = vp->next) + if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) + == 0) { + return r300->selected_vp = vp; } - wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); - wpos_idx = i; - } - - if (vpc->mesa_program.IsPositionInvariant) { - wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); - wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS); - } else { - add_outputs(&wanted_key, VERT_RESULT_HPOS); - } - - if (InputsRead & FRAG_BIT_COL0) { - add_outputs(&wanted_key, VERT_RESULT_COL0); - } + wpos_idx = -1; + if (wanted_key.FpReads & FRAG_BIT_WPOS) { + GLint i; - if (InputsRead & FRAG_BIT_COL1) { - add_outputs(&wanted_key, VERT_RESULT_COL1); - } + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + if (!(wanted_key.FpReads & (FRAG_BIT_TEX(i)))) + break; - if (InputsRead & FRAG_BIT_FOGC) { - add_outputs(&wanted_key, VERT_RESULT_FOGC); - } + if (i == ctx->Const.MaxTextureUnits) { + fprintf(stderr, "\tno free texcoord found\n"); + _mesa_exit(-1); + } - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (InputsRead & (FRAG_BIT_TEX0 << i)) { - add_outputs(&wanted_key, VERT_RESULT_TEX0 + i); - } + wpos_idx = i; } - for (vp = vpc->progs; vp; vp = vp->next) - if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) - == 0) { - return r300->selected_vp = vp; - } - vp = build_program(ctx, &wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; @@ -1663,8 +1654,8 @@ void r300SetupVertexProgram(r300ContextPtr rmesa) r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code)); inst_count = (prog->hw_code.length / 4) - 1; - r300VapCntl(rmesa, _mesa_bitcount(prog->key.InputsRead), - _mesa_bitcount(prog->key.OutputsWritten), prog->num_temporaries); + r300VapCntl(rmesa, _mesa_bitcount(prog->Base->Base.InputsRead), + _mesa_bitcount(prog->Base->Base.OutputsWritten), prog->num_temporaries); R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | -- cgit v1.2.3 From f79ef95df4f19124c24e59583bf9fb1e347d8f2b Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 5 Jul 2009 02:32:51 +0200 Subject: r300: rewrite FOGC and HPOS attribs handling Rewrite vertex and fragment programs so that we don't have to do any hacks on lower level. --- src/mesa/drivers/dri/r300/r300_context.h | 8 ++- src/mesa/drivers/dri/r300/r300_emit.c | 9 --- src/mesa/drivers/dri/r300/r300_fragprog_common.c | 62 ++++++++++++++++++- src/mesa/drivers/dri/r300/r300_shader.c | 3 +- src/mesa/drivers/dri/r300/r300_state.c | 53 ---------------- src/mesa/drivers/dri/r300/r300_swtcl.c | 38 +++++------- src/mesa/drivers/dri/r300/r300_vertprog.c | 79 ++++++++++++++---------- 7 files changed, 130 insertions(+), 122 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 6f99e49050..32104b8158 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -410,6 +410,8 @@ struct r300_vertex_program { struct r300_vertex_program_key { GLuint FpReads; + GLuint FogAttr; + GLuint WPosAttr; } key; struct r300_vertex_shader_hw_code { @@ -425,7 +427,6 @@ struct r300_vertex_program { int pos_end; int num_temporaries; /* Number of temp vars used by program */ - int wpos_idx; int inputs[VERT_ATTRIB_MAX]; int outputs[VERT_RESULT_MAX]; }; @@ -560,6 +561,11 @@ struct r300_fragment_program { GLuint optimization; struct r300_fragment_program *next; + + /* attribute that we are sending the WPOS in */ + gl_frag_attrib wpos_attr; + /* attribute that we are sending the fog coordinate in */ + gl_frag_attrib fog_attr; }; struct r300_fragment_program_cont { diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index c3817721dc..707d1284ed 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -116,15 +116,6 @@ GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) } } - if (fp_reads & FRAG_BIT_WPOS) { - ret |= (4 << (3 * first_free_texcoord)); - ++first_free_texcoord; - } - - if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) { - ret |= 4 << (3 * first_free_texcoord); - } - if (first_free_texcoord > 8) { fprintf(stderr, "\tout of free texcoords\n"); _mesa_exit(-1); diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index b25cf24007..e90be9b7f8 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -69,8 +69,10 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) { GLuint InputsRead = compiler->fp->Base->InputsRead; - if (!(InputsRead & FRAG_BIT_WPOS)) + if (!(InputsRead & FRAG_BIT_WPOS)) { + compiler->fp->wpos_attr = FRAG_ATTRIB_MAX; return; + } static gl_state_index tokens[STATE_LENGTH] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0 @@ -78,10 +80,23 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) struct prog_instruction *fpi; GLuint window_index; int i = 0; + + for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i) + { + if (!(InputsRead & (1 << i))) { + InputsRead &= ~(1 << FRAG_ATTRIB_WPOS); + InputsRead |= 1 << i; + compiler->fp->Base->InputsRead = InputsRead; + compiler->fp->wpos_attr = i; + break; + } + } + GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); _mesa_insert_instructions(compiler->program, 0, 3); fpi = compiler->program->Instructions; + i = 0; /* perspective divide */ fpi[i].Opcode = OPCODE_RCP; @@ -92,7 +107,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) fpi[i].DstReg.CondMask = COND_TR; fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr; fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; i++; @@ -104,7 +119,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) fpi[i].DstReg.CondMask = COND_TR; fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr; fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; @@ -147,6 +162,45 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) } } +static void rewriteFog(struct r300_fragment_program_compiler *compiler) +{ + struct r300_fragment_program *fp = compiler->fp; + GLuint InputsRead; + int i; + + InputsRead = fp->Base->InputsRead; + + if (!(InputsRead & FRAG_BIT_FOGC)) { + fp->fog_attr = FRAG_ATTRIB_MAX; + return; + } + + for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i) + { + if (!(InputsRead & (1 << i))) { + InputsRead &= ~(1 << FRAG_ATTRIB_FOGC); + InputsRead |= 1 << i; + fp->Base->InputsRead = InputsRead; + fp->fog_attr = i; + break; + } + } + + { + struct prog_instruction *inst; + + inst = compiler->program->Instructions; + while (inst->Opcode != OPCODE_END) { + const int src_regs = _mesa_num_inst_src_regs(inst->Opcode); + for (i = 0; i < src_regs; ++i) { + if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) + inst->SrcReg[i].Index = fp->fog_attr; + } + ++inst; + } + } +} + static GLuint build_dtm(GLuint depthmode) { switch(depthmode) { @@ -204,6 +258,8 @@ void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *f insert_WPOS_trailer(&compiler); + rewriteFog(&compiler); + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { struct radeon_program_transformation transformations[] = { { &r500_transform_TEX, &compiler }, diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 854eb5d80a..62228a3786 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -66,8 +66,7 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, case GL_VERTEX_STATE_PROGRAM_NV: case GL_VERTEX_PROGRAM_ARB: vp = CALLOC_STRUCT(r300_vertex_program_cont); - return _mesa_init_vertex_program(ctx, &vp->mesa_program, - target, id); + return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); case GL_FRAGMENT_PROGRAM_NV: case GL_FRAGMENT_PROGRAM_ARB: diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 0f3198e792..bae2f0f3cb 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1519,29 +1519,6 @@ static void r300SetupRSUnit(GLcontext * ctx) ++fp_reg; } - if (InputsRead & FRAG_BIT_WPOS) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count); - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - - if (InputsRead & FRAG_BIT_FOGC) { - if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0); - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count); - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n"); - } - } - /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0); @@ -1640,36 +1617,6 @@ static void r500SetupRSUnit(GLcontext * ctx) ++fp_reg; } - if (InputsRead & FRAG_BIT_WPOS) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | - ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | - ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | - ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); - - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - - if (InputsRead & FRAG_BIT_FOGC) { - if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | - (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); - - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n"); - } - } - /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0); diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index db4ccce6f1..d73508d36e 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -192,31 +192,23 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_ } } - /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */ - if (fp_reads & FRAG_BIT_WPOS) { - if (first_free_tex >= ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tout of free texcoords to write w pos\n"); - _mesa_exit(-1); - } + if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) { + int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0; - InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex); - OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex); - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); - ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW, 0); - ++first_free_tex; + VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS]; + RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); } - if (fp_reads & FRAG_BIT_FOGC) { - if (first_free_tex >= ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); - _mesa_exit(-1); - } + if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) { + int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0; - InputsRead |= 1 << VERT_ATTRIB_FOG; - OutputsWritten |= 1 << VERT_RESULT_FOGC; - GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F ); - ADD_ATTR(VERT_ATTRIB_FOG, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0); + VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG]; + RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); + } + + if (first_free_tex >= ctx->Const.MaxTextureUnits) { + fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); + _mesa_exit(-1); } R300_NEWPRIM(rmesa); @@ -497,11 +489,13 @@ void r300RenderStart(GLcontext *ctx) r300ContextPtr rmesa = R300_CONTEXT( ctx ); r300ChooseRenderState(ctx); + + r300UpdateShaders(rmesa); + r300PrepareVertices(ctx); r300ValidateBuffers(ctx); - r300UpdateShaders(rmesa); r300UpdateShaderStates(rmesa); r300EmitCacheFlush(rmesa); diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 0b04830350..6f9b4db40f 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -1223,8 +1223,7 @@ void r300TranslateVertexShader(struct r300_vertex_program *vp) } } -static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, - GLuint temp_index) +static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id) { struct prog_instruction *vpi; @@ -1248,7 +1247,7 @@ static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, vpi->Opcode = OPCODE_MOV; vpi->DstReg.File = PROGRAM_OUTPUT; - vpi->DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx; + vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id; vpi->DstReg.WriteMask = WRITEMASK_XYZW; vpi->DstReg.CondMask = COND_TR; @@ -1259,12 +1258,9 @@ static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, ++vpi; vpi->Opcode = OPCODE_END; - - prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + vp->wpos_idx); } -static void pos_as_texcoord(struct r300_vertex_program *vp, - struct gl_program *prog) +static void pos_as_texcoord(struct gl_program *prog, int tex_id) { struct prog_instruction *vpi; GLuint tempregi = prog->NumTemporaries; @@ -1278,7 +1274,37 @@ static void pos_as_texcoord(struct r300_vertex_program *vp, } } - insert_wpos(vp, prog, tempregi); + insert_wpos(prog, tempregi, tex_id); + + prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id); +} + +/** + @TODO + We can put X001 swizzle only if input components are directly mapped from output components. + For some insts we need to skip source swizzles and add: MOV OUTPUT[fog_attr].yzw, CONST[0].0001 + */ +static void fog_as_texcoord(struct gl_program *prog, int tex_id) +{ + struct prog_instruction *vpi; + int i; + + vpi = prog->Instructions; + while (vpi->Opcode != OPCODE_END) { + if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) { + vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id; + vpi->DstReg.WriteMask = WRITEMASK_XYZW; + + for (i = 0; i < _mesa_num_inst_src_regs(vpi->Opcode); ++i) { + vpi->SrcReg[i].Swizzle = combineSwizzles(vpi->SrcReg[i].Swizzle, SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE); + } + } + + ++vpi; + } + + prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC); + prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id); } static int translateABS(struct gl_program *prog, int pos) @@ -1513,16 +1539,15 @@ static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog) static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_key *wanted_key, - const struct gl_vertex_program *mesa_vp, - GLint wpos_idx) + const struct gl_vertex_program *mesa_vp) { + r300ContextPtr r300 = R300_CONTEXT(ctx); struct r300_vertex_program *vp; struct gl_program *prog; vp = _mesa_calloc(sizeof(*vp)); vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base); _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); - vp->wpos_idx = wpos_idx; prog = &vp->Base->Base; @@ -1532,12 +1557,16 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, fflush(stdout); } - if (mesa_vp->IsPositionInvariant) { + if (vp->Base->IsPositionInvariant) { _mesa_insert_mvp_code(ctx, vp->Base); } - if (wpos_idx > -1) { - pos_as_texcoord(vp, prog); + if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) { + pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0); + } + + if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) { + fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0); } addArtificialOutputs(ctx, prog); @@ -1562,34 +1591,20 @@ struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx) struct r300_vertex_program_key wanted_key = { 0 }; struct r300_vertex_program_cont *vpc; struct r300_vertex_program *vp; - GLint wpos_idx; vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; wanted_key.FpReads = r300->selected_fp->Base->InputsRead; + wanted_key.FogAttr = r300->selected_fp->fog_attr; + wanted_key.WPosAttr = r300->selected_fp->wpos_attr; - for (vp = vpc->progs; vp; vp = vp->next) + for (vp = vpc->progs; vp; vp = vp->next) { if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { return r300->selected_vp = vp; } - - wpos_idx = -1; - if (wanted_key.FpReads & FRAG_BIT_WPOS) { - GLint i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (!(wanted_key.FpReads & (FRAG_BIT_TEX(i)))) - break; - - if (i == ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tno free texcoord found\n"); - _mesa_exit(-1); - } - - wpos_idx = i; } - vp = build_program(ctx, &wanted_key, &vpc->mesa_program, wpos_idx); + vp = build_program(ctx, &wanted_key, &vpc->mesa_program); vp->next = vpc->progs; vpc->progs = vp; -- cgit v1.2.3 From bdc8a95fc906dcc617995479fbffbf8fdd1f4e34 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sat, 4 Jul 2009 23:38:59 +0200 Subject: r300: removed unnecessary params We don't have check which attributes are used by fragment program - it's already done by NQSSADCE. --- src/mesa/drivers/dri/r300/r300_emit.c | 10 +++++----- src/mesa/drivers/dri/r300/r300_emit.h | 4 ++-- src/mesa/drivers/dri/r300/r300_state.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri/r300/r300_state.c') diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 707d1284ed..feb3370f37 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -81,17 +81,17 @@ GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) return vic_1; } -GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) +GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes) { GLuint ret = 0; if (vp_writes & (1 << VERT_RESULT_HPOS)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; - if (vp_writes & (1 << VERT_RESULT_COL0) && fp_reads & FRAG_BIT_COL0) + if (vp_writes & (1 << VERT_RESULT_COL0)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT; - if (vp_writes & (1 << VERT_RESULT_COL1) && fp_reads & FRAG_BIT_COL1) + if (vp_writes & (1 << VERT_RESULT_COL1)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT; /* Two sided lighting works only if all 4 colors are written */ @@ -105,12 +105,12 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) return ret; } -GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) +GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes) { GLuint i, ret = 0, first_free_texcoord = 0; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (vp_writes & (1 << (VERT_RESULT_TEX0 + i)) && fp_reads & FRAG_BIT_TEX(i)) { + if (vp_writes & (1 << (VERT_RESULT_TEX0 + i))) { ret |= (4 << (3 * first_free_texcoord)); ++first_free_texcoord; } diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 2fb8b82d3a..3f8c60ffae 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -225,7 +225,7 @@ extern void r300EmitCacheFlush(r300ContextPtr rmesa); extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead); extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); -extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); -extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); +extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes); +extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes); #endif diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index bae2f0f3cb..4d504d14e3 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2225,8 +2225,8 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten) rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, rmesa->selected_fp->Base->InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, rmesa->selected_fp->Base->InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten); } void r300UpdateShaderStates(r300ContextPtr rmesa) -- cgit v1.2.3