r600: implement FRAG_ATTRIB_FACE, glsl/twoside works
[mesa.git] / src / mesa / drivers / dri / r600 / r700_oglprog.c
index c49b90c1cc9d633ebae2bb0c440822adfb9bb7ad..0d476fcd8639a594c5fff456a287361b1bb1e295 100644 (file)
 #include "r700_vertprog.h"
 
 
+static void freeVertProgCache(GLcontext *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);
+               /* Clean up */
+               Clean_Up_Assembler(&(vp->r700AsmCode));
+               Clean_Up_Shader(&(vp->r700Shader));
+               
+               _mesa_reference_vertprog(ctx, &vp->mesa_program, NULL);
+               _mesa_free(vp);
+               vp = tmp;
+       }
+}
+
 static struct gl_program *r700NewProgram(GLcontext * 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:
@@ -86,21 +102,17 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
 
 static void r700DeleteProgram(GLcontext * 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:
@@ -123,7 +135,24 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
 static void
 r700ProgramStringNotify(GLcontext * 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);
+               Clean_Up_Assembler(&(fp->r700AsmCode));
+               Clean_Up_Shader(&(fp->r700Shader));
+               fp->translated = GL_FALSE;
+               fp->loaded     = GL_FALSE;
+               fp->shaderbo   = NULL;
+               break;
+       }
+               
 }
 
 static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)