r300: merge r300/r500 fragment program structures

This commit is contained in:
Maciej Cencora 2009-04-18 03:16:16 +02:00 committed by Dave Airlie
parent 27d4546f60
commit aa04e7d475
8 changed files with 70 additions and 169 deletions

View file

@ -458,7 +458,7 @@ struct r300_vertex_program_cont {
#define PFS_NUM_CONST_REGS 16
struct r300_pfs_compile_state;
struct r500_pfs_compile_state;
/**
* Stores state that influences the compilation of a fragment program.
@ -528,47 +528,6 @@ struct r300_fragment_program_code {
int max_temp_idx;
};
/**
* Store everything about a fragment program that is needed
* to render with that program.
*/
struct r300_fragment_program {
struct gl_fragment_program mesa_program;
GLboolean translated;
GLboolean error;
struct r300_fragment_program_external_state state;
struct r300_fragment_program_code code;
GLboolean WritesDepth;
GLuint optimization;
};
struct r500_pfs_compile_state;
struct r500_fragment_program_external_state {
struct {
/**
* If the sampler is used as a shadow sampler,
* this field is:
* 0 - GL_LUMINANCE
* 1 - GL_INTENSITY
* 2 - GL_ALPHA
* depending on the depth texture mode.
*/
GLuint depth_texture_mode : 2;
/**
* If the sampler is used as a shadow sampler,
* this field is (texture_compare_func - GL_NEVER).
* [e.g. if compare function is GL_LEQUAL, this field is 3]
*
* Otherwise, this field is 0.
*/
GLuint texture_compare_func : 3;
} unit[16];
};
struct r500_fragment_program_code {
struct {
@ -593,18 +552,23 @@ struct r500_fragment_program_code {
int max_temp_idx;
};
struct r500_fragment_program {
struct gl_fragment_program mesa_program;
/**
* Store everything about a fragment program that is needed
* to render with that program.
*/
struct r300_fragment_program {
struct gl_fragment_program Base;
GLcontext *ctx;
GLboolean translated;
GLboolean error;
struct r500_fragment_program_external_state state;
struct r500_fragment_program_code code;
struct r300_fragment_program_external_state state;
union {
struct r300_fragment_program_code r300;
struct r500_fragment_program_code r500;
} code;
GLboolean writes_depth;
GLuint optimization;
};

View file

@ -247,13 +247,11 @@ static GLboolean transform_TEX(
}
static void update_params(r300ContextPtr r300, struct r300_fragment_program *fp)
static void update_params(GLcontext *ctx, struct gl_fragment_program *fp)
{
struct gl_fragment_program *mp = &fp->mesa_program;
/* Ask Mesa nicely to fill in ParameterValues for us */
if (mp->Base.Parameters)
_mesa_load_state_parameters(r300->radeon.glCtx, mp->Base.Parameters);
if (fp->Base.Parameters)
_mesa_load_state_parameters(ctx, fp->Base.Parameters);
}
@ -270,7 +268,7 @@ static void update_params(r300ContextPtr r300, struct r300_fragment_program *fp)
*/
static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead;
GLuint InputsRead = compiler->fp->Base.Base.InputsRead;
if (!(InputsRead & FRAG_BIT_WPOS))
return;
@ -391,7 +389,7 @@ static void build_state(
_mesa_bzero(state, sizeof(*state));
for(unit = 0; unit < 16; ++unit) {
if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) {
if (fp->Base.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);
@ -419,7 +417,7 @@ void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
compiler.r300 = r300;
compiler.fp = r300_fp;
compiler.code = &r300_fp->code;
compiler.code = &r300_fp->code.r300;
compiler.program = _mesa_clone_program(ctx, &fp->Base);
if (RADEON_DEBUG & DEBUG_PIXEL) {
@ -467,11 +465,11 @@ void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
r300_fp->translated = GL_TRUE;
if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
r300FragmentProgramDump(r300_fp, &r300_fp->code);
r300FragmentProgramDump(r300_fp, &r300_fp->code.r300);
r300UpdateStateParameters(ctx, _NEW_PROGRAM);
}
update_params(r300, r300_fp);
update_params(ctx, fp);
}
/* just some random things... */

View file

@ -201,7 +201,7 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
if (inst->Alpha.DepthWriteMask) {
code->alu.inst[ip].inst3 |= R300_ALU_DSTA_DEPTH;
code->node[code->cur_node].flags |= R300_W_OUT;
c->fp->WritesDepth = GL_TRUE;
c->fp->writes_depth = GL_TRUE;
}
return GL_TRUE;

View file

@ -429,24 +429,11 @@ static int r300Fallback(GLcontext * ctx)
const unsigned back = ctx->Stencil._BackFace;
FALLBACK_IF(r300->radeon.Fallback);
/* 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 *) ctx->FragmentProgram._Current;
if (fp) {
if (!fp->translated)
r300->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
FALLBACK_IF(fp->error);
}
} else {
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
if (fp) {
if (!fp->translated)
r300->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
FALLBACK_IF(fp->error);
}
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
if (fp && !fp->translated) {
r300->vtbl.TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
FALLBACK_IF(fp->error);
}
FALLBACK_IF(ctx->RenderMode != GL_RENDER);

View file

@ -9,10 +9,8 @@
static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
GLuint id)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_vertex_program_cont *vp;
struct r300_fragment_program *r300_fp;
struct r500_fragment_program *r500_fp;
struct r300_fragment_program *fp;
switch (target) {
case GL_VERTEX_STATE_PROGRAM_NV:
@ -20,28 +18,12 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
vp = CALLOC_STRUCT(r300_vertex_program_cont);
return _mesa_init_vertex_program(ctx, &vp->mesa_program,
target, id);
case GL_FRAGMENT_PROGRAM_ARB:
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
r500_fp = CALLOC_STRUCT(r500_fragment_program);
r500_fp->ctx = ctx;
return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program,
target, id);
} else {
r300_fp = CALLOC_STRUCT(r300_fragment_program);
return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program,
target, id);
}
case GL_FRAGMENT_PROGRAM_NV:
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
r500_fp = CALLOC_STRUCT(r500_fragment_program);
return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program,
target, id);
} else {
r300_fp = CALLOC_STRUCT(r300_fragment_program);
return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program,
target, id);
}
case GL_FRAGMENT_PROGRAM_ARB:
fp = CALLOC_STRUCT(r300_fragment_program);
return _mesa_init_fragment_program(ctx, &fp->Base, target, id);
default:
_mesa_problem(ctx, "Bad target in r300NewProgram");
}
@ -57,20 +39,15 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog)
static void
r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_vertex_program_cont *vp = (void *)prog;
struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog;
struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)prog;
switch (target) {
case GL_VERTEX_PROGRAM_ARB:
vp->progs = NULL;
break;
case GL_FRAGMENT_PROGRAM_ARB:
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
r500_fp->translated = GL_FALSE;
else
r300_fp->translated = GL_FALSE;
r300_fp->translated = GL_FALSE;
break;
}
@ -83,23 +60,11 @@ r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct gl_fragment_program * fp = (struct gl_fragment_program *) prog;
struct r300_fragment_program *fp = (struct r300_fragment_program *)prog;
if (!fp->translated)
rmesa->vtbl.TranslateFragmentShader(ctx, &fp->Base);
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)fp;
if (!r500_fp->translated)
rmesa->vtbl.TranslateFragmentShader(ctx, fp);
return !r500_fp->error;
} else {
struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp;
if (!r300_fp->translated)
rmesa->vtbl.TranslateFragmentShader(ctx, fp);
return !r300_fp->error;
}
return !fp->error;
} else
return GL_TRUE;
}

View file

@ -449,18 +449,9 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
struct r300_fragment_program *fp = (struct r300_fragment_program *)
(char *)ctx->FragmentProgram._Current;
return (fp && fp->WritesDepth);
} else {
struct r500_fragment_program* fp =
(struct r500_fragment_program*)(char*)
ctx->FragmentProgram._Current;
return (fp && fp->writes_depth);
}
return (fp && fp->writes_depth);
}
static void r300SetEarlyZState(GLcontext * ctx)
@ -1072,7 +1063,7 @@ void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
if (!fp)
return;
paramList = fp->mesa_program.Base.Parameters;
paramList = fp->Base.Base.Parameters;
if (!paramList)
return;
@ -1191,9 +1182,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
struct r300_fragment_program *fp = (struct r300_fragment_program *)
(char *)ctx->FragmentProgram._Current;
struct r300_fragment_program_code *code = &fp->code;
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
struct r300_fragment_program_code *code = &fp->code.r300;
R300_STATECHANGE(r300, fpt);
@ -1234,9 +1224,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
int i;
struct r500_fragment_program *fp = (struct r500_fragment_program *)
(char *)ctx->FragmentProgram._Current;
struct r500_fragment_program_code *code = &fp->code;
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
struct r500_fragment_program_code *code = &fp->code.r500;
/* find all the texture instructions and relocate the texture units */
for (i = 0; i < code->inst_end + 1; i++) {
@ -1391,7 +1380,7 @@ static void r300SetupTextures(GLcontext * ctx)
return;
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
if (fp->mesa_program.UsesKill && last_hw_tmu < 0) {
if (fp->Base.UsesKill && last_hw_tmu < 0) {
// The KILL operation requires the first texture unit
// to be enabled.
r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
@ -2310,7 +2299,7 @@ static GLboolean r300SetupPixelShader(GLcontext *ctx)
if (fp->error)
return GL_FALSE;
code = &fp->code;
code = &fp->code.r300;
r300SetupTextures(ctx);
@ -2355,7 +2344,7 @@ static GLboolean r300SetupPixelShader(GLcontext *ctx)
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->mesa_program.Base, code->constant[i]);
&fp->Base.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]);
@ -2382,7 +2371,7 @@ static GLboolean r300SetupPixelShader(GLcontext *ctx)
static GLboolean r500SetupPixelShader(GLcontext *ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r500_fragment_program *fp = (struct r500_fragment_program *) ctx->FragmentProgram._Current;
struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
int i;
struct r500_fragment_program_code *code;
@ -2393,7 +2382,7 @@ static GLboolean r500SetupPixelShader(GLcontext *ctx)
if (fp->error)
return GL_FALSE;
code = &fp->code;
code = &fp->code.r500;
r300SetupTextures(ctx);
@ -2425,7 +2414,7 @@ static GLboolean r500SetupPixelShader(GLcontext *ctx)
R300_STATECHANGE(rmesa, r500fp_const);
for (i = 0; i < code->const_nr; i++) {
const GLfloat *constant = get_fragmentprogram_constant(ctx,
&fp->mesa_program.Base, code->constant[i]);
&fp->Base.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]);

View file

@ -189,13 +189,11 @@ static GLboolean transform_TEX(
}
static void update_params(r300ContextPtr r300, struct r500_fragment_program *fp)
static void update_params(GLcontext *ctx, struct gl_fragment_program *fp)
{
struct gl_fragment_program *mp = &fp->mesa_program;
/* Ask Mesa nicely to fill in ParameterValues for us */
if (mp->Base.Parameters)
_mesa_load_state_parameters(r300->radeon.glCtx, mp->Base.Parameters);
if (fp->Base.Parameters)
_mesa_load_state_parameters(ctx, fp->Base.Parameters);
}
@ -212,7 +210,7 @@ static void update_params(r300ContextPtr r300, struct r500_fragment_program *fp)
*/
static void insert_WPOS_trailer(struct r500_fragment_program_compiler *compiler)
{
GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead;
GLuint InputsRead = compiler->fp->Base.Base.InputsRead;
if (!(InputsRead & FRAG_BIT_WPOS))
return;
@ -420,15 +418,15 @@ static GLuint build_func(GLuint comparefunc)
*/
static void build_state(
r300ContextPtr r300,
struct r500_fragment_program *fp,
struct r500_fragment_program_external_state *state)
struct r300_fragment_program *fp,
struct r300_fragment_program_external_state *state)
{
int unit;
_mesa_bzero(state, sizeof(*state));
for(unit = 0; unit < 16; ++unit) {
if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) {
if (fp->Base.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);
@ -442,22 +440,22 @@ static void dump_program(struct r500_fragment_program_code *code);
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;
struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp;
struct r300_fragment_program_external_state state;
build_state(r300, r500_fp, &state);
if (_mesa_memcmp(&r500_fp->state, &state, sizeof(state))) {
build_state(r300, r300_fp, &state);
if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) {
/* TODO: cache compiled programs */
r500_fp->translated = GL_FALSE;
_mesa_memcpy(&r500_fp->state, &state, sizeof(state));
r300_fp->translated = GL_FALSE;
_mesa_memcpy(&r300_fp->state, &state, sizeof(state));
}
if (!r500_fp->translated) {
if (!r300_fp->translated) {
struct r500_fragment_program_compiler compiler;
compiler.r300 = r300;
compiler.fp = r500_fp;
compiler.code = &r500_fp->code;
compiler.fp = r300_fp;
compiler.code = &r300_fp->code.r500;
compiler.program = _mesa_clone_program(ctx, &fp->Base);
if (RADEON_DEBUG & DEBUG_PIXEL) {
@ -494,9 +492,9 @@ void r500TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
}
if (!r500FragmentProgramEmit(&compiler))
r500_fp->error = GL_TRUE;
r300_fp->error = GL_TRUE;
r500_fp->translated = GL_TRUE;
r300_fp->translated = GL_TRUE;
/* Subtle: Rescue any parameters that have been added during transformations */
_mesa_free_parameter_list(fp->Base.Parameters);
@ -508,15 +506,15 @@ void r500TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
r300UpdateStateParameters(ctx, _NEW_PROGRAM);
if (RADEON_DEBUG & DEBUG_PIXEL) {
if (!r500_fp->error) {
if (!r300_fp->error) {
_mesa_printf("Machine-readable code:\n");
dump_program(&r500_fp->code);
dump_program(&r300_fp->code.r500);
}
}
}
update_params(r300, r500_fp);
update_params(ctx, fp);
}

View file

@ -51,7 +51,7 @@ extern void r500TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_progr
struct r500_fragment_program_compiler {
r300ContextPtr r300;
struct r500_fragment_program *fp;
struct r300_fragment_program *fp;
struct r500_fragment_program_code *code;
struct gl_program *program;
};