radeonInitSpanFuncs( ctx );
r300InitCmdBuf(r300);
r300InitState(r300);
+ r300InitShaderFunctions(r300);
if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
r300InitSwtcl(ctx);
int sw_tcl_inputs[VERT_ATTRIB_MAX];
};
+struct r300_vtable {
+ void (* SetupRSUnit)(GLcontext *ctx);
+ void (* SetupFragmentShaderTextures)(GLcontext *ctx, int *tmu_mappings);
+ void ( *TranslateFragmentShader)(GLcontext *ctx, struct gl_fragment_program *fp);
+ GLboolean (* SetupPixelShader)(GLcontext *ctx);
+};
+
/**
* \brief R300 context structure.
struct r300_context {
struct radeon_context radeon; /* parent class, must be first */
+ struct r300_vtable vtbl;
+
struct r300_hw_state hw;
struct r300_vertex_shader_state vertex_shader;
}
-void r300TranslateFragmentShader(r300ContextPtr r300,
- struct r300_fragment_program *fp)
+void r300TranslateFragmentShader(GLcontext *ctx, struct gl_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;
- build_state(r300, fp, &state);
- if (_mesa_memcmp(&fp->state, &state, sizeof(state))) {
+ build_state(r300, r300_fp, &state);
+ if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) {
/* TODO: cache compiled programs */
- fp->translated = GL_FALSE;
- _mesa_memcpy(&fp->state, &state, sizeof(state));
+ r300_fp->translated = GL_FALSE;
+ _mesa_memcpy(&r300_fp->state, &state, sizeof(state));
}
- if (!fp->translated) {
+ if (!r300_fp->translated) {
struct r300_fragment_program_compiler compiler;
compiler.r300 = r300;
- compiler.fp = fp;
- compiler.code = &fp->code;
- compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base);
+ compiler.fp = r300_fp;
+ compiler.code = &r300_fp->code;
+ compiler.program = _mesa_clone_program(ctx, &fp->Base);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Fragment Program: Initial program:\n");
{ &radeonTransformALU, 0 },
{ &radeonTransformTrigSimple, 0 }
};
- radeonLocalTransform(
- r300->radeon.glCtx,
- compiler.program,
- 3, transformations);
+ radeonLocalTransform(ctx, compiler.program, 3, transformations);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Fragment Program: After native rewrite:\n");
.BuildSwizzle = &r300FPBuildSwizzle,
.RewriteDepthOut = GL_TRUE
};
- radeonNqssaDce(r300->radeon.glCtx, compiler.program, &nqssadce);
+ radeonNqssaDce(ctx, compiler.program, &nqssadce);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Compiler: after NqSSA-DCE:\n");
}
if (!r300FragmentProgramEmit(&compiler))
- fp->error = GL_TRUE;
+ r300_fp->error = GL_TRUE;
/* Subtle: Rescue any parameters that have been added during transformations */
- _mesa_free_parameter_list(fp->mesa_program.Base.Parameters);
- fp->mesa_program.Base.Parameters = compiler.program->Parameters;
+ _mesa_free_parameter_list(fp->Base.Parameters);
+ fp->Base.Parameters = compiler.program->Parameters;
compiler.program->Parameters = 0;
- _mesa_reference_program(r300->radeon.glCtx, &compiler.program, NULL);
+ _mesa_reference_program(ctx, &compiler.program, NULL);
- fp->translated = GL_TRUE;
+ r300_fp->translated = GL_TRUE;
- if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
- r300FragmentProgramDump(fp, &fp->code);
- r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
+ if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
+ r300FragmentProgramDump(r300_fp, &r300_fp->code);
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
}
- update_params(r300, fp);
+ update_params(r300, r300_fp);
}
/* just some random things... */
struct r300_fragment_program;
-extern void r300TranslateFragmentShader(r300ContextPtr r300,
- struct r300_fragment_program *fp);
-
+extern void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp);
/**
* Used internally by the r300 fragment program code to store compile-time
/* Do we need to use new-style shaders?
* Also is there a better way to do this? */
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct r500_fragment_program *fp = (struct r500_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
+ struct r500_fragment_program *fp = (struct r500_fragment_program *) ctx->FragmentProgram._Current;
if (fp) {
if (!fp->translated)
- r500TranslateFragmentShader(r300, fp);
+ r300->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
FALLBACK_IF(fp->error);
}
} else {
- struct r300_fragment_program *fp = (struct r300_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
+ struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
if (fp) {
if (!fp->translated)
- r300TranslateFragmentShader(r300, fp);
+ r300->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
FALLBACK_IF(fp->error);
}
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct gl_fragment_program * fp = (struct gl_fragment_program *) prog;
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)prog;
+ struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)fp;
if (!r500_fp->translated)
- r500TranslateFragmentShader(rmesa, r500_fp);
+ rmesa->vtbl.TranslateFragmentShader(ctx, fp);
return !r500_fp->error;
} else {
- struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog;
+ struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp;
if (!r300_fp->translated)
- r300TranslateFragmentShader(rmesa, r300_fp);
+ rmesa->vtbl.TranslateFragmentShader(ctx, fp);
return !r300_fp->error;
}
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1);
}
- r300SetupFragmentShaderTextures(ctx, tmu_mappings);
- } else
- r500SetupFragmentShaderTextures(ctx, tmu_mappings);
+ }
+ r300->vtbl.SetupFragmentShaderTextures(ctx, tmu_mappings);
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n",
}
-static GLboolean r300SetupPixelShader(r300ContextPtr rmesa)
+static GLboolean r300SetupPixelShader(GLcontext *ctx)
{
- GLcontext *ctx = rmesa->radeon.glCtx;
- struct r300_fragment_program *fp = (struct r300_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
struct r300_fragment_program_code *code;
int i, k;
- r300TranslateFragmentShader(rmesa, fp);
-
/* Program is not native, fallback to software */
if (fp->error)
return GL_FALSE;
if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
} while(0)
-static GLboolean r500SetupPixelShader(r300ContextPtr rmesa)
+static GLboolean r500SetupPixelShader(GLcontext *ctx)
{
- GLcontext *ctx = rmesa->radeon.glCtx;
- struct r500_fragment_program *fp = (struct r500_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct r500_fragment_program *fp = (struct r500_fragment_program *) ctx->FragmentProgram._Current;
int i;
struct r500_fragment_program_code *code;
((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0;
- r500TranslateFragmentShader(rmesa, fp);
-
/* Program is not native, fallback to software */
if (fp->error)
return GL_FALSE;
rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc;
}
- if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- if (!r500SetupPixelShader(rmesa))
- return;
- r500SetupRSUnit(ctx);
- } else {
- if (!r300SetupPixelShader(rmesa))
- return;
- r300SetupRSUnit(ctx);
- }
+ rmesa->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
+
+ if (!rmesa->vtbl.SetupPixelShader(ctx))
+ return;
+
+ rmesa->vtbl.SetupRSUnit(ctx);
if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
r300SetupVertexProgram(rmesa);
functions->DrawBuffer = radeonDrawBuffer;
functions->ReadBuffer = radeonReadBuffer;
}
+
+void r300InitShaderFunctions(r300ContextPtr r300)
+{
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ r300->vtbl.SetupRSUnit = r500SetupRSUnit;
+ r300->vtbl.SetupPixelShader = r500SetupPixelShader;
+ r300->vtbl.SetupFragmentShaderTextures = r500SetupFragmentShaderTextures;
+ r300->vtbl.TranslateFragmentShader = r500TranslateFragmentShader;
+ } else {
+ r300->vtbl.SetupRSUnit = r300SetupRSUnit;
+ r300->vtbl.SetupPixelShader = r300SetupPixelShader;
+ r300->vtbl.SetupFragmentShaderTextures = r300SetupFragmentShaderTextures;
+ r300->vtbl.TranslateFragmentShader = r300TranslateFragmentShader;
+ }
+}
static void dump_program(struct r500_fragment_program_code *code);
-void r500TranslateFragmentShader(r300ContextPtr r300,
- struct r500_fragment_program *fp)
+void r500TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)fp;
struct r500_fragment_program_external_state state;
- build_state(r300, fp, &state);
- if (_mesa_memcmp(&fp->state, &state, sizeof(state))) {
+ build_state(r300, r500_fp, &state);
+ if (_mesa_memcmp(&r500_fp->state, &state, sizeof(state))) {
/* TODO: cache compiled programs */
- fp->translated = GL_FALSE;
- _mesa_memcpy(&fp->state, &state, sizeof(state));
+ r500_fp->translated = GL_FALSE;
+ _mesa_memcpy(&r500_fp->state, &state, sizeof(state));
}
- if (!fp->translated) {
+ if (!r500_fp->translated) {
struct r500_fragment_program_compiler compiler;
compiler.r300 = r300;
- compiler.fp = fp;
- compiler.code = &fp->code;
- compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base);
+ compiler.fp = r500_fp;
+ compiler.code = &r500_fp->code;
+ compiler.program = _mesa_clone_program(ctx, &fp->Base);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Compiler: Initial program:\n");
{ &radeonTransformDeriv, 0 },
{ &radeonTransformTrigScale, 0 }
};
- radeonLocalTransform(r300->radeon.glCtx, compiler.program,
- 4, transformations);
+ radeonLocalTransform(ctx, compiler.program, 4, transformations);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Compiler: after native rewrite:\n");
.BuildSwizzle = &nqssadce_build_swizzle,
.RewriteDepthOut = GL_TRUE
};
- radeonNqssaDce(r300->radeon.glCtx, compiler.program, &nqssadce);
+ radeonNqssaDce(ctx, compiler.program, &nqssadce);
if (RADEON_DEBUG & DEBUG_PIXEL) {
_mesa_printf("Compiler: after NqSSA-DCE:\n");
}
if (!r500FragmentProgramEmit(&compiler))
- fp->error = GL_TRUE;
+ r500_fp->error = GL_TRUE;
- fp->translated = GL_TRUE;
+ r500_fp->translated = GL_TRUE;
/* Subtle: Rescue any parameters that have been added during transformations */
- _mesa_free_parameter_list(fp->mesa_program.Base.Parameters);
- fp->mesa_program.Base.Parameters = compiler.program->Parameters;
+ _mesa_free_parameter_list(fp->Base.Parameters);
+ fp->Base.Parameters = compiler.program->Parameters;
compiler.program->Parameters = 0;
- _mesa_reference_program(r300->radeon.glCtx, &compiler.program, 0);
+ _mesa_reference_program(ctx, &compiler.program, 0);
- r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
if (RADEON_DEBUG & DEBUG_PIXEL) {
- if (!fp->error) {
+ if (!r500_fp->error) {
_mesa_printf("Machine-readable code:\n");
- dump_program(&fp->code);
+ dump_program(&r500_fp->code);
}
}
}
- update_params(r300, fp);
+ update_params(r300, r500_fp);
}
struct r500_fragment_program;
-extern void r500TranslateFragmentShader(r300ContextPtr r300,
- struct r500_fragment_program *fp);
+extern void r500TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp);
struct r500_fragment_program_compiler {
r300ContextPtr r300;