fp=CALLOC_STRUCT(fragment_program);
return _mesa_init_fragment_program(ctx, fp, target, id);
#endif
+#if 00
+ /* _mesa_new_ati_fragment_shader() is now called instead */
case GL_FRAGMENT_SHADER_ATI:
afs=CALLOC_STRUCT(ati_fragment_shader);
return _mesa_init_ati_fragment_shader(ctx, afs, target, id);
+#endif
default:
_mesa_problem(ctx, "Bad target in r300NewProgram");
}
#include "histogram.h"
#include "hint.h"
#include "hash.h"
+#include "atifragshader.h"
#include "light.h"
#include "lines.h"
#include "macros.h"
goto cleanup;
#endif
#if FEATURE_ATI_fragment_shader
- ss->DefaultFragmentShader = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, 0);
+ ss->ATIShaders = _mesa_NewHashTable();
+ ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
if (!ss->DefaultFragmentShader)
goto cleanup;
#endif
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentShader);
+ _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
if (ss->BufferObjects)
_mesa_delete_program(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
- _mesa_delete_program(ctx, ss->DefaultFragmentShader);
+ _mesa_free(ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
/**
- * NV_fragment_program runtime state
+ * State used during execution of fragment programs.
*/
struct fp_machine
{
GLuint CondCodes[4];
};
-/**
- * ATI_fragment_shader runtime state
- */
-#define ATI_FS_INPUT_PRIMARY 0
-#define ATI_FS_INPUT_SECONDARY 1
-
-/* 6 register sets - 2 inputs (primary, secondary) */
-struct atifs_machine
-{
- GLfloat Registers[6][4];
- GLfloat PrevPassRegisters[6][4];
- GLfloat Inputs[2][4];
- GLuint pass;
-};
-
/**
* Names of the various vertex/fragment program register files, etc.
/** Vertex and fragment instructions */
struct prog_instruction;
-struct atifs_instruction;
-struct atifs_setupinst;
struct program_parameter_list;
GLboolean UsesKill;
};
-struct ati_fragment_shader
-{
- struct program Base;
- struct atifs_instruction *Instructions[2];
- struct atifs_setupinst *SetupInst[2];
- GLfloat Constants[8][4];
- GLuint localConstDef;
- GLubyte numArithInstr[2];
- GLubyte regsAssigned[2];
- GLubyte NumPasses;
- GLubyte cur_pass;
- GLubyte last_optype;
- GLboolean interpinp1;
- GLboolean isValid;
- GLuint swizzlerq;
-};
/**
* State common to vertex and fragment programs.
struct gl_vertex_program_state
{
GLboolean Enabled; /**< GL_VERTEX_PROGRAM_NV */
- GLboolean _Enabled; /**< Really enabled? */
+ GLboolean _Enabled; /**< Enabled and valid program? */
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */
struct vertex_program *Current; /**< ptr to currently bound program */
/**
- * State for GL_ARB/NV_fragment_program
+ * Context state for GL_ARB/NV_fragment_program
*/
struct gl_fragment_program_state
{
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
- GLboolean _Enabled; /* Really enabled? */
- GLboolean _Active; /* Really really enabled? */
+ GLboolean _Enabled; /* Enabled and valid program? */
+ GLboolean _Active;
struct fragment_program *Current; /* ptr to currently bound program */
struct fragment_program *_Current; /* ptr to currently active program
(including internal programs) */
/**
- * State for GL_ATI_fragment_shader
+ * ATI_fragment_shader runtime state
+ */
+#define ATI_FS_INPUT_PRIMARY 0
+#define ATI_FS_INPUT_SECONDARY 1
+
+struct atifs_instruction;
+struct atifs_setupinst;
+
+/**
+ * State for executing ATI fragment shader.
+ */
+struct atifs_machine
+{
+ GLfloat Registers[6][4]; /** six temporary registers */
+ GLfloat PrevPassRegisters[6][4];
+ GLfloat Inputs[2][4]; /** Primary, secondary input colors */
+};
+
+
+/**
+ * ATI fragment shader
+ */
+struct ati_fragment_shader
+{
+ GLuint Id;
+ GLint RefCount;
+ struct atifs_instruction *Instructions[2];
+ struct atifs_setupinst *SetupInst[2];
+ GLfloat Constants[8][4];
+ GLbitfield LocalConstDef; /** Indicates which constants have been set */
+ GLubyte numArithInstr[2];
+ GLubyte regsAssigned[2];
+ GLubyte NumPasses; /** 1 or 2 */
+ GLubyte cur_pass;
+ GLubyte last_optype;
+ GLboolean interpinp1;
+ GLboolean isValid;
+ GLuint swizzlerq;
+};
+
+/**
+ * Context state for GL_ATI_fragment_shader
*/
struct gl_ati_fragment_shader_state
{
GLboolean Enabled;
- GLboolean _Enabled;
+ GLboolean _Enabled; /** enabled and valid shader? */
GLboolean Compiling;
- GLfloat globalConstants[8][4];
+ GLfloat GlobalConstants[8][4];
struct atifs_machine Machine; /* machine state */
struct ati_fragment_shader *Current;
};
+/**
+ * Occlusion/timer query object.
+ */
struct gl_query_object
{
GLuint Id;
};
+/**
+ * Context state for query objects.
+ */
struct gl_query_state
{
struct _mesa_HashTable *QueryObjects;
};
+/**
+ * Context state for vertex/fragment shaders.
+ */
struct gl_shader_objects_state
{
struct gl2_program_intf **current_program;
#if FEATURE_ARB_fragment_program
struct program *DefaultFragmentProgram;
#endif
+ /*@}*/
+
#if FEATURE_ATI_fragment_shader
- struct program *DefaultFragmentShader;
+ struct _mesa_HashTable *ATIShaders;
+ struct ati_fragment_shader *DefaultFragmentShader;
#endif
- /*@}*/
#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
struct _mesa_HashTable *BufferObjects;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
&& ctx->FragmentProgram.Current->Base.Instructions;
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
- && ctx->ATIFragmentShader.Current->Base.Instructions;
+ && ctx->ATIFragmentShader.Current->Instructions;
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
#define MESA_DEBUG_ATI_FS 0
-extern struct program _mesa_DummyProgram;
+static struct ati_fragment_shader DummyShader;
+
+
+/**
+ * Allocate and initialize a new ATI fragment shader object.
+ */
+struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
+{
+ struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
+ (void) ctx;
+ if (s) {
+ s->Id = id;
+ s->RefCount = 1;
+ }
+ return s;
+}
+
+
+/**
+ * Delete the given ati fragment shader
+ */
+void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
+{
+ GLuint i;
+ for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
+ if (s->Instructions[i])
+ _mesa_free(s->Instructions[i]);
+ if (s->SetupInst[i])
+ _mesa_free(s->SetupInst[i]);
+ }
+ _mesa_free(s);
+}
+
+
static void
new_arith_inst(struct ati_fragment_shader *prog)
return 0;
}
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, range);
+ first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
for (i = 0; i < range; i++) {
- _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram);
+ _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
}
return first;
void GLAPIENTRY
_mesa_BindFragmentShaderATI(GLuint id)
{
- struct program *prog;
GET_CURRENT_CONTEXT(ctx);
struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+ struct ati_fragment_shader *newProg;
if (ctx->ATIFragmentShader.Compiling) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- if (curProg->Base.Id == id) {
+ if (curProg->Id == id) {
return;
}
- if (curProg->Base.Id != 0) {
- curProg->Base.RefCount--;
- if (curProg->Base.RefCount <= 0) {
- _mesa_HashRemove(ctx->Shared->Programs, id);
+ /* unbind current */
+ if (curProg->Id != 0) {
+ curProg->RefCount--;
+ if (curProg->RefCount <= 0) {
+ _mesa_HashRemove(ctx->Shared->ATIShaders, id);
}
}
- /* Go bind */
+ /* find new shader */
if (id == 0) {
- prog = ctx->Shared->DefaultFragmentShader;
+ newProg = ctx->Shared->DefaultFragmentShader;
}
else {
- prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
- if (!prog || prog == &_mesa_DummyProgram) {
+ newProg = (struct ati_fragment_shader *)
+ _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+ if (!newProg || newProg == &DummyShader) {
/* allocate a new program now */
- prog = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, id);
- if (!prog) {
+ newProg = _mesa_new_ati_fragment_shader(ctx, id);
+ if (!newProg) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
return;
}
- _mesa_HashInsert(ctx->Shared->Programs, id, prog);
+ _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
}
}
/* do actual bind */
- ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) prog;
+ ctx->ATIFragmentShader.Current = newProg;
ASSERT(ctx->ATIFragmentShader.Current);
- if (prog)
- prog->RefCount++;
+ if (newProg)
+ newProg->RefCount++;
/*if (ctx->Driver.BindProgram)
ctx->Driver.BindProgram(ctx, target, prog); */
}
if (id != 0) {
- struct program *prog = (struct program *)
- _mesa_HashLookup(ctx->Shared->Programs, id);
- if (prog == &_mesa_DummyProgram) {
- _mesa_HashRemove(ctx->Shared->Programs, id);
+ struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
+ _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+ if (prog == &DummyShader) {
+ _mesa_HashRemove(ctx->Shared->ATIShaders, id);
}
else if (prog) {
if (ctx->ATIFragmentShader.Current &&
- ctx->ATIFragmentShader.Current->Base.Id == id) {
+ ctx->ATIFragmentShader.Current->Id == id) {
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
_mesa_BindFragmentShaderATI(0);
}
}
-#if 0
- if (!prog->DeletePending) {
- prog->DeletePending = GL_TRUE;
- prog->RefCount--;
- }
- if (prog->RefCount <= 0) {
- _mesa_HashRemove(ctx->Shared->Programs, id);
- ctx->Driver.DeleteProgram(ctx, prog);
- }
-#else
+
/* The ID is immediately available for re-use now */
- _mesa_HashRemove(ctx->Shared->Programs, id);
+ _mesa_HashRemove(ctx->Shared->ATIShaders, id);
prog->RefCount--;
if (prog->RefCount <= 0) {
- ctx->Driver.DeleteProgram(ctx, prog);
+ _mesa_free(prog);
}
-#endif
}
}
+
void GLAPIENTRY
_mesa_BeginFragmentShaderATI(void)
{
}
/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
- ctx->ATIFragmentShader.Current->localConstDef = 0;
+ ctx->ATIFragmentShader.Current->LocalConstDef = 0;
ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
if (ctx->ATIFragmentShader.Compiling) {
struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
COPY_4V(curProg->Constants[dstindex], value);
- curProg->localConstDef |= 1 << dstindex;
+ curProg->LocalConstDef |= 1 << dstindex;
}
else {
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- COPY_4V(ctx->ATIFragmentShader.globalConstants[dstindex], value);
+ COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
}
}
GLenum swizzle;
};
+
+extern struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx,
+ struct ati_fragment_shader *s);
+
+
extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range);
extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id);
ctx->FragmentProgram.Current->Base.RefCount++;
#endif
+ /* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
ctx->ATIFragmentShader.Enabled = GL_FALSE;
ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
assert(ctx->ATIFragmentShader.Current);
- ctx->ATIFragmentShader.Current->Base.RefCount++;
+ ctx->ATIFragmentShader.Current->RefCount++;
#endif
}
ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
}
#endif
+ /* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader
if (ctx->ATIFragmentShader.Current) {
- ctx->ATIFragmentShader.Current->Base.RefCount--;
- if (ctx->ATIFragmentShader.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->ATIFragmentShader.Current->Base));
+ ctx->ATIFragmentShader.Current->RefCount--;
+ if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+ _mesa_free(ctx->ATIFragmentShader.Current);
+ }
}
#endif
_mesa_free((void *) ctx->Program.ErrorString);
return NULL;
}
-/**
- * Initialize a new ATI fragment shader object.
- */
-struct program *
-_mesa_init_ati_fragment_shader( GLcontext *ctx,
- struct ati_fragment_shader *prog,
- GLenum target, GLuint id )
-{
- if (prog)
- return _mesa_init_program_struct( ctx, &prog->Base, target, id );
- else
- return NULL;
-}
-
-
/**
* Allocate and initialize a new fragment/vertex program object but
case GL_FRAGMENT_PROGRAM_ARB:
return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(fragment_program),
target, id );
- case GL_FRAGMENT_SHADER_ATI:
- return _mesa_init_ati_fragment_shader( ctx, CALLOC_STRUCT(ati_fragment_shader),
- target, id );
-
default:
_mesa_problem(ctx, "bad target in _mesa_new_program");
return NULL;
if (prog->Parameters)
_mesa_free_parameter_list(prog->Parameters);
- if (prog->Target == GL_FRAGMENT_SHADER_ATI) {
- struct ati_fragment_shader *atifs = (struct ati_fragment_shader *)prog;
- GLuint i;
- for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
- if (atifs->Instructions[i])
- _mesa_free(atifs->Instructions[i]);
- if (atifs->SetupInst[i])
- _mesa_free(atifs->SetupInst[i]);
- }
- }
-
_mesa_free(prog);
}
struct fragment_program *prog,
GLenum target, GLuint id);
-extern struct program *
-_mesa_init_ati_fragment_shader(GLcontext *ctx,
- struct ati_fragment_shader *prog,
- GLenum target, GLuint id );
-
extern struct program *
_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id);
#include "program.h"
#include "s_atifragshader.h"
-#include "s_nvfragprog.h"
-#include "s_span.h"
/**
SETUP_SRC_REG(optype, i,
machine->Registers[index - GL_REG_0_ATI]);
else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
- if (shader->localConstDef & (1 << (index - GL_CON_0_ATI))) {
+ if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
SETUP_SRC_REG(optype, i,
shader->Constants[index - GL_CON_0_ATI]);
} else {
SETUP_SRC_REG(optype, i,
- ctx->ATIFragmentShader.globalConstants[index - GL_CON_0_ATI]);
+ ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]);
}
}
else if (index == GL_ONE)
for (i = 0; i < 6; i++) {
for (j = 0; j < 4; j++)
ctx->ATIFragmentShader.Machine.Registers[i][j] = 0.0;
-
}
ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][0] =
CHAN_TO_FLOAT(span->array->spec[col][2]);
ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][3] =
CHAN_TO_FLOAT(span->array->spec[col][3]);
-
- ctx->ATIFragmentShader.Machine.pass = 0;
}
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]);
}
}
-
}
-
ctx->_CurrentProgram = 0;
-
}