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 \
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 \
#include "glheader.h"
#include "context.h"
+#include "pipe/p_defines.h"
#include "st_context.h"
#include "st_atom.h"
+#include "st_program.h"
&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,
&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,
};
/* 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;
+ }
+ }
}
}
+/* 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:
*/
struct st_state_flags *state = &st->dirty;
GLuint i;
+ check_program_state( st );
+
if (state->st == 0)
return;
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 );
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
+++ /dev/null
-/**************************************************************************
- *
- * 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
-};
-
#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
#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
-
-/**
- * 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
-};
}
}
+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 )
return GL_TRUE;
}
+
static void st_program_string_notify( GLcontext *ctx,
GLenum target,
struct gl_program *prog )
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;
} state;
struct {
- struct st_tracked_state tracked_state;
+ struct st_tracked_state tracked_state[2];
} constants;
struct {
GLfloat polygon_offset_scale; /* ?? */
+ struct st_vertex_program *vp;
+ struct st_fragment_program *fp;
+
struct pipe_buffer_handle *default_attrib_buffer;
};
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;
};
struct x86_function sse2_program;
#endif
-#if 0
- struct pipe_constant_buffer constants;
-#endif
+ struct pipe_shader_state vs;
GLuint param_state;
};
#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 );