From: Brian Date: Wed, 22 Aug 2007 18:24:51 +0000 (-0600) Subject: Rework of shader constant buffers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0bb4ba9e665e40a325d82aa2ee48d7b8abd603b;p=mesa.git Rework of shader constant buffers. They're now totally independent of the actual shaders. Also, implemented in terms of pipe_buffer_handles/objects. --- diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 2fce1322c50..893db1e0c65 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -103,6 +103,8 @@ void draw_set_mapped_element_buffer( struct draw_context *draw, void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer); +void draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer); void draw_set_vertex_buffer(struct draw_context *draw, diff --git a/src/mesa/pipe/draw/draw_prim.c b/src/mesa/pipe/draw/draw_prim.c index 97484d5fb95..94cedb02a97 100644 --- a/src/mesa/pipe/draw/draw_prim.c +++ b/src/mesa/pipe/draw/draw_prim.c @@ -165,7 +165,7 @@ run_vertex_program(struct draw_context *draw, NULL /*samplers*/ ); /* Consts does not require 16 byte alignment. */ - machine.Consts = draw->vertex_shader.constants->constant; + machine.Consts = (float (*)[4]) draw->mapped_constants; machine.Inputs = ALIGN16_ASSIGN(inputs); machine.Outputs = ALIGN16_ASSIGN(outputs); @@ -742,6 +742,13 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, } +void draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer) +{ + draw->mapped_constants = buffer; +} + + unsigned draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) { diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 85feb146882..75f7c5d84e6 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -167,6 +167,8 @@ struct draw_context unsigned eltSize; /**< bytes per index (0, 1, 2 or 4) */ /** The mapped vertex arrays */ const void *mapped_vbuffer[PIPE_ATTRIB_MAX]; + /** The mapped constant buffers (for vertex shader) */ + const void *mapped_constants; /* Clip derived state: */ diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c index 9856c7c10c3..f4121419f79 100644 --- a/src/mesa/pipe/i915simple/i915_context.c +++ b/src/mesa/pipe/i915simple/i915_context.c @@ -186,6 +186,9 @@ static boolean i915_draw_elements( struct pipe_context *pipe, draw_set_mapped_element_buffer(draw, 0, NULL); } + draw_set_mapped_constant_buffer(draw, + i915->current.constants[PIPE_SHADER_VERTEX]); + /* draw! */ draw_arrays(i915->draw, prim, start, count); diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index b40dfa695bc..a037b202892 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -30,10 +30,10 @@ #include "pipe/p_context.h" +#include "pipe/p_defines.h" #include "pipe/p_state.h" - #define I915_TEX_UNITS 8 #define I915_DYNAMIC_MODES4 0 @@ -74,6 +74,7 @@ #define I915_CACHE_CONSTANTS 5 #define I915_MAX_CACHE 6 +#define I915_MAX_CONSTANT 32 struct i915_cache_context; @@ -85,10 +86,14 @@ struct i915_state unsigned immediate[I915_MAX_IMMEDIATE]; unsigned dynamic[I915_MAX_DYNAMIC]; + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + /** user constants, plus extra constants from shader translation */ + uint num_constants[PIPE_SHADER_TYPES]; + uint *program; uint program_len; - uint *constants; - uint num_constants; unsigned sampler[I915_TEX_UNITS][3]; unsigned sampler_enable_flags; @@ -112,6 +117,7 @@ struct i915_context struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; struct pipe_depth_state depth_test; struct pipe_framebuffer_state framebuffer; struct pipe_shader_state fs; @@ -124,8 +130,6 @@ struct i915_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_constant_buffer temp_constants; /*XXX temporary*/ - unsigned dirty; unsigned *batch_start; @@ -156,6 +160,8 @@ struct i915_context #define I915_NEW_SAMPLER 0x400 #define I915_NEW_TEXTURE 0x800 #define I915_NEW_STENCIL 0x1000 +#define I915_NEW_CONSTANTS 0x2000 + /* Driver's internally generated state flags: */ diff --git a/src/mesa/pipe/i915simple/i915_fpc.h b/src/mesa/pipe/i915simple/i915_fpc.h index 30bc290ad8f..afef7064187 100644 --- a/src/mesa/pipe/i915simple/i915_fpc.h +++ b/src/mesa/pipe/i915simple/i915_fpc.h @@ -37,7 +37,6 @@ #define I915_PROGRAM_SIZE 192 -#define I915_MAX_CONSTANT 32 #define MAX_VARYING 8 @@ -99,9 +98,10 @@ struct i915_fp_compile { uint declarations[I915_PROGRAM_SIZE]; uint program[I915_PROGRAM_SIZE]; - uint constant_flags[I915_MAX_CONSTANT]; - - struct pipe_constant_buffer *constants; + /** points into the i915->current.constants array: */ + float (*constants)[4]; + uint num_constants; + uint constant_flags[I915_MAX_CONSTANT]; /**< status of each constant */ uint *csr; /* Cursor, points into program. */ diff --git a/src/mesa/pipe/i915simple/i915_fpc_emit.c b/src/mesa/pipe/i915simple/i915_fpc_emit.c index 26a4f36e710..dfbc5f180c6 100644 --- a/src/mesa/pipe/i915simple/i915_fpc_emit.c +++ b/src/mesa/pipe/i915simple/i915_fpc_emit.c @@ -244,25 +244,14 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) continue; for (idx = 0; idx < 4; idx++) { -#if 0 - if (!(p->constant_flags[reg] & (1 << idx)) || - p->fp->constant[reg][idx] == c0) { - p->fp->constant[reg][idx] = c0; - p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->fp->nr_constants) - p->fp->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); - } -#else if (!(p->constant_flags[reg] & (1 << idx)) || - p->constants->constant[reg][idx] == c0) { - p->constants->constant[reg][idx] = c0; + p->constants[reg][idx] == c0) { + p->constants[reg][idx] = c0; p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->constants->nr_constants) - p->constants->nr_constants = reg + 1; + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); } -#endif } } @@ -291,23 +280,12 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) continue; for (idx = 0; idx < 3; idx++) { if (!(p->constant_flags[reg] & (3 << idx))) { -#if 0 - p->fp->constant[reg][idx] = c0; - p->fp->constant[reg][idx + 1] = c1; + p->constants[reg][idx + 0] = c0; + p->constants[reg][idx + 1] = c1; p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->fp->nr_constants) - p->fp->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, - ONE); -#else - p->constants->constant[reg][idx + 0] = c0; - p->constants->constant[reg][idx + 1] = c1; - p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->constants->nr_constants) - p->constants->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, - ONE); -#endif + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); } } } @@ -326,40 +304,21 @@ i915_emit_const4f(struct i915_fp_compile * p, for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { if (p->constant_flags[reg] == 0xf && -#if 0 - p->fp->constant[reg][0] == c0 && - p->fp->constant[reg][1] == c1 && - p->fp->constant[reg][2] == c2 && - p->fp->constant[reg][3] == c3 -#else - p->constants->constant[reg][0] == c0 && - p->constants->constant[reg][1] == c1 && - p->constants->constant[reg][2] == c2 && - p->constants->constant[reg][3] == c3 -#endif - ) { + p->constants[reg][0] == c0 && + p->constants[reg][1] == c1 && + p->constants[reg][2] == c2 && + p->constants[reg][3] == c3) { return UREG(REG_TYPE_CONST, reg); } else if (p->constant_flags[reg] == 0) { -#if 0 - p->fp->constant[reg][0] = c0; - p->fp->constant[reg][1] = c1; - p->fp->constant[reg][2] = c2; - p->fp->constant[reg][3] = c3; -#else - p->constants->constant[reg][0] = c0; - p->constants->constant[reg][1] = c1; - p->constants->constant[reg][2] = c2; - p->constants->constant[reg][3] = c3; -#endif + + p->constants[reg][0] = c0; + p->constants[reg][1] = c1; + p->constants[reg][2] = c2; + p->constants[reg][3] = c3; p->constant_flags[reg] = 0xf; -#if 0 - if (reg + 1 > p->fp->nr_constants) - p->fp->nr_constants = reg + 1; -#else - if (reg + 1 > p->constants->nr_constants) - p->constants->nr_constants = reg + 1; -#endif + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; return UREG(REG_TYPE_CONST, reg); } } diff --git a/src/mesa/pipe/i915simple/i915_fpc_translate.c b/src/mesa/pipe/i915simple/i915_fpc_translate.c index db2691ebe1c..dcf0d18f4ed 100644 --- a/src/mesa/pipe/i915simple/i915_fpc_translate.c +++ b/src/mesa/pipe/i915simple/i915_fpc_translate.c @@ -102,8 +102,8 @@ i915_use_passthrough_shader(struct i915_context *i915) i915->current.program_len = Elements(passthrough); } - i915->current.constants = NULL; - i915->current.num_constants = 0; + i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0; + i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0; } @@ -870,11 +870,11 @@ i915_init_compile(struct i915_context *i915, p->shader = &i915->fs; - /* a bit of a hack, need to improve constant buffer infrastructure */ - if (i915->fs.constants) - p->constants = i915->fs.constants; - else - p->constants = &i915->temp_constants; + /* new constants found during translation get appended after the + * user-provided constants. + */ + p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT]; + p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]; p->nr_tex_indirect = 1; /* correct? */ p->nr_tex_insn = 0; @@ -960,8 +960,10 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) program_size * sizeof(uint)); } - i915->current.constants = (uint *) p->constants->constant; - i915->current.num_constants = p->constants->nr_constants; + /* update number of constants */ + i915->current.num_constants[PIPE_SHADER_FRAGMENT] = p->num_constants; + assert(i915->current.num_constants[PIPE_SHADER_FRAGMENT] + >= i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]); } /* Release the compilation struct: diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index e8ffd1fd7b8..8f8b13253d1 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -30,6 +30,7 @@ #include "pipe/draw/draw_context.h" +#include "pipe/p_winsys.h" #include "i915_context.h" #include "i915_state.h" @@ -131,6 +132,44 @@ static void i915_set_vs_state( struct pipe_context *pipe, } +static void i915_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct i915_context *i915 = i915_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* Make a copy of shader constants. + * During fragment program translation we may add additional + * constants to the array. + * + * We want to consider the situation where some user constants + * (ex: a material color) may change frequently but the shader program + * stays the same. In that case we should only be updating the first + * N constants, leaving any extras from shader translation alone. + */ + { + void *mapped; + if (buf->size && + (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_FLAG_READ))) { + memcpy(i915->current.constants[shader], mapped, buf->size); + fprintf(stderr, "i915 problem: map of constant buffer failed\n"); + ws->buffer_unmap(ws, buf->buffer); + i915->current.num_user_constants[shader] + = buf->size / (4 * sizeof(float)); + } + else { + i915->current.num_user_constants[shader] = 0; + } + } + + i915->dirty |= I915_NEW_CONSTANTS; +} + + static void i915_set_sampler_state(struct pipe_context *pipe, unsigned unit, const struct pipe_sampler_state *sampler) @@ -256,6 +295,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_blend_state = i915_set_blend_state; i915->pipe.set_clip_state = i915_set_clip_state; i915->pipe.set_clear_color_state = i915_set_clear_color_state; + i915->pipe.set_constant_buffer = i915_set_constant_buffer; i915->pipe.set_depth_state = i915_set_depth_test_state; i915->pipe.set_framebuffer_state = i915_set_framebuffer_state; i915->pipe.set_fs_state = i915_set_fs_state; diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c index dcf02abb14c..dff9d40a83d 100644 --- a/src/mesa/pipe/i915simple/i915_state_emit.c +++ b/src/mesa/pipe/i915simple/i915_state_emit.c @@ -216,9 +216,11 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* constants */ if (i915->hardware_dirty & I915_HW_PROGRAM) { - const uint nr = i915->current.num_constants; + const uint nr = i915->current.num_constants[PIPE_SHADER_FRAGMENT]; + assert(nr <= I915_MAX_CONSTANT); if (nr > 0) { - const uint *c = (const uint *) i915->current.constants; + const uint *c + = (const uint *) i915->current.constants[PIPE_SHADER_FRAGMENT]; uint i; OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 3a656b272ea..0d90a967cc3 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -99,8 +99,12 @@ struct pipe_context { void (*set_clear_color_state)( struct pipe_context *, const struct pipe_clear_color_state * ); + void (*set_constant_buffer)( struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf ); + void (*set_depth_state)( struct pipe_context *, - const struct pipe_depth_state * ); + const struct pipe_depth_state * ); void (*set_framebuffer_state)( struct pipe_context *, const struct pipe_framebuffer_state * ); diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h index 43d1c438aed..636711938c8 100644 --- a/src/mesa/pipe/p_defines.h +++ b/src/mesa/pipe/p_defines.h @@ -276,6 +276,14 @@ #define PIPE_FLUSH_TEXTURE_CACHE 0x2 +/** + * Shaders + */ +#define PIPE_SHADER_VERTEX 0 +#define PIPE_SHADER_FRAGMENT 1 +#define PIPE_SHADER_TYPES 2 + + /** * Primitive types: */ diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 42bf50a6175..317e8e5634e 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -115,9 +115,12 @@ struct pipe_clip_state { }; +/** + * Constants for vertex/fragment shaders + */ struct pipe_constant_buffer { - float constant[PIPE_MAX_CONSTANT][4]; - unsigned nr_constants; + struct pipe_buffer_handle *buffer; + unsigned size; /** in bytes */ }; @@ -125,7 +128,6 @@ struct pipe_shader_state { unsigned inputs_read; /**< FRAG/VERT_ATTRIB_x */ unsigned outputs_written; /**< FRAG/VERT_RESULT_x */ const struct tgsi_token *tokens; - struct pipe_constant_buffer *constants; /* XXX temporary? */ }; struct pipe_depth_state diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index ab9becc99e2..5404b7f7905 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -237,6 +237,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.set_blend_state = softpipe_set_blend_state; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; softpipe->pipe.set_depth_state = softpipe_set_depth_test_state; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_fs_state = softpipe_set_fs_state; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 14ae9f21056..64585739171 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -33,6 +33,7 @@ #include "pipe/p_state.h" #include "pipe/p_context.h" +#include "pipe/p_defines.h" #include "sp_quad.h" @@ -64,6 +65,7 @@ enum interp_mode { #define SP_NEW_STENCIL 0x1000 #define SP_NEW_VERTEX 0x2000 #define SP_NEW_VS 0x4000 +#define SP_NEW_CONSTANTS 0x8000 struct softpipe_context { @@ -78,6 +80,7 @@ struct softpipe_context { struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; + struct pipe_constant_buffer constants[2]; struct pipe_depth_state depth_test; struct pipe_framebuffer_state framebuffer; struct pipe_shader_state fs; @@ -105,7 +108,9 @@ struct softpipe_context { * Mapped vertex buffers */ ubyte *mapped_vbuffer[PIPE_ATTRIB_MAX]; - + + /** Mapped constant buffers */ + void *mapped_constants[PIPE_SHADER_TYPES]; /* FS + setup derived state: */ diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index 0392b6b64e0..5198a493da3 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -43,6 +43,34 @@ +static void +softpipe_map_constant_buffers(struct softpipe_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, + PIPE_BUFFER_FLAG_READ); + } + + draw_set_mapped_constant_buffer(sp->draw, + sp->mapped_constants[PIPE_SHADER_VERTEX]); +} + +static void +softpipe_unmap_constant_buffers(struct softpipe_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + ws->buffer_unmap(ws, sp->constants[i].buffer); + sp->mapped_constants[i] = NULL; + } +} + + boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -81,6 +109,8 @@ softpipe_draw_elements(struct pipe_context *pipe, softpipe_map_surfaces(sp); + softpipe_map_constant_buffers(sp); + /* * Map vertex buffers */ @@ -123,6 +153,7 @@ softpipe_draw_elements(struct pipe_context *pipe, } softpipe_unmap_surfaces(sp); + softpipe_unmap_constant_buffers(sp); return TRUE; } diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index c20f09d3090..ceba94aa94d 100755 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -33,6 +33,7 @@ */ #include "pipe/p_util.h" +#include "pipe/p_defines.h" #include "sp_context.h" #include "sp_headers.h" @@ -83,7 +84,7 @@ shade_quad( qss->samplers ); /* Consts does not require 16 byte alignment. */ - machine.Consts = softpipe->fs.constants->constant; + machine.Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; machine.Inputs = ALIGN16_ASSIGN(inputs); machine.Outputs = ALIGN16_ASSIGN(outputs); diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 5e1ecd94e05..354580b2a5a 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -52,6 +52,10 @@ void softpipe_set_clear_color_state( struct pipe_context *, void softpipe_set_clip_state( struct pipe_context *, const struct pipe_clip_state * ); +void softpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + void softpipe_set_depth_test_state( struct pipe_context *, const struct pipe_depth_state * ); diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index bab407f047b..9e3ff6d35c0 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -28,6 +28,8 @@ #include "sp_context.h" #include "sp_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" #include "pipe/draw/draw_context.h" @@ -53,3 +55,24 @@ void softpipe_set_vs_state( struct pipe_context *pipe, draw_set_vertex_shader(softpipe->draw, vs); } + + +void softpipe_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + ws->buffer_unreference(ws, &softpipe->constants[shader].buffer); + softpipe->constants[shader].buffer = ws->buffer_reference(ws, buf->buffer); + softpipe->constants[shader].size = buf->size; + + softpipe->dirty |= SP_NEW_CONSTANTS; +} + + diff --git a/src/mesa/state_tracker/st_atom_fs.c b/src/mesa/state_tracker/st_atom_fs.c index 9aba9aaa565..019b6457e09 100644 --- a/src/mesa/state_tracker/st_atom_fs.c +++ b/src/mesa/state_tracker/st_atom_fs.c @@ -32,6 +32,8 @@ #include "shader/prog_parameter.h" #include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" #include "pipe/tgsi/mesa/mesa_to_tgsi.h" #include "pipe/tgsi/core/tgsi_dump.h" @@ -53,12 +55,36 @@ static void compile_fs( struct st_context *st, } +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 */ if (st->ctx->Shader.CurrentProgram && st->ctx->Shader.CurrentProgram->LinkStatus && st->ctx->Shader.CurrentProgram->FragmentProgram) { @@ -72,25 +98,21 @@ static void update_fs( struct st_context *st ) params = st->ctx->FragmentProgram._Current->Base.Parameters; } + /* update constants */ if (fp && params) { - /* load program's constants array */ - _mesa_load_state_parameters(st->ctx, params); - - fp->constants.nr_constants = params->NumParameters; - memcpy(fp->constants.constant, - params->ParameterValues, - params->NumParameters * sizeof(GLfloat) * 4); + 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 = fp->Base.Base.InputsRead; fs.outputs_written = fp->Base.Base.OutputsWritten; fs.tokens = &fp->tokens[0]; - fs.constants = &fp->constants; if (memcmp(&fs, &st->state.fs, sizeof(fs)) != 0 || fp->dirty) diff --git a/src/mesa/state_tracker/st_atom_vs.c b/src/mesa/state_tracker/st_atom_vs.c index c8bd805e022..8a38020afd7 100644 --- a/src/mesa/state_tracker/st_atom_vs.c +++ b/src/mesa/state_tracker/st_atom_vs.c @@ -34,6 +34,8 @@ #include "tnl/t_vp_build.h" #include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" #include "pipe/tgsi/mesa/mesa_to_tgsi.h" #include "pipe/tgsi/core/tgsi_dump.h" @@ -56,17 +58,36 @@ static void compile_vs( struct st_context *st, } +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; -#if 0 - if (st->ctx->VertexProgram._MaintainTnlProgram) - _tnl_UpdateFixedFunctionProgram( st->ctx ); -#endif - + /* find active shader and params */ if (st->ctx->Shader.CurrentProgram && st->ctx->Shader.CurrentProgram->LinkStatus && st->ctx->Shader.CurrentProgram->VertexProgram) { @@ -80,31 +101,21 @@ static void update_vs( struct st_context *st ) params = st->ctx->VertexProgram._Current->Base.Parameters; } - /* XXXX temp */ -#if 1 - if (!vp) - return; -#endif + /* update constants */ if (vp && params) { - /* load program's constants array */ - - /* XXX this should probably be done elsewhere/separately */ _mesa_load_state_parameters(st->ctx, params); - - vp->constants.nr_constants = params->NumParameters; - memcpy(vp->constants.constant, - params->ParameterValues, - params->NumParameters * sizeof(GLfloat) * 4); + update_vs_constants(st, params); } + /* translate shader to TGSI format */ if (vp->dirty) compile_vs( st, vp ); + /* update pipe state */ memset( &vs, 0, sizeof(vs) ); vs.outputs_written = vp->Base.Base.OutputsWritten; vs.inputs_read = vp->Base.Base.InputsRead; vs.tokens = &vp->tokens[0]; - vs.constants = &vp->constants; if (memcmp(&vs, &st->state.vs, sizeof(vs)) != 0 || vp->dirty) diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 2f2d11c0147..e3690deb5ae 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -350,7 +350,6 @@ clear_with_quad(GLcontext *ctx, memset(&fs, 0, sizeof(fs)); fs.inputs_read = stfp->Base.Base.InputsRead; fs.tokens = &stfp->tokens[0]; - fs.constants = NULL; pipe->set_fs_state(pipe, &fs); } @@ -365,7 +364,6 @@ clear_with_quad(GLcontext *ctx, vs.inputs_read = stvp->Base.Base.InputsRead; vs.outputs_written = stvp->Base.Base.OutputsWritten; vs.tokens = &stvp->tokens[0]; - vs.constants = NULL; pipe->set_vs_state(pipe, &vs); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index d3f060e691e..a45700e1db5 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -332,7 +332,6 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, memset(&fs, 0, sizeof(fs)); fs.inputs_read = stfp->Base.Base.InputsRead; fs.tokens = &stfp->tokens[0]; - fs.constants = NULL; pipe->set_fs_state(pipe, &fs); } @@ -347,7 +346,6 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, vs.inputs_read = stvp->Base.Base.InputsRead; vs.outputs_written = stvp->Base.Base.OutputsWritten; vs.tokens = &stvp->tokens[0]; - vs.constants = NULL; pipe->set_vs_state(pipe, &vs); } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 35774a790e2..38d6a3ed86e 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -71,16 +71,17 @@ struct st_context struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; + struct pipe_constant_buffer constants[2]; struct pipe_depth_state depth; struct pipe_framebuffer_state framebuffer; - struct pipe_shader_state fs; - struct pipe_shader_state vs; + struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_poly_stipple poly_stipple; struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; struct pipe_setup_state setup; + struct pipe_shader_state fs; + struct pipe_shader_state vs; struct pipe_stencil_state stencil; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; } state; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index b077fdf0698..3ff4f4e9c78 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -53,8 +53,6 @@ struct st_fragment_program struct tgsi_token tokens[ST_FP_MAX_TOKENS]; GLboolean dirty; - struct pipe_constant_buffer constants; - #if 0 GLfloat (*cbuffer)[4]; GLuint nr_constants; @@ -85,7 +83,9 @@ struct st_vertex_program struct tgsi_token tokens[ST_FP_MAX_TOKENS]; GLboolean dirty; +#if 0 struct pipe_constant_buffer constants; +#endif GLuint param_state; };