checkpoint in constant tracking rework
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 24 Aug 2007 17:30:00 +0000 (18:30 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Sat, 25 Aug 2007 21:01:32 +0000 (22:01 +0100)
src/mesa/sources
src/mesa/state_tracker/st_atom.c
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_cbuf.c [deleted file]
src/mesa/state_tracker/st_atom_fs.c
src/mesa/state_tracker/st_atom_vs.c
src/mesa/state_tracker/st_cb_program.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_program.h
src/mesa/tnl/t_vp_build.h

index 61a8d580ad97d3c6c46a6a6621c1fbd48b2fcc13..53969774f9e61175942f60a19c1da726a7e35726 100644 (file)
@@ -186,10 +186,11 @@ STATETRACKER_SOURCES = \
        state_tracker/st_atom_blend.c \
        state_tracker/st_atom_clear_color.c \
        state_tracker/st_atom_clip.c \
+       state_tracker/st_atom_constbuf.c \
        state_tracker/st_atom_depth.c \
-       state_tracker/st_atom_fs.c \
-       state_tracker/st_atom_vs.c \
+       state_tracker/st_atom_fixedfunction.c \
        state_tracker/st_atom_framebuffer.c \
+       state_tracker/st_atom_fs.c \
        state_tracker/st_atom_sampler.c \
        state_tracker/st_atom_scissor.c \
        state_tracker/st_atom_setup.c \
@@ -197,6 +198,7 @@ STATETRACKER_SOURCES = \
        state_tracker/st_atom_stipple.c \
        state_tracker/st_atom_texture.c \
        state_tracker/st_atom_viewport.c \
+       state_tracker/st_atom_vs.c \
        state_tracker/st_cb_bufferobjects.c \
        state_tracker/st_cb_clear.c \
        state_tracker/st_cb_flush.c \
index d67291e50bbdb6dc82a5a099ddfa84cf9cbc97b1..99fcbdfda7b0ed297ca0a32d344526b68667f36a 100644 (file)
 #include "glheader.h"
 #include "context.h"
 
+#include "pipe/p_defines.h"
 #include "st_context.h"
 #include "st_atom.h"
+#include "st_program.h"
 
        
 
@@ -46,9 +48,11 @@ static const struct st_tracked_state *atoms[] =
    &st_update_clear_color,
    &st_update_depth,
    &st_update_clip,
+
    &st_update_tnl,
    &st_update_vs,
    &st_update_fs,
+
    &st_update_setup,
    &st_update_polygon_stipple,
    &st_update_viewport,
@@ -57,8 +61,8 @@ static const struct st_tracked_state *atoms[] =
    &st_update_stencil,
    &st_update_sampler,
    &st_update_texture,
-   /* will be patched out at runtime */
-/*    &st_update_constants */
+   &st_update_vs_constants,
+   &st_update_fs_constants,
 };
 
 
@@ -72,13 +76,17 @@ void st_init_atoms( struct st_context *st )
 
    /* Patch in a pointer to the dynamic state atom:
     */
-   for (i = 0; i < st->nr_atoms; i++)
-      if (st->atoms[i] == &st_update_constants)
-        st->atoms[i] = &st->constants.tracked_state;
+   for (i = 0; i < st->nr_atoms; i++) {
+      if (st->atoms[i] == &st_update_vs_constants) {
+        st->atoms[i] = &st->constants.tracked_state[PIPE_SHADER_VERTEX];
+        st->atoms[i][0] = st_update_vs_constants;
+      }
 
-   memcpy(&st->constants.tracked_state, 
-          &st_update_constants,
-          sizeof(st_update_constants));
+      if (st->atoms[i] == &st_update_fs_constants) {
+        st->atoms[i] = &st->constants.tracked_state[PIPE_SHADER_FRAGMENT];
+        st->atoms[i][0] = st_update_fs_constants;
+      }
+   }
 }
 
 
@@ -118,6 +126,21 @@ static void xor_states( struct st_state_flags *result,
 }
 
 
+/* Too complex to figure out, just check every time:
+ */
+static void check_program_state( struct st_context *st )
+{
+   GLcontext *ctx = st->ctx;
+
+   if (ctx->VertexProgram._Current != &st->vp->Base)
+      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+
+   if (ctx->FragmentProgram._Current != &st->fp->Base)
+      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+
+}
+
+
 /***********************************************************************
  * Update all derived state:
  */
@@ -127,6 +150,8 @@ void st_validate_state( struct st_context *st )
    struct st_state_flags *state = &st->dirty;
    GLuint i;
 
+   check_program_state( st );
+
    if (state->st == 0)
       return;
 
@@ -142,10 +167,12 @@ void st_validate_state( struct st_context *st )
       for (i = 0; i < st->nr_atoms; i++) {      
         const struct st_tracked_state *atom = st->atoms[i];
         struct st_state_flags generated;
-
-        assert(atom->dirty.mesa ||
-               atom->dirty.st);
-        assert(atom->update);
+        
+        if (!(atom->dirty.mesa || atom->dirty.st) ||
+            !atom->update) {
+           _mesa_printf("malformed atom %d\n", i);
+           assert(0);
+        }
 
         if (check_state(state, &atom->dirty)) {
            st->atoms[i]->update( st );
index 51da489f6db78289694689760eb48f0ed4deaa2d..447430bfef1456f5f51bf8323031ee9ac2697edc 100644 (file)
@@ -54,12 +54,13 @@ const struct st_tracked_state st_update_vs;
 const struct st_tracked_state st_update_setup;
 const struct st_tracked_state st_update_polygon_stipple;
 const struct st_tracked_state st_update_viewport;
-const struct st_tracked_state st_update_constants;
 const struct st_tracked_state st_update_scissor;
 const struct st_tracked_state st_update_blend;
 const struct st_tracked_state st_update_stencil;
 const struct st_tracked_state st_update_sampler;
 const struct st_tracked_state st_update_texture;
+const struct st_tracked_state st_update_fs_constants;
+const struct st_tracked_state st_update_vs_constants;
 
 
 #endif
diff --git a/src/mesa/state_tracker/st_atom_cbuf.c b/src/mesa/state_tracker/st_atom_cbuf.c
deleted file mode 100644 (file)
index 0f90aa7..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  */
-#include "st_context.h"
-#include "pipe/p_context.h"
-#include "st_atom.h"
-
-extern GLboolean xmesa_get_cbuf_details( GLcontext *ctx,
-                                        void **ptr,
-                                        GLuint *cpp,
-                                        GLint *stride,
-                                        GLuint *format );
-
-
-/* This is a hack to work with the X11 driver as a test harness
- */
-static void update_cbuf_state( struct st_context *st )
-{
-   struct pipe_surface cbuf;
-   GLboolean ok;
-
-   ok = xmesa_get_cbuf_details( st->ctx,
-                               (void **)&cbuf.ptr,
-                               &cbuf.cpp,
-                               &cbuf.stride,
-                               &cbuf.format );
-
-   assert(ok);
-
-   if (memcmp(&cbuf, &st->state.cbuf, sizeof(cbuf)) != 0) {
-      st->state.cbuf = cbuf;
-      st->pipe->set_cbuf_state( st->pipe, &cbuf );
-   }
-}
-
-const struct st_tracked_state st_update_cbuf = {
-   .dirty = {
-      .mesa = _NEW_BUFFERS,
-      .st  = 0,
-   },
-   .update = update_cbuf_state
-};
-
index a164ded18408922629cf383b883a494248a3c90f..f706761198c3f47ef5a0e297581afbf16baed6fb 100644 (file)
 
 #define TGSI_DEBUG 0
 
-static void compile_fs( struct st_context *st,
-                       struct st_fragment_program *fs )
+static void compile_fs( struct st_context *st )
 {
+   struct st_fragment_program *fp = st->fp;
+
    /* XXX: fix static allocation of tokens:
     */
-   tgsi_mesa_compile_fp_program( &fs->Base, fs->tokens, ST_FP_MAX_TOKENS );
-
-   if (TGSI_DEBUG)
-      tgsi_dump( fs->tokens, TGSI_DUMP_VERBOSE );
-}
-
-
-static void
-update_fs_constants(struct st_context *st,
-                    struct gl_program_parameter_list *params)
-
-{
-   const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
-   struct pipe_winsys *ws = st->pipe->winsys;
-   struct pipe_constant_buffer *cbuf
-      = &st->state.constants[PIPE_SHADER_FRAGMENT];
+   tgsi_mesa_compile_fp_program( &fp->Base, fp->tokens, ST_FP_MAX_TOKENS );
 
-   if (!cbuf->buffer)   
-      cbuf->buffer = ws->buffer_create(ws, 1);
+   fp->fs.inputs_read
+      = tgsi_mesa_translate_vertex_input_mask(fp->Base.Base.InputsRead);
+   fp->fs.outputs_written
+      = tgsi_mesa_translate_vertex_output_mask(fp->Base.Base.OutputsWritten);
+   fp->fs.tokens = &fp->tokens[0];
 
-   /* load Mesa constants into the constant buffer */
-   if (paramBytes)
-      ws->buffer_data(ws, cbuf->buffer, paramBytes, params->ParameterValues);
-
-   cbuf->size = paramBytes;
+   if (TGSI_DEBUG)
+      tgsi_dump( fp->tokens, TGSI_DUMP_VERBOSE );
 
-   st->pipe->set_constant_buffer(st->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+   fp->dirty = 0;
 }
 
 
+
 static void update_fs( struct st_context *st )
 {
-   struct pipe_shader_state fs;
    struct st_fragment_program *fp = NULL;
-   struct gl_program_parameter_list *params = NULL;
 
-   /* find active shader and params */
+   /* find active shader and params.  Changes to this Mesa state
+    * should be covered by ST_NEW_FRAGMENT_PROGRAM, thanks to the
+    * logic in st_cb_program.c
+    */
    if (st->ctx->Shader.CurrentProgram &&
        st->ctx->Shader.CurrentProgram->LinkStatus &&
        st->ctx->Shader.CurrentProgram->FragmentProgram) {
       struct gl_fragment_program *f
          = st->ctx->Shader.CurrentProgram->FragmentProgram;
       fp = st_fragment_program(f);
-      params = f->Base.Parameters;
    }
-   else if (st->ctx->FragmentProgram._Current) {
+   else {
+      assert(st->ctx->FragmentProgram._Current);
       fp = st_fragment_program(st->ctx->FragmentProgram._Current);
-      params = st->ctx->FragmentProgram._Current->Base.Parameters;
-   }
-
-   /* update constants */
-   if (fp && params) {
-      _mesa_load_state_parameters(st->ctx, params);
-      update_fs_constants(st, params);
    }
 
    /* translate shader to TGSI format */
-   if (fp->dirty)
-      compile_fs( st, fp );
-
-   /* update pipe state */
-   memset( &fs, 0, sizeof(fs) );
-   fs.inputs_read
-      = tgsi_mesa_translate_fragment_input_mask(fp->Base.Base.InputsRead);
-   fs.outputs_written
-      = tgsi_mesa_translate_fragment_output_mask(fp->Base.Base.OutputsWritten);
-   fs.tokens = &fp->tokens[0];
-
-   if (memcmp(&fs, &st->state.fs, sizeof(fs)) != 0 ||
-       fp->dirty) 
-   {
-      fp->dirty = 0;
-      st->state.fs = fs;
-      st->pipe->set_fs_state(st->pipe, &fs);
+   if (st->fp != fp || fp->dirty) {
+      st->fp = fp;
+
+      if (fp->dirty)
+        compile_fs( st );
+
+      st->state.fs = fp->fs;
+      st->pipe->set_fs_state(st->pipe, &st->state.fs);
    }
 }
 
 
 const struct st_tracked_state st_update_fs = {
    .dirty = {
-      .mesa  = _NEW_PROGRAM,
+      .mesa  = 0,
       .st   = ST_NEW_FRAGMENT_PROGRAM,
    },
    .update = update_fs
index b2d25fa993b8d03b7751454f0e97cb63569fdbdf..ab7e2ae4bea5997f7a7010717bb285261452ae0c 100644 (file)
 #include "st_program.h"
 
 
-#define TGSI_DEBUG 0
+#define TGSI_DEBUG 1
 
-static void compile_vs( struct st_context *st,
-                       struct st_vertex_program *vs )
+
+
+
+/* translate shader to TGSI format 
+*/
+static void compile_vs( struct st_context *st )
 {
+   struct st_vertex_program *vp = st->vp;
+
    /* XXX: fix static allocation of tokens:
     */
-   tgsi_mesa_compile_vp_program( &vs->Base, vs->tokens, ST_FP_MAX_TOKENS );
+   tgsi_mesa_compile_vp_program( &vp->Base, vp->tokens, ST_FP_MAX_TOKENS );
+
+   vp->vs.inputs_read
+      = tgsi_mesa_translate_vertex_input_mask(vp->Base.Base.InputsRead);
+   vp->vs.outputs_written
+      = tgsi_mesa_translate_vertex_output_mask(vp->Base.Base.OutputsWritten);
+   vp->vs.tokens = &vp->tokens[0];
 
    if (TGSI_DEBUG)
-      tgsi_dump( vs->tokens, TGSI_DUMP_VERBOSE );
+      tgsi_dump( vp->tokens, 0 );
 
 #if defined(USE_X86_ASM) || defined(SLANG_X86)
    tgsi_emit_sse2(
-      vs->tokens,
-      &vs->sse2_program );
+      vp->vs.tokens,
+      &vp->vs.sse2_program );
 #endif
-}
-
-
-static void
-update_vs_constants(struct st_context *st,
-                    struct gl_program_parameter_list *params)
-
-{
-   const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
-   struct pipe_winsys *ws = st->pipe->winsys;
-   struct pipe_constant_buffer *cbuf
-      = &st->state.constants[PIPE_SHADER_VERTEX];
-
-   if (!cbuf->buffer)   
-      cbuf->buffer = ws->buffer_create(ws, 1);
-
-   /* load Mesa constants into the constant buffer */
-   if (paramBytes)
-      ws->buffer_data(ws, cbuf->buffer, paramBytes, params->ParameterValues);
-
-   cbuf->size = paramBytes;
 
-   st->pipe->set_constant_buffer(st->pipe, PIPE_SHADER_VERTEX, 0, cbuf);
+   vp->dirty = 0;
 }
 
 
+
 static void update_vs( struct st_context *st )
 {
-   struct pipe_shader_state vs;
-   struct st_vertex_program *vp = NULL;
-   struct gl_program_parameter_list *params = NULL;
+   struct st_vertex_program *vp;
 
-   /* find active shader and params */
+   /* find active shader and params -- Should be covered by
+    * ST_NEW_VERTEX_PROGRAM
+    */
    if (st->ctx->Shader.CurrentProgram &&
        st->ctx->Shader.CurrentProgram->LinkStatus &&
        st->ctx->Shader.CurrentProgram->VertexProgram) {
       struct gl_vertex_program *f
          = st->ctx->Shader.CurrentProgram->VertexProgram;
       vp = st_vertex_program(f);
-      params = f->Base.Parameters;
    }
-   else if (st->ctx->VertexProgram._Current) {
+   else {
+      assert(st->ctx->VertexProgram._Current);
       vp = st_vertex_program(st->ctx->VertexProgram._Current);
-      params = st->ctx->VertexProgram._Current->Base.Parameters;
    }
 
-   /* update constants */
-   if (vp && params) {
-      _mesa_load_state_parameters(st->ctx, params);
-      /*_mesa_print_parameter_list(params);*/
-      update_vs_constants(st, params);
-   }
+   if (st->vp != vp || vp->dirty) {
+      st->vp = vp;
 
-   /* translate shader to TGSI format */
-   if (vp->dirty)
-      compile_vs( st, vp );
-
-   /* update pipe state */
-   memset( &vs, 0, sizeof(vs) );
-   vs.inputs_read
-      = tgsi_mesa_translate_vertex_input_mask(vp->Base.Base.InputsRead);
-   vs.outputs_written
-      = tgsi_mesa_translate_vertex_output_mask(vp->Base.Base.OutputsWritten);
-   vs.tokens = &vp->tokens[0];
+      if (vp->dirty) 
+        compile_vs( st );
 
 #if defined(USE_X86_ASM) || defined(SLANG_X86)
-   vs.executable = (void *) x86_get_func( &vp->sse2_program );
+      vs.executable = (void *) x86_get_func( &vp->sse2_program );
 #endif
 
-   if (memcmp(&vs, &st->state.vs, sizeof(vs)) != 0 ||
-       vp->dirty) 
-   {
-      vp->dirty = 0;
-      st->state.vs = vs;
-      st->pipe->set_vs_state(st->pipe, &vs);
+      st->state.vs = st->vp->vs;
+      st->pipe->set_vs_state(st->pipe, &st->state.vs);
    }
 }
 
 
 const struct st_tracked_state st_update_vs = {
    .dirty = {
-      .mesa  = (_NEW_PROGRAM |
-                _NEW_MODELVIEW |
-                _NEW_PROJECTION |
-                _NEW_LIGHT), /*XXX MORE?*/
+      .mesa  = 0, 
       .st   = ST_NEW_VERTEX_PROGRAM,
    },
    .update = update_vs
@@ -155,28 +126,3 @@ const struct st_tracked_state st_update_vs = {
 
 
 
-
-/**
- * When TnL state has changed, need to generate new vertex program.
- * This should be done before updating the vertes shader (vs) state.
- */
-static void update_tnl( struct st_context *st )
-{
-   uint before = st->ctx->NewState;
-   if (st->ctx->VertexProgram._MaintainTnlProgram)
-      _tnl_UpdateFixedFunctionProgram( st->ctx );
-   assert(before == st->ctx->NewState);
-}
-
-
-const struct st_tracked_state st_update_tnl = {
-   .dirty = {
-      .mesa  = (_NEW_PROGRAM |
-                _NEW_LIGHT |
-                _NEW_TEXTURE |
-                _NEW_TRANSFORM |
-                _NEW_LIGHT), /* XXX more? */
-      .st   = 0
-   },
-   .update = update_tnl
-};
index b84f552404fb0e3974d122f18ec80762961974bd..b9c19bdd3e489f84a1999d88ef193d4d41f6deae 100644 (file)
@@ -64,6 +64,17 @@ static void st_bind_program( GLcontext *ctx,
    }
 }
 
+static void st_use_program( GLcontext *ctx,
+                           GLuint program )
+{
+   struct st_context *st = st_context(ctx);
+
+   st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
+   st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+
 static struct gl_program *st_new_program( GLcontext *ctx,
                                          GLenum target, 
                                          GLuint id )
@@ -132,6 +143,7 @@ static GLboolean st_is_program_native( GLcontext *ctx,
    return GL_TRUE;
 }
 
+
 static void st_program_string_notify( GLcontext *ctx,
                                      GLenum target,
                                      struct gl_program *prog )
@@ -166,10 +178,8 @@ static void st_program_string_notify( GLcontext *ctx,
 
 void st_init_program_functions(struct dd_function_table *functions)
 {
-#if 0
-   assert(functions->ProgramStringNotify == _tnl_program_string); 
-#endif
    functions->BindProgram = st_bind_program;
+   functions->UseProgram = st_use_program;
    functions->NewProgram = st_new_program;
    functions->DeleteProgram = st_delete_program;
    functions->IsProgramNative = st_is_program_native;
index 13ea28237c9a91dd051025902b5823dd7678517b..9e8015d4c7f729e6e7f5b5dceadf942baaab81cf 100644 (file)
@@ -86,7 +86,7 @@ struct st_context
    } state;
 
    struct {
-      struct st_tracked_state tracked_state;
+      struct st_tracked_state tracked_state[2];
    } constants;
 
    struct {
@@ -109,6 +109,9 @@ struct st_context
 
    GLfloat polygon_offset_scale; /* ?? */
 
+   struct st_vertex_program *vp;
+   struct st_fragment_program *fp;
+
    struct pipe_buffer_handle *default_attrib_buffer;
 };
 
index 883953399cf2a477da363f4f54450bdf2ae8c7db..7a91983ce9e89e27b468fcf5597dbef4a3ba26ad 100644 (file)
@@ -54,21 +54,7 @@ struct st_fragment_program
    struct tgsi_token tokens[ST_FP_MAX_TOKENS];
    GLboolean dirty;
    
-#if 0   
-   GLfloat (*cbuffer)[4];
-   GLuint nr_constants;
-
-   /* Translate all the parameters, etc, into a constant buffer which
-    * we update on state changes.
-    */
-   struct
-   {
-      GLuint reg;               /* Constant idx */
-      const GLfloat *values;    /* Pointer to tracked values */
-   } *param;
-   GLuint nr_params;
-#endif
-
+   struct pipe_shader_state fs;
    GLuint param_state;
 };
 
@@ -89,9 +75,7 @@ struct st_vertex_program
    struct x86_function  sse2_program;
 #endif
 
-#if 0
-   struct pipe_constant_buffer constants;
-#endif
+   struct pipe_shader_state vs;
    GLuint param_state;
 };
 
index 4a98fff026d03929f96666c8f76196a5e14228d9..5e22fcf8c40caeea2f87d2c7f82487026bc79633 100644 (file)
 
 #include "mtypes.h"
 
+#define TNL_FIXED_FUNCTION_STATE_FLAGS (_NEW_PROGRAM |         \
+                                       _NEW_LIGHT |            \
+                                       _NEW_TEXTURE |          \
+                                       _NEW_TRANSFORM |        \
+                                       _NEW_FOG |              \
+                                       _NEW_POINT)
+
 extern void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx );
 
 extern void _tnl_ProgramCacheInit( GLcontext *ctx );