#include "main/glheader.h"
#include "main/imports.h"
-#include "shader/program.h"
+#include "program/program.h"
#include "tnl/tnl.h"
#include "r600_context.h"
#include "r700_vertprog.h"
-static struct gl_program *r700NewProgram(GLcontext * ctx,
+static void freeVertProgCache(struct gl_context *ctx, struct r700_vertex_program_cont *cache)
+{
+ struct r700_vertex_program *tmp, *vp = cache->progs;
+
+ while (vp) {
+ tmp = vp->next;
+ /* Release DMA region */
+ r600DeleteShader(ctx, vp->shaderbo);
+
+ if(NULL != vp->constbo0)
+ {
+ r600DeleteShader(ctx, vp->constbo0);
+ }
+
+ /* Clean up */
+ Clean_Up_Assembler(&(vp->r700AsmCode));
+ Clean_Up_Shader(&(vp->r700Shader));
+
+ _mesa_reference_vertprog(ctx, &vp->mesa_program, NULL);
+ free(vp);
+ vp = tmp;
+ }
+}
+
+static struct gl_program *r700NewProgram(struct gl_context * ctx,
GLenum target,
GLuint id)
{
struct gl_program *pProgram = NULL;
- struct r700_vertex_program *vp;
+ struct r700_vertex_program_cont *vpc;
struct r700_fragment_program *fp;
+ radeon_print(RADEON_SHADER, RADEON_VERBOSE,
+ "%s %u, %u\n", __func__, target, id);
+
switch (target)
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp = CALLOC_STRUCT(r700_vertex_program);
+ vpc = CALLOC_STRUCT(r700_vertex_program_cont);
pProgram = _mesa_init_vertex_program(ctx,
- &vp->mesa_program,
+ &vpc->mesa_program,
target,
id);
- vp->translated = GL_FALSE;
- vp->loaded = GL_FALSE;
-
- vp->shaderbo = NULL;
-
+
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
fp->shaderbo = NULL;
+ fp->constbo0 = NULL;
+
break;
default:
_mesa_problem(ctx, "Bad target in r700NewProgram");
return pProgram;
}
-static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
+static void r700DeleteProgram(struct gl_context * ctx, struct gl_program *prog)
{
- struct r700_vertex_program * vp;
+ struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
struct r700_fragment_program * fp;
+ radeon_print(RADEON_SHADER, RADEON_VERBOSE,
+ "%s %p\n", __func__, prog);
+
switch (prog->Target)
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp = (struct r700_vertex_program*)prog;
- /* Release DMA region */
-
- r600DeleteShader(ctx, vp->shaderbo);
-
- /* Clean up */
- Clean_Up_Assembler(&(vp->r700AsmCode));
- Clean_Up_Shader(&(vp->r700Shader));
+ freeVertProgCache(ctx, vpc);
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
r600DeleteShader(ctx, fp->shaderbo);
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ }
+
/* Clean up */
Clean_Up_Assembler(&(fp->r700AsmCode));
Clean_Up_Shader(&(fp->r700Shader));
_mesa_delete_program(ctx, prog);
}
-static void
-r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
+static GLboolean
+r700ProgramStringNotify(struct gl_context * ctx, GLenum target, struct gl_program *prog)
{
-
+ struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
+ struct r700_fragment_program * fp = (struct r700_fragment_program*)prog;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ freeVertProgCache(ctx, vpc);
+ vpc->progs = NULL;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ r600DeleteShader(ctx, fp->shaderbo);
+
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ fp->constbo0 = NULL;
+ }
+
+ Clean_Up_Assembler(&(fp->r700AsmCode));
+ Clean_Up_Shader(&(fp->r700Shader));
+ fp->translated = GL_FALSE;
+ fp->loaded = GL_FALSE;
+ fp->shaderbo = NULL;
+ break;
+ }
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
-static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
+static GLboolean r700IsProgramNative(struct gl_context * ctx, GLenum target, struct gl_program *prog)
{
return GL_TRUE;