checkpoint in constant tracking rework

This commit is contained in:
Keith Whitwell
2007-08-24 18:30:00 +01:00
parent 599ba515f9
commit 07d97e80e6
10 changed files with 132 additions and 252 deletions

View 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 \

View File

@@ -29,8 +29,10 @@
#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;
@@ -143,9 +168,11 @@ void st_validate_state( struct st_context *st )
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 );

View 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

View File

@@ -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
};

View File

@@ -43,92 +43,64 @@
#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 );
tgsi_mesa_compile_fp_program( &fp->Base, fp->tokens, ST_FP_MAX_TOKENS );
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];
if (TGSI_DEBUG)
tgsi_dump( fs->tokens, TGSI_DUMP_VERBOSE );
tgsi_dump( fp->tokens, TGSI_DUMP_VERBOSE );
fp->dirty = 0;
}
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];
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_FRAGMENT, 0, cbuf);
}
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 );
if (st->fp != fp || fp->dirty) {
st->fp = 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 (fp->dirty)
compile_fs( st );
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);
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

View File

@@ -45,108 +45,79 @@
#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
vp->dirty = 0;
}
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);
}
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
};

View 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;

View 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;
};

View 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;
};

View File

@@ -28,6 +28,13 @@
#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 );