From b642730be93149baa7556e5791393168ab396175 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 15 Feb 2008 17:35:24 +0900 Subject: Code reorganization: move files into their places. This is in a separate commit to ensure renames are properly preserved. --- src/gallium/drivers/i915simple/i915_state_emit.c | 374 +++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 src/gallium/drivers/i915simple/i915_state_emit.c (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c new file mode 100644 index 0000000000..3339287f49 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -0,0 +1,374 @@ +/************************************************************************** + * + * Copyright 2003 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. + * + **************************************************************************/ + + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_batch.h" +#include "i915_reg.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" + +static unsigned translate_format( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + return COLOR_BUF_ARGB8888; + case PIPE_FORMAT_R5G6B5_UNORM: + return COLOR_BUF_RGB565; + default: + assert(0); + return 0; + } +} + +static unsigned translate_depth_format( enum pipe_format zformat ) +{ + switch (zformat) { + case PIPE_FORMAT_S8Z24_UNORM: + return DEPTH_FRMT_24_FIXED_8_OTHER; + case PIPE_FORMAT_Z16_UNORM: + return DEPTH_FRMT_16_FIXED; + default: + assert(0); + return 0; + } +} + + +/** + * Examine framebuffer state to determine width, height. + */ +static boolean +framebuffer_size(const struct pipe_framebuffer_state *fb, + uint *width, uint *height) +{ + if (fb->cbufs[0]) { + *width = fb->cbufs[0]->width; + *height = fb->cbufs[0]->height; + return TRUE; + } + else if (fb->zsbuf) { + *width = fb->zsbuf->width; + *height = fb->zsbuf->height; + return TRUE; + } + else { + *width = *height = 0; + return FALSE; + } +} + + +/* Push the state into the sarea and/or texture memory. + */ +void +i915_emit_hardware_state(struct i915_context *i915 ) +{ + /* XXX: there must be an easier way */ + const unsigned dwords = ( 14 + + 7 + + I915_MAX_DYNAMIC + + 8 + + 2 + I915_TEX_UNITS*3 + + 2 + I915_TEX_UNITS*3 + + 2 + I915_MAX_CONSTANT*4 + + i915->current.program_len + + 6 + ) * 3/2; /* plus 50% margin */ + const unsigned relocs = ( I915_TEX_UNITS + + 3 + ) * 3/2; /* plus 50% margin */ + +#if 0 + debug_printf("i915_emit_hardware_state: %d dwords, %d relocs\n", dwords, relocs); +#endif + + if(!BEGIN_BATCH(dwords, relocs)) { + FLUSH_BATCH(); + assert(BEGIN_BATCH(dwords, relocs)); + } + + /* 14 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_INVARIENT) + { + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | + CSB_TCB(5, 5) | + CSB_TCB(6, 6) | + CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_TEXKILL_3D_4D | + TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0)); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + /* disable indirect state for now + */ + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); + OUT_BATCH(0); + } + + /* 7 dwords, 1 relocs */ + if (i915->hardware_dirty & I915_HW_IMMEDIATE) + { + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(0) | + I1_LOAD_S(1) | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | + I1_LOAD_S(6) | + (5)); + + if(i915->vbo) + OUT_RELOC(i915->vbo, + I915_BUFFER_ACCESS_READ, + i915->current.immediate[I915_IMMEDIATE_S0]); + else + /* FIXME: we should not do this */ + OUT_BATCH(0); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S6]); + } + + /* I915_MAX_DYNAMIC dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_DYNAMIC) + { + int i; + for (i = 0; i < I915_MAX_DYNAMIC; i++) { + OUT_BATCH(i915->current.dynamic[i]); + } + } + + /* 8 dwords, 2 relocs */ + if (i915->hardware_dirty & I915_HW_STATIC) + { + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; + + if (cbuf_surface) { + unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp); + + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); + + OUT_BATCH(BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + OUT_RELOC(cbuf_surface->buffer, + I915_BUFFER_ACCESS_WRITE, + 0); + } + + /* What happens if no zbuf?? + */ + if (depth_surface) { + unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); + + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); + + OUT_BATCH(BUF_3D_ID_DEPTH | + BUF_3D_PITCH(zpitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + OUT_RELOC(depth_surface->buffer, + I915_BUFFER_ACCESS_WRITE, + 0); + } + + { + unsigned cformat, zformat = 0; + + if (cbuf_surface) + cformat = cbuf_surface->format; + else + cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */ + cformat = translate_format(cformat); + + if (depth_surface) + zformat = translate_depth_format( i915->framebuffer.zsbuf->format ); + + OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); + OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + cformat | + zformat ); + } + } + +#if 01 + /* texture images */ + /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */ + if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER)) + { + /* XXX: we were refering to sampler state + * (current.sampler_enable_nr) below, but only checking + * I915_HW_MAP above. Should probably calculate the enabled + * flags separately - but there will be further rework of + * state so perhaps not necessary yet. + */ + const uint nr = i915->current.sampler_enable_nr; + if (nr) { + const uint enabled = i915->current.sampler_enable_flags; + uint unit; + uint count = 0; + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH(enabled); + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + if (enabled & (1 << unit)) { + struct pipe_buffer *buf = + i915->texture[unit]->buffer; + uint offset = 0; + assert(buf); + + count++; + + OUT_RELOC(buf, + I915_BUFFER_ACCESS_READ, + offset); + OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ + OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ + } + } + assert(count == nr); + } + } +#endif + +#if 01 + /* samplers */ + /* 2 + I915_TEX_UNITS*3 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_SAMPLER) + { + if (i915->current.sampler_enable_nr) { + int i; + + OUT_BATCH( _3DSTATE_SAMPLER_STATE | + (3 * i915->current.sampler_enable_nr) ); + + OUT_BATCH( i915->current.sampler_enable_flags ); + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (i915->current.sampler_enable_flags & (1<current.sampler[i][0] ); + OUT_BATCH( i915->current.sampler[i][1] ); + OUT_BATCH( i915->current.sampler[i][2] ); + } + } + } + } +#endif + + /* constants */ + /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_PROGRAM) + { + 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[PIPE_SHADER_FRAGMENT]; + uint i; + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); + OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + for (i = 0; i < nr; i++) { + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + } + } + } + + /* Fragment program */ + /* i915->current.program_len dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_PROGRAM) + { + uint i; + /* we should always have, at least, a pass-through program */ + assert(i915->current.program_len > 0); + for (i = 0; i < i915->current.program_len; i++) { + OUT_BATCH(i915->current.program[i]); + } + } + + /* drawing surface size */ + /* 6 dwords, 0 relocs */ + { + uint w, h; + boolean k = framebuffer_size(&i915->framebuffer, &w, &h); + assert(k); + + OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(((w - 1) & 0xffff) | ((h - 1) << 16)); + OUT_BATCH(0); + OUT_BATCH(0); + } + + + i915->hardware_dirty = 0; +} -- cgit v1.2.3 From c74900ee5d80c7c2b7cbe4ed87395526a742a13e Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 16:48:05 -0700 Subject: gallium/i915: overhaul of fragment shader compilation, constant/immediate allocation Before, fragment shaders were translated to i915 hw code at bind time, rather than create time. Now there's an i915_fragment_shader struct with the expected contents that's created by i915_create_fs_state(). Translation to i915 code takes place there too. Immediates are handled correctly now. During program translation we keep track of which constant buffer slots are free (i.e. not referenced by the shader). Then the TGSI immediates and ancillary immediates (introduced for SIN/COS/etc) are put into those free slots. When it's time to upload the constant buffer, use the fp->constant_flags[] array to determine if we should grab an immediate from the shader, or a user-defined parameter from the gallium constant buffer. --- src/gallium/drivers/i915simple/i915_context.h | 42 ++++++- src/gallium/drivers/i915simple/i915_fpc.h | 23 ++-- src/gallium/drivers/i915simple/i915_fpc_emit.c | 101 +++++----------- .../drivers/i915simple/i915_fpc_translate.c | 132 +++++++++++++-------- src/gallium/drivers/i915simple/i915_state.c | 36 ++++-- .../drivers/i915simple/i915_state_derived.c | 3 +- src/gallium/drivers/i915simple/i915_state_emit.c | 39 ++++-- 7 files changed, 226 insertions(+), 150 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 2d876925b2..5cc38cdc85 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -79,6 +79,40 @@ #define I915_MAX_CONSTANT 32 +/** See constant_flags[] below */ +#define I915_CONSTFLAG_USER 0x1f + + +/** + * Subclass of pipe_shader_state + */ +struct i915_fragment_shader +{ + struct pipe_shader_state state; + uint *program; + uint program_len; + + /** + * constants introduced during translation. + * These are placed at the end of the constant buffer and grow toward + * the beginning (eg: slot 31, 30 29, ...) + * User-provided constants start at 0. + * This allows both types of constants to co-exist (until there's too many) + * and doesn't require regenerating/changing the fragment program to + * shuffle constants around. + */ + uint num_constants; + float constants[I915_MAX_CONSTANT][4]; + + /** + * Status of each constant + * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding + * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + struct i915_cache_context; @@ -93,11 +127,6 @@ struct i915_state 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; /* texture sampler state */ unsigned sampler[I915_TEX_UNITS][3]; @@ -187,7 +216,8 @@ struct i915_context const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct i915_depth_stencil_state *depth_stencil; const struct i915_rasterizer_state *rasterizer; - const struct pipe_shader_state *fs; + + struct i915_fragment_shader *fs; struct pipe_blend_color blend_color; struct pipe_clip_state clip; diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h index 8c7b68aefb..250dfe6dbf 100644 --- a/src/gallium/drivers/i915simple/i915_fpc.h +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -44,9 +44,16 @@ * Program translation state */ struct i915_fp_compile { - const struct pipe_shader_state *shader; + struct i915_fragment_shader *shader; /* the shader we're compiling */ - struct vertex_info *vertex_info; + boolean used_constants[I915_MAX_CONSTANT]; + + /** maps TGSI immediate index to constant slot */ + uint num_immediates; + uint immediates_map[I915_MAX_CONSTANT]; + float immediates[I915_MAX_CONSTANT][4]; + + boolean first_instruction; uint declarations[I915_PROGRAM_SIZE]; uint program[I915_PROGRAM_SIZE]; @@ -57,11 +64,6 @@ struct i915_fp_compile { uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - /** 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. */ uint *decl; /**< Cursor, points into declarations. */ @@ -155,7 +157,9 @@ swizzle(int reg, uint x, uint y, uint z, uint w) /*********************************************************************** * Public interface for the compiler */ -extern void i915_translate_fragment_program( struct i915_context *i915 ); +extern void +i915_translate_fragment_program( struct i915_context *i915, + struct i915_fragment_shader *fs); @@ -206,8 +210,5 @@ extern void i915_disassemble_program(const uint * program, uint sz); extern void i915_program_error(struct i915_fp_compile *p, const char *msg, ...); -extern void -i915_translate_fragment_program(struct i915_context *i915); - #endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index 74924ff0a1..a59ee23403 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -61,8 +61,6 @@ (REG_NR_MASK << UREG_NR_SHIFT)) -#define I915_CONSTFLAG_PARAM 0x1f - uint i915_get_temp(struct i915_fp_compile *p) { @@ -235,6 +233,7 @@ uint i915_emit_texld( struct i915_fp_compile *p, uint i915_emit_const1f(struct i915_fp_compile * p, float c0) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg, idx; if (c0 == 0.0) @@ -243,15 +242,15 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER) continue; for (idx = 0; idx < 4; idx++) { - if (!(p->constant_flags[reg] & (1 << idx)) || - p->constants[reg][idx] == c0) { - p->constants[reg][idx] = c0; - p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + if (!(ifs->constant_flags[reg] & (1 << idx)) || + ifs->constants[reg][idx] == c0) { + ifs->constants[reg][idx] = c0; + ifs->constant_flags[reg] |= 1 << idx; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); } } @@ -264,6 +263,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) uint i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg, idx; if (c0 == 0.0) @@ -277,16 +277,16 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf || - p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + if (ifs->constant_flags[reg] == 0xf || + ifs->constant_flags[reg] == I915_CONSTFLAG_USER) continue; for (idx = 0; idx < 3; idx++) { - if (!(p->constant_flags[reg] & (3 << idx))) { - p->constants[reg][idx + 0] = c0; - p->constants[reg][idx + 1] = c1; - p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + if (!(ifs->constant_flags[reg] & (3 << idx))) { + ifs->constants[reg][idx + 0] = c0; + ifs->constants[reg][idx + 1] = c1; + ifs->constant_flags[reg] |= 3 << idx; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); } } @@ -302,25 +302,26 @@ uint i915_emit_const4f(struct i915_fp_compile * p, float c0, float c1, float c2, float c3) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg; for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf && - p->constants[reg][0] == c0 && - p->constants[reg][1] == c1 && - p->constants[reg][2] == c2 && - p->constants[reg][3] == c3) { + if (ifs->constant_flags[reg] == 0xf && + ifs->constants[reg][0] == c0 && + ifs->constants[reg][1] == c1 && + ifs->constants[reg][2] == c2 && + ifs->constants[reg][3] == c3) { return UREG(REG_TYPE_CONST, reg); } - else if (p->constant_flags[reg] == 0) { - - 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 (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + else if (ifs->constant_flags[reg] == 0) { + + ifs->constants[reg][0] = c0; + ifs->constants[reg][1] = c1; + ifs->constants[reg][2] = c2; + ifs->constants[reg][3] = c3; + ifs->constant_flags[reg] = 0xf; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return UREG(REG_TYPE_CONST, reg); } } @@ -335,41 +336,3 @@ i915_emit_const4fv(struct i915_fp_compile * p, const float * c) { return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); } - - -#if 00000/*UNUSED*/ -/* Reserve a slot in the constant file for a Mesa state parameter. - * These will later need to be tracked on statechanges, but that is - * done elsewhere. - */ -uint -i915_emit_param4fv(struct i915_fp_compile * p, const float * values) -{ - struct i915_fragment_program *fp = p->fp; - int i; - - for (i = 0; i < fp->nr_params; i++) { - if (fp->param[i].values == values) - return UREG(REG_TYPE_CONST, fp->param[i].reg); - } - - if (p->constants->nr_constants == I915_MAX_CONSTANT || - fp->nr_params == I915_MAX_CONSTANT) { - i915_program_error(p, "i915_emit_param4fv: out of constants\n"); - return 0; - } - - { - int reg = p->constants->nr_constants++; - int i = fp->nr_params++; - - assert (p->constant_flags[reg] == 0); - p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - - fp->param[i].values = values; - fp->param[i].reg = reg; - - return UREG(REG_TYPE_CONST, reg); - } -} -#endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 6c1524c768..afe7e25dce 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -34,6 +34,7 @@ #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_dump.h" #include "draw/draw_vertex.h" @@ -97,19 +98,19 @@ negate(int reg, int x, int y, int z, int w) } +/** + * In the event of a translation failure, we'll generate a simple color + * pass-through program. + */ static void -i915_use_passthrough_shader(struct i915_context *i915) +i915_use_passthrough_shader(struct i915_fragment_shader *fs) { - debug_printf("**** Using i915 pass-through fragment shader\n"); - - i915->current.program = (uint *) MALLOC(sizeof(passthrough)); - if (i915->current.program) { - memcpy(i915->current.program, passthrough, sizeof(passthrough)); - i915->current.program_len = Elements(passthrough); + fs->program = (uint *) MALLOC(sizeof(passthrough)); + if (fs->program) { + memcpy(fs->program, passthrough, sizeof(passthrough)); + fs->program_len = Elements(passthrough); } - - i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0; - i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0; + fs->num_constants = 0; } @@ -161,9 +162,6 @@ src_vector(struct i915_fp_compile *p, * We also use a texture coordinate to pass wpos when possible. */ - /* use vertex format info to map a slot number to a VF attrib */ - assert(index < p->vertex_info->num_attribs); - sem_name = p->input_semantic_name[index]; sem_ind = p->input_semantic_index[index]; @@ -201,7 +199,8 @@ src_vector(struct i915_fp_compile *p, break; case TGSI_FILE_IMMEDIATE: - /* XXX unfinished - need to append immediates onto const buffer */ + assert(index < p->num_immediates); + index = p->immediates_map[index]; /* fall-through */ case TGSI_FILE_CONSTANT: src = UREG(REG_TYPE_CONST, index); @@ -896,6 +895,7 @@ static void i915_translate_instructions(struct i915_fp_compile *p, const struct tgsi_token *tokens) { + struct i915_fragment_shader *ifs = p->shader; struct tgsi_parse_context parse; tgsi_parse_init( &parse, tokens ); @@ -928,13 +928,54 @@ i915_translate_instructions(struct i915_fp_compile *p, p->output_semantic_name[ind] = sem; p->output_semantic_index[ind] = semi; } + else if (parse.FullToken.FullDeclaration.Declaration.File + == TGSI_FILE_CONSTANT) { + uint i; + for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + i++) { + assert(ifs->constant_flags[i] == 0x0); + ifs->constant_flags[i] = I915_CONSTFLAG_USER; + ifs->num_constants = MAX2(ifs->num_constants, i + 1); + } + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX append the immediate to the const buffer... */ + { + const struct tgsi_full_immediate *imm + = &parse.FullToken.FullImmediate; + const uint pos = p->num_immediates++; + uint j; + for (j = 0; j < imm->Immediate.Size; j++) { + p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float; + } + } break; case TGSI_TOKEN_TYPE_INSTRUCTION: + if (p->first_instruction) { + /* resolve location of immediates */ + uint i, j; + for (i = 0; i < p->num_immediates; i++) { + /* find constant slot for this immediate */ + for (j = 0; j < I915_MAX_CONSTANT; j++) { + if (ifs->constant_flags[j] == 0x0) { + memcpy(ifs->constants[j], + p->immediates[i], + 4 * sizeof(float)); + /*printf("immediate %d maps to const %d\n", i, j);*/ + ifs->constant_flags[j] = 0xf; /* all four comps used */ + p->immediates_map[i] = j; + ifs->num_constants = MAX2(ifs->num_constants, j + 1); + break; + } + } + } + + p->first_instruction = FALSE; + } + i915_translate_instruction(p, &parse.FullToken.FullInstruction); break; @@ -950,27 +991,28 @@ i915_translate_instructions(struct i915_fp_compile *p, static struct i915_fp_compile * i915_init_compile(struct i915_context *i915, - const struct pipe_shader_state *fs) + struct i915_fragment_shader *ifs) { struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); - p->shader = i915->fs; + p->shader = ifs; - p->vertex_info = &i915->current.vertex_info; - - /* new constants found during translation get appended after the - * user-provided constants. + /* Put new constants at end of const buffer, growing downward. + * The problem is we don't know how many user-defined constants might + * be specified with pipe->set_constant_buffer(). + * Should pre-scan the user's program to determine the highest-numbered + * constant referenced. */ - p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT]; - p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]; + ifs->num_constants = 0; + memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags)); + + p->first_instruction = TRUE; p->nr_tex_indirect = 1; /* correct? */ p->nr_tex_insn = 0; p->nr_alu_insn = 0; p->nr_decl_insn = 0; - memset(p->constant_flags, 0, sizeof(p->constant_flags)); - p->csr = p->program; p->decl = p->declarations; p->decl_s = 0; @@ -993,6 +1035,7 @@ i915_init_compile(struct i915_context *i915, static void i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) { + struct i915_fragment_shader *ifs = p->shader; unsigned long program_size = (unsigned long) (p->csr - p->program); unsigned long decl_size = (unsigned long) (p->decl - p->declarations); @@ -1008,19 +1051,13 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) if (p->nr_decl_insn > I915_MAX_DECL_INSN) i915_program_error(p, "Exceeded max DECL instructions"); - /* free old program, if present */ - if (i915->current.program) { - FREE(i915->current.program); - i915->current.program_len = 0; - } - if (p->error) { p->NumNativeInstructions = 0; p->NumNativeAluInstructions = 0; p->NumNativeTexInstructions = 0; p->NumNativeTexIndirections = 0; - i915_use_passthrough_shader(i915); + i915_use_passthrough_shader(ifs); } else { p->NumNativeInstructions @@ -1034,24 +1071,20 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) /* Copy compilation results to fragment program struct: */ - i915->current.program + assert(!ifs->program); + ifs->program = (uint *) MALLOC((program_size + decl_size) * sizeof(uint)); - if (i915->current.program) { - i915->current.program_len = program_size + decl_size; + if (ifs->program) { + ifs->program_len = program_size + decl_size; - memcpy(i915->current.program, + memcpy(ifs->program, p->declarations, decl_size * sizeof(uint)); - memcpy(i915->current.program + decl_size, + memcpy(ifs->program + decl_size, p->program, program_size * sizeof(uint)); } - - /* 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: @@ -1085,7 +1118,7 @@ i915_find_wpos_space(struct i915_fp_compile *p) i915_program_error(p, "No free texcoord for wpos value"); } #else - if (p->shader->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->state.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { /* frag shader using the fragment position input */ #if 0 assert(0); @@ -1106,7 +1139,7 @@ static void i915_fixup_depth_write(struct i915_fp_compile *p) { /* XXX assuming pos/depth is always in output[0] */ - if (p->shader->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->state.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { const uint depth = UREG(REG_TYPE_OD, 0); i915_emit_arith(p, @@ -1121,13 +1154,18 @@ i915_fixup_depth_write(struct i915_fp_compile *p) void -i915_translate_fragment_program( struct i915_context *i915 ) +i915_translate_fragment_program( struct i915_context *i915, + struct i915_fragment_shader *fs) { - struct i915_fp_compile *p = i915_init_compile(i915, i915->fs); - const struct tgsi_token *tokens = i915->fs->tokens; + struct i915_fp_compile *p = i915_init_compile(i915, fs); + const struct tgsi_token *tokens = fs->state.tokens; i915_find_wpos_space(p); +#if 0 + tgsi_dump(tokens, 0); +#endif + i915_translate_instructions(p, tokens); i915_fixup_depth_write(p); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e055eed7e0..e4288d4e31 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -38,6 +38,7 @@ #include "i915_reg.h" #include "i915_state.h" #include "i915_state_inlines.h" +#include "i915_fpc.h" /* The i915 (and related graphics cores) do not support GL_CLAMP. The @@ -416,26 +417,47 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe, } -static void * i915_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) + +static void * +i915_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { - return 0; + struct i915_context *i915 = i915_context(pipe); + struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader); + if (!ifs) + return NULL; + + ifs->state = *templ; + + /* The shader's compiled to i915 instructions here */ + i915_translate_fragment_program(i915, ifs); + + return ifs; } -static void i915_bind_fs_state(struct pipe_context *pipe, void *fs) +static void +i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); - i915->fs = (struct pipe_shader_state *)fs; + i915->fs = (struct i915_fragment_shader*) shader; i915->dirty |= I915_NEW_FS; } -static void i915_delete_fs_state(struct pipe_context *pipe, void *shader) +static +void i915_delete_fs_state(struct pipe_context *pipe, void *shader) { - /*do nothing*/ + struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; + + if (ifs->program) + FREE(ifs->program); + ifs->program_len = 0; + + FREE(ifs); } + static void * i915_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 4767584fc6..f654f543cc 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -43,7 +43,7 @@ */ static void calculate_vertex_layout( struct i915_context *i915 ) { - const struct pipe_shader_state *fs = i915->fs; + const struct pipe_shader_state *fs = &i915->fs->state; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; @@ -164,7 +164,6 @@ void i915_update_derived( struct i915_context *i915 ) i915_update_dynamic( i915 ); if (i915->dirty & I915_NEW_FS) { - i915_translate_fragment_program(i915); i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ } diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 3339287f49..6bbaac4e34 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -99,7 +99,11 @@ i915_emit_hardware_state(struct i915_context *i915 ) 2 + I915_TEX_UNITS*3 + 2 + I915_TEX_UNITS*3 + 2 + I915_MAX_CONSTANT*4 + +#if 0 i915->current.program_len + +#else + i915->fs->program_len + +#endif 6 ) * 3/2; /* plus 50% margin */ const unsigned relocs = ( I915_TEX_UNITS + @@ -325,15 +329,34 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */ if (i915->hardware_dirty & I915_HW_PROGRAM) { - 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[PIPE_SHADER_FRAGMENT]; + /* Collate the user-defined constants with the fragment shader's + * immediates according to the constant_flags[] array. + */ + const uint nr = i915->fs->num_constants; + if (nr) { uint i; + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + for (i = 0; i < nr; i++) { + const uint *c; + if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) { + /* grab user-defined constant */ + c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i]; + } + else { + /* emit program constant */ + c = (uint *) i915->fs->constants[i]; + } +#if 0 /* debug */ + { + float *f = (float *) c; + printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3], + (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER + ? "user" : "immediate")); + } +#endif OUT_BATCH(*c++); OUT_BATCH(*c++); OUT_BATCH(*c++); @@ -348,9 +371,9 @@ i915_emit_hardware_state(struct i915_context *i915 ) { uint i; /* we should always have, at least, a pass-through program */ - assert(i915->current.program_len > 0); - for (i = 0; i < i915->current.program_len; i++) { - OUT_BATCH(i915->current.program[i]); + assert(i915->fs->program_len > 0); + for (i = 0; i < i915->fs->program_len; i++) { + OUT_BATCH(i915->fs->program[i]); } } -- cgit v1.2.3 From 4528287e040415c2071012d02f20979ff995c754 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 5 Mar 2008 10:50:14 +0100 Subject: gallium: michel's patch to rework texture/sampler binding interface Bind all the samplers/textures at once rather than piecemeal. This is easier for drivers to understand. --- src/gallium/auxiliary/draw/draw_aaline.c | 54 +- src/gallium/auxiliary/draw/draw_pstipple.c | 51 +- src/gallium/drivers/failover/fo_context.h | 7 +- src/gallium/drivers/failover/fo_state.c | 59 +- src/gallium/drivers/failover/fo_state_emit.c | 18 +- src/gallium/drivers/i915simple/i915_context.h | 675 +++++----- src/gallium/drivers/i915simple/i915_state.c | 46 +- src/gallium/drivers/i915simple/i915_state_emit.c | 6 - .../drivers/i915simple/i915_state_sampler.c | 6 +- src/gallium/drivers/i965simple/brw_context.h | 1365 ++++++++++---------- src/gallium/drivers/i965simple/brw_state.c | 896 ++++++------- .../drivers/i965simple/brw_wm_sampler_state.c | 3 +- .../drivers/i965simple/brw_wm_surface_state.c | 2 +- src/gallium/drivers/softpipe/sp_context.c | 486 +++---- src/gallium/drivers/softpipe/sp_context.h | 3 + src/gallium/drivers/softpipe/sp_quad_fs.c | 417 +++--- src/gallium/drivers/softpipe/sp_state.h | 390 +++--- src/gallium/drivers/softpipe/sp_state_sampler.c | 56 +- src/gallium/drivers/softpipe/sp_texture.c | 404 +++--- src/gallium/include/pipe/p_context.h | 8 +- src/mesa/state_tracker/st_atom_sampler.c | 16 +- src/mesa/state_tracker/st_atom_texture.c | 15 +- src/mesa/state_tracker/st_cb_drawpixels.c | 11 +- src/mesa/state_tracker/st_context.h | 5 +- src/mesa/state_tracker/st_gen_mipmap.c | 11 +- 25 files changed, 2561 insertions(+), 2449 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 7660e56fe6..3ec73b0800 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -78,7 +78,8 @@ struct aaline_stage void *sampler_cso; struct pipe_texture *texture; - uint sampler_unit; + uint num_samplers; + uint num_textures; /* @@ -98,11 +99,10 @@ struct aaline_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); - - void (*driver_set_sampler_texture)(struct pipe_context *, - unsigned sampler, - struct pipe_texture *); + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, + void **); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); struct pipe_context *pipe; }; @@ -607,6 +607,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) auto struct aaline_stage *aaline = aaline_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = aaline->pipe; + uint num = MAX2(aaline->num_textures, aaline->num_samplers); assert(draw->rasterizer->line_smooth); @@ -624,8 +625,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) */ bind_aaline_fragment_shader(aaline); - aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso); - aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture); + aaline->state.sampler[num] = aaline->sampler_cso; + aaline->state.texture[num] = aaline->texture; + + aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture); /* now really draw first line */ stage->line = aaline_line; @@ -647,10 +651,10 @@ aaline_flush(struct draw_stage *stage, unsigned flags) aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); /* XXX restore original texture, sampler state */ - aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, - aaline->state.sampler[aaline->sampler_unit]); - aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, - aaline->state.texture[aaline->sampler_unit]); + aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, + aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, aaline->num_textures, + aaline->state.texture); draw->extra_vp_outputs.slot = 0; } @@ -745,26 +749,28 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs) static void -aaline_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +aaline_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); /* save current */ - aaline->state.sampler[unit] = sampler; + memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); + aaline->num_samplers = num; /* pass-through */ - aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler); + aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); } static void -aaline_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, struct pipe_texture *texture) +aaline_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); /* save current */ - aaline->state.texture[sampler] = texture; + memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *)); + aaline->num_textures = num; /* pass-through */ - aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture); + aaline->driver_set_sampler_textures(aaline->pipe, num, texture); } @@ -798,14 +804,14 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_bind_fs_state = pipe->bind_fs_state; aaline->driver_delete_fs_state = pipe->delete_fs_state; - aaline->driver_bind_sampler_state = pipe->bind_sampler_state; - aaline->driver_set_sampler_texture = pipe->set_sampler_texture; + aaline->driver_bind_sampler_states = pipe->bind_sampler_states; + aaline->driver_set_sampler_textures = pipe->set_sampler_textures; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; pipe->bind_fs_state = aaline_bind_fs_state; pipe->delete_fs_state = aaline_delete_fs_state; - pipe->bind_sampler_state = aaline_bind_sampler_state; - pipe->set_sampler_texture = aaline_set_sampler_texture; + pipe->bind_sampler_states = aaline_bind_sampler_states; + pipe->set_sampler_textures = aaline_set_sampler_textures; } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 2cfeb813b3..894b136f2c 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -68,7 +68,8 @@ struct pstip_stage void *sampler_cso; struct pipe_texture *texture; - uint sampler_unit; + uint num_samplers; + uint num_textures; /* * Currently bound state @@ -88,11 +89,10 @@ struct pstip_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_texture)(struct pipe_context *, - unsigned sampler, - struct pipe_texture *); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); void (*driver_set_polygon_stipple)(struct pipe_context *, const struct pipe_poly_stipple *); @@ -328,8 +328,6 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_dump(pstip_fs.tokens, 0); #endif - pstip->sampler_unit = transform.maxSampler + 1; - #if 1 /* XXX remove */ if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; @@ -486,6 +484,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) struct pstip_stage *pstip = pstip_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = pstip->pipe; + uint num = MAX2(pstip->num_textures, pstip->num_samplers); assert(draw->rasterizer->poly_stipple_enable); @@ -494,8 +493,8 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) */ bind_pstip_fragment_shader(pstip); - pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso); - pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture); + pstip->driver_bind_sampler_states(pipe, num + 1, pstip->state.sampler); + pstip->driver_set_sampler_textures(pipe, num + 1, pstip->state.texture); /* now really draw first line */ stage->tri = passthrough_tri; @@ -517,10 +516,10 @@ pstip_flush(struct draw_stage *stage, unsigned flags) pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); /* XXX restore original texture, sampler state */ - pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, - pstip->state.sampler[pstip->sampler_unit]); - pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, - pstip->state.texture[pstip->sampler_unit]); + pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, + pstip->state.sampler); + pstip->driver_set_sampler_textures(pipe, pstip->num_textures, + pstip->state.texture); } @@ -613,26 +612,28 @@ pstip_delete_fs_state(struct pipe_context *pipe, void *fs) static void -pstip_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +pstip_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - pstip->state.sampler[unit] = sampler; + memcpy(pstip->state.sampler, sampler, num * sizeof(void *)); + pstip->num_samplers = num; /* pass-through */ - pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler); + pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); } static void -pstip_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, struct pipe_texture *texture) +pstip_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - pstip->state.texture[sampler] = texture; + memcpy(pstip->state.texture, texture, num * sizeof(struct pipe_texture *)); + pstip->num_textures = num; /* pass-through */ - pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture); + pstip->driver_set_sampler_textures(pstip->pipe, num, texture); } @@ -682,8 +683,8 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->driver_bind_fs_state = pipe->bind_fs_state; pstip->driver_delete_fs_state = pipe->delete_fs_state; - pstip->driver_bind_sampler_state = pipe->bind_sampler_state; - pstip->driver_set_sampler_texture = pipe->set_sampler_texture; + pstip->driver_bind_sampler_states = pipe->bind_sampler_states; + pstip->driver_set_sampler_textures = pipe->set_sampler_textures; pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; /* override the driver's functions */ @@ -691,7 +692,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_fs_state = pstip_bind_fs_state; pipe->delete_fs_state = pstip_delete_fs_state; - pipe->bind_sampler_state = pstip_bind_sampler_state; - pipe->set_sampler_texture = pstip_set_sampler_texture; + pipe->bind_sampler_states = pstip_bind_sampler_states; + pipe->set_sampler_textures = pstip_set_sampler_textures; pipe->set_polygon_stipple = pstip_set_polygon_stipple; } diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 1dc87291c9..8f3ad3ee79 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -87,12 +87,15 @@ struct failover_context { struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + void *sw_sampler_state[PIPE_MAX_SAMPLERS]; + void *hw_sampler_state[PIPE_MAX_SAMPLERS]; + unsigned dirty; - unsigned dirty_sampler; - unsigned dirty_texture; unsigned dirty_vertex_buffer; unsigned dirty_vertex_element; + unsigned num_samplers; + unsigned num_textures; unsigned mode; struct pipe_context *hw; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 0fc5568da1..11eec2714e 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -28,6 +28,8 @@ /* Authors: Keith Whitwell */ +#include "pipe/p_inlines.h" + #include "fo_context.h" @@ -322,18 +324,27 @@ failover_create_sampler_state(struct pipe_context *pipe, } static void -failover_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +failover_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct failover_context *failover = failover_context(pipe); struct fo_state *state = (struct fo_state*)sampler; - failover->sampler[unit] = state; + uint i; + assert(num <= PIPE_MAX_SAMPLERS); + /* Check for no-op */ + if (num == failover->num_samplers && + !memcmp(failover->sampler, sampler, num * sizeof(void *))) + return; + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + failover->sw_sampler_state[i] = i < num ? state[i].sw_state : NULL; + failover->hw_sampler_state[i] = i < num ? state[i].hw_state : NULL; + } failover->dirty |= FO_NEW_SAMPLER; - failover->dirty_sampler |= (1<sw->bind_sampler_state(failover->sw, unit, - state->sw_state); - failover->hw->bind_sampler_state(failover->hw, unit, - state->hw_state); + failover->num_samplers = num; + failover->sw->bind_sampler_states(failover->sw, num, + failover->sw_sampler_state); + failover->hw->bind_sampler_states(failover->hw, num, + failover->hw_sampler_state); } static void @@ -351,17 +362,29 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) static void -failover_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) +failover_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) { struct failover_context *failover = failover_context(pipe); - - failover->texture[unit] = texture; + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == failover->num_textures && + !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *))) + return; + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &failover->texture[i], + texture[i]); + for (i = num; i < failover->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &failover->texture[i], + NULL); failover->dirty |= FO_NEW_TEXTURE; - failover->dirty_texture |= (1<sw->set_sampler_texture( failover->sw, unit, texture ); - failover->hw->set_sampler_texture( failover->hw, unit, texture ); + failover->num_textures = num; + failover->sw->set_sampler_textures( failover->sw, num, texture ); + failover->hw->set_sampler_textures( failover->hw, num, texture ); } @@ -429,7 +452,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.bind_blend_state = failover_bind_blend_state; failover->pipe.delete_blend_state = failover_delete_blend_state; failover->pipe.create_sampler_state = failover_create_sampler_state; - failover->pipe.bind_sampler_state = failover_bind_sampler_state; + failover->pipe.bind_sampler_states = failover_bind_sampler_states; failover->pipe.delete_sampler_state = failover_delete_sampler_state; failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state; failover->pipe.bind_depth_stencil_alpha_state = failover_bind_depth_stencil_state; @@ -449,7 +472,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; - failover->pipe.set_sampler_texture = failover_set_sampler_texture; + failover->pipe.set_sampler_textures = failover_set_sampler_textures; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; failover->pipe.set_vertex_element = failover_set_vertex_element; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index c663dd4947..3de931e04e 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -94,21 +94,13 @@ failover_state_emit( struct failover_context *failover ) failover->sw->set_viewport_state( failover->sw, &failover->viewport ); if (failover->dirty & FO_NEW_SAMPLER) { - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (failover->dirty_sampler & (1<sw->bind_sampler_state( failover->sw, i, - failover->sampler[i]->sw_state ); - } - } + failover->sw->bind_sampler_states( failover->sw, failover->num_samplers, + failover->sw_sampler_state ); } if (failover->dirty & FO_NEW_TEXTURE) { - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (failover->dirty_texture & (1<sw->set_sampler_texture( failover->sw, i, - failover->texture[i] ); - } - } + failover->sw->set_sampler_textures( failover->sw, failover->num_textures, + failover->texture ); } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { @@ -132,6 +124,4 @@ failover_state_emit( struct failover_context *failover ) failover->dirty = 0; failover->dirty_vertex_element = 0; failover->dirty_vertex_buffer = 0; - failover->dirty_texture = 0; - failover->dirty_sampler = 0; } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 6401112f83..746f18ba38 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -1,336 +1,339 @@ - /************************************************************************** - * - * Copyright 2003 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. - * - **************************************************************************/ - -#ifndef I915_CONTEXT_H -#define I915_CONTEXT_H - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "draw/draw_vertex.h" - -#include "tgsi/util/tgsi_scan.h" - - -#define I915_TEX_UNITS 8 - -#define I915_DYNAMIC_MODES4 0 -#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ -#define I915_DYNAMIC_DEPTHSCALE_1 2 -#define I915_DYNAMIC_IAB 3 -#define I915_DYNAMIC_BC_0 4 /* just the header */ -#define I915_DYNAMIC_BC_1 5 -#define I915_DYNAMIC_BFO_0 6 -#define I915_DYNAMIC_BFO_1 7 -#define I915_DYNAMIC_STP_0 8 -#define I915_DYNAMIC_STP_1 9 -#define I915_DYNAMIC_SC_ENA_0 10 -#define I915_DYNAMIC_SC_RECT_0 11 -#define I915_DYNAMIC_SC_RECT_1 12 -#define I915_DYNAMIC_SC_RECT_2 13 -#define I915_MAX_DYNAMIC 14 - - -#define I915_IMMEDIATE_S0 0 -#define I915_IMMEDIATE_S1 1 -#define I915_IMMEDIATE_S2 2 -#define I915_IMMEDIATE_S3 3 -#define I915_IMMEDIATE_S4 4 -#define I915_IMMEDIATE_S5 5 -#define I915_IMMEDIATE_S6 6 -#define I915_IMMEDIATE_S7 7 -#define I915_MAX_IMMEDIATE 8 - -/* These must mach the order of LI0_STATE_* bits, as they will be used - * to generate hardware packets: - */ -#define I915_CACHE_STATIC 0 -#define I915_CACHE_DYNAMIC 1 /* handled specially */ -#define I915_CACHE_SAMPLER 2 -#define I915_CACHE_MAP 3 -#define I915_CACHE_PROGRAM 4 -#define I915_CACHE_CONSTANTS 5 -#define I915_MAX_CACHE 6 - -#define I915_MAX_CONSTANT 32 - - -/** See constant_flags[] below */ -#define I915_CONSTFLAG_USER 0x1f - - -/** - * Subclass of pipe_shader_state - */ -struct i915_fragment_shader -{ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - uint *program; - uint program_len; - - /** - * constants introduced during translation. - * These are placed at the end of the constant buffer and grow toward - * the beginning (eg: slot 31, 30 29, ...) - * User-provided constants start at 0. - * This allows both types of constants to co-exist (until there's too many) - * and doesn't require regenerating/changing the fragment program to - * shuffle constants around. - */ - uint num_constants; - float constants[I915_MAX_CONSTANT][4]; - - /** - * Status of each constant - * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding - * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) - * Else, the bitmask indicates which components are occupied by immediates. - */ - ubyte constant_flags[I915_MAX_CONSTANT]; -}; - - -struct i915_cache_context; - -/* Use to calculate differences between state emitted to hardware and - * current driver-calculated state. - */ -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]; - - /* texture sampler state */ - unsigned sampler[I915_TEX_UNITS][3]; - unsigned sampler_enable_flags; - unsigned sampler_enable_nr; - - /* texture image buffers */ - unsigned texbuffer[I915_TEX_UNITS][2]; - - /** Describes the current hardware vertex layout */ - struct vertex_info vertex_info; - - unsigned id; /* track lost context events */ -}; - -struct i915_blend_state { - unsigned iab; - unsigned modes4; - unsigned LIS5; - unsigned LIS6; -}; - -struct i915_depth_stencil_state { - unsigned stencil_modes4; - unsigned bfo[2]; - unsigned stencil_LIS5; - unsigned depth_LIS6; -}; - -struct i915_rasterizer_state { - int light_twoside : 1; - unsigned st; - enum interp_mode color_interp; - - unsigned LIS4; - unsigned LIS7; - unsigned sc[1]; - - const struct pipe_rasterizer_state *templ; - - union { float f; unsigned u; } ds[2]; -}; - -struct i915_sampler_state { - unsigned state[3]; - const struct pipe_sampler_state *templ; -}; - - -struct i915_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -struct i915_context -{ - struct pipe_context pipe; - struct i915_winsys *winsys; - struct draw_context *draw; - - /* The most recent drawing state as set by the driver: - */ - const struct i915_blend_state *blend; - const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - const struct i915_depth_stencil_state *depth_stencil; - const struct i915_rasterizer_state *rasterizer; - - struct i915_fragment_shader *fs; - - struct pipe_blend_color blend_color; - struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; - struct pipe_framebuffer_state framebuffer; - struct pipe_poly_stipple poly_stipple; - struct pipe_scissor_state scissor; - struct i915_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - - unsigned dirty; - - unsigned *batch_start; - - /** Vertex buffer */ - struct pipe_buffer *vbo; - - struct i915_state current; - unsigned hardware_dirty; - - unsigned debug; -}; - -/* A flag for each state_tracker state object: - */ -#define I915_NEW_VIEWPORT 0x1 -#define I915_NEW_RASTERIZER 0x2 -#define I915_NEW_FS 0x4 -#define I915_NEW_BLEND 0x8 -#define I915_NEW_CLIP 0x10 -#define I915_NEW_SCISSOR 0x20 -#define I915_NEW_STIPPLE 0x40 -#define I915_NEW_FRAMEBUFFER 0x80 -#define I915_NEW_ALPHA_TEST 0x100 -#define I915_NEW_DEPTH_STENCIL 0x200 -#define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 -#define I915_NEW_CONSTANTS 0x1000 -#define I915_NEW_VBO 0x2000 -#define I915_NEW_VS 0x4000 - - -/* Driver's internally generated state flags: - */ -#define I915_NEW_VERTEX_FORMAT 0x10000 - - -/* Dirty flags for hardware emit - */ -#define I915_HW_STATIC (1<set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +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]; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + + struct i915_fragment_shader *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + + unsigned dirty; + + unsigned num_samplers; + unsigned num_textures; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1<sampler[unit] = (const struct i915_sampler_state*)sampler; + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == i915->num_samplers && + !memcmp(i915->sampler, sampler, num * sizeof(void *))) + return; + + memcpy(i915->sampler, sampler, num * sizeof(void *)); + memset(&i915->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * sizeof(void *)); + + i915->num_samplers = num; i915->dirty |= I915_NEW_SAMPLER; } @@ -526,14 +535,29 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } -static void i915_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture) +static void i915_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) { struct i915_context *i915 = i915_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == i915->num_textures && + !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &i915->texture[i], + texture[i]); + + for (i = num; i < i915->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &i915->texture[i], + NULL); - pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler], - texture); + i915->num_textures = num; i915->dirty |= I915_NEW_TEXTURE; } @@ -691,7 +715,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.delete_blend_state = i915_delete_blend_state; i915->pipe.create_sampler_state = i915_create_sampler_state; - i915->pipe.bind_sampler_state = i915_bind_sampler_state; + i915->pipe.bind_sampler_states = i915_bind_sampler_states; i915->pipe.delete_sampler_state = i915_delete_sampler_state; i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; @@ -715,7 +739,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; i915->pipe.set_scissor_state = i915_set_scissor_state; - i915->pipe.set_sampler_texture = i915_set_sampler_texture; + i915->pipe.set_sampler_textures = i915_set_sampler_textures; i915->pipe.set_viewport_state = i915_set_viewport_state; i915->pipe.set_vertex_buffer = i915_set_vertex_buffer; i915->pipe.set_vertex_element = i915_set_vertex_element; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 6bbaac4e34..a7498d22b7 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -267,12 +267,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */ if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER)) { - /* XXX: we were refering to sampler state - * (current.sampler_enable_nr) below, but only checking - * I915_HW_MAP above. Should probably calculate the enabled - * flags separately - but there will be further rework of - * state so perhaps not necessary yet. - */ const uint nr = i915->current.sampler_enable_nr; if (nr) { const uint enabled = i915->current.sampler_enable_flags; diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 9c1a5bbbd6..9dbb1b1b23 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -106,7 +106,8 @@ void i915_update_samplers( struct i915_context *i915 ) i915->current.sampler_enable_nr = 0; i915->current.sampler_enable_flags = 0x0; - for (unit = 0; unit < I915_TEX_UNITS; unit++) { + for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { @@ -219,7 +220,8 @@ i915_update_textures(struct i915_context *i915) { uint unit; - for (unit = 0; unit < I915_TEX_UNITS; unit++) { + for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 4da3a8cffc..b83a13c3b6 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -1,681 +1,684 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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, sublicense, 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 NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 - */ - - -#ifndef BRWCONTEXT_INC -#define BRWCONTEXT_INC - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "tgsi/util/tgsi_scan.h" - -#include "brw_structs.h" -#include "brw_winsys.h" - - -/* Glossary: - * - * URB - uniform resource buffer. A mid-sized buffer which is - * partitioned between the fixed function units and used for passing - * values (vertices, primitives, constants) between them. - * - * CURBE - constant URB entry. An urb region (entry) used to hold - * constant values which the fixed function units can be instructed to - * preload into the GRF when spawining a thread. - * - * VUE - vertex URB entry. An urb entry holding a vertex and usually - * a vertex header. The header contains control information and - * things like primitive type, Begin/end flags and clip codes. - * - * PUE - primitive URB entry. An urb entry produced by the setup (SF) - * unit holding rasterization and interpolation parameters. - * - * GRF - general register file. One of several register files - * addressable by programmed threads. The inputs (r0, payload, curbe, - * urb) of the thread are preloaded to this area before the thread is - * spawned. The registers are individually 8 dwords wide and suitable - * for general usage. Registers holding thread input values are not - * special and may be overwritten. - * - * MRF - message register file. Threads communicate (and terminate) - * by sending messages. Message parameters are placed in contigous - * MRF registers. All program output is via these messages. URB - * entries are populated by sending a message to the shared URB - * function containing the new data, together with a control word, - * often an unmodified copy of R0. - * - * R0 - GRF register 0. Typically holds control information used when - * sending messages to other threads. - * - * EU or GEN4 EU: The name of the programmable subsystem of the - * i965 hardware. Threads are executed by the EU, the registers - * described above are part of the EU architecture. - * - * Fixed function units: - * - * CS - Command streamer. Notional first unit, little software - * interaction. Holds the URB entries used for constant data, ie the - * CURBEs. - * - * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of - * this unit is responsible for pulling vertices out of vertex buffers - * in vram and injecting them into the processing pipe as VUEs. If - * enabled, it first passes them to a VS thread which is a good place - * for the driver to implement any active vertex shader. - * - * GS - Geometry Shader. This corresponds to a new DX10 concept. If - * enabled, incoming strips etc are passed to GS threads in individual - * line/triangle/point units. The GS thread may perform arbitary - * computation and emit whatever primtives with whatever vertices it - * chooses. This makes GS an excellent place to implement GL's - * unfilled polygon modes, though of course it is capable of much - * more. Additionally, GS is used to translate away primitives not - * handled by latter units, including Quads and Lineloops. - * - * CS - Clipper. Mesa's clipping algorithms are imported to run on - * this unit. The fixed function part performs cliptesting against - * the 6 fixed clipplanes and makes descisions on whether or not the - * incoming primitive needs to be passed to a thread for clipping. - * User clip planes are handled via cooperation with the VS thread. - * - * SF - Strips Fans or Setup: Triangles are prepared for - * rasterization. Interpolation coefficients are calculated. - * Flatshading and two-side lighting usually performed here. - * - * WM - Windower. Interpolation of vertex attributes performed here. - * Fragment shader implemented here. SIMD aspects of EU taken full - * advantage of, as pixels are processed in blocks of 16. - * - * CC - Color Calculator. No EU threads associated with this unit. - * Handles blending and (presumably) depth and stencil testing. - */ - -#define BRW_MAX_CURBE (32*16) - -struct brw_context; -struct brw_winsys; - - -/* Raised when we receive new state across the pipe interface: - */ -#define BRW_NEW_VIEWPORT 0x1 -#define BRW_NEW_RASTERIZER 0x2 -#define BRW_NEW_FS 0x4 -#define BRW_NEW_BLEND 0x8 -#define BRW_NEW_CLIP 0x10 -#define BRW_NEW_SCISSOR 0x20 -#define BRW_NEW_STIPPLE 0x40 -#define BRW_NEW_FRAMEBUFFER 0x80 -#define BRW_NEW_ALPHA_TEST 0x100 -#define BRW_NEW_DEPTH_STENCIL 0x200 -#define BRW_NEW_SAMPLER 0x400 -#define BRW_NEW_TEXTURE 0x800 -#define BRW_NEW_CONSTANTS 0x1000 -#define BRW_NEW_VBO 0x2000 -#define BRW_NEW_VS 0x4000 - -/* Raised for other internal events: - */ -#define BRW_NEW_URB_FENCE 0x10000 -#define BRW_NEW_PSP 0x20000 -#define BRW_NEW_CURBE_OFFSETS 0x40000 -#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 -#define BRW_NEW_PRIMITIVE 0x100000 -#define BRW_NEW_SCENE 0x200000 -#define BRW_NEW_SF_LINKAGE 0x400000 - -extern int BRW_DEBUG; - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_PRIMS 0x8 -#define DEBUG_VERTS 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_DRI 0x80 -#define DEBUG_DMA 0x100 -#define DEBUG_SANITY 0x200 -#define DEBUG_SYNC 0x400 -#define DEBUG_SLEEP 0x800 -#define DEBUG_PIXEL 0x1000 -#define DEBUG_STATS 0x2000 -#define DEBUG_TILE 0x4000 -#define DEBUG_SINGLE_THREAD 0x8000 -#define DEBUG_WM 0x10000 -#define DEBUG_URB 0x20000 -#define DEBUG_VS 0x40000 -#define DEBUG_BATCH 0x80000 -#define DEBUG_BUFMGR 0x100000 -#define DEBUG_BLIT 0x200000 -#define DEBUG_REGION 0x400000 -#define DEBUG_MIPTREE 0x800000 - -#define DBG(...) do { \ - if (BRW_DEBUG & FILE_DEBUG_FLAG) \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -#define PRINT(...) do { \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -struct brw_state_flags { - unsigned cache; - unsigned brw; -}; - - -struct brw_vertex_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - int id; -}; - - -struct brw_fragment_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - - boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ - int id; -}; - - -struct pipe_setup_linkage { - struct { - unsigned vp_output:5; - unsigned interp_mode:4; - unsigned bf_vp_output:5; - } fp_input[PIPE_MAX_SHADER_INPUTS]; - - unsigned fp_input_count:5; - unsigned max_vp_output:5; -}; - - - -struct brw_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ - -struct brw_wm_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - - unsigned first_curbe_grf; - unsigned total_grf; - unsigned total_scratch; - - /* Internally generated constants for the CURBE. These are loaded - * ahead of the data from the constant buffer. - */ - const float internal_const[8]; - unsigned nr_internal_consts; - unsigned max_const; - - boolean error; -}; - -struct brw_sf_prog_data { - unsigned urb_read_length; - unsigned total_grf; - - /* Each vertex may have upto 12 attributes, 4 components each, - * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 - * rows. - * - * Actually we use 4 for each, so call it 12 rows. - */ - unsigned urb_entry_size; -}; - -struct brw_clip_prog_data { - unsigned curb_read_length; /* user planes? */ - unsigned clip_mode; - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_gs_prog_data { - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_vs_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - unsigned total_grf; - unsigned outputs_written; - - unsigned inputs_read; - - unsigned max_const; - - float imm_buf[PIPE_MAX_CONSTANT][4]; - unsigned num_imm; - unsigned num_consts; - - /* Used for calculating urb partitions: - */ - unsigned urb_entry_size; -}; - - -#define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 - -/* Create a fixed sized struct for caching binding tables: - */ -struct brw_surface_binding_table { - unsigned surf_ss_offset[BRW_WM_MAX_SURF]; -}; - - -struct brw_cache; - -struct brw_mem_pool { - struct pipe_buffer *buffer; - - unsigned size; - unsigned offset; /* offset of first free byte */ - - struct brw_context *brw; -}; - -struct brw_cache_item { - unsigned hash; - unsigned key_size; /* for variable-sized keys */ - const void *key; - - unsigned offset; /* offset within pool's buffer */ - unsigned data_size; - - struct brw_cache_item *next; -}; - - - -struct brw_cache { - unsigned id; - - const char *name; - - struct brw_context *brw; - struct brw_mem_pool *pool; - - struct brw_cache_item **items; - unsigned size, n_items; - - unsigned key_size; /* for fixed-size keys */ - unsigned aux_size; - - unsigned last_addr; /* offset of active item */ -}; - - - - -/* Considered adding a member to this struct to document which flags - * an update might raise so that ordering of the state atoms can be - * checked or derived at runtime. Dropped the idea in favor of having - * a debug mode where the state is monitored for flags which are - * raised that have already been tested against. - */ -struct brw_tracked_state { - struct brw_state_flags dirty; - void (*update)( struct brw_context *brw ); -}; - - -/* Flags for brw->state.cache. - */ -#define CACHE_NEW_CC_VP (1< 32. Wouldn't life - * be easier if C allowed arrays of packed elements? - */ -#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) - - - - -struct brw_vertex_info { - unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ - unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ -}; - - - - - -struct brw_context -{ - struct pipe_context pipe; - struct brw_winsys *winsys; - - unsigned primitive; - unsigned reduced_primitive; - - boolean emit_state_always; - - struct { - struct brw_state_flags dirty; - } state; - - - struct { - const struct pipe_blend_state *Blend; - const struct pipe_depth_stencil_alpha_state *DepthStencil; - const struct pipe_poly_stipple *PolygonStipple; - const struct pipe_rasterizer_state *Raster; - const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; - const struct brw_vertex_program *VertexProgram; - const struct brw_fragment_program *FragmentProgram; - - struct pipe_clip_state Clip; - struct pipe_blend_color BlendColor; - struct pipe_scissor_state Scissor; - struct pipe_viewport_state Viewport; - struct pipe_framebuffer_state FrameBuffer; - - const struct pipe_constant_buffer *Constants[2]; - const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; - } attribs; - - struct brw_mem_pool pool[BRW_MAX_POOL]; - struct brw_cache cache[BRW_MAX_CACHE]; - struct brw_cached_batch_item *cached_batch_items; - - struct { - - /* Arrays with buffer objects to copy non-bufferobj arrays into - * for upload: - */ - const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; - - struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; - -#define BRW_NR_UPLOAD_BUFS 17 -#define BRW_UPLOAD_INIT_SIZE (128*1024) - - /* Summary of size and varying of active arrays, so we can check - * for changes to this state: - */ - struct brw_vertex_info info; - } vb; - - - unsigned hardware_dirty; - unsigned dirty; - unsigned pci_id; - /* BRW_NEW_URB_ALLOCATIONS: - */ - struct { - unsigned vsize; /* vertex size plus header in urb registers */ - unsigned csize; /* constant buffer size in urb registers */ - unsigned sfsize; /* setup data size in urb registers */ - - boolean constrained; - - unsigned nr_vs_entries; - unsigned nr_gs_entries; - unsigned nr_clip_entries; - unsigned nr_sf_entries; - unsigned nr_cs_entries; - -/* unsigned vs_size; */ -/* unsigned gs_size; */ -/* unsigned clip_size; */ -/* unsigned sf_size; */ -/* unsigned cs_size; */ - - unsigned vs_start; - unsigned gs_start; - unsigned clip_start; - unsigned sf_start; - unsigned cs_start; - } urb; - - - /* BRW_NEW_CURBE_OFFSETS: - */ - struct { - unsigned wm_start; - unsigned wm_size; - unsigned clip_start; - unsigned clip_size; - unsigned vs_start; - unsigned vs_size; - unsigned total_size; - - unsigned gs_offset; - - float *last_buf; - unsigned last_bufsz; - } curbe; - - struct { - struct brw_vs_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } vs; - - struct { - struct brw_gs_prog_data *prog_data; - - boolean prog_active; - unsigned prog_gs_offset; - unsigned state_gs_offset; - } gs; - - struct { - struct brw_clip_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } clip; - - - struct { - struct brw_sf_prog_data *prog_data; - - struct pipe_setup_linkage linkage; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } sf; - - struct { - struct brw_wm_prog_data *prog_data; - -// struct brw_wm_compiler *compile_data; - - - /** - * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER - * cache - */ - struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; - - unsigned render_surf; - unsigned nr_surfaces; - - unsigned max_threads; - struct pipe_buffer *scratch_buffer; - unsigned scratch_buffer_size; - - unsigned sampler_count; - unsigned sampler_gs_offset; - - struct brw_surface_binding_table bind; - unsigned bind_ss_offset; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } wm; - - - struct { - unsigned vp_gs_offset; - unsigned state_gs_offset; - } cc; - - - /* Used to give every program string a unique id - */ - unsigned program_id; -}; - - -#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) - - -/*====================================================================== - * brw_vtbl.c - */ -void brw_do_flush( struct brw_context *brw, - unsigned flags ); - - -/*====================================================================== - * brw_state.c - */ -void brw_validate_state(struct brw_context *brw); -void brw_init_state(struct brw_context *brw); -void brw_destroy_state(struct brw_context *brw); - - -/*====================================================================== - * brw_tex.c - */ -void brwUpdateTextureState( struct brw_context *brw ); - - -/* brw_urb.c - */ -void brw_upload_urb_fence(struct brw_context *brw); - -void brw_upload_constant_buffer_state(struct brw_context *brw); - -void brw_init_surface_functions(struct brw_context *brw); -void brw_init_state_functions(struct brw_context *brw); -void brw_init_flush_functions(struct brw_context *brw); -void brw_init_string_functions(struct brw_context *brw); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static inline struct brw_context * -brw_context( struct pipe_context *ctx ) -{ - return (struct brw_context *)ctx; -} - -#endif - +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + 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, sublicense, 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 NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "tgsi/util/tgsi_scan.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + int id; +}; + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ + int id; +}; + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1< 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + unsigned num_samplers; + unsigned num_textures; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; + + struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 6744a8aa4f..f5efe9fc06 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -1,434 +1,462 @@ -/************************************************************************** - * - * 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: Zack Rusin - * Keith Whitwell - */ - - -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_dump.h" - -#include "brw_context.h" -#include "brw_defines.h" -#include "brw_state.h" -#include "brw_draw.h" - - -#define DUP( TYPE, VAL ) \ -do { \ - struct TYPE *x = malloc(sizeof(*x)); \ - memcpy(x, VAL, sizeof(*x) ); \ - return x; \ -} while (0) - -/************************************************************************ - * Blend - */ -static void * -brw_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - DUP( pipe_blend_state, blend ); -} - -static void brw_bind_blend_state(struct pipe_context *pipe, - void *blend) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Blend = (struct pipe_blend_state*)blend; - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - - -static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - free(blend); -} - -static void brw_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.BlendColor = *blend_color; - - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - -/************************************************************************ - * Sampler - */ - -static void * -brw_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - DUP( pipe_sampler_state, sampler ); -} - -static void brw_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Samplers[unit] = sampler; - brw->state.dirty.brw |= BRW_NEW_SAMPLER; -} - -static void brw_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - free(sampler); -} - - -/************************************************************************ - * Depth stencil - */ - -static void * -brw_create_depth_stencil_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - DUP( pipe_depth_stencil_alpha_state, depth_stencil ); -} - -static void brw_bind_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; - - brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; -} - -static void brw_delete_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - free(depth_stencil); -} - -/************************************************************************ - * Scissor - */ -static void brw_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct brw_context *brw = brw_context(pipe); - - memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); - brw->state.dirty.brw |= BRW_NEW_SCISSOR; -} - - -/************************************************************************ - * Stipple - */ - -static void brw_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ -} - - -/************************************************************************ - * Fragment shader - */ - -static void * brw_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); - - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_fp->program = *shader; - brw_fp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_fp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_fp->info2); -#endif - - tgsi_dump(shader->tokens, 0); - - - return (void *)brw_fp; -} - -static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; - brw->state.dirty.brw |= BRW_NEW_FS; -} - -static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) -{ - FREE(shader); -} - - -/************************************************************************ - * Vertex shader and other TNL state - */ - -static void *brw_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); - - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_vp->program = *shader; - brw_vp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_vp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_vp->info2); -#endif - tgsi_dump(shader->tokens, 0); - - return (void *)brw_vp; -} - -static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; - brw->state.dirty.brw |= BRW_NEW_VS; - - debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); -} - -static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) -{ - FREE(shader); -} - - -static void brw_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Clip = *clip; -} - - -static void brw_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Viewport = *viewport; /* struct copy */ - brw->state.dirty.brw |= BRW_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - //draw_set_viewport_state(brw->draw, viewport); -} - - -static void brw_set_vertex_buffer( struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer ) -{ - struct brw_context *brw = brw_context(pipe); - brw->vb.vbo_array[index] = buffer; -} - -static void brw_set_vertex_element(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *element) -{ - /* flush ? */ - struct brw_context *brw = brw_context(pipe); - - assert(index < PIPE_ATTRIB_MAX); - struct brw_vertex_element_state el; - memset(&el, 0, sizeof(el)); - - el.ve0.src_offset = element->src_offset; - el.ve0.src_format = brw_translate_surface_format(element->src_format); - el.ve0.valid = 1; - el.ve0.vertex_buffer_index = element->vertex_buffer_index; - - el.ve1.dst_offset = index * 4; - - el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - - switch (element->nr_components) { - case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } - - brw->vb.inputs[index] = el; -} - - - -/************************************************************************ - * Constant buffers - */ - -static void brw_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct brw_context *brw = brw_context(pipe); - - assert(buf == 0 || index == 0); - - brw->attribs.Constants[shader] = buf; - brw->state.dirty.brw |= BRW_NEW_CONSTANTS; -} - - -/************************************************************************ - * Texture surfaces - */ - - -static void brw_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) -{ - struct brw_context *brw = brw_context(pipe); - - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit], - texture); - - brw->state.dirty.brw |= BRW_NEW_TEXTURE; -} - - -/************************************************************************ - * Render targets, etc - */ - -static void brw_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FrameBuffer = *fb; /* struct copy */ - - brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; -} - - - -/************************************************************************ - * Rasterizer state - */ - -static void * -brw_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *rasterizer) -{ - DUP(pipe_rasterizer_state, rasterizer); -} - -static void brw_bind_rasterizer_state( struct pipe_context *pipe, - void *setup ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; - - /* Also pass-through to draw module: - */ - //draw_set_rasterizer_state(brw->draw, setup); - - brw->state.dirty.brw |= BRW_NEW_RASTERIZER; -} - -static void brw_delete_rasterizer_state(struct pipe_context *pipe, - void *setup) -{ - free(setup); -} - - - -void -brw_init_state_functions( struct brw_context *brw ) -{ - brw->pipe.create_blend_state = brw_create_blend_state; - brw->pipe.bind_blend_state = brw_bind_blend_state; - brw->pipe.delete_blend_state = brw_delete_blend_state; - - brw->pipe.create_sampler_state = brw_create_sampler_state; - brw->pipe.bind_sampler_state = brw_bind_sampler_state; - brw->pipe.delete_sampler_state = brw_delete_sampler_state; - - brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; - brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; - brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; - - brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; - brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; - brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; - brw->pipe.create_fs_state = brw_create_fs_state; - brw->pipe.bind_fs_state = brw_bind_fs_state; - brw->pipe.delete_fs_state = brw_delete_fs_state; - brw->pipe.create_vs_state = brw_create_vs_state; - brw->pipe.bind_vs_state = brw_bind_vs_state; - brw->pipe.delete_vs_state = brw_delete_vs_state; - - brw->pipe.set_blend_color = brw_set_blend_color; - brw->pipe.set_clip_state = brw_set_clip_state; - brw->pipe.set_constant_buffer = brw_set_constant_buffer; - brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; - -// brw->pipe.set_feedback_state = brw_set_feedback_state; -// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; - - brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; - brw->pipe.set_scissor_state = brw_set_scissor_state; - brw->pipe.set_sampler_texture = brw_set_sampler_texture; - brw->pipe.set_viewport_state = brw_set_viewport_state; - brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; - brw->pipe.set_vertex_element = brw_set_vertex_element; -} +/************************************************************************** + * + * 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: Zack Rusin + * Keith Whitwell + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_dump.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct brw_context *brw = brw_context(pipe); + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_samplers && + !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) + return; + + memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); + memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + brw->num_samplers = num; + + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_fp->program = *shader; + brw_fp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_fp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_fp->info2); +#endif + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_vp->program = *shader; + brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_vp->info2); +#endif + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffer( struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer ) +{ + struct brw_context *brw = brw_context(pipe); + brw->vb.vbo_array[index] = buffer; +} + +static void brw_set_vertex_element(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *element) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + + assert(index < PIPE_ATTRIB_MAX); + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = element->src_offset; + el.ve0.src_format = brw_translate_surface_format(element->src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = element->vertex_buffer_index; + + el.ve1.dst_offset = index * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (element->nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[index] = el; +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) +{ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_textures && + !memcmp(brw->attribs.Texture, texture, num * + sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + texture[i]); + + for (i = num; i < brw->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + NULL); + + brw->num_textures = num; + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_states = brw_bind_sampler_states; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_textures = brw_set_sampler_textures; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; + brw->pipe.set_vertex_element = brw_set_vertex_element; +} diff --git a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c index de42ffc5b1..ff5ba7e7c7 100644 --- a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c @@ -235,7 +235,8 @@ static void upload_wm_samplers(struct brw_context *brw) unsigned sampler_count = 0; /* BRW_NEW_SAMPLER */ - for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { + for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ if (brw->attribs.Texture[unit]) { const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit]; diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c index d16d919bce..853c743ccf 100644 --- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -237,7 +237,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) /* BRW_NEW_TEXTURE */ - for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + for (i = 0; i < brw->num_textures && i < brw->num_samplers; i++) { const struct brw_texture *texUnit = brw->attribs.Texture[i]; if (texUnit && diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fa16ed94e8..316ae552b8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -1,243 +1,243 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/* Author: - * Keith Whitwell - */ - -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "sp_clear.h" -#include "sp_context.h" -#include "sp_flush.h" -#include "sp_prim_setup.h" -#include "sp_prim_vbuf.h" -#include "sp_state.h" -#include "sp_surface.h" -#include "sp_tile_cache.h" -#include "sp_texture.h" -#include "sp_winsys.h" -#include "sp_query.h" - - - -/** - * Map any drawing surfaces which aren't already mapped - */ -void -softpipe_map_surfaces(struct softpipe_context *sp) -{ - unsigned i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); - } - - sp_tile_cache_map_surfaces(sp->zsbuf_cache); -} - - -/** - * Unmap any mapped drawing surfaces - */ -void -softpipe_unmap_surfaces(struct softpipe_context *sp) -{ - uint i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) - sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - sp_flush_tile_cache(sp, sp->zsbuf_cache); - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); - } - sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); -} - - -static void softpipe_destroy( struct pipe_context *pipe ) -{ - struct softpipe_context *softpipe = softpipe_context( pipe ); - struct pipe_winsys *ws = pipe->winsys; - uint i; - - draw_destroy( softpipe->draw ); - - softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); - softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); - softpipe->quad.shade->destroy( softpipe->quad.shade ); - softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); - softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); - softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); - softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); - softpipe->quad.coverage->destroy( softpipe->quad.coverage ); - softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); - softpipe->quad.blend->destroy( softpipe->quad.blend ); - softpipe->quad.colormask->destroy( softpipe->quad.colormask ); - softpipe->quad.output->destroy( softpipe->quad.output ); - - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - sp_destroy_tile_cache(softpipe->cbuf_cache[i]); - sp_destroy_tile_cache(softpipe->zsbuf_cache); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - sp_destroy_tile_cache(softpipe->tex_cache[i]); - - for (i = 0; i < Elements(softpipe->constants); i++) { - if (softpipe->constants[i].buffer) { - pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); - } - } - - FREE( softpipe ); -} - - -struct pipe_context * -softpipe_create( struct pipe_screen *screen, - struct pipe_winsys *pipe_winsys, - struct softpipe_winsys *softpipe_winsys ) -{ - struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); - uint i; - -#if defined(__i386__) || defined(__386__) - softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - softpipe->use_sse = FALSE; -#endif - - softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; - - softpipe->pipe.winsys = pipe_winsys; - softpipe->pipe.screen = screen; - softpipe->pipe.destroy = softpipe_destroy; - - /* state setters */ - softpipe->pipe.create_blend_state = softpipe_create_blend_state; - softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; - softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; - - softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; - softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; - softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; - - softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; - softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; - softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; - - softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; - softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; - softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; - - softpipe->pipe.create_fs_state = softpipe_create_fs_state; - softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; - softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; - - softpipe->pipe.create_vs_state = softpipe_create_vs_state; - softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; - softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; - - softpipe->pipe.set_blend_color = softpipe_set_blend_color; - softpipe->pipe.set_clip_state = softpipe_set_clip_state; - softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; - softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; - softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; - softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_sampler_texture = softpipe_set_sampler_texture; - softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; - - softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; - softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; - - softpipe->pipe.draw_arrays = softpipe_draw_arrays; - softpipe->pipe.draw_elements = softpipe_draw_elements; - - softpipe->pipe.clear = softpipe_clear; - softpipe->pipe.flush = softpipe_flush; - - softpipe_init_query_funcs( softpipe ); - softpipe_init_texture_funcs( softpipe ); - - /* - * Alloc caches for accessing drawing surfaces and textures. - * Must be before quad stage setup! - */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); - - - /* setup quad rendering stages */ - softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); - softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); - softpipe->quad.shade = sp_quad_shade_stage(softpipe); - softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); - softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); - softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); - softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); - softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); - softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); - softpipe->quad.blend = sp_quad_blend_stage(softpipe); - softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); - softpipe->quad.output = sp_quad_output_stage(softpipe); - - softpipe->winsys = softpipe_winsys; - - /* - * Create drawing context and plug our rendering stage into it. - */ - softpipe->draw = draw_create(); - assert(softpipe->draw); - softpipe->setup = sp_draw_render_stage(softpipe); - - if (GETENV( "SP_VBUF" ) != NULL) { - sp_init_vbuf(softpipe); - } - else { - draw_set_rasterize_stage(softpipe->draw, softpipe->setup); - } - - /* plug in AA line/point stages */ - draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); - draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); - -#if USE_DRAW_STAGE_PSTIPPLE - /* Do polygon stipple w/ texture map + frag prog? */ - draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); -#endif - - sp_init_surface_functions(softpipe); - - return &softpipe->pipe; -} +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_flush.h" +#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_texture.h" +#include "sp_winsys.h" +#include "sp_query.h" + + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +softpipe_map_surfaces(struct softpipe_context *sp) +{ + unsigned i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); + } + + sp_tile_cache_map_surfaces(sp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +softpipe_unmap_surfaces(struct softpipe_context *sp) +{ + uint i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); + } + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); +} + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct pipe_winsys *ws = pipe->winsys; + uint i; + + draw_destroy( softpipe->draw ); + + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + sp_destroy_tile_cache(softpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + sp_destroy_tile_cache(softpipe->tex_cache[i]); + + for (i = 0; i < Elements(softpipe->constants); i++) { + if (softpipe->constants[i].buffer) { + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + } + } + + FREE( softpipe ); +} + + +struct pipe_context * +softpipe_create( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + uint i; + +#if defined(__i386__) || defined(__386__) + softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + softpipe->use_sse = FALSE; +#endif + + softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + + softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.screen = screen; + softpipe->pipe.destroy = softpipe_destroy; + + /* state setters */ + softpipe->pipe.create_blend_state = softpipe_create_blend_state; + softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; + softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + + softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; + + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; + softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; + softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + + softpipe->pipe.create_fs_state = softpipe_create_fs_state; + softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + + softpipe->pipe.create_vs_state = softpipe_create_vs_state; + softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; + + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + + softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; + softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + + softpipe->pipe.draw_arrays = softpipe_draw_arrays; + softpipe->pipe.draw_elements = softpipe_draw_elements; + + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.flush = softpipe_flush; + + softpipe_init_query_funcs( softpipe ); + softpipe_init_texture_funcs( softpipe ); + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zsbuf_cache = sp_create_tile_cache(); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + + /* setup quad rendering stages */ + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + softpipe->winsys = softpipe_winsys; + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + assert(softpipe->draw); + softpipe->setup = sp_draw_render_stage(softpipe); + + if (GETENV( "SP_VBUF" ) != NULL) { + sp_init_vbuf(softpipe); + } + else { + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + } + + /* plug in AA line/point stages */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + + sp_init_surface_functions(softpipe); + + return &softpipe->pipe; +} diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index feeafc7084..19e6cfaf02 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -81,6 +81,9 @@ struct softpipe_context { struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; unsigned dirty; + unsigned num_samplers; + unsigned num_textures; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 1fbb2e38c4..9198198db3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -1,208 +1,209 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/* Vertices are just an array of floats, with all the attributes - * packed. We currently assume a layout like: - * - * attr[0][0..3] - window position - * attr[1..n][0..3] - remaining attributes. - * - * Attributes are assumed to be 4 floats wide but are packed so that - * all the enabled attributes run contiguously. - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_headers.h" -#include "sp_quad.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" - - -struct quad_shade_stage -{ - struct quad_stage stage; - struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; - struct tgsi_exec_machine machine; - struct tgsi_exec_vector *inputs, *outputs; - int colorOutSlot, depthOutSlot; -}; - - -/** cast wrapper */ -static INLINE struct quad_shade_stage * -quad_shade_stage(struct quad_stage *qs) -{ - return (struct quad_shade_stage *) qs; -} - - - -/** - * Execute fragment shader for the four fragments in the quad. - */ -static void -shade_quad( - struct quad_stage *qs, - struct quad_header *quad ) -{ - struct quad_shade_stage *qss = quad_shade_stage( qs ); - struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = &qss->machine; - - /* Consts do not require 16 byte alignment. */ - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; - - machine->InterpCoefs = quad->coef; - - /* run shader */ - quad->mask &= softpipe->fs->run( softpipe->fs, - &qss->machine, - quad ); - - /* store result color */ - if (qss->colorOutSlot >= 0) { - /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - memcpy( - quad->outputs.color, - &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], - sizeof( quad->outputs.color ) ); - } - - /* - * XXX the following code for updating quad->outputs.depth - * isn't really needed if we did early z testing. - */ - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; - } - } - else { - /* copy input Z (which was interpolated by the executor) to output Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; - /* XXX not sure the above line is always correct. The following - * might be better: - quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; - */ - } - } - - /* shader may cull fragments */ - if( quad->mask ) { - qs->next->run( qs->next, quad ); - } -} - -/** - * Per-primitive (or per-begin?) setup - */ -static void shade_begin(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = quad_shade_stage(qs); - struct softpipe_context *softpipe = qs->softpipe; - unsigned i; - - /* set TGSI sampler state that varies */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = softpipe->texture[i]; - } - - /* find output slots for depth, color */ - qss->colorOutSlot = -1; - qss->depthOutSlot = -1; - for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { - switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - qss->depthOutSlot = i; - break; - case TGSI_SEMANTIC_COLOR: - qss->colorOutSlot = i; - break; - } - } - - softpipe->fs->prepare( softpipe->fs, - &qss->machine, - qss->samplers ); - - qs->next->begin(qs->next); -} - - -static void shade_destroy(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; - - tgsi_exec_machine_free_data(&qss->machine); - FREE( qss->inputs ); - FREE( qss->outputs ); - FREE( qs ); -} - - -struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) -{ - struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); - uint i; - - /* allocate storage for program inputs/outputs, aligned to 16 bytes */ - qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); - qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); - qss->machine.Inputs = align16(qss->inputs); - qss->machine.Outputs = align16(qss->outputs); - - qss->stage.softpipe = softpipe; - qss->stage.begin = shade_begin; - qss->stage.run = shade_quad; - qss->stage.destroy = shade_destroy; - - /* set TGSI sampler state that's constant */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - assert(softpipe->tex_cache[i]); - qss->samplers[i].get_samples = sp_get_samples; - qss->samplers[i].pipe = &softpipe->pipe; - qss->samplers[i].cache = softpipe->tex_cache[i]; - } - - tgsi_exec_machine_init( &qss->machine ); - - return &qss->stage; -} +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_texture.h" +#include "sp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; + struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; + struct tgsi_exec_machine machine; + struct tgsi_exec_vector *inputs, *outputs; + int colorOutSlot, depthOutSlot; +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = &qss->machine; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* run shader */ + quad->mask &= softpipe->fs->run( softpipe->fs, + &qss->machine, + quad ); + + /* store result color */ + if (qss->colorOutSlot >= 0) { + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + memcpy( + quad->outputs.color, + &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); + } + + /* + * XXX the following code for updating quad->outputs.depth + * isn't really needed if we did early z testing. + */ + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; + /* XXX not sure the above line is always correct. The following + * might be better: + quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; + */ + } + } + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + +/** + * Per-primitive (or per-begin?) setup + */ +static void shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + unsigned i; + unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers); + + /* set TGSI sampler state that varies */ + for (i = 0; i < num; i++) { + qss->samplers[i].state = softpipe->sampler[i]; + qss->samplers[i].texture = softpipe->texture[i]; + } + + /* find output slots for depth, color */ + qss->colorOutSlot = -1; + qss->depthOutSlot = -1; + for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { + switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + qss->depthOutSlot = i; + break; + case TGSI_SEMANTIC_COLOR: + qss->colorOutSlot = i; + break; + } + } + + softpipe->fs->prepare( softpipe->fs, + &qss->machine, + qss->samplers ); + + qs->next->begin(qs->next); +} + + +static void shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_free_data(&qss->machine); + FREE( qss->inputs ); + FREE( qss->outputs ); + FREE( qs ); +} + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; + + /* allocate storage for program inputs/outputs, aligned to 16 bytes */ + qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->machine.Inputs = align16(qss->inputs); + qss->machine.Outputs = align16(qss->outputs); + + qss->stage.softpipe = softpipe; + qss->stage.begin = shade_begin; + qss->stage.run = shade_quad; + qss->stage.destroy = shade_destroy; + + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + + tgsi_exec_machine_init( &qss->machine ); + + return &qss->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 3943d4ed2b..45d159143f 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -1,195 +1,195 @@ -/************************************************************************** - * - * 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 - */ - -#ifndef SP_STATE_H -#define SP_STATE_H - -#include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" - - -#define SP_NEW_VIEWPORT 0x1 -#define SP_NEW_RASTERIZER 0x2 -#define SP_NEW_FS 0x4 -#define SP_NEW_BLEND 0x8 -#define SP_NEW_CLIP 0x10 -#define SP_NEW_SCISSOR 0x20 -#define SP_NEW_STIPPLE 0x40 -#define SP_NEW_FRAMEBUFFER 0x80 -#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 -#define SP_NEW_CONSTANTS 0x200 -#define SP_NEW_SAMPLER 0x400 -#define SP_NEW_TEXTURE 0x800 -#define SP_NEW_VERTEX 0x1000 -#define SP_NEW_VS 0x2000 -#define SP_NEW_QUERY 0x4000 - - -struct tgsi_sampler; -struct tgsi_exec_machine; - - -/** Subclass of pipe_shader_state (though it doesn't really need to be). - * - * This is starting to look an awful lot like a quad pipeline stage... - */ -struct sp_fragment_shader { - struct pipe_shader_state shader; - - struct tgsi_shader_info info; - - void (*prepare)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct tgsi_sampler *samplers); - - /* Run the shader - this interface will get cleaned up in the - * future: - */ - unsigned (*run)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct quad_header *quad ); - - - void (*delete)( struct sp_fragment_shader * ); -}; - -struct vertex_info; - -/** Subclass of pipe_shader_state */ -struct sp_vertex_shader { - struct pipe_shader_state shader; - struct draw_vertex_shader *draw_data; -}; - - - -void * -softpipe_create_blend_state(struct pipe_context *, - const struct pipe_blend_state *); -void softpipe_bind_blend_state(struct pipe_context *, - void *); -void softpipe_delete_blend_state(struct pipe_context *, - void *); - -void * -softpipe_create_sampler_state(struct pipe_context *, - const struct pipe_sampler_state *); -void softpipe_bind_sampler_state(struct pipe_context *, unsigned, void *); -void softpipe_delete_sampler_state(struct pipe_context *, void *); - -void * -softpipe_create_depth_stencil_state(struct pipe_context *, - const struct pipe_depth_stencil_alpha_state *); -void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); -void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); - -void * -softpipe_create_rasterizer_state(struct pipe_context *, - const struct pipe_rasterizer_state *); -void softpipe_bind_rasterizer_state(struct pipe_context *, void *); -void softpipe_delete_rasterizer_state(struct pipe_context *, void *); - -void softpipe_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); - -void softpipe_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ); - -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_create_fs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_fs_state(struct pipe_context *, void *); -void softpipe_delete_fs_state(struct pipe_context *, void *); -void *softpipe_create_vs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_vs_state(struct pipe_context *, void *); -void softpipe_delete_vs_state(struct pipe_context *, void *); - -void softpipe_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); - -void softpipe_set_scissor_state( struct pipe_context *, - const struct pipe_scissor_state * ); - -void softpipe_set_sampler_texture( struct pipe_context *, - unsigned unit, - struct pipe_texture * ); - -void softpipe_set_viewport_state( struct pipe_context *, - const struct pipe_viewport_state * ); - -void softpipe_set_vertex_element(struct pipe_context *, - unsigned index, - const struct pipe_vertex_element *); - -void softpipe_set_vertex_buffer(struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer *); - - -void softpipe_update_derived( struct softpipe_context *softpipe ); - - -boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); - -boolean softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count); - - -void -softpipe_map_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_surfaces(struct softpipe_context *sp); - -void -softpipe_map_texture_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_texture_surfaces(struct softpipe_context *sp); - - -struct vertex_info * -softpipe_get_vertex_info(struct softpipe_context *softpipe); - -struct vertex_info * -softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); - - -#endif +/************************************************************************** + * + * 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 + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + +struct tgsi_sampler; +struct tgsi_exec_machine; + + +/** Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct sp_fragment_shader { + struct pipe_shader_state shader; + + struct tgsi_shader_info info; + + void (*prepare)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct sp_fragment_shader * ); +}; + +struct vertex_info; + +/** Subclass of pipe_shader_state */ +struct sp_vertex_shader { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +softpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void softpipe_bind_blend_state(struct pipe_context *, + void *); +void softpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void softpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +softpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void softpipe_bind_rasterizer_state(struct pipe_context *, void *); +void softpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +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_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_sampler_textures( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void softpipe_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + + +void softpipe_update_derived( struct softpipe_context *softpipe ); + + +boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + +void +softpipe_map_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_surfaces(struct softpipe_context *sp); + +void +softpipe_map_texture_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_texture_surfaces(struct softpipe_context *sp); + + +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe); + +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); + + +#endif diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 1d6dd17d1d..7cf85b9207 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -50,45 +50,67 @@ softpipe_create_sampler_state(struct pipe_context *pipe, return mem_dup(sampler, sizeof(*sampler)); } + void -softpipe_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +softpipe_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == softpipe->num_samplers && + !memcmp(softpipe->sampler, sampler, num * sizeof(void *))) + return; + draw_flush(softpipe->draw); - assert(unit < PIPE_MAX_SAMPLERS); - softpipe->sampler[unit] = (struct pipe_sampler_state *)sampler; + memcpy(softpipe->sampler, sampler, num * sizeof(void *)); + memset(&softpipe->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + softpipe->num_samplers = num; softpipe->dirty |= SP_NEW_SAMPLER; } void -softpipe_delete_sampler_state(struct pipe_context *pipe, - void *sampler) +softpipe_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { - FREE( sampler ); -} + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + assert(num <= PIPE_MAX_SAMPLERS); -void -softpipe_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); + /* Check for no-op */ + if (num == softpipe->num_textures && + !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) + return; draw_flush(softpipe->draw); - assert(unit < PIPE_MAX_SAMPLERS); - pipe_texture_reference(&softpipe->texture[unit], texture); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + pipe_texture_reference(&softpipe->texture[i], tex); + sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex); + } - sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); + softpipe->num_textures = num; softpipe->dirty |= SP_NEW_TEXTURE; } +void +softpipe_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index c605ed925b..bbf2d80308 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -1,202 +1,202 @@ -/************************************************************************** - * - * Copyright 2006 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 - * Michel Dänzer - */ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_texture.h" -#include "sp_tile_cache.h" - - -/* Simple, maximally packed layout. - */ - -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - - -static void -softpipe_texture_layout(struct softpipe_texture * spt) -{ - struct pipe_texture *pt = &spt->base; - unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; - - spt->buffer_size = 0; - - for (level = 0; level <= pt->last_level; level++) { - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; - - spt->level_offset[level] = spt->buffer_size; - - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; - - width = minify(width); - height = minify(height); - depth = minify(depth); - } -} - - -static struct pipe_texture * -softpipe_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); - if (!spt) - return NULL; - - spt->base = *templat; - spt->base.refcount = 1; - spt->base.screen = screen; - - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; - } - - assert(spt->base.refcount == 1); - - return &spt->base; -} - - -static void -softpipe_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) -{ - if (!*pt) - return; - - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ - if (--(*pt)->refcount <= 0) { - struct softpipe_texture *spt = softpipe_texture(*pt); - - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - - FREE(spt); - } - *pt = NULL; -} - - -static struct pipe_surface * -softpipe_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = softpipe_texture(pt); - struct pipe_surface *ps; - - assert(level <= pt->last_level); - - ps = ws->surface_alloc(ws); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe_buffer_reference(ws, &ps->buffer, spt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = ps->width; - ps->offset = spt->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { - ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - } - return ps; -} - - -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } - } -} - - -void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) -{ - softpipe->pipe.texture_update = softpipe_texture_update; -} - - -void -softpipe_init_screen_texture_funcs(struct pipe_screen *screen) -{ - screen->texture_create = softpipe_texture_create_screen; - screen->texture_release = softpipe_texture_release_screen; - screen->get_tex_surface = softpipe_get_tex_surface_screen; -} +/************************************************************************** + * + * Copyright 2006 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 + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +softpipe_texture_layout(struct softpipe_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +static struct pipe_texture * +softpipe_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *templat; + spt->base.refcount = 1; + spt->base.screen = screen; + + softpipe_texture_layout(spt); + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + assert(spt->base.refcount == 1); + + return &spt->base; +} + + +static void +softpipe_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +static struct pipe_surface * +softpipe_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = ws->surface_alloc(ws); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + +static void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < softpipe->num_textures; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + +void +softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +{ + softpipe->pipe.texture_update = softpipe_texture_update; +} + + +void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = softpipe_texture_create_screen; + screen->texture_release = softpipe_texture_release_screen; + screen->get_tex_surface = softpipe_get_tex_surface_screen; +} diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 1501b52f3e..b64948f0f3 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -100,7 +100,7 @@ struct pipe_context { void * (*create_sampler_state)(struct pipe_context *, const struct pipe_sampler_state *); - void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *); + void (*bind_sampler_states)(struct pipe_context *, unsigned num, void **); void (*delete_sampler_state)(struct pipe_context *, void *); void * (*create_rasterizer_state)(struct pipe_context *, @@ -148,9 +148,9 @@ struct pipe_context { /* Currently a sampler is constrained to sample from a single texture: */ - void (*set_sampler_texture)( struct pipe_context *, - unsigned sampler, - struct pipe_texture * ); + void (*set_sampler_textures)( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); void (*set_viewport_state)( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 92263cb688..1000f98ffc 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -120,10 +120,11 @@ update_samplers(struct st_context *st) const struct st_fragment_program *fs = st->fp; GLuint su; + st->state.num_samplers = 0; + /* loop over sampler units (aka tex image units) */ for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_state sampler; - const struct cso_sampler *cso; memset(&sampler, 0, sizeof(sampler)); @@ -168,17 +169,16 @@ update_samplers(struct st_context *st) = st_compare_func_to_pipe(texobj->CompareFunc); } + st->state.num_samplers = su + 1; + /* XXX more sampler state here */ } - cso = st_cached_sampler_state(st, &sampler); - - if (cso != st->state.sampler[su]) { - /* state has changed */ - st->state.sampler[su] = cso; - st->pipe->bind_sampler_state(st->pipe, su, cso->data); - } + st->state.sampler[su] = st_cached_sampler_state(st, &sampler)->data; } + + st->pipe->bind_sampler_states(st->pipe, st->state.num_samplers, + st->state.sampler); } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 697d2cdfb4..e53a897637 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -37,6 +37,7 @@ #include "st_texture.h" #include "st_cb_texture.h" #include "pipe/p_context.h" +#include "pipe/p_inlines.h" /** @@ -51,6 +52,8 @@ update_textures(struct st_context *st) struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; GLuint unit; + st->state.num_textures = 0; + for (unit = 0; unit < st->ctx->Const.MaxTextureCoordUnits; unit++) { const GLuint su = fprog->Base.SamplerUnits[unit]; struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current; @@ -62,6 +65,8 @@ update_textures(struct st_context *st) retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush); /* XXX retval indicates whether there's a texture border */ + + st->state.num_textures = unit + 1; } /* XXX: need to ensure that textures are unbound/removed from @@ -70,18 +75,16 @@ update_textures(struct st_context *st) */ pt = st_get_stobj_texture(stObj); - - if (st->state.sampler_texture[unit] != pt) { - st->state.sampler_texture[unit] = pt; - st->pipe->set_sampler_texture(st->pipe, unit, pt); - } + pipe_texture_reference(&st->state.sampler_texture[unit], pt); if (stObj && stObj->dirtyData) { st->pipe->texture_update(st->pipe, pt); stObj->dirtyData = GL_FALSE; } - } + + st->pipe->set_sampler_textures(st->pipe, st->state.num_textures, + st->state.sampler_texture); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 65c9fda9cb..dee4c4132a 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -641,7 +641,6 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, const GLfloat *color, GLboolean invertTex) { - const GLuint unit = 0; struct pipe_context *pipe = ctx->st->pipe; GLfloat x0, y0, x1, y1; GLuint maxSize; @@ -684,7 +683,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; sampler.normalized_coords = 1; cso = st_cached_sampler_state(ctx->st, &sampler); - pipe->bind_sampler_state(pipe, unit, cso->data); + pipe->bind_sampler_states(pipe, 1, (void**)&cso->data); } /* viewport state: viewport matching window dims */ @@ -705,7 +704,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* texture state: */ { - pipe->set_sampler_texture(pipe, unit, pt); + pipe->set_sampler_textures(pipe, 1, &pt); } /* Compute window coords (y=0=bottom) with pixel zoom. @@ -727,8 +726,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->bind_rasterizer_state(pipe, ctx->st->state.rasterizer->data); pipe->bind_fs_state(pipe, ctx->st->state.fs->data); pipe->bind_vs_state(pipe, ctx->st->state.vs->cso->data); - pipe->set_sampler_texture(pipe, unit, ctx->st->state.sampler_texture[unit]); - pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]->data); + pipe->set_sampler_textures(pipe, ctx->st->state.num_textures, + ctx->st->state.sampler_texture); + pipe->bind_sampler_states(pipe, ctx->st->state.num_samplers, + ctx->st->state.sampler); pipe->set_viewport_state(pipe, &ctx->st->state.viewport); } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 1fbf9721e7..897a5109b7 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -76,7 +76,7 @@ struct st_context struct { const struct cso_alpha_test *alpha_test; const struct cso_blend *blend; - const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS]; + void *sampler[PIPE_MAX_SAMPLERS]; const struct cso_depth_stencil_alpha *depth_stencil; const struct cso_rasterizer *rasterizer; const struct cso_fragment_shader *fs; @@ -90,6 +90,9 @@ struct st_context struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; + + GLuint num_samplers; + GLuint num_textures; } state; struct { diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 841d77abbc..3723e26d45 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -284,7 +284,7 @@ st_render_mipmap(struct st_context *st, */ sampler.min_lod = sampler.max_lod = srcLevel; sampler_cso = pipe->create_sampler_state(pipe, &sampler); - pipe->bind_sampler_state(pipe, 0, sampler_cso); + pipe->bind_sampler_states(pipe, 1, &sampler_cso); simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); @@ -293,7 +293,7 @@ st_render_mipmap(struct st_context *st, * the right mipmap level. */ /*pt->first_level = srcLevel;*/ - pipe->set_sampler_texture(pipe, 0, pt); + pipe->set_sampler_textures(pipe, 1, &pt); draw_quad(st->ctx); @@ -310,9 +310,10 @@ st_render_mipmap(struct st_context *st, pipe->bind_fs_state(pipe, st->state.fs->data); if (st->state.vs) pipe->bind_vs_state(pipe, st->state.vs->cso->data); - if (st->state.sampler[0]) - pipe->bind_sampler_state(pipe, 0, st->state.sampler[0]->data); - pipe->set_sampler_texture(pipe, 0, st->state.sampler_texture[0]); + pipe->bind_sampler_states(pipe, st->state.num_samplers, + st->state.sampler); + pipe->set_sampler_textures(pipe, st->state.num_textures, + st->state.sampler_texture); pipe->set_viewport_state(pipe, &st->state.viewport); return TRUE; -- cgit v1.2.3 From 4abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 26 Mar 2008 09:36:40 +0000 Subject: gallium: Change pipe->flush() interface to optionally return a fence. The cell driver still uses an internal CELL_FLUSH_WAIT flag, in the long run proper fencing should be implemented for it. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- src/gallium/drivers/cell/ppu/cell_flush.c | 15 +++++++--- src/gallium/drivers/cell/ppu/cell_flush.h | 5 +++- src/gallium/drivers/cell/ppu/cell_vbuf.c | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 2 +- src/gallium/drivers/failover/fo_context.c | 4 +-- src/gallium/drivers/i915simple/i915_batch.h | 4 +-- src/gallium/drivers/i915simple/i915_blit.c | 4 +-- src/gallium/drivers/i915simple/i915_flush.c | 14 +++------- src/gallium/drivers/i915simple/i915_prim_emit.c | 2 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- src/gallium/drivers/i915simple/i915_state_emit.c | 2 +- src/gallium/drivers/i915simple/i915_winsys.h | 5 ++-- src/gallium/drivers/i965simple/brw_flush.c | 13 ++------- src/gallium/drivers/softpipe/sp_flush.c | 10 +++---- src/gallium/drivers/softpipe/sp_flush.h | 4 ++- src/gallium/include/pipe/p_context.h | 5 ++-- src/gallium/include/pipe/p_defines.h | 3 +- src/gallium/winsys/dri/intel/intel_context.c | 4 +-- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 25 ++++++++++------- src/gallium/winsys/xlib/xm_winsys.c | 31 +++++++++++++++++++++ src/mesa/state_tracker/st_cb_accum.c | 2 +- src/mesa/state_tracker/st_cb_drawpixels.c | 4 +-- src/mesa/state_tracker/st_cb_fbo.c | 2 +- src/mesa/state_tracker/st_cb_flush.c | 34 +++++++++++++---------- src/mesa/state_tracker/st_cb_readpixels.c | 2 +- src/mesa/state_tracker/st_framebuffer.c | 3 +- src/mesa/state_tracker/st_public.h | 5 +++- 28 files changed, 127 insertions(+), 83 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e129c062be..ed12768e7f 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -935,7 +935,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 4, /* verts */ 2); /* attribs/vert */ - pipe->flush(pipe, PIPE_FLUSH_WAIT); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ pipe->texture_update(pipe, pt, face, (1 << dstLevel)); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 66a5627d84..3aaf3de668 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -35,12 +35,19 @@ void -cell_flush(struct pipe_context *pipe, unsigned flags) +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct cell_context *cell = cell_context(pipe); + if (fence) { + *fence = NULL; + /* XXX: Implement real fencing */ + flags |= CELL_FLUSH_WAIT; + } + if (flags & PIPE_FLUSH_SWAPBUFFERS) - flags |= PIPE_FLUSH_WAIT; + flags |= CELL_FLUSH_WAIT; draw_flush( cell->draw ); cell_flush_int(pipe, flags); @@ -58,7 +65,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) ASSERT(!flushing); flushing = TRUE; - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t)); *cmd = CELL_CMD_FINISH; } @@ -72,7 +79,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) } #endif - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { /* Wait for ack */ for (i = 0; i < cell->num_spus; i++) { uint k = wait_mbox_message(cell_global.spe_contexts[i]); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h index 7f940ae76b..8f0645c429 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.h +++ b/src/gallium/drivers/cell/ppu/cell_flush.h @@ -29,8 +29,11 @@ #ifndef CELL_FLUSH #define CELL_FLUSH +#define CELL_FLUSH_WAIT 0x80000000 + extern void -cell_flush(struct pipe_context *pipe, unsigned flags); +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); extern void cell_flush_int(struct pipe_context *pipe, unsigned flags); diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index cc727ff4ed..3a181b585c 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -243,7 +243,7 @@ cell_vbuf_draw(struct vbuf_render *vbr, #if 0 /* helpful for debug */ - cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT); #endif } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index f5c27852c1..b418857ccd 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -133,7 +133,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) vs->num_elts = n; send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE); - cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index afc0d7eb1e..cb95ba516f 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -69,7 +69,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, start, count )) { - failover->hw->flush( failover->hw, ~0 ); + failover->hw->flush( failover->hw, ~0, NULL ); failover->mode = FO_SW; } } @@ -92,7 +92,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, * intervening flush. Unlikely to be much performance impact to * this: */ - failover->sw->flush( failover->sw, ~0 ); + failover->sw->flush( failover->sw, ~0, NULL ); } return TRUE; diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index fb88cd6db0..4ea06ce02b 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -44,9 +44,9 @@ #define ADVANCE_BATCH() -#define FLUSH_BATCH() do { \ +#define FLUSH_BATCH(fence) do { \ if (0) i915_dump_batchbuffer( i915 ); \ - i915->winsys->batch_flush( i915->winsys ); \ + i915->winsys->batch_flush( i915->winsys, fence ); \ i915->batch_start = NULL; \ i915->hardware_dirty = ~0; \ } while (0) diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index db4671ff55..24449e3fb3 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -70,7 +70,7 @@ i915_fill_blit(struct i915_context *i915, if (!BEGIN_BATCH(6, 1)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(6, 1)); } OUT_BATCH(CMD); @@ -145,7 +145,7 @@ i915_copy_blit( struct i915_context *i915, if (!BEGIN_BATCH(8, 2)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(8, 2)); } OUT_BATCH(CMD); diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 96a54281f1..7d23e6b6b9 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -37,11 +37,9 @@ #include "i915_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void i915_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct i915_context *i915 = i915_context(pipe); @@ -60,7 +58,7 @@ static void i915_flush( struct pipe_context *pipe, flush |= FLUSH_MAP_CACHE; if (!BEGIN_BATCH(1, 0)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(1, 0)); } OUT_BATCH( flush ); @@ -69,11 +67,7 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH(); - - if (flags & PIPE_FLUSH_WAIT) { - i915->winsys->batch_finish(i915->winsys); - } + FLUSH_BATCH(fence); } diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index d8de5178f6..b6fb0a6d88 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -140,7 +140,7 @@ emit_prim( struct draw_stage *stage, assert(vertex_size >= 12); /* never smaller than 12 bytes */ if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index eb64f51943..7fb2adbb53 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -161,7 +161,7 @@ i915_vbuf_render_draw( struct vbuf_render *render, i915_emit_hardware_state( i915 ); if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index a7498d22b7..6f947d4346 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -115,7 +115,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) #endif if(!BEGIN_BATCH(dwords, relocs)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(dwords, relocs)); } diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index aea3003281..5e16543f4e 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -56,6 +56,7 @@ extern "C" { */ struct pipe_buffer; +struct pipe_fence_handle; struct pipe_winsys; struct pipe_screen; @@ -103,8 +104,8 @@ struct i915_winsys { unsigned access_flags, unsigned delta ); - void (*batch_flush)( struct i915_winsys *sws ); - void (*batch_finish)( struct i915_winsys *sws ); + void (*batch_flush)( struct i915_winsys *sws, + struct pipe_fence_handle **fence ); }; #define I915_BUFFER_ACCESS_WRITE 0x1 diff --git a/src/gallium/drivers/i965simple/brw_flush.c b/src/gallium/drivers/i965simple/brw_flush.c index 5216c680cf..e6001c30d9 100644 --- a/src/gallium/drivers/i965simple/brw_flush.c +++ b/src/gallium/drivers/i965simple/brw_flush.c @@ -36,14 +36,11 @@ #include "brw_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void brw_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct brw_context *brw = brw_context(pipe); - struct pipe_fence_handle *fence; /* Do we need to emit an MI_FLUSH command to flush the hardware * caches? @@ -65,11 +62,7 @@ static void brw_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH( &fence ); - - if (flags & PIPE_FLUSH_WAIT) { -// brw->winsys->wait_fence(brw->winsys, fence); - } + FLUSH_BATCH( fence ); } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 2cbd0d7cab..0625b69099 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -40,13 +40,10 @@ #include "sp_winsys.h" -/* There will be actual work to do here. In future we may want a - * fence-like interface instead of finish, and perhaps flush will take - * flags to indicate what type of flush is required. - */ void softpipe_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -72,5 +69,8 @@ softpipe_flush( struct pipe_context *pipe, * to unmap surfaces when flushing. */ softpipe_unmap_surfaces(softpipe); + + if (fence) + *fence = NULL; } diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index 34ec617866..68d9b5fa83 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -29,7 +29,9 @@ #define SP_FLUSH_H struct pipe_context; +struct pipe_fence_handle; -void softpipe_flush(struct pipe_context *pipe, unsigned flags ); +void softpipe_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); #endif diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index a3824601be..b2e49bef4c 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -37,7 +37,7 @@ extern "C" { struct pipe_screen; - +struct pipe_fence_handle; struct pipe_state_cache; /* Opaque driver handles: @@ -202,7 +202,8 @@ struct pipe_context { /* Flush rendering: */ void (*flush)( struct pipe_context *pipe, - unsigned flags ); + unsigned flags, + struct pipe_fence_handle **fence ); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bc938ba253..586951d956 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -201,8 +201,7 @@ enum pipe_texture_target { */ #define PIPE_FLUSH_RENDER_CACHE 0x1 #define PIPE_FLUSH_TEXTURE_CACHE 0x2 -#define PIPE_FLUSH_WAIT 0x4 -#define PIPE_FLUSH_SWAPBUFFERS 0x8 +#define PIPE_FLUSH_SWAPBUFFERS 0x4 /** diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 79b320c6bf..8eba33c313 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) assert(intel); /* should never be null */ if (intel) { - st_flush(intel->st, PIPE_FLUSH_WAIT); + st_finish(intel->st); intel_batchbuffer_free(intel->batch); @@ -256,7 +256,7 @@ GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, 0x0); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* XXX make_current(NULL)? */ return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 2def1afc31..4d183db7c3 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,12 +39,14 @@ #include "intel_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" #include "i915simple/i915_winsys.h" #include "i915simple/i915_screen.h" struct intel_i915_winsys { struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; struct intel_context *intel; }; @@ -112,19 +114,22 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, -static void intel_i915_batch_flush( struct i915_winsys *sws ) +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) { - struct intel_context *intel = intel_i915_winsys(sws)->intel; + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; - intel_batchbuffer_flush( intel->batch ); -// if (0) intel_i915_batch_wait_idle( sws ); -} + fu.dri = intel_batchbuffer_flush( intel->batch ); + if (fu.dri) + iws->pws->fence_reference(iws->pws, fence, fu.pipe); -static void intel_i915_batch_finish( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_finish( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); } @@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_dword = intel_i915_batch_dword; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; - iws->winsys.batch_finish = intel_i915_batch_finish; + iws->pws = winsys; iws->intel = intel; screen = i915_create_screen(winsys, intel->intelScreen->deviceID); diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7baaae295c..c930a1d196 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -570,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) } +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + /** * Return pointer to a pipe_winsys object. @@ -603,6 +630,10 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; + ws->fence_reference = xm_fence_reference; + ws->fence_signalled = xm_fence_signalled; + ws->fence_finish = xm_fence_finish; + ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index f1fddc4e02..a623d0bcc0 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -214,7 +214,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) const GLint height = ctx->DrawBuffer->_Ymax - ypos; /* make sure color bufs aren't cached */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); switch (op) { case GL_ADD: diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 026f015fd8..43cc21d1fb 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -737,7 +737,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLint skipPixels; ubyte *stmap; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* map the stencil buffer */ stmap = pipe_surface_map(ps); @@ -952,7 +952,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, enum pipe_format srcFormat, texFormat; /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); st_validate_state(st); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 5384252a8e..ec7788923a 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -366,7 +366,7 @@ st_finish_render_texture(GLcontext *ctx, assert(strb); - ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE); + ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index dbec993f1b..a536a059bd 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -43,19 +43,21 @@ #include "pipe/p_winsys.h" -void st_flush( struct st_context *st, uint pipeFlushFlags ) +void st_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ) { FLUSH_VERTICES(st->ctx, 0); - st->pipe->flush( st->pipe, pipeFlushFlags ); + st->pipe->flush( st->pipe, pipeFlushFlags, fence ); } -static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) +static void st_gl_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ) { GLframebuffer *fb = st->ctx->DrawBuffer; - FLUSH_VERTICES(st->ctx, 0); + st_flush( st, pipeFlushFlags, fence ); if (!fb) return; @@ -80,15 +82,6 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); struct pipe_surface *front_surf = strb->surface; - /* If we aren't rendering to the frontbuffer, this is a noop. - * This should be uncontroversial for glFlush, though people may - * feel more strongly about glFinish. - * - * Additionally, need to make sure that the frontbuffer_dirty - * flag really gets set on frontbuffer rendering. - */ - st->pipe->flush( st->pipe, pipeFlushFlags ); - /* Hook for copying "fake" frontbuffer if necessary: */ st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, @@ -103,7 +96,18 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) */ static void st_glFlush(GLcontext *ctx) { - st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); + st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); +} + + +void st_finish( struct st_context *st ) +{ + struct pipe_fence_handle *fence; + + st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); + + st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0); + st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL); } @@ -112,7 +116,7 @@ static void st_glFlush(GLcontext *ctx) */ static void st_glFinish(GLcontext *ctx) { - st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT); + st_finish( ctx->st ); } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 4cf9adcd28..e9fcdf69a1 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -160,7 +160,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, return; /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); if (format == GL_STENCIL_INDEX) { st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index d46a9178b1..075e9d1bd6 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -186,7 +186,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) if (ctx && ctx->DrawBuffer == &stfb->Base) { st_flush( ctx->st, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS); + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS, + NULL ); } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 3c397b126a..9d88ce9764 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -45,6 +45,7 @@ struct st_context; struct st_framebuffer; struct pipe_context; +struct pipe_fence_handle; struct pipe_surface; @@ -78,7 +79,9 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); -void st_flush( struct st_context *st, uint pipeFlushFlags ); +void st_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ); +void st_finish( struct st_context *st ); void st_notify_swapbuffers(struct st_framebuffer *stfb); void st_notify_swapbuffers_complete(struct st_framebuffer *stfb); -- cgit v1.2.3 From ce56bcb640072496809d2aefede5a32fe9256ace Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 21:15:36 +0200 Subject: i915: Prepare for tiled private front and back buffers --- src/gallium/drivers/i915simple/i915_state_emit.c | 1 + src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 26 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 6f947d4346..8bcc26ad35 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -217,6 +217,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_BATCH(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(pitch) | /* pitch in bytes */ +// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */ BUF_3D_USE_FENCE); OUT_RELOC(cbuf_surface->buffer, diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index fb8f44c845..2e6c452cd1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -212,6 +212,15 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } +static unsigned +power_of_two(unsigned x) +{ + int value = 1; + while (value <= x) + value = value << 1; + return value; +} + /*pipe_buffer_reference(winsys, &i915_render->vbo, NULL);*/ /** * Copied from xm_winsys.c */ @@ -224,18 +233,31 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned tex_usage) { const unsigned alignment = 64; + assert(!surf->buffer); +#if 0 + surf->width = width; + surf->height = round_up(height, 8); + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = power_of_two(MAX2(width * surf->cpp, 512)); + surf->buffer = winsys->buffer_create(winsys, 2*4096, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->height); + + surf->pitch = surf->pitch / surf->cpp; + surf->height = height; +#else surf->width = width; surf->height = height; surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, surf->pitch * surf->cpp * surf->height); - +#endif if(!surf->buffer) return -1; -- cgit v1.2.3 From c1949e2bd3acc45c23cc434eef2b0d6aae9092ca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 12:55:35 +0200 Subject: i915: Fixed some warnings --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 4 +--- src/gallium/drivers/i915simple/i915_state_emit.c | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index f9297e29fc..adfb16fbc5 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -253,7 +253,6 @@ draw_arrays_fallback( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; unsigned nr_indices; if (i915->dirty) @@ -372,7 +371,6 @@ i915_vbuf_render_draw( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; unsigned save_nr_indices; save_nr_indices = nr_indices; @@ -424,7 +422,6 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; size_t size = (size_t)vertex_size * (size_t)vertices_used; assert(i915->vbo); @@ -502,6 +499,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ) render->destroy(render); return NULL; } + /** TODO JB: this shouldn't be here */ draw_set_render(i915->draw, render); return stage; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 8bcc26ad35..de0c1a787a 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -377,6 +377,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) { uint w, h; boolean k = framebuffer_size(&i915->framebuffer, &w, &h); + (void)k; assert(k); OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); -- cgit v1.2.3 From d1397fd779ce63416bb59662a3c96f9c0a6ef7f5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 19:07:29 +0200 Subject: i915: Fix offsets not being used for surface targets --- src/gallium/drivers/i915simple/i915_state_emit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index de0c1a787a..480b0b54c4 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -222,7 +222,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_RELOC(cbuf_surface->buffer, I915_BUFFER_ACCESS_WRITE, - 0); + cbuf_surface->offset); } /* What happens if no zbuf?? @@ -238,7 +238,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_RELOC(depth_surface->buffer, I915_BUFFER_ACCESS_WRITE, - 0); + depth_surface->offset); } { -- cgit v1.2.3 From 3da77b33bb0093ff27c16833ed93a3a114c3e95e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 20:46:14 +0200 Subject: i915: Improved the not used tile code --- src/gallium/drivers/i915simple/i915_state_emit.c | 21 ++++++++++----- src/gallium/drivers/i915simple/i915_texture.c | 33 +++++++++++++++--------- 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 480b0b54c4..bc801a82f0 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -211,14 +211,18 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; if (cbuf_surface) { - unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned ctile = BUF_3D_USE_FENCE; +#if 0 + if (!((cpitch - 1) & cpitch) && cpitch >= 512) + ctile = BUF_3D_TILED_SURFACE; +#endif OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(pitch) | /* pitch in bytes */ -// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */ - BUF_3D_USE_FENCE); + BUF_3D_PITCH(cpitch) | /* pitch in bytes */ + ctile); OUT_RELOC(cbuf_surface->buffer, I915_BUFFER_ACCESS_WRITE, @@ -229,12 +233,17 @@ i915_emit_hardware_state(struct i915_context *i915 ) */ if (depth_surface) { unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); - + unsigned ztile = BUF_3D_USE_FENCE; +#if 0 + if (!((zpitch - 1) & zpitch) && zpitch >= 512) + ztile = BUF_3D_TILED_SURFACE; +#endif + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_DEPTH | BUF_3D_PITCH(zpitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); + ztile); OUT_RELOC(depth_surface->buffer, I915_BUFFER_ACCESS_WRITE, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 7a1665d48b..d591b09e3c 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,16 +104,14 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } -#if 0 static unsigned power_of_two(unsigned x) { - int value = 1; + unsigned value = 1; while (value <= x) value = value << 1; return value; } -#endif static unsigned round_up(unsigned n, unsigned multiple) @@ -125,8 +123,7 @@ round_up(unsigned n, unsigned multiple) * Special case to deal with display targets. */ static boolean -i915_displaytarget_layout(struct pipe_screen *screen, - struct i915_texture *tex) +i915_displaytarget_layout(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; @@ -139,13 +136,19 @@ i915_displaytarget_layout(struct pipe_screen *screen, 1 ); i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); -#if 0 - tex->pitch = MAX2(512, power_of_two(tex->base.width[0] * pt->cpp)) / pt->cpp; - tex->total_height = round_up(tex->base.height[0], 8); -#else - tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); - tex->total_height = tex->base.height[0]; -#endif + if (tex->base.width[0] >= 128) { + tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; + tex->total_height = round_up(tex->base.height[0], 8); + } else { + tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); + tex->total_height = tex->base.height[0]; + } + +/* + printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + tex->base.width[0], tex->base.height[0], pt->cpp, + tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); +*/ return 1; } @@ -161,6 +164,12 @@ i945_miptree_layout_2d( struct i915_texture *tex ) unsigned width = pt->width[0]; unsigned height = pt->height[0]; +#if 0 /* used for tiled display targets */ + if (pt->last_level == 0 && pt->cpp == 4) + if (i915_displaytarget_layout(tex)) + return; +#endif + tex->pitch = pt->width[0]; /* May need to adjust pitch to accomodate the placement of -- cgit v1.2.3 From f52ab4cc22bfb6708724f3c3966ce734d605cddd Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 23 Jun 2008 17:57:45 +0200 Subject: i915: Add render and texture support for tiled texture and buffers This is step towards tiled textures and buffer support for i915. But the tiled attribute is never set. --- src/gallium/drivers/i915simple/i915_context.h | 2 ++ src/gallium/drivers/i915simple/i915_state_emit.c | 12 ++++++------ src/gallium/drivers/i915simple/i915_state_sampler.c | 8 +++++++- src/gallium/drivers/i915simple/i915_texture.c | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 9e02f78714..5d411a6648 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -192,6 +192,8 @@ struct i915_texture { unsigned depth_pitch; /* per-image on i945? */ unsigned total_height; + unsigned tiled; + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; /* Explicitly store the offset of each image for each cube face or diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index bc801a82f0..19d968fd8b 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -213,10 +213,10 @@ i915_emit_hardware_state(struct i915_context *i915 ) if (cbuf_surface) { unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); unsigned ctile = BUF_3D_USE_FENCE; -#if 0 - if (!((cpitch - 1) & cpitch) && cpitch >= 512) + if (cbuf_surface->texture && + ((struct i915_texture*)(cbuf_surface->texture))->tiled) { ctile = BUF_3D_TILED_SURFACE; -#endif + } OUT_BATCH(_3DSTATE_BUF_INFO_CMD); @@ -234,10 +234,10 @@ i915_emit_hardware_state(struct i915_context *i915 ) if (depth_surface) { unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); unsigned ztile = BUF_3D_USE_FENCE; -#if 0 - if (!((zpitch - 1) & zpitch) && zpitch >= 512) + if (depth_surface->texture && + ((struct i915_texture*)(depth_surface->texture))->tiled) { ztile = BUF_3D_TILED_SURFACE; -#endif + } OUT_BATCH(_3DSTATE_BUF_INFO_CMD); diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 24440843f3..379aff3846 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -234,6 +234,7 @@ i915_update_texture(struct i915_context *i915, const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; const uint num_levels = pt->last_level; unsigned max_lod = num_levels * 4; + unsigned tiled = MS3_USE_FENCE_REGS; assert(tex); assert(width); @@ -246,12 +247,17 @@ i915_update_texture(struct i915_context *i915, assert(format); assert(pitch); + if (tex->tiled) { + assert(!((pitch - 1) & pitch)); + tiled = MS3_TILED_SURFACE; + } + /* MS3 state */ state[0] = (((height - 1) << MS3_HEIGHT_SHIFT) | ((width - 1) << MS3_WIDTH_SHIFT) | format - | MS3_USE_FENCE_REGS); + | tiled); /* * XXX When min_filter != mag_filter and there's just one mipmap level, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index d9b33df1d5..ae107c6676 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -174,6 +174,7 @@ i915_displaytarget_layout(struct i915_texture *tex) if (tex->base.width[0] >= 128) { tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; tex->total_height = round_up(tex->base.height[0], 8); + tex->tiled = 1; } else { tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); tex->total_height = tex->base.height[0]; -- cgit v1.2.3 From 4ddd65967915ca4846f2831bc676c878a29dae4a Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 27 Jun 2008 19:37:56 +0900 Subject: gallium: Drop pipe_texture->cpp and pipe_surface->cpp. The chars-per-pixel concept falls apart with compressed and yuv images, where more than one pixel are coded in a single data block. --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 6 +- src/gallium/auxiliary/util/p_tile.c | 98 ++++------- src/gallium/auxiliary/util/p_util.c | 100 +++++++++-- src/gallium/auxiliary/util/u_blit.c | 2 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 8 +- src/gallium/drivers/i915simple/i915_blit.c | 2 - src/gallium/drivers/i915simple/i915_context.h | 6 +- src/gallium/drivers/i915simple/i915_state_emit.c | 4 +- .../drivers/i915simple/i915_state_sampler.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 68 ++----- src/gallium/drivers/i915simple/i915_texture.c | 196 +++++++++++---------- src/gallium/drivers/i965simple/brw_context.h | 4 +- src/gallium/drivers/i965simple/brw_misc_state.c | 8 +- src/gallium/drivers/i965simple/brw_surface.c | 69 ++------ src/gallium/drivers/i965simple/brw_tex_layout.c | 117 ++++++------ .../drivers/i965simple/brw_wm_surface_state.c | 6 +- src/gallium/drivers/softpipe/sp_surface.c | 45 ++--- src/gallium/drivers/softpipe/sp_texture.c | 20 ++- src/gallium/drivers/softpipe/sp_texture.h | 2 +- src/gallium/include/pipe/p_format.h | 41 +++++ src/gallium/include/pipe/p_state.h | 11 +- src/gallium/include/pipe/p_util.h | 15 +- src/gallium/winsys/xlib/brw_aub.c | 9 +- src/gallium/winsys/xlib/xm_winsys.c | 24 +-- src/gallium/winsys/xlib/xm_winsys_aub.c | 31 ++-- src/mesa/state_tracker/st_cb_accum.c | 24 +-- src/mesa/state_tracker/st_cb_bitmap.c | 4 +- src/mesa/state_tracker/st_cb_drawpixels.c | 11 +- src/mesa/state_tracker/st_cb_fbo.c | 8 +- src/mesa/state_tracker/st_cb_readpixels.c | 6 +- src/mesa/state_tracker/st_cb_texture.c | 17 +- src/mesa/state_tracker/st_gen_mipmap.c | 4 +- src/mesa/state_tracker/st_texture.c | 26 ++- 34 files changed, 513 insertions(+), 485 deletions(-) (limited to 'src/gallium/drivers/i915simple/i915_state_emit.c') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index ecdebca5f1..3dd7ee19fd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -398,7 +398,7 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.depth[0] = 1; - texTemp.cpp = 1; + pf_get_block(texTemp.format, &texTemp.block); aaline->texture = screen->texture_create(screen, &texTemp); if (!aaline->texture) @@ -439,7 +439,7 @@ aaline_create_texture(struct aaline_stage *aaline) else { d = 255; } - data[i * surface->pitch + j] = d; + data[i * surface->stride + j] = d; } } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4087cf7a49..1f63f94365 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -394,11 +394,11 @@ pstip_update_texture(struct pstip_stage *pstip) for (j = 0; j < 32; j++) { if (stipple[i] & (bit31 >> j)) { /* fragment "on" */ - data[i * surface->pitch + j] = 0; + data[i * surface->stride + j] = 0; } else { /* fragment "off" */ - data[i * surface->pitch + j] = 255; + data[i * surface->stride + j] = 255; } } } @@ -426,7 +426,7 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.width[0] = 32; texTemp.height[0] = 32; texTemp.depth[0] = 1; - texTemp.cpp = 1; + pf_get_block(texTemp.format, &texTemp.block); pstip->texture = screen->texture_create(screen, &texTemp); if (pstip->texture == NULL) diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 5728757d2f..ab603ff6e4 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -48,34 +48,23 @@ void pipe_get_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, - void *p, int dst_stride) + void *dst, int dst_stride) { struct pipe_screen *screen = pipe->screen; - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint src_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (dst_stride == 0) { - dst_stride = w * cpp; - } + const void *src; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) screen->surface_map(screen, ps, - PIPE_BUFFER_USAGE_CPU_READ); - assert(pSrc); /* XXX: proper error handling! */ + if (dst_stride == 0) + dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - pSrc += (y * ps->pitch + x) * cpp; - pDest = (ubyte *) p; + src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + assert(src); + if(!src) + return; - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } + pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); screen->surface_unmap(screen, ps); } @@ -89,34 +78,23 @@ void pipe_put_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, - const void *p, int src_stride) + const void *src, int src_stride) { struct pipe_screen *screen = pipe->screen; - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint dst_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (src_stride == 0) { - src_stride = w * cpp; - } + void *dst; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) p; + if (src_stride == 0) + src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); - assert(pDest); /* XXX: proper error handling */ - - pDest += (y * ps->pitch + x) * cpp; + dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(dst); + if(!dst) + return; - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } + pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); screen->surface_unmap(screen, ps); } @@ -692,12 +670,12 @@ pipe_get_tile_rgba(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - packed = MALLOC(h * w * ps->cpp); + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); if (!packed) return; - pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0); switch (ps->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -774,7 +752,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - packed = MALLOC(h * w * ps->cpp); + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); if (!packed) return; @@ -829,7 +807,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, assert(0); } - pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0); FREE(packed); } @@ -846,14 +824,14 @@ pipe_get_tile_z(struct pipe_context *pipe, { struct pipe_screen *screen = pipe->screen; const uint dstStride = w; - void *map; + ubyte *map; uint *pDest = z; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); if (!map) { assert(0); return; @@ -863,11 +841,11 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_Z32_UNORM: { const uint *pSrc - = (const uint *)map + (y * ps->pitch + x); + = (const uint *)(map + y * ps->stride + x*4); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/4; } } break; @@ -875,28 +853,28 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc - = (const uint *)map + (y * ps->pitch + x); + = (const uint *)(map + y * ps->stride + x*4); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 24-bit Z to 32-bit Z */ pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff); } pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/4; } } break; case PIPE_FORMAT_Z16_UNORM: { const ushort *pSrc - = (const ushort *)map + (y * ps->pitch + x); + = (const ushort *)(map + y * ps->stride + x*2); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 16-bit Z to 32-bit Z */ pDest[j] = (pSrc[j] << 16) | pSrc[j]; } pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/2; } } break; @@ -917,13 +895,13 @@ pipe_put_tile_z(struct pipe_context *pipe, struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; - void *map; + ubyte *map; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); if (!map) { assert(0); return; @@ -932,10 +910,10 @@ pipe_put_tile_z(struct pipe_context *pipe, switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { - uint *pDest = (uint *) map + (y * ps->pitch + x); + uint *pDest = (uint *) (map + y * ps->stride + x*4); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); - pDest += ps->pitch; + pDest += ps->stride/4; pSrc += srcStride; } } @@ -943,26 +921,26 @@ pipe_put_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: { - uint *pDest = (uint *) map + (y * ps->pitch + x); + uint *pDest = (uint *) (map + y * ps->stride + x*4); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z (0 stencil) */ pDest[j] = pSrc[j] >> 8; } - pDest += ps->pitch; + pDest += ps->stride/4; pSrc += srcStride; } } break; case PIPE_FORMAT_Z16_UNORM: { - ushort *pDest = (ushort *) map + (y * ps->pitch + x); + ushort *pDest = (ushort *) (map + y * ps->stride + x*2); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 16-bit Z */ pDest[j] = pSrc[j] >> 16; } - pDest += ps->pitch; + pDest += ps->stride/2; pSrc += srcStride; } } diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c index 4e60b1b841..271be4edf1 100644 --- a/src/gallium/auxiliary/util/p_util.c +++ b/src/gallium/auxiliary/util/p_util.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_format.h" /** @@ -41,42 +42,109 @@ */ void pipe_copy_rect(ubyte * dst, - unsigned cpp, - unsigned dst_pitch, + const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, unsigned width, unsigned height, const ubyte * src, - int src_pitch, + int src_stride, unsigned src_x, int src_y) { unsigned i; - int src_pitch_pos = src_pitch < 0 ? -src_pitch : src_pitch; + int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; - assert(cpp > 0); + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); assert(src_x >= 0); assert(src_y >= 0); assert(dst_x >= 0); assert(dst_y >= 0); - dst_pitch *= cpp; - src_pitch *= cpp; - src_pitch_pos *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * src_pitch_pos; - width *= cpp; + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + src_x /= block->width; + src_y /= block->height; + + dst += dst_x * block->size; + src += src_x * block->size; + dst += dst_y * dst_stride; + src += src_y * src_stride_pos; + width *= block->size; - if (width == dst_pitch && width == src_pitch) + if (width == dst_stride && width == src_stride) memcpy(dst, src, height * width); else { for (i = 0; i < height; i++) { memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; + dst += dst_stride; + src += src_stride; } } } + +void +pipe_fill_rect(ubyte * dst, + const struct pipe_format_block *block, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + uint32_t value) +{ + unsigned i, j; + unsigned width_size; + + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + assert(dst_x >= 0); + assert(dst_y >= 0); + + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + + dst += dst_x * block->size; + dst += dst_y * dst_stride; + width_size = width * block->size; + + switch (block->size) { + case 1: + if(dst_stride == width_size) + memset(dst, (ubyte) value, height * width_size); + else { + for (i = 0; i < height; i++) { + memset(dst, (ubyte) value, width_size); + dst += dst_stride; + } + } + break; + case 2: + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) + *row++ = (uint16_t) value; + dst += dst_stride; + } + break; + case 4: + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) + *row++ = value; + dst += dst_stride; + } + break; + default: + assert(0); + break; + } +} diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 6555dcd588..ae779335dc 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -324,7 +324,7 @@ util_blit_pixels(struct blit_state *ctx, texTemp.height[0] = srcH; texTemp.depth[0] = 1; texTemp.compressed = 0; - texTemp.cpp = pf_get_size(src->format); + pf_get_block(src->format, &texTemp.block); tex = screen->texture_create(screen, &texTemp); if (!tex) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 7d71aefda9..5313a8008a 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -625,7 +625,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, struct pipe_winsys *winsys = pipe->winsys; const uint zslice = 0; uint dstLevel; - const int bpt = pf_get_size(pt->format); + + assert(pt->block.width == 1); + assert(pt->block.height == 1); for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; @@ -646,9 +648,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, reduce_2d(pt->format, srcSurf->width, srcSurf->height, - srcSurf->pitch * bpt, srcMap, + srcSurf->stride, srcMap, dstSurf->width, dstSurf->height, - dstSurf->pitch * bpt, dstMap); + dstSurf->stride, dstMap); winsys->buffer_unmap(winsys, srcSurf->buffer); winsys->buffer_unmap(winsys, dstSurf->buffer); diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index 22f91fab92..45fae4c999 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -47,8 +47,6 @@ i915_fill_blit(struct i915_context *i915, { unsigned BR13, CMD; - dst_pitch *= (short) cpp; - switch (cpp) { case 1: case 2: diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 5d411a6648..c8db4f608c 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -188,9 +188,9 @@ struct i915_texture { /* Derived from the above: */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; + unsigned stride; + unsigned depth_stride; /* per-image on i945? */ + unsigned total_nblocksy; unsigned tiled; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 19d968fd8b..9bd6f92323 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -211,7 +211,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; if (cbuf_surface) { - unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned cpitch = cbuf_surface->stride; unsigned ctile = BUF_3D_USE_FENCE; if (cbuf_surface->texture && ((struct i915_texture*)(cbuf_surface->texture))->tiled) { @@ -232,7 +232,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* What happens if no zbuf?? */ if (depth_surface) { - unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); + unsigned zpitch = depth_surface->stride; unsigned ztile = BUF_3D_USE_FENCE; if (depth_surface->texture && ((struct i915_texture*)(depth_surface->texture))->tiled) { diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 379aff3846..7868f21ca6 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -242,7 +242,7 @@ i915_update_texture(struct i915_context *i915, assert(depth); format = translate_texture_format(pt->format); - pitch = tex->pitch * pt->cpp; + pitch = tex->stride; assert(format); assert(pitch); diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index cc55a0910e..0061b22f26 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -48,7 +48,9 @@ i915_surface_copy(struct pipe_context *pipe, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { assert( dst != src ); - assert( dst->cpp == src->cpp ); + assert( dst->block.size == src->block.size ); + assert( dst->block.width == src->block.height ); + assert( dst->block.height == src->block.height ); if (0) { void *dst_map = pipe->screen->surface_map( pipe->screen, @@ -60,38 +62,30 @@ i915_surface_copy(struct pipe_context *pipe, PIPE_BUFFER_USAGE_CPU_READ ); pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); i915_copy_blit( i915_context(pipe), do_flip, - dst->cpp, - (short) src->pitch, src->buffer, src->offset, - (short) dst->pitch, dst->buffer, dst->offset, + dst->block.size, + (short) src->stride/src->block.size, src->buffer, src->offset, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); } } -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void * -get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) -{ - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; -} - - static void i915_surface_fill(struct pipe_context *pipe, struct pipe_surface *dst, @@ -99,50 +93,20 @@ i915_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { if (0) { - unsigned i, j; void *dst_map = pipe->screen->surface_map( pipe->screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - - switch (dst->cpp) { - case 1: { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; - case 2: { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; - case 4: { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - break; - default: - assert(0); - break; - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); i915_fill_blit( i915_context(pipe), - dst->cpp, - (short) dst->pitch, + dst->block.size, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, (short) dstx, (short) dsty, (short) width, (short) height, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b2e490c7db..2815e61345 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -109,6 +109,9 @@ i915_miptree_set_level_info(struct i915_texture *tex, pt->width[level] = w; pt->height[level] = h; pt->depth[level] = d; + + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h); tex->nr_images[level] = nr_images; @@ -140,7 +143,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); - tex->image_offset[level][img] = (x + y * tex->pitch); + tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size; /* printf("%s level %d img %d pos %d,%d image_offset %x\n", @@ -162,7 +165,7 @@ i915_displaytarget_layout(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; - if (pt->last_level > 0 || pt->cpp != 4) + if (pt->last_level > 0 || pt->block.size != 4) return 0; i915_miptree_set_level_info( tex, 0, 1, @@ -172,18 +175,18 @@ i915_displaytarget_layout(struct i915_texture *tex) i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); if (tex->base.width[0] >= 128) { - tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; - tex->total_height = round_up(tex->base.height[0], 8); + tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); + tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); tex->tiled = 1; } else { - tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); - tex->total_height = tex->base.height[0]; + tex->stride = round_up(tex->base.nblocksx[0] * pt->block.size, 64); + tex->total_nblocksy = tex->base.nblocksy[0]; } /* printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - tex->base.width[0], tex->base.height[0], pt->cpp, - tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); + tex->base.width[0], tex->base.height[0], pt->block.size, + tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); */ return 1; @@ -193,12 +196,14 @@ static void i945_miptree_layout_2d( struct i915_texture *tex ) { struct pipe_texture *pt = &tex->base; - int align_h = 2, align_w = 4; + const int align_x = 2, align_y = 4; unsigned level; unsigned x = 0; unsigned y = 0; unsigned width = pt->width[0]; unsigned height = pt->height[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; #if 0 /* used for tiled display targets */ if (pt->last_level == 0 && pt->cpp == 4) @@ -206,7 +211,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) return; #endif - tex->pitch = pt->width[0]; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap level. This occurs when the alignment @@ -214,47 +219,43 @@ i945_miptree_layout_2d( struct i915_texture *tex ) * 2nd mipmap level out past the width of its parent. */ if (pt->last_level > 0) { - unsigned mip1_width = align_int(minify(pt->width[0]), align_w) - + minify(minify(pt->width[0])); + unsigned mip1_nblocksx + = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + + pf_get_nblocksx(&pt->block, minify(minify(width))); - if (mip1_width > pt->width[0]) - tex->pitch = mip1_width; + if (mip1_nblocksx > nblocksx) + tex->stride = mip1_nblocksx * pt->block.size; } - /* Pitch must be a whole number of dwords, even though we - * express it in texels. + /* Pitch must be a whole number of dwords */ - tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp; - tex->total_height = 0; + tex->stride = align_int(tex->stride, 64); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - unsigned img_height; - i915_miptree_set_level_info(tex, level, 1, width, height, 1); i915_miptree_set_image_offset(tex, level, 0, x, y); - if (pt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align_int(height, align_h); - + nblocksy = align_int(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: */ - tex->total_height = MAX2(tex->total_height, y + img_height); + tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align_int(width, align_w); + x += align_int(nblocksx, align_x); } else { - y += img_height; + y += nblocksy; } width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } } @@ -264,15 +265,16 @@ i945_miptree_layout_cube(struct i915_texture *tex) struct pipe_texture *pt = &tex->base; unsigned level; - const unsigned dim = pt->width[0]; + const unsigned nblocks = pt->nblocksx[0]; unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; /* printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]); */ - assert(lvlWidth == lvlHeight); /* cubemap images are square */ + assert(width == height); /* cubemap images are square */ /* * XXX Should only be used for compressed formats. But lets @@ -282,35 +284,32 @@ i945_miptree_layout_cube(struct i915_texture *tex) * determined either by the old-style packing of cubemap faces, * or the final row of 4x4, 2x2 and 1x1 faces below this. */ - if (dim > 32) - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + if (nblocks > 32) + tex->stride = round_up(nblocks * pt->block.size * 2, 4); else - tex->pitch = 14 * 8; + tex->stride = 14 * 8 * pt->block.size; - /* - * XXX The 4 is only needed for compressed formats. See above. - */ - tex->total_height = dim * 4 + 4; + tex->total_nblocksy = nblocks * 4; /* Set all the levels to effectively occupy the whole rectangular region. */ for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; + i915_miptree_set_level_info(tex, level, 6, width, height, 1); + width /= 2; + height /= 2; } for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; + unsigned x = initial_offsets[face][0] * nblocks; + unsigned y = initial_offsets[face][1] * nblocks; + unsigned d = nblocks; #if 0 /* Fix and enable this code for compressed formats */ - if (dim == 4 && face >= 4) { + if (nblocks == 4 && face >= 4) { y = tex->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0)) { + else if (nblocks < 4 && (face > 0)) { y = tex->total_height - 4; x = face * 8; } @@ -369,28 +368,28 @@ i915_miptree_layout(struct i915_texture * tex) switch (pt->target) { case PIPE_TEXTURE_CUBE: { - const unsigned dim = pt->width[0]; + const unsigned nblocks = pt->nblocksx[0]; unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + unsigned width = pt->width[0], height = pt->height[0]; - assert(lvlWidth == lvlHeight); /* cubemap images are square */ + assert(width == height); /* cubemap images are square */ /* double pitch for cube layouts */ - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; - tex->total_height = dim * 4; + tex->stride = round_up(nblocks * pt->block.size * 2, 4); + tex->total_nblocksy = nblocks * 4; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, - lvlWidth, lvlHeight, + width, height, 1); - lvlWidth /= 2; - lvlHeight /= 2; + width /= 2; + height /= 2; } for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; + unsigned x = initial_offsets[face][0] * nblocks; + unsigned y = initial_offsets[face][1] * nblocks; + unsigned d = nblocks; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); @@ -405,25 +404,29 @@ i915_miptree_layout(struct i915_texture * tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; - unsigned stack_height = 0; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; + unsigned stack_nblocksy = 0; /* Calculate the size of a single slice. */ - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); /* XXX: hardware expects/requires 9 levels at minimum. */ for (level = 0; level <= MAX2(8, pt->last_level); level++) { i915_miptree_set_level_info(tex, level, depth, - width, height, depth); + width, height, depth); - stack_height += MAX2(2, height); + stack_nblocksy += MAX2(2, nblocksy); width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } /* Fixup depth image_offsets: @@ -433,7 +436,7 @@ i915_miptree_layout(struct i915_texture * tex) unsigned i; for (i = 0; i < depth; i++) i915_miptree_set_image_offset(tex, level, i, - 0, i * stack_height); + 0, i * stack_nblocksy); depth = minify(depth); } @@ -443,33 +446,33 @@ i915_miptree_layout(struct i915_texture * tex) * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - tex->total_height = stack_height * pt->depth[0]; + tex->total_nblocksy = stack_nblocksy * pt->depth[0]; break; } default:{ unsigned width = pt->width[0]; unsigned height = pt->height[0]; - unsigned img_height; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; - tex->total_height = 0; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, - width, height, 1); + width, height, 1); i915_miptree_set_image_offset(tex, level, 0, - 0, tex->total_height); + 0, tex->total_nblocksy); - if (pt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = (MAX2(2, height) + 1) & ~1; + nblocksy = round_up(MAX2(2, nblocksy), 2); - tex->total_height += img_height; + tex->total_nblocksy += nblocksy; width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } break; } @@ -477,7 +480,7 @@ i915_miptree_layout(struct i915_texture * tex) /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, tex->pitch, - tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy); */ return TRUE; @@ -498,14 +501,16 @@ i945_miptree_layout(struct i915_texture * tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; - tex->total_height = 0; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); + tex->total_nblocksy = 0; - pack_y_pitch = MAX2(pt->height[0], 2); - pack_x_pitch = tex->pitch; + pack_y_pitch = MAX2(pt->nblocksy[0], 2); + pack_x_pitch = tex->stride / pt->block.size; pack_x_nr = 1; for (level = 0; level <= pt->last_level; level++) { @@ -515,11 +520,11 @@ i945_miptree_layout(struct i915_texture * tex) unsigned q, j; i915_miptree_set_level_info(tex, level, nr_images, - width, height, depth); + width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_height); + i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); x += pack_x_pitch; } @@ -528,12 +533,12 @@ i945_miptree_layout(struct i915_texture * tex) } - tex->total_height += y; + tex->total_nblocksy += y; if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= tex->pitch); + assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride); } if (pack_y_pitch > 2) { @@ -543,6 +548,8 @@ i945_miptree_layout(struct i915_texture * tex) width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } break; } @@ -560,7 +567,7 @@ i945_miptree_layout(struct i915_texture * tex) /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, tex->pitch, - tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy); */ return TRUE; @@ -582,6 +589,9 @@ i915_texture_create(struct pipe_screen *screen, tex->base.refcount = 1; tex->base.screen = screen; + tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]); + tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]); + if (i915screen->is_i945) { if (!i945_miptree_layout(tex)) goto fail; @@ -592,8 +602,8 @@ i915_texture_create(struct pipe_screen *screen, tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->stride * + tex->total_nblocksy); if (!tex->buffer) goto fail; @@ -648,13 +658,13 @@ i915_get_tex_surface(struct pipe_screen *screen, unsigned offset; /* in bytes */ if (pt->target == PIPE_TEXTURE_CUBE) { - offset = tex->image_offset[level][face] * pt->cpp; + offset = tex->image_offset[level][face]; } else if (pt->target == PIPE_TEXTURE_3D) { - offset = tex->image_offset[level][zslice] * pt->cpp; + offset = tex->image_offset[level][zslice]; } else { - offset = tex->image_offset[level][0] * pt->cpp; + offset = tex->image_offset[level][0]; assert(face == 0); assert(zslice == 0); } @@ -666,10 +676,12 @@ i915_get_tex_surface(struct pipe_screen *screen, pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = tex->pitch; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = tex->stride; ps->offset = offset; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; @@ -680,7 +692,7 @@ i915_get_tex_surface(struct pipe_screen *screen, static struct pipe_texture * i915_texture_blanket(struct pipe_screen * screen, const struct pipe_texture *base, - const unsigned *pitch, + const unsigned *stride, struct pipe_buffer *buffer) { struct i915_texture *tex; @@ -699,7 +711,7 @@ i915_texture_blanket(struct pipe_screen * screen, tex->base = *base; - tex->pitch = pitch[0]; + tex->stride = stride[0]; i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 8ac6b4e689..2cae7665f7 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -231,9 +231,9 @@ struct brw_texture { /* Derived from the above: */ - unsigned pitch; + unsigned stride; unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; + unsigned total_nblocksy; unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; diff --git a/src/gallium/drivers/i965simple/brw_misc_state.c b/src/gallium/drivers/i965simple/brw_misc_state.c index 925049ecc1..be812c5da9 100644 --- a/src/gallium/drivers/i965simple/brw_misc_state.c +++ b/src/gallium/drivers/i965simple/brw_misc_state.c @@ -224,7 +224,9 @@ static void upload_depthbuffer(struct brw_context *brw) } else { unsigned int format; - switch (depth_surface->cpp) { + assert(depth_surface->block.width == 1); + assert(depth_surface->block.height == 1); + switch (depth_surface->block.size) { case 2: format = BRW_DEPTHFORMAT_D16_UNORM; break; @@ -239,7 +241,7 @@ static void upload_depthbuffer(struct brw_context *brw) return; } - OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) | + OUT_BATCH((depth_surface->stride - 1) | (format << 18) | (BRW_TILEWALK_YMAJOR << 26) | // (depth_surface->region->tiled << 27) | @@ -247,7 +249,7 @@ static void upload_depthbuffer(struct brw_context *brw) OUT_RELOC(depth_surface->buffer, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0); OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) | - ((depth_surface->pitch - 1) << 6) | + ((depth_surface->stride/depth_surface->block.size - 1) << 6) | ((depth_surface->height - 1) << 19)); OUT_BATCH(0); } diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 3d98a2bf19..0be3dfc743 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -47,8 +47,10 @@ brw_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - assert(dst != src); - assert(dst->cpp == src->cpp); + assert( dst != src ); + assert( dst->block.size == src->block.size ); + assert( dst->block.width == src->block.height ); + assert( dst->block.height == src->block.height ); if (0) { void *dst_map = pipe->screen->surface_map( pipe->screen, @@ -60,37 +62,30 @@ brw_surface_copy(struct pipe_context *pipe, PIPE_BUFFER_USAGE_CPU_READ ); pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); brw_copy_blit(brw_context(pipe), do_flip, - dst->cpp, - (short) src->pitch, src->buffer, src->offset, FALSE, - (short) dst->pitch, dst->buffer, dst->offset, FALSE, + dst->block.size, + (short) src->stride/src->block.size, src->buffer, src->offset, FALSE, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, FALSE, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height, PIPE_LOGICOP_COPY); } } -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void * -get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) -{ - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; -} - static void brw_surface_fill(struct pipe_context *pipe, @@ -99,50 +94,20 @@ brw_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { if (0) { - unsigned i, j; void *dst_map = pipe->screen->surface_map( pipe->screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - - switch (dst->cpp) { - case 1: { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; - case 2: { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; - case 4: { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - break; - default: - assert(0); - break; - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); brw_fill_blit(brw_context(pipe), - dst->cpp, - (short) dst->pitch, + dst->block.size, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, FALSE, (short) dstx, (short) dsty, (short) width, (short) height, diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 78ae0b1223..8c7725605b 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -81,7 +81,7 @@ static void intel_miptree_set_image_offset(struct brw_texture *tex, assert(x == 0 && y == 0); assert(img < tex->nr_images[level]); - tex->image_offset[level][img] = (x + y * tex->pitch) * pt->cpp; + tex->image_offset[level][img] = y * tex->stride + x * pt->block.size; } static void intel_miptree_set_level_info(struct brw_texture *tex, @@ -97,8 +97,11 @@ static void intel_miptree_set_level_info(struct brw_texture *tex, pt->width[level] = w; pt->height[level] = h; pt->depth[level] = d; + + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h); - tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; + tex->level_offset[level] = y * tex->stride + x * tex->base.block.size; tex->nr_images[level] = nr_images; /* @@ -123,77 +126,60 @@ static void intel_miptree_set_level_info(struct brw_texture *tex, static void i945_miptree_layout_2d(struct brw_texture *tex) { struct pipe_texture *pt = &tex->base; - unsigned align_h = 2, align_w = 4; + const int align_x = 2, align_y = 4; unsigned level; unsigned x = 0; unsigned y = 0; unsigned width = pt->width[0]; unsigned height = pt->height[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; - tex->pitch = pt->width[0]; - -#if 0 - if (pt->compressed) { - align_w = intel_compressed_alignment(pt->internal_format); - tex->pitch = ALIGN(pt->width[0], align_w); - } -#endif + tex->stride = align(pt->nblocksx[0] * pt->block.size, 4); /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment + * the 2nd mipmap level. This occurs when the alignment * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. + * 2nd mipmap level out past the width of its parent. */ if (pt->last_level > 0) { - unsigned mip1_width; - - if (pt->compressed) { - mip1_width = align(minify(pt->width[0]), align_w) - + align(minify(minify(pt->width[0])), align_w); - } else { - mip1_width = align(minify(pt->width[0]), align_w) - + minify(minify(pt->width[0])); - } + unsigned mip1_nblocksx + = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + + pf_get_nblocksx(&pt->block, minify(minify(width))); - if (mip1_width > tex->pitch) { - tex->pitch = mip1_width; - } + if (mip1_nblocksx > nblocksx) + tex->stride = mip1_nblocksx * pt->block.size; } - /* Pitch must be a whole number of dwords, even though we - * express it in texels. + /* Pitch must be a whole number of dwords */ - tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; - tex->total_height = 0; + tex->stride = align_int(tex->stride, 64); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - unsigned img_height; - intel_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); - if (pt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align(height, align_h); - + nblocksy = align_int(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: */ - tex->total_height = MAX2(tex->total_height, y + img_height); + tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); - /* Layout_below: step right after second mipmap. + /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align(width, align_w); + x += align_int(nblocksx, align_x); } else { - y += img_height; + y += nblocksy; } width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } } @@ -210,26 +196,20 @@ static boolean brw_miptree_layout(struct brw_texture *tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; unsigned align_h = 2; unsigned align_w = 4; - tex->total_height = 0; -#if 0 - if (pt->compressed) { - align_w = intel_compressed_alignment(pt->internal_format); - pt->pitch = align(width, align_w); - pack_y_pitch = (height + 3) / 4; - } else -#endif - { - tex->pitch = align(pt->width[0] * pt->cpp, 4) / pt->cpp; - pack_y_pitch = align(pt->height[0], align_h); - } + tex->total_nblocksy = 0; + + tex->stride = align(pt->nblocksx[0], 4); + pack_y_pitch = align(pt->nblocksy[0], align_h); - pack_x_pitch = tex->pitch; + pack_x_pitch = tex->stride / pt->block.size; pack_x_nr = 1; for (level = 0; level <= pt->last_level; level++) { @@ -239,7 +219,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex) uint q, j; intel_miptree_set_level_info(tex, level, nr_images, - 0, tex->total_height, + 0, tex->total_nblocksy, width, height, depth); for (q = 0; q < nr_images;) { @@ -253,10 +233,12 @@ static boolean brw_miptree_layout(struct brw_texture *tex) } - tex->total_height += y; + tex->total_nblocksy += y; width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); if (pt->compressed) { pack_y_pitch = (height + 3) / 4; @@ -269,7 +251,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex) if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= tex->pitch); + assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride); } if (pack_y_pitch > 2) { @@ -289,9 +271,9 @@ static boolean brw_miptree_layout(struct brw_texture *tex) #if 0 PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, pt->pitch, - pt->total_height, - pt->cpp, - pt->pitch * pt->total_height * pt->cpp ); + pt->total_nblocksy, + pt->block.size, + pt->stride * pt->total_nblocksy ); #endif return TRUE; @@ -309,11 +291,14 @@ brw_texture_create_screen(struct pipe_screen *screen, tex->base = *templat; tex->base.refcount = 1; + tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]); + tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]); + if (brw_miptree_layout(tex)) tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->stride * + tex->total_nblocksy); if (!tex->buffer) { FREE(tex); @@ -370,10 +355,10 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, offset = tex->level_offset[level]; if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; + offset += tex->image_offset[level][face]; } else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; + offset += tex->image_offset[level][zslice]; } else { assert(face == 0); @@ -386,10 +371,12 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, assert(ps->refcount); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = tex->pitch; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = tex->stride; ps->offset = offset; } return ps; diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c index 69e56dc8bd..1a326f9918 100644 --- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -160,7 +160,7 @@ void brw_update_texture_surface( struct brw_context *brw, surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; surf.ss3.tiled_surface = 0; /* always zero */ - surf.ss3.pitch = tObj->pitch - 1; + surf.ss3.pitch = tObj->stride - 1; surf.ss3.depth = tObj->base.depth[0] - 1; surf.ss4.min_lod = 0; @@ -197,7 +197,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) memset(&surf, 0, sizeof(surf)); if (pipe_surface != NULL) { - if (pipe_surface->cpp == 4) + if (pipe_surface->block.size == 4) surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; else surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; @@ -210,7 +210,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) surf.ss2.height = pipe_surface->height - 1; surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; surf.ss3.tiled_surface = 0; - surf.ss3.pitch = (pipe_surface->pitch * pipe_surface->cpp) - 1; + surf.ss3.pitch = pipe_surface->stride - 1; } else { surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; surf.ss0.surface_type = BRW_SURFACE_NULL; diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 9fd48aeccc..7dc15c38d1 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -58,18 +58,20 @@ sp_surface_copy(struct pipe_context *pipe, src, PIPE_BUFFER_USAGE_CPU_READ ); - assert(dst->cpp == src->cpp); + assert(dst->block.size == src->block.size); + assert(dst->block.width == src->block.width); + assert(dst->block.height == src->block.height); assert(src_map); assert(dst_map); /* If do_flip, invert src_y position and pass negative src stride */ pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? src->height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); @@ -80,7 +82,7 @@ sp_surface_copy(struct pipe_context *pipe, static void * get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) { - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; + return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size; } @@ -102,39 +104,14 @@ sp_surface_fill(struct pipe_context *pipe, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - assert(dst->pitch > 0); - assert(width <= dst->pitch); + assert(dst->stride > 0); - switch (dst->cpp) { + switch (dst->block.size) { case 1: - { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; case 2: - { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; case 4: - { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); break; case 8: { @@ -155,7 +132,7 @@ sp_surface_fill(struct pipe_context *pipe, row[j*4+2] = val2; row[j*4+3] = val3; } - row += dst->pitch * 4; + row += dst->stride/2; } } break; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 2ef17a220b..4db045cdc3 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -71,13 +71,15 @@ softpipe_texture_layout(struct pipe_screen *screen, pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; - spt->pitch[level] = width; + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); + spt->stride[level] = pt->nblocksx[level]*pt->block.size; spt->level_offset[level] = buffer_size; - buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) * + buffer_size += (pt->nblocksy[level] * ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp); + spt->stride[level]); width = minify(width); height = minify(height); @@ -121,7 +123,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ spt->buffer = surf.buffer; - spt->pitch[0] = surf.pitch; + spt->stride[0] = surf.stride; return spt->buffer != NULL; } @@ -195,10 +197,12 @@ softpipe_get_tex_surface(struct pipe_screen *screen, assert(ps->winsys); pipe_buffer_reference(ws, &ps->buffer, spt->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; + ps->block = pt->block; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = spt->pitch[level]; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = spt->stride[level]; ps->offset = spt->level_offset[level]; ps->usage = usage; @@ -228,8 +232,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; + ps->nblocksy * + ps->stride; } else { assert(face == 0); diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 0e1017632c..bf437a7c61 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -42,7 +42,7 @@ struct softpipe_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index d973fb357b..a2c6155d01 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -501,6 +501,47 @@ pf_get_block(enum pipe_format format, struct pipe_format_block *block) } } +static INLINE unsigned +pf_get_nblocksx(const struct pipe_format_block *block, unsigned x) +{ + return (x + block->width - 1)/block->width; +} + +static INLINE unsigned +pf_get_nblocksy(const struct pipe_format_block *block, unsigned y) +{ + return (y + block->height - 1)/block->height; +} + +static INLINE unsigned +pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned height) +{ + return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height); +} + +static INLINE void +pipe_rect_to_blocks(const struct pipe_format_block *block, + unsigned *width, unsigned *height, + unsigned *src_x, unsigned *src_y, + unsigned *dst_x, unsigned *dst_y) +{ + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + if(width) + *width = pf_get_nblocksx(block, *width); + if(height) + *height = pf_get_nblocksy(block, *height); + if(src_x) + *src_x /= block->width; + if(src_y) + *src_y /= block->height; + if(dst_x) + *dst_x /= block->width; + if(dst_y) + *dst_y /= block->height; +} + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e7ee8c97ed..2992e2f3b3 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -267,10 +267,12 @@ struct pipe_surface enum pipe_format format; /**< PIPE_FORMAT_x */ unsigned status; /**< PIPE_SURFACE_STATUS_x */ unsigned clear_value; /**< XXX may be temporary */ - unsigned cpp; /**< bytes per pixel */ unsigned width; unsigned height; - unsigned pitch; /**< in pixels */ + struct pipe_format_block block; + unsigned nblocksx; + unsigned nblocksy; + unsigned stride; /**< in bytes */ unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; @@ -303,7 +305,10 @@ struct pipe_texture unsigned height[PIPE_MAX_TEXTURE_LEVELS]; unsigned depth[PIPE_MAX_TEXTURE_LEVELS]; - unsigned cpp:8; + struct pipe_format_block block; + unsigned nblocksx[PIPE_MAX_TEXTURE_LEVELS]; + unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS]; + unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index cf2447822a..7dcdd28287 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -31,6 +31,7 @@ #include "p_config.h" #include "p_compiler.h" #include "p_debug.h" +#include "p_format.h" #include "p_pointer.h" #include #include @@ -401,11 +402,15 @@ static INLINE int align(int value, int alignment) /* util/p_util.c */ -extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, - unsigned dst_x, unsigned dst_y, unsigned width, - unsigned height, const ubyte * src, - int src_pitch, unsigned src_x, int src_y); - +extern void pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, const ubyte * src, + int src_stride, unsigned src_x, int src_y); + +extern void +pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, uint32_t value); #if defined(_MSC_VER) diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 10eedd8402..6e814ce5d1 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -322,7 +322,10 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, struct aub_dump_bmp db; unsigned format; - if (surface->cpp == 4) + assert(surface->block.width == 1); + assert(surface->block.height == 1); + + if (surface->block.size == 4) format = 0x7; else format = 0x3; @@ -331,8 +334,8 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, db.xmin = 0; db.ymin = 0; db.format = format; - db.bpp = surface->cpp * 8; - db.pitch = surface->pitch; + db.bpp = surface->block.size * 8; + db.pitch = surface->stride/surface->block.size; db.xsize = surface->width; db.ysize = surface->height; db.addr = gtt_offset; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index b14758f333..9225ee510d 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -364,9 +364,10 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) return; } - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height); + assert(surf->block.width == 1); + assert(surf->block.height == 1); + alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height); } ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; @@ -386,7 +387,7 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) /* update XImage's fields */ ximage->width = surf->width; ximage->height = surf->height; - ximage->bytes_per_line = surf->pitch * surf->cpp; + ximage->bytes_per_line = surf->stride; XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height); @@ -497,18 +498,21 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; -#ifdef GALLIUM_CELL /* XXX a bit of a hack */ - height = round_up(height, TILE_SIZE); -#endif - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + surf->stride * round_up(surf->nblocksy, TILE_SIZE)); +#else + surf->stride * surf->nblocksy); +#endif + if(!surf->buffer) return -1; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 77376099f0..7fc9debdd5 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -279,22 +279,25 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); if(!surf->buffer) - return -1; + return -1; - return 0; + return 0; } static void diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 8098d75e18..809a906ba3 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -66,15 +66,17 @@ acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, uint x, uint y, uint w, uint h, float *p) { const enum pipe_format f = acc_ps->format; - const int cpp = acc_ps->cpp; + const struct pipe_format_block b = acc_ps->block; acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_ps->cpp = 8; + acc_ps->block.size = 8; + acc_ps->block.width = 1; + acc_ps->block.height = 1; pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p); acc_ps->format = f; - acc_ps->cpp = cpp; + acc_ps->block = b; } @@ -88,15 +90,17 @@ acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, uint x, uint y, uint w, uint h, const float *p) { enum pipe_format f = acc_ps->format; - const int cpp = acc_ps->cpp; + const struct pipe_format_block b = acc_ps->block; acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_ps->cpp = 8; + acc_ps->block.size = 8; + acc_ps->block.width = 1; + acc_ps->block.height = 1; pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p); acc_ps->format = f; - acc_ps->cpp = cpp; + acc_ps->block = b; } @@ -111,7 +115,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint ypos = ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - xpos; const GLint height = ctx->DrawBuffer->_Ymax - ypos; - GLvoid *map; + GLubyte *map; acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -128,8 +132,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]); int i, j; for (i = 0; i < height; i++) { - GLshort *dst = ((GLshort *) map - + ((ypos + i) * acc_ps->pitch + xpos) * 4); + GLshort *dst = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8); for (j = 0; j < width; j++) { dst[0] = r; dst[1] = g; @@ -168,8 +171,7 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, { int i, j; for (i = 0; i < height; i++) { - GLshort *acc = ((GLshort *) map - + ((ypos + i) * acc_ps->pitch + xpos) * 4); + GLshort *acc = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8); for (j = 0; j < width * 4; j++) { float val = SHORT_TO_FLOAT(acc[j]) * scale + bias; acc[j] = FLOAT_TO_SHORT(val); diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 6fa3cbd533..f3bc3b8584 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -341,9 +341,9 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); /* Put image into texture surface */ - memset(dest, 0xff, height * surface->pitch); + memset(dest, 0xff, height * surface->stride); unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap, - dest, surface->pitch); + dest, surface->stride); _mesa_unmap_bitmap_pbo(ctx, unpack); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index d8f1d2367c..a7781f3ab2 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -382,7 +382,7 @@ make_texture(struct st_context *st, mformat, /* gl_texture_format */ dest, /* dest */ 0, 0, 0, /* dstX/Y/Zoffset */ - surface->pitch * cpp, /* dstRowStride, bytes */ + surface->stride, /* dstRowStride, bytes */ &dstImageOffsets, /* dstImageOffsets */ width, height, 1, /* size */ format, type, /* src format/type */ @@ -786,13 +786,13 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, switch (ps->format) { case PIPE_FORMAT_S8_UNORM: { - ubyte *dest = stmap + spanY * ps->pitch + spanX; + ubyte *dest = stmap + spanY * ps->stride + spanX; memcpy(dest, values, spanWidth); } break; case PIPE_FORMAT_S8Z24_UNORM: { - uint *dest = (uint *) stmap + spanY * ps->pitch + spanX; + uint *dest = (uint *) (stmap + spanY * ps->stride + spanX*4); GLint k; for (k = 0; k < spanWidth; k++) { uint p = dest[k]; @@ -903,6 +903,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(psDraw->block.width == 1); + assert(psDraw->block.height == 1); + /* map the stencil buffer */ drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -919,7 +922,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, y = ctx->DrawBuffer->Height - y - 1; } - dst = drawMap + (y * psDraw->pitch + dstx) * psDraw->cpp; + dst = drawMap + y * psDraw->stride + dstx * psDraw->block.size; src = buffer + i * width; switch (psDraw->format) { diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index db25ddd615..1067caf9b3 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -113,7 +113,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, template.target = PIPE_TEXTURE_2D; template.compressed = 0; - template.cpp = pf_get_size(template.format); + pf_get_block(template.format, &template.block); template.width[0] = width; template.height[0] = height; template.depth[0] = 1; @@ -171,10 +171,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, assert(strb->surface->buffer); assert(strb->surface->format); - assert(strb->surface->cpp); + assert(strb->surface->block.size); + assert(strb->surface->block.width); + assert(strb->surface->block.height); assert(strb->surface->width == width); assert(strb->surface->height == height); - assert(strb->surface->pitch); + assert(strb->surface->stride); return strb->surface != NULL; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index c5193631a7..09d9c29e44 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -94,13 +94,13 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, switch (ps->format) { case PIPE_FORMAT_S8_UNORM: { - const ubyte *src = stmap + srcY * ps->pitch + x; + const ubyte *src = stmap + srcY * ps->stride + x; memcpy(values, src, width); } break; case PIPE_FORMAT_S8Z24_UNORM: { - const uint *src = (uint *) stmap + srcY * ps->pitch + x; + const uint *src = (uint *) (stmap + srcY * ps->stride + x*4); GLint k; for (k = 0; k < width; k++) { values[k] = src[k] >> 24; @@ -109,7 +109,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, break; case PIPE_FORMAT_Z24S8_UNORM: { - const uint *src = (uint *) stmap + srcY * ps->pitch + x; + const uint *src = (uint *) (stmap + srcY * ps->stride + x*4); GLint k; for (k = 0; k < width; k++) { values[k] = src[k] & 0xff; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 7d52d1da1b..b9aa513d72 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -658,7 +658,7 @@ st_TexImage(GLcontext * ctx, texImage->Data = st_texture_image_map(ctx->st, stImage, 0, PIPE_BUFFER_USAGE_CPU_WRITE); if (stImage->surface) - dstRowStride = stImage->surface->pitch * stImage->surface->cpp; + dstRowStride = stImage->surface->stride; } else { /* Allocate regular memory and store the image there temporarily. */ @@ -820,7 +820,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, */ texImage->Data = st_texture_image_map(ctx->st, stImage, 0, PIPE_BUFFER_USAGE_CPU_READ); - texImage->RowStride = stImage->surface->pitch; + texImage->RowStride = stImage->surface->stride / stImage->pt->block.size; } else { /* Otherwise, the image should actually be stored in @@ -925,7 +925,7 @@ st_TexSubimage(GLcontext * ctx, texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, PIPE_BUFFER_USAGE_CPU_WRITE); if (stImage->surface) - dstRowStride = stImage->surface->pitch * stImage->surface->cpp; + dstRowStride = stImage->surface->stride; } if (!texImage->Data) { @@ -1425,9 +1425,11 @@ copy_image_data_to_texture(struct st_context *st, stImage->face, dstLevel, stImage->base.Data, - stImage->base.RowStride, + stImage->base.RowStride * + stObj->pt->block.size, stImage->base.RowStride * - stImage->base.Height); + stImage->base.Height * + stObj->pt->block.size); _mesa_align_free(stImage->base.Data); stImage->base.Data = NULL; } @@ -1477,6 +1479,7 @@ st_finalize_texture(GLcontext *ctx, pipe_texture_reference(&stObj->pt, firstImage->pt); } + /* FIXME: determine format block instead of cpp */ if (firstImage->base.IsCompressed) { comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); cpp = comp_byte; @@ -1497,7 +1500,9 @@ st_finalize_texture(GLcontext *ctx, stObj->pt->width[0] != firstImage->base.Width2 || stObj->pt->height[0] != firstImage->base.Height2 || stObj->pt->depth[0] != firstImage->base.Depth2 || - stObj->pt->cpp != cpp || + stObj->pt->block.size != cpp || + stObj->pt->block.width != 1 || + stObj->pt->block.height != 1 || stObj->pt->compressed != firstImage->base.IsCompressed) { pipe_texture_release(&stObj->pt); ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 851f17c3b4..2fc00df429 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -137,10 +137,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, _mesa_generate_mipmap_level(target, datatype, comps, 0 /*border*/, pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], - srcSurf->pitch * srcSurf->cpp, /* stride in bytes */ + srcSurf->stride, /* stride in bytes */ srcData, pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], - dstSurf->pitch * dstSurf->cpp, /* stride in bytes */ + dstSurf->stride, /* stride in bytes */ dstData); pipe_buffer_unmap(pipe, srcSurf->buffer); diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 9553b34e31..8222826e7a 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -98,7 +98,7 @@ st_texture_create(struct st_context *st, pt.height[0] = height0; pt.depth[0] = depth0; pt.compressed = compress_byte ? 1 : 0; - pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format); + pf_get_block(format, &pt.block); pt.tex_usage = usage; newtex = screen->texture_create(screen, &pt); @@ -231,16 +231,19 @@ static void st_surface_data(struct pipe_context *pipe, struct pipe_surface *dst, unsigned dstx, unsigned dsty, - const void *src, unsigned src_pitch, + const void *src, unsigned src_stride, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { struct pipe_screen *screen = pipe->screen; void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE); pipe_copy_rect(map, - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); + &dst->block, + dst->stride, + dstx, dsty, + width, height, + src, src_stride, + srcx, srcy); screen->surface_unmap(screen, dst); } @@ -254,34 +257,29 @@ st_texture_image_data(struct pipe_context *pipe, GLuint face, GLuint level, void *src, - GLuint src_row_pitch, GLuint src_image_pitch) + GLuint src_row_stride, GLuint src_image_stride) { struct pipe_screen *screen = pipe->screen; GLuint depth = dst->depth[level]; GLuint i; - GLuint height = 0; const GLubyte *srcUB = src; struct pipe_surface *dst_surface; DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { - height = dst->height[level]; - if(dst->compressed) - height /= 4; - dst_surface = screen->get_tex_surface(screen, dst, face, level, i, PIPE_BUFFER_USAGE_CPU_WRITE); st_surface_data(pipe, dst_surface, 0, 0, /* dstx, dsty */ srcUB, - src_row_pitch, + src_row_stride, 0, 0, /* source x, y */ - dst->width[level], height); /* width, height */ + dst->width[level], dst->height[level]); /* width, height */ screen->tex_surface_release(screen, &dst_surface); - srcUB += src_image_pitch * dst->cpp; + srcUB += src_image_stride; } } -- cgit v1.2.3