* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "glheader.h"
-#include "context.h"
-#include "hash.h"
-#include "imports.h"
-#include "macros.h"
-#include "enums.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "main/mtypes.h"
#include "atifragshader.h"
#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)
{
return;
}
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
/* if the shader was already defined free instructions and get new ones
(or, could use the same mem but would need to reinitialize) */
/* no idea if it's allowed to redefine a shader */
}
/* 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;
}
}
#endif
+ if (ctx->Driver.ProgramStringNotify)
+ ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL );
}
void GLAPIENTRY
_mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
return;
}
- if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
+ if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
+ ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
return;
}
if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
- ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE5_ARB))) {
- /* is this texture5 or texture7? spec is a bit unclear there */
+ ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
+ ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
_mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
return;
}
_mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
return;
}
- if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+ if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
return;
}
_mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
return;
}
- if (coord <= GL_TEXTURE5) {
- if ((((curProg->swizzlerq >> (coord * 2)) & 3) != 0) &&
- (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (coord * 2)) & 3))) {
+ if (coord <= GL_TEXTURE7_ARB) {
+ GLuint tmp = coord - GL_TEXTURE0_ARB;
+ if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
+ (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
return;
} else {
- curProg->swizzlerq |= (((swizzle & 1) + 1) << (coord * 2));
+ curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
}
}
_mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
return;
}
- if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
+ if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
+ ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
return;
}
if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
- ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE5_ARB))) {
+ ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
+ ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
/* is this texture5 or texture7? spec is a bit unclear there */
_mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
return;
_mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
return;
}
- if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+ if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
return;
}
_mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
return;
}
- if (interp <= GL_TEXTURE5) {
- if ((((curProg->swizzlerq >> (interp * 2)) & 3) != 0) &&
- (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (interp * 2)) & 3))) {
+ if (interp <= GL_TEXTURE7_ARB) {
+ GLuint tmp = interp - GL_TEXTURE0_ARB;
+ if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
+ (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
return;
} else {
- curProg->swizzlerq |= (((swizzle & 1) + 1) << (interp * 2));
+ curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
}
}
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 {
- COPY_4V(ctx->ATIFragmentShader.globalConstants[dstindex], value);
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
}
}