the state tracker will use it Acked-by: Brian Paul <brianp@vmware.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Signed-off-by: Miklós Máté <mtmkls@gmail.com> Signed-off-by: Marek Olšák <marek.olsak@amd.com>tags/12.0-branchpoint
@@ -117,6 +117,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) | |||
driver->NewProgram = _mesa_new_program; | |||
driver->DeleteProgram = _mesa_delete_program; | |||
/* ATI_fragment_shader */ | |||
driver->NewATIfs = NULL; | |||
/* simple state commands */ | |||
driver->AlphaFunc = NULL; | |||
driver->BlendColor = NULL; |
@@ -30,6 +30,7 @@ | |||
#include "main/mtypes.h" | |||
#include "main/dispatch.h" | |||
#include "main/atifragshader.h" | |||
#include "program/program.h" | |||
#define MESA_DEBUG_ATI_FS 0 | |||
@@ -63,6 +64,7 @@ _mesa_delete_ati_fragment_shader(struct gl_context *ctx, struct ati_fragment_sha | |||
free(s->Instructions[i]); | |||
free(s->SetupInst[i]); | |||
} | |||
_mesa_reference_program(ctx, &s->Program, NULL); | |||
free(s); | |||
} | |||
@@ -321,6 +323,8 @@ _mesa_BeginFragmentShaderATI(void) | |||
free(ctx->ATIFragmentShader.Current->SetupInst[i]); | |||
} | |||
_mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, NULL); | |||
/* malloc the instructions here - not sure if the best place but its | |||
a start */ | |||
for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { | |||
@@ -405,7 +409,14 @@ _mesa_EndFragmentShaderATI(void) | |||
} | |||
#endif | |||
if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) { | |||
if (ctx->Driver.NewATIfs) { | |||
struct gl_program *prog = ctx->Driver.NewATIfs(ctx, | |||
ctx->ATIFragmentShader.Current); | |||
_mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, prog); | |||
} | |||
if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, | |||
curProg->Program)) { | |||
ctx->ATIFragmentShader.Current->isValid = GL_FALSE; | |||
/* XXX is this the right error? */ | |||
_mesa_error(ctx, GL_INVALID_OPERATION, |
@@ -476,6 +476,11 @@ struct dd_function_table { | |||
GLuint id); | |||
/** Delete a program */ | |||
void (*DeleteProgram)(struct gl_context *ctx, struct gl_program *prog); | |||
/** | |||
* Allocate a program to associate with the new ATI fragment shader (optional) | |||
*/ | |||
struct gl_program * (*NewATIfs)(struct gl_context *ctx, | |||
struct ati_fragment_shader *curProg); | |||
/** | |||
* Notify driver that a program string (and GPU code) has been specified | |||
* or modified. Return GL_TRUE or GL_FALSE to indicate if the program is |
@@ -2196,6 +2196,7 @@ struct ati_fragment_shader | |||
GLboolean interpinp1; | |||
GLboolean isValid; | |||
GLuint swizzlerq; | |||
struct gl_program *Program; | |||
}; | |||
/** |
@@ -124,7 +124,8 @@ update_program(struct gl_context *ctx) | |||
* follows: | |||
* 1. OpenGL 2.0/ARB vertex/fragment shaders | |||
* 2. ARB/NV vertex/fragment programs | |||
* 3. Programs derived from fixed-function state. | |||
* 3. ATI fragment shader | |||
* 4. Programs derived from fixed-function state. | |||
* | |||
* Note: it's possible for a vertex shader to get used with a fragment | |||
* program (and vice versa) here, but in practice that shouldn't ever | |||
@@ -152,6 +153,17 @@ update_program(struct gl_context *ctx) | |||
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, | |||
NULL); | |||
} | |||
else if (ctx->ATIFragmentShader._Enabled && | |||
ctx->ATIFragmentShader.Current->Program) { | |||
/* Use the enabled ATI fragment shader's associated program */ | |||
_mesa_reference_shader_program(ctx, | |||
&ctx->_Shader->_CurrentFragmentProgram, | |||
NULL); | |||
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, | |||
gl_fragment_program(ctx->ATIFragmentShader.Current->Program)); | |||
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, | |||
NULL); | |||
} | |||
else if (ctx->FragmentProgram._MaintainTexEnvProgram) { | |||
/* Use fragment program generated from fixed-function state */ | |||
struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); |