diff options
author | Chia-I Wu <[email protected]> | 2010-01-12 11:25:02 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2010-01-12 11:25:02 +0800 |
commit | 562c127693200822f04a145db50add1be2425d7b (patch) | |
tree | 9441774fb212b17ddf2a364f06abc43f166cc00b /src/mesa/state_tracker | |
parent | e5d351dcfde58777162552cf5cd2a9cd8299f4cd (diff) | |
parent | 077d6dd7508af88509dd0499c5dfbdaa186b4015 (diff) |
Merge branch 'master' into opengl-es-v2
Conflicts:
src/mesa/main/dd.h
Diffstat (limited to 'src/mesa/state_tracker')
38 files changed, 1019 insertions, 1165 deletions
diff --git a/src/mesa/state_tracker/st_api.c b/src/mesa/state_tracker/st_api.c deleted file mode 100644 index fc0e9a23164..00000000000 --- a/src/mesa/state_tracker/st_api.c +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - - -/** - * Just a global symbol for EGL to look for to identify the supported - * graphics API. - */ -int st_api_OpenGL = 1; diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index ca15ce1b474..73df44d1988 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -46,7 +46,8 @@ static const struct st_tracked_state *atoms[] = &st_update_clip, &st_finalize_textures, - &st_update_shader, + &st_update_fp, + &st_update_vp, &st_update_rasterizer, &st_update_polygon_stipple, @@ -137,7 +138,7 @@ void st_validate_state( struct st_context *st ) if (state->st == 0) return; -// _mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st); + /*_mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/ if (1) { /* Debug version which enforces various sanity checks on the @@ -152,7 +153,7 @@ void st_validate_state( struct st_context *st ) const struct st_tracked_state *atom = atoms[i]; struct st_state_flags generated; -// _mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st); + /*_mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/ if (!(atom->dirty.mesa || atom->dirty.st) || !atom->update) { @@ -162,7 +163,7 @@ void st_validate_state( struct st_context *st ) if (check_state(state, &atom->dirty)) { atoms[i]->update( st ); -// _mesa_printf("after: %x\n", atom->dirty.mesa); + /*_mesa_printf("after: %x\n", atom->dirty.mesa);*/ } accumulate_state(&examined, &atom->dirty); @@ -175,7 +176,7 @@ void st_validate_state( struct st_context *st ) assert(!check_state(&examined, &generated)); prev = *state; } -// _mesa_printf("\n"); + /*_mesa_printf("\n");*/ } else { diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index c7cffd85c8a..f34b49203b2 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -47,7 +47,8 @@ void st_validate_state( struct st_context *st ); extern const struct st_tracked_state st_update_framebuffer; extern const struct st_tracked_state st_update_clip; extern const struct st_tracked_state st_update_depth_stencil_alpha; -extern const struct st_tracked_state st_update_shader; +extern const struct st_tracked_state st_update_fp; +extern const struct st_tracked_state st_update_vp; extern const struct st_tracked_state st_update_rasterizer; extern const struct st_tracked_state st_update_polygon_stipple; extern const struct st_tracked_state st_update_viewport; diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 35c09c3e08f..43e62c29f3e 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -200,13 +200,13 @@ update_blend( struct st_context *st ) } /* Colormask - maybe reverse these bits? */ - if (st->ctx->Color.ColorMask[0]) + if (st->ctx->Color.ColorMask[0][0]) blend->colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[1]) + if (st->ctx->Color.ColorMask[0][1]) blend->colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[2]) + if (st->ctx->Color.ColorMask[0][2]) blend->colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[3]) + if (st->ctx->Color.ColorMask[0][3]) blend->colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index e18c0f6e0a1..8ca4335e330 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -40,6 +40,7 @@ #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_rect.h" +#include "util/u_math.h" @@ -64,8 +65,8 @@ update_renderbuffer_surface(struct st_context *st, GLuint level; /* find matching mipmap level size */ for (level = 0; level <= texture->last_level; level++) { - if (texture->width[level] == rtt_width && - texture->height[level] == rtt_height) { + if (u_minify(texture->width0, level) == rtt_width && + u_minify(texture->height0, level) == rtt_height) { pipe_surface_reference(&strb->surface, NULL); diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index babfcc87b4a..6a5854e9ba5 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -145,7 +145,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) const GLuint gSize = ctx->PixelMaps.GtoG.Size; const GLuint bSize = ctx->PixelMaps.BtoB.Size; const GLuint aSize = ctx->PixelMaps.AtoA.Size; - const uint texSize = pt->width[0]; + const uint texSize = pt->width0; uint *dest; uint i, j; @@ -162,12 +162,14 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) */ for (i = 0; i < texSize; i++) { for (j = 0; j < texSize; j++) { + union util_color uc; int k = (i * texSize + j); ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize]; ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize]; ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize]; ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize]; - util_pack_color_ub(r, g, b, a, pt->format, dest + k); + util_pack_color_ub(r, g, b, a, pt->format, &uc); + *(dest + k) = uc.ui; } } diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 6611956ae83..7b84a86ba48 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -208,15 +208,11 @@ update_samplers(struct st_context *st) assert(sampler->min_lod <= sampler->max_lod); } - xlate_border_color(texobj->BorderColor, + xlate_border_color(texobj->BorderColor.f, teximg ? teximg->_BaseFormat : GL_RGBA, sampler->border_color); sampler->max_anisotropy = texobj->MaxAnisotropy; - if (sampler->max_anisotropy > 1.0) { - sampler->min_img_filter = PIPE_TEX_FILTER_ANISO; - sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO; - } /* only care about ARB_shadow, not SGI shadow */ if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) { @@ -229,14 +225,23 @@ update_samplers(struct st_context *st) /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, sampler); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, sampler); + } } else { /*printf("%s su=%u null\n", __FUNCTION__, su);*/ cso_single_sampler(st->cso_context, su, NULL); + if (su < st->ctx->Const.MaxVertexTextureImageUnits) { + cso_single_vertex_sampler(st->cso_context, su, NULL); + } } } cso_single_sampler_done(st->cso_context); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_single_vertex_sampler_done(st->cso_context); + } } diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index ee649be885e..46c8cbb3098 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -56,82 +56,18 @@ #include "st_mesa_to_tgsi.h" -/** - * This represents a vertex program, especially translated to match - * the inputs of a particular fragment shader. - */ -struct translated_vertex_program -{ - struct st_vertex_program *master; - - /** The fragment shader "signature" this vertex shader is meant for: */ - GLbitfield frag_inputs; - - /** Compared against master vertex program's serialNo: */ - GLuint serialNo; - - /** Maps VERT_RESULT_x to slot */ - GLuint output_to_slot[VERT_RESULT_MAX]; - ubyte output_to_semantic_name[VERT_RESULT_MAX]; - ubyte output_to_semantic_index[VERT_RESULT_MAX]; - - /** Pointer to the translated vertex program */ - struct st_vertex_program *vp; - struct translated_vertex_program *next; /**< next in linked list */ -}; - - - -/** - * Given a vertex program output attribute, return the corresponding - * fragment program input attribute. - * \return -1 for vertex outputs that have no corresponding fragment input - */ -static GLint -vp_out_to_fp_in(GLuint vertResult) -{ - if (vertResult >= VERT_RESULT_TEX0 && - vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS) - return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0); - - if (vertResult >= VERT_RESULT_VAR0 && - vertResult < VERT_RESULT_VAR0 + MAX_VARYING) - return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0); - - switch (vertResult) { - case VERT_RESULT_HPOS: - return FRAG_ATTRIB_WPOS; - case VERT_RESULT_COL0: - return FRAG_ATTRIB_COL0; - case VERT_RESULT_COL1: - return FRAG_ATTRIB_COL1; - case VERT_RESULT_FOGC: - return FRAG_ATTRIB_FOGC; - default: - /* Back-face colors, edge flags, etc */ - return -1; - } -} -/** - * Find a translated vertex program that corresponds to stvp and - * has outputs matched to stfp's inputs. - * This performs vertex and fragment translation (to TGSI) when needed. +/* + * Translate fragment program if needed. */ -static struct translated_vertex_program * -find_translated_vp(struct st_context *st, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp) +static void +translate_fp(struct st_context *st, + struct st_fragment_program *stfp) { - static const GLuint UNUSED = ~0; - struct translated_vertex_program *xvp; const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - /* - * Translate fragment program if needed. - */ if (!stfp->state.tokens) { GLuint inAttr, numIn = 0; @@ -141,7 +77,7 @@ find_translated_vp(struct st_context *st, numIn++; } else { - stfp->input_to_slot[inAttr] = UNUSED; + stfp->input_to_slot[inAttr] = -1; } } @@ -151,170 +87,74 @@ find_translated_vp(struct st_context *st, st_translate_fragment_program(st, stfp, stfp->input_to_slot); } +} - /* See if we've got a translated vertex program whose outputs match - * the fragment program's inputs. - * XXX This could be a hash lookup, using InputsRead as the key. - */ - for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) { - if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) { - break; - } - } - - /* No? Allocate translated vp object now */ - if (!xvp) { - xvp = ST_CALLOC_STRUCT(translated_vertex_program); - xvp->frag_inputs = fragInputsRead; - xvp->master = stvp; - - xvp->next = stfp->vertex_programs; - stfp->vertex_programs = xvp; - } - /* See if we need to translate vertex program to TGSI form */ - if (xvp->serialNo != stvp->serialNo) { - GLuint outAttr; - const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten; - GLuint numVpOuts = 0; - GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE; - GLbitfield usedGenerics = 0x0; - GLbitfield usedOutputSlots = 0x0; - - /* Compute mapping of vertex program outputs to slots, which depends - * on the fragment program's input->slot mapping. - */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - /* set defaults: */ - xvp->output_to_slot[outAttr] = UNUSED; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT; - xvp->output_to_semantic_index[outAttr] = 99; - - if (outAttr == VERT_RESULT_HPOS) { - /* always put xformed position into slot zero */ - GLuint slot = 0; - xvp->output_to_slot[VERT_RESULT_HPOS] = slot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION; - xvp->output_to_semantic_index[outAttr] = 0; - numVpOuts++; - usedOutputSlots |= (1 << slot); - } - else if (outputsWritten & (1 << outAttr)) { - /* see if the frag prog wants this vert output */ - GLint fpInAttrib = vp_out_to_fp_in(outAttr); - if (fpInAttrib >= 0) { - GLuint fpInSlot = stfp->input_to_slot[fpInAttrib]; - if (fpInSlot != ~0) { - /* match this vp output to the fp input */ - GLuint vpOutSlot = stfp->input_map[fpInSlot]; - xvp->output_to_slot[outAttr] = vpOutSlot; - xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot]; - xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot]; - numVpOuts++; - usedOutputSlots |= (1 << vpOutSlot); - } - else { -#if 0 /*debug*/ - printf("VP output %d not used by FP\n", outAttr); -#endif - } - } - else if (outAttr == VERT_RESULT_PSIZ) - emitPntSize = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC0) - emitBFC0 = GL_TRUE; - else if (outAttr == VERT_RESULT_BFC1) - emitBFC1 = GL_TRUE; - } -#if 0 /*debug*/ - printf("assign vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif - } +/** + * Find a translated vertex program that corresponds to stvp and + * has outputs matched to stfp's inputs. + * This performs vertex and fragment translation (to TGSI) when needed. + */ +static struct st_vp_varient * +find_translated_vp(struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + struct st_vp_varient_key key; - /* must do these last */ - if (emitPntSize) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_PSIZ] = slot; - xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE; - xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC0) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC0] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0; - usedOutputSlots |= (1 << slot); - } - if (emitBFC1) { - GLuint slot = numVpOuts++; - xvp->output_to_slot[VERT_RESULT_BFC1] = slot; - xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR; - xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1; - usedOutputSlots |= (1 << slot); - } + /* Nothing in our key yet. This will change: + */ + memset(&key, 0, sizeof key); + + /* When this is true, we will add an extra input to the vertex + * shader translation (for edgeflags), an extra output with + * edgeflag semantics, and extend the vertex shader to pass through + * the input to the output. We'll need to use similar logic to set + * up the extra vertex_element input for edgeflags. + * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA + */ + key.passthrough_edgeflags = (st->vertdata_edgeflags && ( + st->ctx->Polygon.FrontMode != GL_FILL || + st->ctx->Polygon.BackMode != GL_FILL)); - /* build usedGenerics mask */ - usedGenerics = 0x0; - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) { - usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]); - } - } - /* For each vertex program output that doesn't match up to a fragment - * program input, map the vertex program output to a free slot and - * free generic attribute. + /* Do we need to throw away old translations after a change in the + * GL program string? + */ + if (stvp->serialNo != stvp->lastSerialNo) { + /* These may have changed if the program string changed. */ - for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) { - if (outputsWritten & (1 << outAttr)) { - if (xvp->output_to_slot[outAttr] == UNUSED) { - GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1; - GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1; - usedGenerics |= (1 << freeGeneric); - usedOutputSlots |= (1 << freeSlot); - xvp->output_to_slot[outAttr] = freeSlot; - xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC; - xvp->output_to_semantic_index[outAttr] = freeGeneric; - } - } + st_prepare_vertex_program( st, stvp ); -#if 0 /*debug*/ - printf("vp output_to_slot[%d] = %d\n", outAttr, - xvp->output_to_slot[outAttr]); -#endif + /* We are now up-to-date: + */ + stvp->lastSerialNo = stvp->serialNo; + } + + /* See if we've got a translated vertex program whose outputs match + * the fragment program's inputs. + */ + for (vpv = stvp->varients; vpv; vpv = vpv->next) { + if (memcmp(&vpv->key, &key, sizeof key) == 0) { + break; } + } - assert(stvp->Base.Base.NumInstructions > 1); - - st_translate_vertex_program(st, stvp, xvp->output_to_slot, - xvp->output_to_semantic_name, - xvp->output_to_semantic_index); - - xvp->vp = stvp; - - /* translated VP is up to date now */ - xvp->serialNo = stvp->serialNo; + /* No? Perform new translation here. */ + if (!vpv) { + vpv = st_translate_vertex_program(st, stvp, &key); + if (!vpv) + return NULL; + + vpv->next = stvp->varients; + stvp->varients = vpv; } - return xvp; + return vpv; } -void -st_free_translated_vertex_programs(struct st_context *st, - struct translated_vertex_program *xvp) -{ - struct translated_vertex_program *next; - - while (xvp) { - next = xvp->next; - _mesa_free(xvp); - xvp = next; - } -} static void * @@ -328,32 +168,19 @@ get_passthrough_fs(struct st_context *st) return st->passthrough_fs; } - static void -update_linkage( struct st_context *st ) +update_fp( struct st_context *st ) { - struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct translated_vertex_program *xvp; - - /* find active shader and params -- Should be covered by - * ST_NEW_VERTEX_PROGRAM - */ - assert(st->ctx->VertexProgram._Current); - stvp = st_vertex_program(st->ctx->VertexProgram._Current); - assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); assert(st->ctx->FragmentProgram._Current); stfp = st_fragment_program(st->ctx->FragmentProgram._Current); assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB); - xvp = find_translated_vp(st, stvp, stfp); + translate_fp(st, stfp); - st_reference_vertprog(st, &st->vp, stvp); st_reference_fragprog(st, &st->fp, stfp); - cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); - if (st->missing_textures) { /* use a pass-through frag shader that uses no textures */ void *fs = get_passthrough_fs(st); @@ -362,16 +189,48 @@ update_linkage( struct st_context *st ) else { cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); } +} + +const struct st_tracked_state st_update_fp = { + "st_update_fp", /* name */ + { /* dirty */ + 0, /* mesa */ + ST_NEW_FRAGMENT_PROGRAM /* st */ + }, + update_fp /* update */ +}; + + + + +static void +update_vp( struct st_context *st ) +{ + struct st_vertex_program *stvp; - st->vertex_result_to_slot = xvp->output_to_slot; + /* find active shader and params -- Should be covered by + * ST_NEW_VERTEX_PROGRAM + */ + assert(st->ctx->VertexProgram._Current); + stvp = st_vertex_program(st->ctx->VertexProgram._Current); + assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB); + + st->vp_varient = find_translated_vp(st, stvp); + + st_reference_vertprog(st, &st->vp, stvp); + + cso_set_vertex_shader_handle(st->cso_context, + st->vp_varient->driver_shader); + + st->vertex_result_to_slot = stvp->result_to_output; } -const struct st_tracked_state st_update_shader = { - "st_update_shader", /* name */ +const struct st_tracked_state st_update_vp = { + "st_update_vp", /* name */ { /* dirty */ - 0, /* mesa */ - ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM /* st */ + _NEW_POLYGON, /* mesa */ + ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */ }, - update_linkage /* update */ + update_vp /* update */ }; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 4d4f97da7ed..0b68447d212 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -32,6 +32,8 @@ */ +#include "main/macros.h" + #include "st_context.h" #include "st_atom.h" #include "st_texture.h" @@ -99,6 +101,12 @@ update_textures(struct st_context *st) cso_set_sampler_textures(st->cso_context, st->state.num_textures, st->state.sampler_texture); + if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + cso_set_vertex_sampler_textures(st->cso_context, + MIN2(st->state.num_textures, + st->ctx->Const.MaxVertexTextureImageUnits), + st->state.sampler_texture); + } } diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index a6b9765452a..da7b97d3253 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -229,7 +229,7 @@ accum_return(GLcontext *ctx, GLfloat value, { struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; - const GLubyte *colormask = ctx->Color.ColorMask; + const GLubyte *colormask = ctx->Color.ColorMask[0]; enum pipe_transfer_usage usage; struct pipe_transfer *color_trans; size_t stride = acc_strb->stride; diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index a22fa68299b..1bdeaccda3e 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -169,11 +169,6 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex) stfp = (struct st_fragment_program *) p; stfp->Base.UsesKill = GL_TRUE; - /* No need to send this incomplete program down to hardware: - * - * st_translate_fragment_program(ctx->st, stfp, NULL); - */ - return stfp; } @@ -526,7 +521,7 @@ reset_cache(struct st_context *st) struct pipe_screen *screen = pipe->screen; struct bitmap_cache *cache = st->bitmap.cache; - //memset(cache->buffer, 0xff, sizeof(cache->buffer)); + /*memset(cache->buffer, 0xff, sizeof(cache->buffer));*/ cache->empty = GL_TRUE; cache->xmin = 1000000; diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 8e09d0b9324..0102d8a6f7d 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -103,6 +103,17 @@ st_bufferobj_subdata(GLcontext *ctx, ASSERT(size >= 0); ASSERT(offset + size <= obj->Size); + if (!size) + return; + + /* + * According to ARB_vertex_buffer_object specification, if data is null, + * then the contents of the buffer object's data store is undefined. We just + * ignore, and leave it unchanged. + */ + if (!data) + return; + st_cond_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, offset, size, data); } @@ -125,6 +136,9 @@ st_bufferobj_get_subdata(GLcontext *ctx, ASSERT(size >= 0); ASSERT(offset + size <= obj->Size); + if (!size) + return; + st_cond_flush_pipe_buffer_read(st_context(ctx), st_obj->buffer, offset, size, data); } @@ -170,15 +184,19 @@ st_bufferobj_data(GLcontext *ctx, pipe_buffer_reference( &st_obj->buffer, NULL ); - st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size ); + if (size != 0) { + st_obj->buffer = pipe_buffer_create(pipe->screen, 32, buffer_usage, size); + + if (!st_obj->buffer) { + return GL_FALSE; + } - if (!st_obj->buffer) { - return GL_FALSE; + if (data) + st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0, + size, data); + return GL_TRUE; } - if (data) - st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0, - size, data); return GL_TRUE; } @@ -219,6 +237,13 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, /** + * Dummy data whose's pointer is used for zero length ranges. + */ +static long +st_bufferobj_zero_length_range = 0; + + +/** * Called via glMapBufferRange(). */ static void * @@ -239,6 +264,9 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, if (access & GL_MAP_FLUSH_EXPLICIT_BIT) flags |= PIPE_BUFFER_USAGE_FLUSH_EXPLICIT; + if (access & GL_MAP_UNSYNCHRONIZED_BIT) + flags |= PIPE_BUFFER_USAGE_UNSYNCHRONIZED; + /* ... other flags ... */ @@ -250,14 +278,26 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target, assert(offset < obj->Size); assert(offset + length <= obj->Size); - obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags); + /* + * We go out of way here to hide the degenerate yet valid case of zero + * length range from the pipe driver. + */ + if (!length) { + obj->Pointer = &st_bufferobj_zero_length_range; + } + else { + obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags); + if (obj->Pointer) { + obj->Pointer = (ubyte *) obj->Pointer + offset; + } + } + if (obj->Pointer) { - obj->Pointer = (ubyte *) obj->Pointer + offset; obj->Offset = offset; obj->Length = length; obj->AccessFlags = access; } - + return obj->Pointer; } @@ -275,6 +315,9 @@ st_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target, assert(length >= 0); assert(offset + length <= obj->Length); + if (!length) + return; + pipe_buffer_flush_mapped_range(pipe->screen, st_obj->buffer, obj->Offset + offset, length); } @@ -289,7 +332,9 @@ st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) struct pipe_context *pipe = st_context(ctx)->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); - pipe_buffer_unmap(pipe->screen, st_obj->buffer); + if(obj->Length) + pipe_buffer_unmap(pipe->screen, st_obj->buffer); + obj->Pointer = NULL; obj->Offset = 0; obj->Length = 0; @@ -312,6 +357,9 @@ st_copy_buffer_subdata(GLcontext *ctx, struct st_buffer_object *dstObj = st_buffer_object(dst); ubyte *srcPtr, *dstPtr; + if(!size) + return; + /* buffer should not already be mapped */ assert(!src->Pointer); assert(!dst->Pointer); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index e83b6c92efb..192d765f453 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -52,6 +52,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" +#include "util/u_format.h" #include "util/u_pack_color.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" @@ -231,13 +232,13 @@ clear_with_quad(GLcontext *ctx, blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { - if (ctx->Color.ColorMask[0]) + if (ctx->Color.ColorMask[0][0]) blend.colormask |= PIPE_MASK_R; - if (ctx->Color.ColorMask[1]) + if (ctx->Color.ColorMask[0][1]) blend.colormask |= PIPE_MASK_G; - if (ctx->Color.ColorMask[2]) + if (ctx->Color.ColorMask[0][2]) blend.colormask |= PIPE_MASK_B; - if (ctx->Color.ColorMask[3]) + if (ctx->Color.ColorMask[0][3]) blend.colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; @@ -299,10 +300,10 @@ check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) ctx->Scissor.Height < rb->Height)) return TRUE; - if (!ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3]) + if (!ctx->Color.ColorMask[0][0] || + !ctx->Color.ColorMask[0][1] || + !ctx->Color.ColorMask[0][2] || + !ctx->Color.ColorMask[0][3]) return TRUE; return FALSE; @@ -341,7 +342,7 @@ static INLINE GLboolean check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); + const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); if (ctx->Scissor.Enabled && (ctx->Scissor.X != 0 || @@ -365,7 +366,7 @@ static INLINE GLboolean check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) { const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format); + const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); const GLuint stencilMax = 0xff; const GLboolean maskStencil = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c new file mode 100644 index 00000000000..780b40c2065 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_condrender.c @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * 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 THE AUTHORS 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. + * + **************************************************************************/ + + +/** + * glBegin/EndCondtionalRender functions + * + * \author Brian Paul + */ + + +#include "main/imports.h" +#include "main/context.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "st_context.h" +#include "st_cb_queryobj.h" +#include "st_cb_condrender.h" + + +/** + * Called via ctx->Driver.BeginConditionalRender() + */ +static void +st_BeginConditionalRender(GLcontext *ctx, struct gl_query_object *q, + GLenum mode) +{ + struct st_query_object *stq = st_query_object(q); + struct pipe_context *pipe = ctx->st->pipe; + uint m; + + switch (mode) { + case GL_QUERY_WAIT: + m = PIPE_RENDER_COND_WAIT; + break; + case GL_QUERY_NO_WAIT: + m = PIPE_RENDER_COND_NO_WAIT; + break; + case GL_QUERY_BY_REGION_WAIT: + m = PIPE_RENDER_COND_BY_REGION_WAIT; + break; + case GL_QUERY_BY_REGION_NO_WAIT: + m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; + break; + default: + assert(0 && "bad mode in st_BeginConditionalRender"); + } + + pipe->render_condition(pipe, stq->pq, m); +} + + +/** + * Called via ctx->Driver.BeginConditionalRender() + */ +static void +st_EndConditionalRender(GLcontext *ctx, struct gl_query_object *q) +{ + struct pipe_context *pipe = ctx->st->pipe; + (void) q; + pipe->render_condition(pipe, NULL, 0); +} + + + +void st_init_cond_render_functions(struct dd_function_table *functions) +{ + functions->BeginConditionalRender = st_BeginConditionalRender; + functions->EndConditionalRender = st_EndConditionalRender; +} diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/mesa/state_tracker/st_cb_condrender.h index 8e9f3e93060..891f1cbcd8c 100644 --- a/src/mesa/state_tracker/st_cb_get.h +++ b/src/mesa/state_tracker/st_cb_condrender.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,20 +18,18 @@ * 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 + * IN NO EVENT SHALL THE AUTHORS 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 ST_CB_CONDRENDER_H +#define ST_CB_CONDRENDER_H -#ifndef ST_CB_GET_H -#define ST_CB_GET_H - -extern void -st_init_get_functions(struct dd_function_table *functions); +extern void st_init_cond_render_functions(struct dd_function_table *functions); #endif diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 1d33e81c2c9..7c664267d4e 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -60,8 +60,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "tgsi/tgsi_ureg.h" #include "util/u_tile.h" #include "util/u_draw_quad.h" +#include "util/u_format.h" #include "util/u_math.h" #include "util/u_rect.h" #include "shader/prog_instruction.h" @@ -236,78 +238,41 @@ make_fragment_shader_z(struct st_context *st) * Create a simple vertex shader that just passes through the * vertex position and texcoord (and optionally, color). */ -static struct st_vertex_program * -st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor) +static void * +st_make_passthrough_vertex_shader(struct st_context *st, + GLboolean passColor) { - GLcontext *ctx = st->ctx; - struct st_vertex_program *stvp; - struct gl_program *p; - GLuint ic = 0; - - if (st->drawpix.vert_shaders[passColor]) - return st->drawpix.vert_shaders[passColor]; - - /* - * Create shader now - */ - p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); - if (!p) - return NULL; - - if (passColor) - p->NumInstructions = 4; - else - p->NumInstructions = 3; - - p->Instructions = _mesa_alloc_instructions(p->NumInstructions); - if (!p->Instructions) { - ctx->Driver.DeleteProgram(ctx, p); - return NULL; - } - _mesa_init_instructions(p->Instructions, p->NumInstructions); - /* MOV result.pos, vertex.pos; */ - p->Instructions[0].Opcode = OPCODE_MOV; - p->Instructions[0].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS; - p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS; - /* MOV result.texcoord0, vertex.texcoord0; */ - p->Instructions[1].Opcode = OPCODE_MOV; - p->Instructions[1].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[1].DstReg.Index = VERT_RESULT_TEX0; - p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_TEX0; - ic = 2; - if (passColor) { - /* MOV result.color0, vertex.color0; */ - p->Instructions[ic].Opcode = OPCODE_MOV; - p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; - p->Instructions[ic].DstReg.Index = VERT_RESULT_COL0; - p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; - p->Instructions[ic].SrcReg[0].Index = VERT_ATTRIB_COLOR0; - ic++; - } - - /* END; */ - p->Instructions[ic].Opcode = OPCODE_END; - ic++; - - assert(ic == p->NumInstructions); + if (!st->drawpix.vert_shaders[passColor]) { + struct ureg_program *ureg = + ureg_create( TGSI_PROCESSOR_VERTEX ); + + if (ureg == NULL) + return NULL; + + /* MOV result.pos, vertex.pos; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), + ureg_DECL_vs_input( ureg, 0 )); + + /* MOV result.texcoord0, vertex.texcoord0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), + ureg_DECL_vs_input( ureg, 1 )); + + if (passColor) { + /* MOV result.color0, vertex.color0; */ + ureg_MOV(ureg, + ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), + ureg_DECL_vs_input( ureg, 2 )); + } - p->InputsRead = VERT_BIT_POS | VERT_BIT_TEX0; - p->OutputsWritten = ((1 << VERT_RESULT_TEX0) | - (1 << VERT_RESULT_HPOS)); - if (passColor) { - p->InputsRead |= VERT_BIT_COLOR0; - p->OutputsWritten |= (1 << VERT_RESULT_COL0); + ureg_END( ureg ); + + st->drawpix.vert_shaders[passColor] = + ureg_create_shader_and_destroy( ureg, st->pipe ); } - stvp = (struct st_vertex_program *) p; - st_translate_vertex_program(st, stvp, NULL, NULL, NULL); - - st->drawpix.vert_shaders[passColor] = stvp; - - return stvp; + return st->drawpix.vert_shaders[passColor]; } @@ -539,8 +504,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, struct pipe_texture *pt, - struct st_vertex_program *stvp, - struct st_fragment_program *stfp, + void *driver_vp, + void *driver_fp, const GLfloat *color, GLboolean invertTex) { @@ -575,10 +540,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - cso_set_fragment_shader_handle(cso, stfp->driver_shader); + cso_set_fragment_shader_handle(cso, driver_fp); /* vertex shader state: position + texcoord pass-through */ - cso_set_vertex_shader_handle(cso, stvp->driver_shader); + cso_set_vertex_shader_handle(cso, driver_vp); /* texture sampling state: */ @@ -621,10 +586,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, struct pipe_texture *textures[2]; textures[0] = pt; textures[1] = st->pixel_xfer.pixelmap_texture; - pipe->set_sampler_textures(pipe, 2, textures); + pipe->set_fragment_sampler_textures(pipe, 2, textures); } else { - pipe->set_sampler_textures(pipe, 1, &pt); + pipe->set_fragment_sampler_textures(pipe, 1, &pt); } /* Compute window coords (y=0=bottom) with pixel zoom. @@ -637,8 +602,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, y1 = y + height * ctx->Pixel.ZoomY; draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex, - (GLfloat) width / pt->width[0], - (GLfloat) height / pt->height[0]); + (GLfloat) width / pt->width0, + (GLfloat) height / pt->height0); /* restore state */ cso_restore_rasterizer(cso); @@ -683,7 +648,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } if(format != GL_DEPTH_STENCIL && - pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0) + util_format_get_component_bits(strb->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0) usage = PIPE_TRANSFER_READ_WRITE; else usage = PIPE_TRANSFER_WRITE; @@ -737,7 +702,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* now pack the stencil (and Z) values in the dest format */ - switch (pt->format) { + switch (pt->texture->format) { case PIPE_FORMAT_S8_UNORM: { ubyte *dest = stmap + spanY * pt->stride + spanX; @@ -806,7 +771,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { struct st_fragment_program *stfp; - struct st_vertex_program *stvp; + void *driver_vp; struct st_context *st = st_context(ctx); struct pipe_surface *ps; const GLfloat *color; @@ -826,13 +791,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (format == GL_DEPTH_COMPONENT) { ps = st->state.framebuffer.zsbuf; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); color = ctx->Current.RasterColor; } else { ps = st->state.framebuffer.cbufs[0]; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); color = NULL; } @@ -843,7 +808,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (pt) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_FALSE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_FALSE); pipe_texture_reference(&pt, NULL); } } @@ -875,7 +843,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); - if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0) + if(util_format_get_component_bits(rbDraw->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0) usage = PIPE_TRANSFER_READ_WRITE; else usage = PIPE_TRANSFER_WRITE; @@ -889,8 +857,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, usage, dstx, dsty, width, height); - assert(ptDraw->block.width == 1); - assert(ptDraw->block.height == 1); + assert(util_format_get_blockwidth(ptDraw->texture->format) == 1); + assert(util_format_get_blockheight(ptDraw->texture->format) == 1); /* map the stencil buffer */ drawMap = screen->transfer_map(screen, ptDraw); @@ -911,7 +879,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, dst = drawMap + y * ptDraw->stride; src = buffer + i * width; - switch (ptDraw->format) { + switch (ptDraw->texture->format) { case PIPE_FORMAT_S8Z24_UNORM: { uint *dst4 = (uint *) dst; @@ -960,7 +928,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *rbRead; - struct st_vertex_program *stvp; + void *driver_vp; struct st_fragment_program *stfp; struct pipe_texture *pt; GLfloat *color; @@ -1009,14 +977,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; stfp = combined_drawpix_fragment_program(ctx); - stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); } else { assert(type == GL_DEPTH); rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; stfp = make_fragment_shader_z(st); - stvp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); } srcFormat = rbRead->texture->format; @@ -1116,7 +1084,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback processing\n", __FUNCTION__); - if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format)) + if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; @@ -1148,7 +1116,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - pt, stvp, stfp, color, GL_TRUE); + pt, + driver_vp, + stfp->driver_shader, + color, GL_TRUE); pipe_texture_reference(&pt, NULL); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 65ce12ccd4f..45ce34a85f7 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -49,6 +49,7 @@ #include "st_public.h" #include "st_texture.h" +#include "util/u_format.h" #include "util/u_rect.h" @@ -98,16 +99,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, strb->defined = GL_FALSE; /* undefined contents now */ if(strb->software) { - struct pipe_format_block block; size_t size; _mesa_free(strb->data); assert(strb->format != PIPE_FORMAT_NONE); - pf_get_block(strb->format, &block); - strb->stride = pf_get_stride(&block, width); - size = pf_get_2d_size(&block, strb->stride, height); + strb->stride = util_format_get_stride(strb->format, width); + size = util_format_get_2d_size(strb->format, strb->stride, height); strb->data = _mesa_malloc(size); @@ -127,13 +126,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; template.format = format; - pf_get_block(format, &template.block); - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; + template.width0 = width; + template.height0 = height; + template.depth0 = 1; template.last_level = 0; template.nr_samples = rb->NumSamples; - if (pf_is_depth_stencil(format)) { + if (util_format_is_depth_or_stencil(format)) { template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; } else { @@ -376,7 +374,7 @@ st_render_texture(GLcontext *ctx, rb->_BaseFormat = texImage->_BaseFormat; /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ - /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/ + /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/ pipe_texture_reference( &strb->texture, pt ); diff --git a/src/mesa/state_tracker/st_cb_get.c b/src/mesa/state_tracker/st_cb_get.c deleted file mode 100644 index e7d7f03bc9b..00000000000 --- a/src/mesa/state_tracker/st_cb_get.c +++ /dev/null @@ -1,97 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - - -/** - * glGet functions - * - * \author Brian Paul - */ - -#include "main/imports.h" -#include "main/context.h" - -#include "pipe/p_defines.h" - -#include "st_cb_fbo.h" -#include "st_cb_get.h" - - - -/** - * Examine the current color read buffer format to determine - * which GL pixel format/type combo is the best match. - */ -static void -get_preferred_read_format_type(GLcontext *ctx, GLint *format, GLint *type) -{ - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct st_renderbuffer *strb = st_renderbuffer(fb->_ColorReadBuffer); - - /* defaults */ - *format = ctx->Const.ColorReadFormat; - *type = ctx->Const.ColorReadType; - - if (strb) { - /* XXX could add more cases here... */ - if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM) { - *format = GL_BGRA; - if (_mesa_little_endian()) - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - else - *type = GL_UNSIGNED_INT_8_8_8_8; - } - } -} - - -/** - * We only intercept the OES preferred ReadPixels format/type. - * Everything else goes to the default _mesa_GetIntegerv. - */ -static GLboolean -st_GetIntegerv(GLcontext *ctx, GLenum pname, GLint *params) -{ - GLint dummy; - - switch (pname) { - case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: - get_preferred_read_format_type(ctx, &dummy, params); - return GL_TRUE; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: - get_preferred_read_format_type(ctx, params, &dummy); - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -void st_init_get_functions(struct dd_function_table *functions) -{ - functions->GetIntegerv = st_GetIntegerv; -} diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index b2d5c39a3a0..8c276f8128e 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -138,24 +138,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } + st_vp_release_varients( st, stvp ); } break; case GL_FRAGMENT_PROGRAM_ARB: @@ -177,8 +160,6 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) _mesa_reference_program(ctx, &prg, NULL); stfp->bitmap_program = NULL; } - - st_free_translated_vertex_programs(st, stfp->vertex_programs); } break; default: @@ -219,8 +200,6 @@ static void st_program_string_notify( GLcontext *ctx, stfp->state.tokens = NULL; } - stfp->param_state = stfp->Base.Base.Parameters->StateFlags; - if (st->fp == stfp) st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; } @@ -229,25 +208,7 @@ static void st_program_string_notify( GLcontext *ctx, stvp->serialNo++; - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; - } - - if (stvp->draw_shader) { -#if FEATURE_feedback || FEATURE_drawpix - /* this would only have been allocated for the RasterPos path */ - draw_delete_vertex_shader(st->draw, stvp->draw_shader); - stvp->draw_shader = NULL; -#endif - } - - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - - stvp->param_state = stvp->Base.Base.Parameters->StateFlags; + st_vp_release_varients( st, stvp ); if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index dcf4c38eb61..10629e92254 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -44,23 +44,6 @@ #include "st_public.h" -struct st_query_object -{ - struct gl_query_object base; - struct pipe_query *pq; -}; - - -/** - * Cast wrapper - */ -static struct st_query_object * -st_query_object(struct gl_query_object *q) -{ - return (struct st_query_object *) q; -} - - static struct gl_query_object * st_NewQueryObject(GLcontext *ctx, GLuint id) { diff --git a/src/mesa/state_tracker/st_cb_queryobj.h b/src/mesa/state_tracker/st_cb_queryobj.h index 9220a212b60..fa256b71824 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.h +++ b/src/mesa/state_tracker/st_cb_queryobj.h @@ -29,6 +29,27 @@ #define ST_CB_QUERYOBJ_H +/** + * Subclass of gl_query_object + */ +struct st_query_object +{ + struct gl_query_object base; + struct pipe_query *pq; +}; + + +/** + * Cast wrapper + */ +static INLINE struct st_query_object * +st_query_object(struct gl_query_object *q) +{ + return (struct st_query_object *) q; +} + + + extern void st_init_query_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 772bb3bb69e..6fa7bb64f2e 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -103,7 +103,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* get stencil (and Z) values */ - switch (pt->format) { + switch (pt->texture->format) { case PIPE_FORMAT_S8_UNORM: { const ubyte *src = stmap + srcY * pt->stride; @@ -243,7 +243,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, GLint row, col, dy, dstStride; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - y = strb->texture->height[0] - y - height; + y = strb->texture->height0 - y - height; } trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, @@ -431,8 +431,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width, format, type); - if (trans->format == PIPE_FORMAT_S8Z24_UNORM || - trans->format == PIPE_FORMAT_X8Z24_UNORM) { + if (trans->texture->format == PIPE_FORMAT_S8Z24_UNORM || + trans->texture->format == PIPE_FORMAT_X8Z24_UNORM) { if (format == GL_DEPTH_COMPONENT) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH]; @@ -463,8 +463,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } } - else if (trans->format == PIPE_FORMAT_Z24S8_UNORM || - trans->format == PIPE_FORMAT_Z24X8_UNORM) { + else if (trans->texture->format == PIPE_FORMAT_Z24S8_UNORM || + trans->texture->format == PIPE_FORMAT_Z24X8_UNORM) { if (format == GL_DEPTH_COMPONENT) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH]; @@ -490,7 +490,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } } - else if (trans->format == PIPE_FORMAT_Z16_UNORM) { + else if (trans->texture->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { GLushort ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; @@ -505,7 +505,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, dst += dstStride; } } - else if (trans->format == PIPE_FORMAT_Z32_UNORM) { + else if (trans->texture->format == PIPE_FORMAT_Z32_UNORM) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 9186db76e16..f01053cdacc 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -62,6 +62,7 @@ #include "pipe/p_shader_tokens.h" #include "util/u_tile.h" #include "util/u_blit.h" +#include "util/u_format.h" #include "util/u_surface.h" #include "util/u_math.h" @@ -93,51 +94,6 @@ gl_target_to_pipe(GLenum target) } -/** - * Return nominal bytes per texel for a compressed format, 0 for non-compressed - * format. - */ -static GLuint -compressed_num_bytes(gl_format format) -{ - switch (format) { -#if FEATURE_texture_fxt1 - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: -#endif -#if FEATURE_texture_s3tc - case MESA_FORMAT_RGB_DXT1: - case MESA_FORMAT_RGBA_DXT1: - return 2; - case MESA_FORMAT_RGBA_DXT3: - case MESA_FORMAT_RGBA_DXT5: - return 4; -#endif - default: - return 0; - } -} - - -static GLboolean -is_compressed_mesa_format(gl_format format) -{ - switch (format) { - case MESA_FORMAT_RGB_DXT1: - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGBA_DXT3: - case MESA_FORMAT_RGBA_DXT5: - case MESA_FORMAT_SRGB_DXT1: - case MESA_FORMAT_SRGBA_DXT1: - case MESA_FORMAT_SRGBA_DXT3: - case MESA_FORMAT_SRGBA_DXT5: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - /** called via ctx->Driver.NewTextureImage() */ static struct gl_texture_image * st_NewTextureImage(GLcontext * ctx) @@ -249,7 +205,7 @@ static GLuint default_usage(enum pipe_format fmt) { GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER; - if (pf_is_depth_stencil(fmt)) + if (util_format_is_depth_or_stencil(fmt)) usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; else usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; @@ -450,10 +406,9 @@ compress_with_blit(GLcontext * ctx, memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.format = st_mesa_format_to_pipe_format(mesa_format); - pf_get_block(templ.format, &templ.block); - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; templ.last_level = 0; templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; src_tex = screen->texture_create(screen, &templ); @@ -663,7 +618,7 @@ st_TexImage(GLcontext * ctx, */ if (!compressed_src && !ctx->Mesa_DXTn && - is_compressed_mesa_format(texImage->TexFormat) && + _mesa_is_format_compressed(texImage->TexFormat) && screen->is_format_supported(screen, stImage->pt->format, stImage->pt->target, @@ -679,7 +634,7 @@ st_TexImage(GLcontext * ctx, if (stImage->pt) { if (format == GL_DEPTH_COMPONENT && - pf_is_depth_and_stencil(stImage->pt->format)) + util_format_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; @@ -725,7 +680,22 @@ st_TexImage(GLcontext * ctx, * conversion and copy: */ if (compressed_src) { - memcpy(texImage->Data, pixels, imageSize); + const GLuint srcImageStride = _mesa_format_row_stride(texImage->TexFormat, width); + if(dstRowStride == srcImageStride) + memcpy(texImage->Data, pixels, imageSize); + else + { + char *dst = texImage->Data; + const char *src = pixels; + int i; + + for(i = 0; i < height; ++i) + { + memcpy(dst, src, srcImageStride); + dst += dstRowStride; + src += srcImageStride; + } + } } else { const GLuint srcImageStride = @@ -878,7 +848,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, /* copy/pack data into user buffer */ if (st_equal_formats(stImage->pt->format, format, type)) { /* memcpy */ - const uint bytesPerRow = width * pf_get_size(stImage->pt->format); + const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); ubyte *map = screen->transfer_map(screen, tex_xfer); GLuint row; for (row = 0; row < height; row++) { @@ -935,7 +905,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, GLubyte *dest; if (stImage->pt && - pf_is_compressed(stImage->pt->format) && + util_format_is_compressed(stImage->pt->format) && !compressed_dst) { /* Need to decompress the texture. * We'll do this by rendering a textured quad. @@ -960,7 +930,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, PIPE_TRANSFER_READ, 0, 0, stImage->base.Width, stImage->base.Height); - texImage->RowStride = stImage->transfer->stride / stImage->pt->block.size; + texImage->RowStride = stImage->transfer->stride / util_format_get_blocksize(stImage->pt->format); } else { /* Otherwise, the image should actually be stored in @@ -1066,7 +1036,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, /* See if we can do texture compression with a blit/render. */ if (!ctx->Mesa_DXTn && - is_compressed_mesa_format(texImage->TexFormat) && + _mesa_is_format_compressed(texImage->TexFormat) && screen->is_format_supported(screen, stImage->pt->format, stImage->pt->target, @@ -1086,7 +1056,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, unsigned face = _mesa_tex_target_to_face(target); if (format == GL_DEPTH_COMPONENT && - pf_is_depth_and_stencil(stImage->pt->format)) + util_format_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; @@ -1135,7 +1105,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, done: _mesa_unmap_teximage_pbo(ctx, packing); - if (stImage->pt) { + if (stImage->pt && texImage->Data) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } @@ -1208,10 +1178,10 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { struct st_texture_image *stImage = st_texture_image(texImage); - struct pipe_format_block block; int srcBlockStride; int dstBlockStride; int y; + enum pipe_format pformat= stImage->pt->format; if (stImage->pt) { unsigned face = _mesa_tex_target_to_face(target); @@ -1223,8 +1193,7 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, xoffset, yoffset, width, height); - block = stImage->pt->block; - srcBlockStride = pf_get_stride(&block, width); + srcBlockStride = util_format_get_stride(pformat, width); dstBlockStride = stImage->transfer->stride; } else { assert(stImage->pt); @@ -1238,16 +1207,16 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, return; } - assert(xoffset % block.width == 0); - assert(yoffset % block.height == 0); - assert(width % block.width == 0); - assert(height % block.height == 0); + assert(xoffset % util_format_get_blockwidth(pformat) == 0); + assert(yoffset % util_format_get_blockheight(pformat) == 0); + assert(width % util_format_get_blockwidth(pformat) == 0); + assert(height % util_format_get_blockheight(pformat) == 0); - for (y = 0; y < height; y += block.height) { + for (y = 0; y < height; y += util_format_get_blockheight(pformat)) { /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */ - const char *src = (const char*)data + srcBlockStride * pf_get_nblocksy(&block, y); - char *dst = (char*)texImage->Data + dstBlockStride * pf_get_nblocksy(&block, y); - memcpy(dst, src, pf_get_stride(&block, width)); + const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y); + char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y); + memcpy(dst, src, util_format_get_stride(pformat, width)); } if (stImage->pt) { @@ -1311,7 +1280,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, if ((baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL) && - pf_is_depth_and_stencil(stImage->pt->format)) + util_format_is_depth_and_stencil(stImage->pt->format)) transfer_usage = PIPE_TRANSFER_READ_WRITE; else transfer_usage = PIPE_TRANSFER_WRITE; @@ -1724,8 +1693,6 @@ copy_image_data_to_texture(struct st_context *st, pipe_texture_reference(&stImage->pt, NULL); } else if (stImage->base.Data) { - assert(stImage->base.Data != NULL); - /* More straightforward upload. */ @@ -1739,10 +1706,10 @@ copy_image_data_to_texture(struct st_context *st, dstLevel, stImage->base.Data, stImage->base.RowStride * - stObj->pt->block.size, + util_format_get_blocksize(stObj->pt->format), stImage->base.RowStride * stImage->base.Height * - stObj->pt->block.size); + util_format_get_blocksize(stObj->pt->format)); _mesa_align_free(stImage->base.Data); stImage->base.Data = NULL; } @@ -1764,7 +1731,7 @@ st_finalize_texture(GLcontext *ctx, { struct st_texture_object *stObj = st_texture_object(tObj); const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint cpp, face; + GLuint blockSize, face; struct st_texture_image *firstImage; *needFlush = GL_FALSE; @@ -1796,13 +1763,8 @@ st_finalize_texture(GLcontext *ctx, pipe_texture_reference(&stObj->pt, firstImage->pt); } - /* FIXME: determine format block instead of cpp */ - if (_mesa_is_format_compressed(firstImage->base.TexFormat)) { - cpp = compressed_num_bytes(firstImage->base.TexFormat); - } - else { - cpp = _mesa_get_format_bytes(firstImage->base.TexFormat); - } + /* bytes per pixel block (blocks are usually 1x1) */ + blockSize = _mesa_get_format_bytes(firstImage->base.TexFormat); /* If we already have a gallium texture, check that it matches the texture * object's format, target, size, num_levels, etc. @@ -1813,11 +1775,9 @@ st_finalize_texture(GLcontext *ctx, if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || stObj->pt->format != fmt || stObj->pt->last_level < stObj->lastLevel || - stObj->pt->width[0] != firstImage->base.Width2 || - stObj->pt->height[0] != firstImage->base.Height2 || - stObj->pt->depth[0] != firstImage->base.Depth2 || - /* Nominal bytes per pixel: */ - stObj->pt->block.size / stObj->pt->block.width != cpp) + stObj->pt->width0 != firstImage->base.Width2 || + stObj->pt->height0 != firstImage->base.Height2 || + stObj->pt->depth0 != firstImage->base.Depth2) { pipe_texture_reference(&stObj->pt, NULL); ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index 75b0a219ce3..ab11c5b4fe0 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -42,8 +42,8 @@ static void st_viewport(GLcontext * ctx, GLint x, GLint y, { struct st_context *st = ctx->st; - if (st->pipe->winsys && st->pipe->winsys->update_buffer) - st->pipe->winsys->update_buffer( st->pipe->winsys, + if (st->pipe->screen && st->pipe->screen->update_buffer) + st->pipe->screen->update_buffer( st->pipe->screen, st->pipe->priv ); } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e82598c8e7e..145bd62b83e 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -43,6 +43,7 @@ #include "st_cb_blit.h" #include "st_cb_bufferobjects.h" #include "st_cb_clear.h" +#include "st_cb_condrender.h" #if FEATURE_drawpix #include "st_cb_drawpixels.h" #include "st_cb_rasterpos.h" @@ -51,7 +52,6 @@ #include "st_cb_drawtex.h" #endif #include "st_cb_fbo.h" -#include "st_cb_get.h" #if FEATURE_feedback #include "st_cb_feedback.h" #endif @@ -336,7 +336,6 @@ void st_init_driver_functions(struct dd_function_table *functions) #endif st_init_fbo_functions(functions); - st_init_get_functions(functions); #if FEATURE_feedback st_init_feedback_functions(functions); #endif @@ -344,6 +343,7 @@ void st_init_driver_functions(struct dd_function_table *functions) #if FEATURE_queryobj st_init_query_functions(functions); #endif + st_init_cond_render_functions(functions); st_init_readpixels_functions(functions); st_init_texture_functions(functions); st_init_flush_functions(functions); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 18adb35e872..831909a3f8f 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -55,6 +55,7 @@ struct bitmap_cache; #define ST_NEW_FRAGMENT_PROGRAM 0x2 #define ST_NEW_VERTEX_PROGRAM 0x4 #define ST_NEW_FRAMEBUFFER 0x8 +#define ST_NEW_EDGEFLAGS_DATA 0x10 struct st_state_flags { @@ -120,6 +121,7 @@ struct st_context struct st_state_flags dirty; GLboolean missing_textures; + GLboolean vertdata_edgeflags; /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; @@ -127,6 +129,8 @@ struct st_context struct st_vertex_program *vp; /**< Currently bound vertex program */ struct st_fragment_program *fp; /**< Currently bound fragment program */ + struct st_vp_varient *vp_varient; + struct gl_texture_object *default_texture; struct { diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index 3009cde9d51..6e699ca5522 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -86,7 +86,8 @@ st_print_current(void) } #endif - tgsi_dump( st->vp->state.tokens, 0 ); + if (st->vp->varients) + tgsi_dump( st->vp->varients[0].state.tokens, 0 ); if (st->vp->Base.Base.Parameters) _mesa_print_parameter_list(st->vp->Base.Base.Parameters); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index c76bff91819..e54f21be600 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -25,10 +25,20 @@ * **************************************************************************/ - /* - * Authors: - * Keith Whitwell <[email protected]> - */ +/* + * This file implements the st_draw_vbo() function which is called from + * Mesa's VBO module. All point/line/triangle rendering is done through + * this function whether the user called glBegin/End, glDrawArrays, + * glDrawElements, glEvalMesh, or glCalList, etc. + * + * We basically convert the VBO's vertex attribute/array information into + * Gallium vertex state, bind the vertex buffer objects and call + * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays(). + * + * Authors: + * Keith Whitwell <[email protected]> + */ + #include "main/imports.h" #include "main/image.h" @@ -207,59 +217,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, } -/* - * If edge flags are needed, setup an bitvector of flags and call - * pipe->set_edgeflags(). - * XXX memleak: need to free the returned pointer at some point - */ -static void * -setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count, - const struct gl_client_array *array) -{ - struct pipe_context *pipe = ctx->st->pipe; - - if ((primMode == GL_TRIANGLES || - primMode == GL_QUADS || - primMode == GL_POLYGON) && - (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL)) { - /* need edge flags */ - GLint i; - unsigned *vec; - struct st_buffer_object *stobj = st_buffer_object(array->BufferObj); - ubyte *map; - - if (!stobj || stobj->Base.Name == 0) { - /* edge flags are not in a VBO */ - return NULL; - } - - vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32)); - if (!vec) - return NULL; - - map = pipe_buffer_map(pipe->screen, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ); - map = ADD_POINTERS(map, array->Ptr); - - for (i = 0; i < count; i++) { - if (*((float *) map)) - vec[i/32] |= 1 << (i % 32); - - map += array->StrideB; - } - - pipe_buffer_unmap(pipe->screen, stobj->buffer); - pipe->set_edgeflags(pipe, vec); - - return vec; - } - else { - /* edge flags not needed */ - pipe->set_edgeflags(pipe, NULL); - return NULL; - } -} /** @@ -269,6 +227,7 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count, */ static GLboolean is_interleaved_arrays(const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLboolean *userSpace) { @@ -278,7 +237,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, GLuint num_client_arrays = 0; const GLubyte *client_addr = NULL; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj; const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */ @@ -311,7 +270,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp, } } - *userSpace = (num_client_arrays == vp->num_inputs); + *userSpace = (num_client_arrays == vpv->num_inputs); /* printf("user space: %d (%d %d)\n", (int) *userSpace,num_client_arrays,vp->num_inputs); */ return GL_TRUE; @@ -323,15 +282,16 @@ is_interleaved_arrays(const struct st_vertex_program *vp, */ static void get_arrays_bounds(const struct st_vertex_program *vp, - const struct gl_client_array **arrays, - GLuint max_index, - const GLubyte **low, const GLubyte **high) + const struct st_vp_varient *vpv, + const struct gl_client_array **arrays, + GLuint max_index, + const GLubyte **low, const GLubyte **high) { const GLubyte *low_addr = NULL; const GLubyte *high_addr = NULL; GLuint attr; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const GLint stride = arrays[mesaAttr]->StrideB; const GLubyte *start = arrays[mesaAttr]->Ptr; @@ -363,6 +323,7 @@ get_arrays_bounds(const struct st_vertex_program *vp, static void setup_interleaved_attribs(GLcontext *ctx, const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLuint max_index, GLboolean userSpace, @@ -371,9 +332,9 @@ setup_interleaved_attribs(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; GLuint attr; - const GLubyte *offset0; + const GLubyte *offset0 = NULL; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; struct st_buffer_object *stobj = st_buffer_object(bufobj); @@ -384,7 +345,7 @@ setup_interleaved_attribs(GLcontext *ctx, if (attr == 0) { const GLubyte *low, *high; - get_arrays_bounds(vp, arrays, max_index, &low, &high); + get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high); /*printf("buffer range: %p %p %d\n", low, high, high-low);*/ offset0 = low; @@ -425,6 +386,7 @@ setup_interleaved_attribs(GLcontext *ctx, static void setup_non_interleaved_attribs(GLcontext *ctx, const struct st_vertex_program *vp, + const struct st_vp_varient *vpv, const struct gl_client_array **arrays, GLuint max_index, GLboolean *userSpace, @@ -434,7 +396,7 @@ setup_non_interleaved_attribs(GLcontext *ctx, struct pipe_context *pipe = ctx->st->pipe; GLuint attr; - for (attr = 0; attr < vp->num_inputs; attr++) { + for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; GLsizei stride = arrays[mesaAttr]->StrideB; @@ -528,6 +490,20 @@ check_uniforms(GLcontext *ctx) } +static unsigned translate_prim( GLcontext *ctx, + unsigned prim ) +{ + /* Avoid quadstrips if it's easy to do so: + */ + if (prim == GL_QUAD_STRIP && + ctx->Light.ShadeModel != GL_FLAT && + ctx->Polygon.FrontMode == GL_FILL && + ctx->Polygon.BackMode == GL_FILL) + prim = GL_TRIANGLE_STRIP; + + return prim; +} + /** * This function gets plugged into the VBO module and is called when * we have something to render. @@ -545,25 +521,36 @@ st_draw_vbo(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; const struct st_vertex_program *vp; + const struct st_vp_varient *vpv; const struct pipe_shader_state *vs; struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; GLuint attr; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; - GLboolean userSpace; + GLboolean userSpace = GL_FALSE; + GLboolean vertDataEdgeFlags; /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) - vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + if (!vbo_all_varyings_in_vbos(arrays)) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); /* sanity check for pointer arithmetic below */ assert(sizeof(arrays[0]->Ptr[0]) == 1); + vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && + arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; + if (vertDataEdgeFlags != ctx->st->vertdata_edgeflags) { + ctx->st->vertdata_edgeflags = vertDataEdgeFlags; + ctx->st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; + } + st_validate_state(ctx->st); /* must get these after state validation! */ vp = ctx->st->vp; - vs = &ctx->st->vp->state; + vpv = ctx->st->vp_varient; + vs = &vpv->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { @@ -576,21 +563,21 @@ st_draw_vbo(GLcontext *ctx, /* * Setup the vbuffer[] and velements[] arrays. */ - if (is_interleaved_arrays(vp, arrays, &userSpace)) { + if (is_interleaved_arrays(vp, vpv, arrays, &userSpace)) { /*printf("Draw interleaved\n");*/ - setup_interleaved_attribs(ctx, vp, arrays, max_index, userSpace, + setup_interleaved_attribs(ctx, vp, vpv, arrays, max_index, userSpace, vbuffer, velements); num_vbuffers = 1; - num_velements = vp->num_inputs; + num_velements = vpv->num_inputs; if (num_velements == 0) num_vbuffers = 0; } else { /*printf("Draw non-interleaved\n");*/ - setup_non_interleaved_attribs(ctx, vp, arrays, max_index, + setup_non_interleaved_attribs(ctx, vp, vpv, arrays, max_index, &userSpace, vbuffer, velements); - num_vbuffers = vp->num_inputs; - num_velements = vp->num_inputs; + num_vbuffers = vpv->num_inputs; + num_velements = vpv->num_inputs; } #if 0 @@ -623,6 +610,7 @@ st_draw_vbo(GLcontext *ctx, struct gl_buffer_object *bufobj = ib->obj; struct pipe_buffer *indexBuf = NULL; unsigned indexSize, indexOffset, i; + unsigned prim; switch (ib->type) { case GL_UNSIGNED_INT: @@ -661,24 +649,20 @@ st_draw_vbo(GLcontext *ctx, * through to driver & draw module. These interfaces still * need a bit of work... */ - setup_edgeflags(ctx, prims[i].mode, - prims[i].start + indexOffset, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); + prim = translate_prim( ctx, prims[i].mode ); pipe->draw_range_elements(pipe, indexBuf, indexSize, min_index, max_index, - prims[i].mode, + prim, prims[i].start + indexOffset, prims[i].count); } else { for (i = 0; i < nr_prims; i++) { - setup_edgeflags(ctx, prims[i].mode, - prims[i].start + indexOffset, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); + prim = translate_prim( ctx, prims[i].mode ); pipe->draw_elements(pipe, indexBuf, indexSize, - prims[i].mode, + prim, prims[i].start + indexOffset, prims[i].count); } } @@ -688,12 +672,12 @@ st_draw_vbo(GLcontext *ctx, else { /* non-indexed */ GLuint i; + GLuint prim; + for (i = 0; i < nr_prims; i++) { - setup_edgeflags(ctx, prims[i].mode, - prims[i].start, prims[i].count, - arrays[VERT_ATTRIB_EDGEFLAG]); + prim = translate_prim( ctx, prims[i].mode ); - pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count); + pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count); } } diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index b2d682ef640..cfc0caac983 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -120,10 +120,10 @@ st_feedback_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &st->vp->state; + vs = &st->vp_varient->state; - if (!st->vp->draw_shader) { - st->vp->draw_shader = draw_create_vertex_shader(draw, vs); + if (!st->vp_varient->draw_shader) { + st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs); } /* @@ -136,7 +136,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_viewport_state(draw, &st->state.viewport); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer); - draw_bind_vertex_shader(draw, st->vp->draw_shader); + draw_bind_vertex_shader(draw, st->vp_varient->draw_shader); set_feedback_vertex_format(ctx); /* loop over TGSI shader inputs to determine vertex buffer @@ -241,7 +241,8 @@ st_feedback_draw_vbo(GLcontext *ctx, mapped_constants = pipe_buffer_map(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX].buffer, PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(st->draw, mapped_constants, + draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, + mapped_constants, st->state.constants[PIPE_SHADER_VERTEX].buffer->size); diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index ce3c302e48e..e25a613d8a9 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -92,6 +92,10 @@ void st_init_limits(struct st_context *st) = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS), MAX_VERTEX_TEXTURE_IMAGE_UNITS); + c->MaxCombinedTextureImageUnits + = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS), + MAX_COMBINED_TEXTURE_IMAGE_UNITS); + c->MaxTextureCoordUnits = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); @@ -288,6 +292,7 @@ void st_init_extensions(struct st_context *st) PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0)) { ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE; + ctx->Extensions.S3_s3tc = GL_TRUE; } /* ycbcr support */ @@ -305,4 +310,8 @@ void st_init_extensions(struct st_context *st) /* we support always support GL_EXT_framebuffer_blit */ ctx->Extensions.ARB_framebuffer_object = GL_TRUE; } + + if (st->pipe->render_condition) { + ctx->Extensions.NV_conditional_render = GL_TRUE; + } } diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 02f80057c29..d00b67a279e 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -42,42 +42,34 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" +#include "util/u_format.h" #include "st_context.h" #include "st_format.h" -static GLuint -format_bits( - pipe_format_rgbazs_t info, - GLuint comp ) -{ - return pf_get_component_bits( (enum pipe_format) info, comp ); -} static GLuint -format_max_bits( - pipe_format_rgbazs_t info ) +format_max_bits(enum pipe_format format) { - GLuint size = format_bits( info, PIPE_FORMAT_COMP_R ); + GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0); - size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_G ) ); - size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_B ) ); - size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_A ) ); - size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_Z ) ); - size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_S ) ); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)); return size; } static GLuint -format_size( - pipe_format_rgbazs_t info ) +format_size(enum pipe_format format) { return - format_bits( info, PIPE_FORMAT_COMP_R ) + - format_bits( info, PIPE_FORMAT_COMP_G ) + - format_bits( info, PIPE_FORMAT_COMP_B ) + - format_bits( info, PIPE_FORMAT_COMP_A ) + - format_bits( info, PIPE_FORMAT_COMP_Z ) + - format_bits( info, PIPE_FORMAT_COMP_S ); + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) + + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1) + + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2) + + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) + + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0) + + util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1); } /* @@ -86,11 +78,13 @@ format_size( GLboolean st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) { - if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) { - pipe_format_rgbazs_t info; + const struct util_format_description *desc; - info = format; + desc = util_format_description(format); + assert(desc); + if (desc->layout == UTIL_FORMAT_LAYOUT_ARITH || + desc->layout == UTIL_FORMAT_LAYOUT_ARRAY) { #if 0 printf("%s\n", pf_name( format ) ); #endif @@ -99,26 +93,27 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) if (format == PIPE_FORMAT_A1R5G5B5_UNORM || format == PIPE_FORMAT_R5G6B5_UNORM) { pinfo->datatype = GL_UNSIGNED_SHORT; } - else if (format == PIPE_FORMAT_S8Z24_UNORM) { + else if (format == PIPE_FORMAT_S8Z24_UNORM || + format == PIPE_FORMAT_Z24S8_UNORM) { pinfo->datatype = GL_UNSIGNED_INT_24_8; } else { - const GLuint size = format_max_bits( info ); + const GLuint size = format_max_bits(format); if (size == 8) { - if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM) + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) pinfo->datatype = GL_UNSIGNED_BYTE; else pinfo->datatype = GL_BYTE; } else if (size == 16) { - if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM) + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) pinfo->datatype = GL_UNSIGNED_SHORT; else pinfo->datatype = GL_SHORT; } else { assert( size <= 32 ); - if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM) + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) pinfo->datatype = GL_UNSIGNED_INT; else pinfo->datatype = GL_INT; @@ -126,23 +121,23 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) } /* Component bits */ - pinfo->red_bits = format_bits( info, PIPE_FORMAT_COMP_R ); - pinfo->green_bits = format_bits( info, PIPE_FORMAT_COMP_G ); - pinfo->blue_bits = format_bits( info, PIPE_FORMAT_COMP_B ); - pinfo->alpha_bits = format_bits( info, PIPE_FORMAT_COMP_A ); - pinfo->depth_bits = format_bits( info, PIPE_FORMAT_COMP_Z ); - pinfo->stencil_bits = format_bits( info, PIPE_FORMAT_COMP_S ); + pinfo->red_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0); + pinfo->green_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1); + pinfo->blue_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2); + pinfo->alpha_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3); + pinfo->depth_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0); + pinfo->stencil_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1); pinfo->luminance_bits = 0; pinfo->intensity_bits = 0; /* Format size */ - pinfo->size = format_size( info ) / 8; + pinfo->size = format_size(format) / 8; /* Luminance & Intensity bits */ - if( pf_swizzle_x(info) == PIPE_FORMAT_COMP_R && - pf_swizzle_y(info) == PIPE_FORMAT_COMP_R && - pf_swizzle_z(info) == PIPE_FORMAT_COMP_R ) { - if( pf_swizzle_w(info) == PIPE_FORMAT_COMP_R ) { + if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X && + desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X && + desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X) { + if (desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) { pinfo->intensity_bits = pinfo->red_bits; } else { @@ -153,7 +148,7 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) pinfo->mesa_format = st_pipe_format_to_mesa_format(format); } - else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) { + else if (desc->layout == UTIL_FORMAT_LAYOUT_YUV) { pinfo->mesa_format = MESA_FORMAT_YCBCR; pinfo->datatype = GL_UNSIGNED_SHORT; pinfo->size = 2; /* two bytes per "texel" */ @@ -291,6 +286,8 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat) return MESA_FORMAT_ARGB8888; case PIPE_FORMAT_X8R8G8B8_UNORM: return MESA_FORMAT_XRGB8888; + case PIPE_FORMAT_B8G8R8A8_UNORM: + return MESA_FORMAT_ARGB8888_REV; case PIPE_FORMAT_A1R5G5B5_UNORM: return MESA_FORMAT_ARGB1555; case PIPE_FORMAT_A4R4G4B4_UNORM: @@ -389,6 +386,33 @@ default_rgba_format(struct pipe_screen *screen, } /** + * Find an RGB format supported by the context/winsys. + */ +static enum pipe_format +default_rgb_format(struct pipe_screen *screen, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + static const enum pipe_format colorFormats[] = { + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_R8G8B8X8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM + }; + uint i; + for (i = 0; i < Elements(colorFormats); i++) { + if (screen->is_format_supported( screen, colorFormats[i], target, tex_usage, geom_flags )) { + return colorFormats[i]; + } + } + return PIPE_FORMAT_NONE; +} + +/** * Find an sRGBA format supported by the context/winsys. */ static enum pipe_format @@ -472,13 +496,14 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: return default_rgba_format( screen, target, tex_usage, geom_flags ); + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + return default_rgb_format( screen, target, tex_usage, geom_flags ); case GL_RGBA16: if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) return default_deep_rgba_format( screen, target, tex_usage, geom_flags ); @@ -500,7 +525,7 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_RGB10: case GL_RGB12: case GL_RGB16: - return default_rgba_format( screen, target, tex_usage, geom_flags ); + return default_rgb_format( screen, target, tex_usage, geom_flags ); case GL_RGB5: case GL_RGB4: diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 16ca2771b0f..2c283d464ae 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -37,7 +37,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_format.h" #include "util/u_gen_mipmap.h" +#include "util/u_math.h" #include "cso_cache/cso_cache.h" #include "cso_cache/cso_context.h" @@ -133,29 +135,33 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, srcLevel, zslice, PIPE_TRANSFER_READ, 0, 0, - pt->width[srcLevel], - pt->height[srcLevel]); + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel)); dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face, dstLevel, zslice, PIPE_TRANSFER_WRITE, 0, 0, - pt->width[dstLevel], - pt->height[dstLevel]); + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel)); srcData = (ubyte *) screen->transfer_map(screen, srcTrans); dstData = (ubyte *) screen->transfer_map(screen, dstTrans); - srcStride = srcTrans->stride / srcTrans->block.size; - dstStride = dstTrans->stride / dstTrans->block.size; + srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->texture->format); + dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->texture->format); _mesa_generate_mipmap_level(target, datatype, comps, - 0 /*border*/, - pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], - srcData, - srcStride, /* stride in texels */ - pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], - dstData, - dstStride); /* stride in texels */ + 0 /*border*/, + u_minify(pt->width0, srcLevel), + u_minify(pt->height0, srcLevel), + u_minify(pt->depth0, srcLevel), + srcData, + srcStride, /* stride in texels */ + u_minify(pt->width0, dstLevel), + u_minify(pt->height0, dstLevel), + u_minify(pt->depth0, dstLevel), + dstData, + dstStride); /* stride in texels */ screen->transfer_unmap(screen, srcTrans); screen->transfer_unmap(screen, dstTrans); @@ -219,6 +225,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, /* find expected last mipmap level */ lastLevel = compute_num_levels(ctx, texObj, target) - 1; + if (lastLevel == 0) + return; + if (pt->last_level < lastLevel) { /* The current gallium texture doesn't have space for all the * mipmap levels we need to generate. So allocate a new texture. @@ -232,9 +241,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, oldTex->target, oldTex->format, lastLevel, - oldTex->width[0], - oldTex->height[0], - oldTex->depth[0], + oldTex->width0, + oldTex->height0, + oldTex->depth0, oldTex->tex_usage); /* The texture isn't in a "complete" state yet so set the expected @@ -269,9 +278,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, = _mesa_get_tex_image(ctx, texObj, target, srcLevel); struct gl_texture_image *dstImage; struct st_texture_image *stImage; - uint dstWidth = pt->width[dstLevel]; - uint dstHeight = pt->height[dstLevel]; - uint dstDepth = pt->depth[dstLevel]; + uint dstWidth = u_minify(pt->width0, dstLevel); + uint dstHeight = u_minify(pt->height0, dstLevel); + uint dstDepth = u_minify(pt->depth0, dstLevel); uint border = srcImage->Border; dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 3d6c2158191..e788008dfe1 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -160,13 +160,14 @@ dst_register( struct st_translate *t, static struct ureg_src src_register( struct st_translate *t, gl_register_file file, - GLuint index ) + GLint index ) { switch( file ) { case PROGRAM_UNDEFINED: return ureg_src_undef(); case PROGRAM_TEMPORARY: + ASSERT(index >= 0); if (ureg_dst_is_undef(t->temps[index])) t->temps[index] = ureg_DECL_temporary( t->ureg ); return ureg_src(t->temps[index]); @@ -174,9 +175,15 @@ src_register( struct st_translate *t, case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: case PROGRAM_ENV_PARAM: + case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: - case PROGRAM_CONSTANT: /* ie, immediate */ + ASSERT(index >= 0); return t->constants[index]; + case PROGRAM_CONSTANT: /* ie, immediate */ + if (index < 0) + return ureg_DECL_constant( t->ureg, 0 ); + else + return t->constants[index]; case PROGRAM_INPUT: return t->inputs[t->inputMapping[index]]; @@ -263,9 +270,14 @@ translate_src( struct st_translate *t, if (SrcReg->Abs) src = ureg_abs(src); - if (SrcReg->RelAddr) + if (SrcReg->RelAddr) { src = ureg_src_indirect( src, ureg_src(t->address[0])); - + /* If SrcReg->Index was negative, it was set to zero in + * src_register(). Reassign it now. + */ + src.Index = SrcReg->Index; + } + return src; } @@ -278,7 +290,7 @@ static struct ureg_src swizzle_4v( struct ureg_src src, /** - * Translate SWZ instructions into a single MAD. EG: + * Translate a SWZ instruction into a MOV, MUL or MAD instruction. EG: * * SWZ dst, src.x-y10 * @@ -396,6 +408,23 @@ static void emit_swz( struct st_translate *t, } +/** + * Negate the value of DDY to match GL semantics where (0,0) is the + * lower-left corner of the window. + * Note that the GL_ARB_fragment_coord_conventions extension will + * effect this someday. + */ +static void emit_ddy( struct st_translate *t, + struct ureg_dst dst, + const struct prog_src_register *SrcReg ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_src src = translate_src( t, SrcReg ); + src = ureg_negate( src ); + ureg_DDY( ureg, dst, src ); +} + + static unsigned translate_opcode( unsigned op ) @@ -619,7 +648,9 @@ compile_instruction( ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) ); break; - + case OPCODE_DDY: + emit_ddy( t, dst[0], &inst->SrcReg[0] ); + break; default: ureg_insn( ureg, @@ -676,6 +707,41 @@ emit_inverted_wpos( struct st_translate *t, /** + * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. + * TGSI uses +1 for front, -1 for back. + * This function converts the TGSI value to the GL value. Simply clamping/ + * saturating the value to [0,1] does the job. + */ +static void +emit_face_var( struct st_translate *t, + const struct gl_program *program ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst face_temp = ureg_DECL_temporary( ureg ); + struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; + + /* MOV_SAT face_temp, input[face] + */ + face_temp = ureg_saturate( face_temp ); + ureg_MOV( ureg, face_temp, face_input ); + + /* Use face_temp as face input from here on: + */ + t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); +} + +static void +emit_edgeflags( struct st_translate *t, + const struct gl_program *program ) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; + struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; + + ureg_MOV( ureg, edge_dst, edge_src ); +} + +/** * Translate Mesa program to TGSI format. * \param program the program to translate * \param numInputs number of input registers used @@ -694,26 +760,24 @@ emit_inverted_wpos( struct st_translate *t, * * \return array of translated tokens, caller's responsibility to free */ -const struct tgsi_token * +enum pipe_error st_translate_mesa_program( GLcontext *ctx, uint procType, + struct ureg_program *ureg, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ) + boolean passthrough_edgeflags ) { struct st_translate translate, *t; - struct ureg_program *ureg; - const struct tgsi_token *tokens = NULL; unsigned i; t = &translate; @@ -722,11 +786,7 @@ st_translate_mesa_program( t->procType = procType; t->inputMapping = inputMapping; t->outputMapping = outputMapping; - t->ureg = ureg_create( procType ); - if (t->ureg == NULL) - return NULL; - - ureg = t->ureg; + t->ureg = ureg; /*_mesa_print_program(program);*/ @@ -748,6 +808,10 @@ st_translate_mesa_program( emit_inverted_wpos( t, program ); } + if (program->InputsRead & FRAG_BIT_FACE) { + emit_face_var( t, program ); + } + /* * Declare output attributes. */ @@ -782,6 +846,8 @@ st_translate_mesa_program( outputSemanticName[i], outputSemanticIndex[i] ); } + if (passthrough_edgeflags) + emit_edgeflags( t, program ); } /* Declare address register. @@ -805,6 +871,7 @@ st_translate_mesa_program( for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { case PROGRAM_ENV_PARAM: + case PROGRAM_LOCAL_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: case PROGRAM_UNIFORM: @@ -853,8 +920,7 @@ st_translate_mesa_program( t->insn[t->labels[i].branch_target] ); } - tokens = ureg_get_tokens( ureg, NULL ); - ureg_destroy( ureg ); + return PIPE_OK; out: FREE(t->insn); @@ -863,17 +929,9 @@ out: if (t->error) { debug_printf("%s: translate error flag set\n", __FUNCTION__); - FREE((void *)tokens); - tokens = NULL; - } - - if (!tokens) { - debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__); - _mesa_print_program(program); - debug_assert(0); } - return tokens; + return PIPE_ERROR_OUT_OF_MEMORY; } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index c0d1ff59e1f..e3c5bd1d94d 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -30,6 +30,7 @@ #define ST_MESA_TO_TGSI_H #include "main/mtypes.h" +#include "tgsi/tgsi_ureg.h" #if defined __cplusplus @@ -39,22 +40,22 @@ extern "C" { struct tgsi_token; struct gl_program; -const struct tgsi_token * +enum pipe_error st_translate_mesa_program( GLcontext *ctx, uint procType, + struct ureg_program *ureg, const struct gl_program *program, GLuint numInputs, const GLuint inputMapping[], const ubyte inputSemanticName[], const ubyte inputSemanticIndex[], const GLuint interpMode[], - const GLbitfield inputFlags[], GLuint numOutputs, const GLuint outputMapping[], const ubyte outputSemanticName[], const ubyte outputSemanticIndex[], - const GLbitfield outputFlags[] ); + boolean passthrough_edgeflags ); void st_free_tokens(const struct tgsi_token *tokens); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index a9be80ce8f3..6a869fae904 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -50,6 +50,39 @@ #include "cso_cache/cso_context.h" + +/** + * Clean out any old compilations: + */ +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ) +{ + struct st_vp_varient *vpv; + + for (vpv = stvp->varients; vpv; ) { + struct st_vp_varient *next = vpv->next; + + if (vpv->driver_shader) + cso_delete_vertex_shader(st->cso_context, vpv->driver_shader); + + if (vpv->draw_shader) + draw_delete_vertex_shader( st->draw, vpv->draw_shader ); + + if (vpv->state.tokens) + st_free_tokens(vpv->state.tokens); + + FREE( vpv ); + + vpv = next; + } + + stvp->varients = NULL; +} + + + + /** * Translate a Mesa vertex shader into a TGSI shader. * \param outputMapping to map vertex program output registers (VERT_RESULT_x) @@ -58,197 +91,78 @@ * \return pointer to cached pipe_shader object. */ void -st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *stvp, - const GLuint outputMapping[], - const ubyte *outputSemanticName, - const ubyte *outputSemanticIndex) +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp) { - struct pipe_context *pipe = st->pipe; - GLuint defaultOutputMapping[VERT_RESULT_MAX]; - GLuint attr, i; - GLuint num_generic = 0; - - ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS]; - ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - uint vs_num_inputs = 0; - - ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; - ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - uint vs_num_outputs = 0; - - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; + GLuint attr; -// memset(&vs, 0, sizeof(vs)); - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); + stvp->num_inputs = 0; + stvp->num_outputs = 0; if (stvp->Base.IsPositionInvariant) _mesa_insert_mvp_code(st->ctx, &stvp->Base); + assert(stvp->Base.Base.NumInstructions > 1); + /* * Determine number of inputs, the mappings between VERT_ATTRIB_x * and TGSI generic input indexes, plus input attrib semantic info. */ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { if (stvp->Base.Base.InputsRead & (1 << attr)) { - const GLuint slot = vs_num_inputs; - - vs_num_inputs++; - - stvp->input_to_index[attr] = slot; - stvp->index_to_input[slot] = attr; - - switch (attr) { - case VERT_ATTRIB_POS: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_WEIGHT: - /* fall-through */ - case VERT_ATTRIB_NORMAL: - /* just label as a generic */ - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR0: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_COLOR1: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_input_semantic_index[slot] = 1; - break; - case VERT_ATTRIB_FOG: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_POINT_SIZE: - vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_input_semantic_index[slot] = 0; - break; - case VERT_ATTRIB_TEX0: - case VERT_ATTRIB_TEX1: - case VERT_ATTRIB_TEX2: - case VERT_ATTRIB_TEX3: - case VERT_ATTRIB_TEX4: - case VERT_ATTRIB_TEX5: - case VERT_ATTRIB_TEX6: - case VERT_ATTRIB_TEX7: - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - case VERT_ATTRIB_GENERIC0: - case VERT_ATTRIB_GENERIC1: - case VERT_ATTRIB_GENERIC2: - case VERT_ATTRIB_GENERIC3: - case VERT_ATTRIB_GENERIC4: - case VERT_ATTRIB_GENERIC5: - case VERT_ATTRIB_GENERIC6: - case VERT_ATTRIB_GENERIC7: - case VERT_ATTRIB_GENERIC8: - case VERT_ATTRIB_GENERIC9: - case VERT_ATTRIB_GENERIC10: - case VERT_ATTRIB_GENERIC11: - case VERT_ATTRIB_GENERIC12: - case VERT_ATTRIB_GENERIC13: - case VERT_ATTRIB_GENERIC14: - case VERT_ATTRIB_GENERIC15: - assert(attr < VERT_ATTRIB_MAX); - assert(slot < Elements(vs_input_semantic_name)); - vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_input_semantic_index[slot] = num_generic++; - break; - default: - assert(0); - } - - input_flags[slot] = stvp->Base.Base.InputFlags[attr]; - } - } - -#if 0 - if (outputMapping && outputSemanticName) { - printf("VERT_RESULT written out_slot semantic_name semantic_index\n"); - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - printf(" %-2d %c %3d %2d %2d\n", - attr, - ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '), - outputMapping[attr], - outputSemanticName[attr], - outputSemanticIndex[attr]); + stvp->input_to_index[attr] = stvp->num_inputs; + stvp->index_to_input[stvp->num_inputs] = attr; + stvp->num_inputs++; } } -#endif - - /* initialize output semantics to defaults */ - for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { - assert(i < Elements(vs_output_semantic_name)); - vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[i] = 0; - output_flags[i] = 0x0; - } + /* bit of a hack, presetup potentially unused edgeflag input */ + stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs; + stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG; - num_generic = 0; - /* - * Determine number of outputs, the (default) output register - * mapping and the semantic information for each output. + /* Compute mapping of vertex program outputs to slots. */ for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (stvp->Base.Base.OutputsWritten & (1 << attr)) { - GLuint slot; - - /* XXX - * Pass in the fragment program's input's semantic info. - * Use the generic semantic indexes from there, instead of - * guessing below. - */ - - if (outputMapping) { - slot = outputMapping[attr]; - assert(slot != ~0); - } - else { - slot = vs_num_outputs; - vs_num_outputs++; - defaultOutputMapping[attr] = slot; - } + if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) { + stvp->result_to_output[attr] = ~0; + } + else { + unsigned slot = stvp->num_outputs++; + + stvp->result_to_output[attr] = slot; switch (attr) { case VERT_RESULT_HPOS: - assert(slot == 0); - vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_COL1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_BFC0: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_BFC1: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; - vs_output_semantic_index[slot] = 1; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; + stvp->output_semantic_index[slot] = 1; break; case VERT_RESULT_FOGC: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_PSIZ: - vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; - vs_output_semantic_index[slot] = 0; + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; + stvp->output_semantic_index[slot] = 0; break; case VERT_RESULT_EDGE: assert(0); break; + case VERT_RESULT_TEX0: case VERT_RESULT_TEX1: case VERT_RESULT_TEX2: @@ -257,92 +171,79 @@ st_translate_vertex_program(struct st_context *st, case VERT_RESULT_TEX5: case VERT_RESULT_TEX6: case VERT_RESULT_TEX7: - /* fall-through */ + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0; + break; + case VERT_RESULT_VAR0: - /* fall-through */ default: - assert(slot < Elements(vs_output_semantic_name)); - if (outputSemanticName) { - /* use provided semantic into */ - assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT); - vs_output_semantic_name[slot] = outputSemanticName[attr]; - vs_output_semantic_index[slot] = outputSemanticIndex[attr]; - } - else { - /* use default semantic info */ - vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - vs_output_semantic_index[slot] = num_generic++; - } + assert(attr < VERT_RESULT_MAX); + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 - + FRAG_ATTRIB_TEX0 + + attr - + VERT_RESULT_VAR0); + break; } - - assert(slot < Elements(output_flags)); - output_flags[slot] = stvp->Base.Base.OutputFlags[attr]; } } + /* similar hack to above, presetup potentially unused edgeflag output */ + stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs; + stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG; + stvp->output_semantic_index[stvp->num_outputs] = 0; +} - if (outputMapping) { - /* find max output slot referenced to compute vs_num_outputs */ - GLuint maxSlot = 0; - for (attr = 0; attr < VERT_RESULT_MAX; attr++) { - if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) - maxSlot = outputMapping[attr]; - } - vs_num_outputs = maxSlot + 1; - } - else { - outputMapping = defaultOutputMapping; - } -#if 0 /* debug */ - { - GLuint i; - printf("outputMapping? %d\n", outputMapping ? 1 : 0); - if (outputMapping) { - printf("attr -> slot\n"); - for (i = 0; i < 16; i++) { - printf(" %2d %3d\n", i, outputMapping[i]); - } - } - printf("slot sem_name sem_index\n"); - for (i = 0; i < vs_num_outputs; i++) { - printf(" %2d %d %d\n", - i, - vs_output_semantic_name[i], - vs_output_semantic_index[i]); - } - } -#endif - - /* free old shader state, if any */ - if (stvp->state.tokens) { - st_free_tokens(stvp->state.tokens); - stvp->state.tokens = NULL; - } - if (stvp->driver_shader) { - cso_delete_vertex_shader(st->cso_context, stvp->driver_shader); - stvp->driver_shader = NULL; +struct st_vp_varient * +st_translate_vertex_program(struct st_context *st, + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key) +{ + struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient); + struct pipe_context *pipe = st->pipe; + struct ureg_program *ureg; + enum pipe_error error; + unsigned num_outputs; + + ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); + if (ureg == NULL) + return NULL; + + vpv->num_inputs = stvp->num_inputs; + num_outputs = stvp->num_outputs; + if (key->passthrough_edgeflags) { + vpv->num_inputs++; + num_outputs++; } - stvp->state.tokens = + error = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_VERTEX, + ureg, &stvp->Base.Base, /* inputs */ - vs_num_inputs, + vpv->num_inputs, stvp->input_to_index, - vs_input_semantic_name, - vs_input_semantic_index, + NULL, /* input semantic name */ + NULL, /* input semantic index */ NULL, - input_flags, /* outputs */ - vs_num_outputs, - outputMapping, - vs_output_semantic_name, - vs_output_semantic_index, - output_flags ); + num_outputs, + stvp->result_to_output, + stvp->output_semantic_name, + stvp->output_semantic_index, + key->passthrough_edgeflags ); - stvp->num_inputs = vs_num_inputs; - stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state); + if (error) + goto fail; + + vpv->state.tokens = ureg_get_tokens( ureg, NULL ); + if (!vpv->state.tokens) + goto fail; + + ureg_destroy( ureg ); + + vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { _mesa_print_program(&stvp->Base.Base); @@ -350,9 +251,19 @@ st_translate_vertex_program(struct st_context *st, } if (ST_DEBUG & DEBUG_TGSI) { - tgsi_dump( stvp->state.tokens, 0 ); + tgsi_dump( vpv->state.tokens, 0 ); debug_printf("\n"); } + + return vpv; + +fail: + debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__); + _mesa_print_program(&stvp->Base.Base); + debug_assert(0); + + ureg_destroy( ureg ); + return NULL; } @@ -373,9 +284,10 @@ st_translate_fragment_program(struct st_context *st, GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; GLuint interpMode[16]; /* XXX size? */ GLuint attr; + enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; + struct ureg_program *ureg; GLuint vslot = 0; - GLuint num_generic = 0; uint fs_num_inputs = 0; @@ -383,13 +295,6 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - GLbitfield input_flags[MAX_PROGRAM_INPUTS]; - GLbitfield output_flags[MAX_PROGRAM_OUTPUTS]; - -// memset(&fs, 0, sizeof(fs)); - memset(input_flags, 0, sizeof(input_flags)); - memset(output_flags, 0, sizeof(output_flags)); - /* which vertex output goes to the first fragment input: */ if (inputsRead & FRAG_BIT_WPOS) vslot = 0; @@ -432,14 +337,25 @@ st_translate_fragment_program(struct st_context *st, break; case FRAG_ATTRIB_FACE: stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE; - stfp->input_semantic_index[slot] = num_generic++; + stfp->input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; - case FRAG_ATTRIB_PNTC: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + + /* In most cases, there is nothing special about these + * inputs, so adopt a convention to use the generic + * semantic name and the mesa FRAG_ATTRIB_ number as the + * index. + * + * All that is required is that the vertex shader labels + * its own outputs similarly, and that the vertex shader + * generates at least every output required by the + * fragment shader plus fixed-function hardware (such as + * BFC). + * + * There is no requirement that semantic indexes start at + * zero or be restricted to a particular range -- nobody + * should be building tables based on semantic index. + */ case FRAG_ATTRIB_TEX0: case FRAG_ATTRIB_TEX1: case FRAG_ATTRIB_TEX2: @@ -448,19 +364,18 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; - interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + case FRAG_ATTRIB_PNTC: case FRAG_ATTRIB_VAR0: - /* fall-through */ default: + /* Actually, let's try and zero-base this just for + * readability of the generated TGSI. + */ + assert(attr >= FRAG_ATTRIB_TEX0); + stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = num_generic++; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + break; } - - input_flags[slot] = stfp->Base.Base.InputFlags[attr]; } } @@ -469,7 +384,7 @@ st_translate_fragment_program(struct st_context *st, */ { uint numColors = 0; - GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten; + GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten; /* if z is written, emit that first */ if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) { @@ -498,8 +413,6 @@ st_translate_fragment_program(struct st_context *st, break; } - output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr]; - fs_num_outputs++; } } @@ -508,9 +421,15 @@ st_translate_fragment_program(struct st_context *st, if (!inputMapping) inputMapping = defaultInputMapping; - stfp->state.tokens = + ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); + if (ureg == NULL) + return; + + + error = st_translate_mesa_program(st->ctx, TGSI_PROCESSOR_FRAGMENT, + ureg, &stfp->Base.Base, /* inputs */ fs_num_inputs, @@ -518,14 +437,14 @@ st_translate_fragment_program(struct st_context *st, stfp->input_semantic_name, stfp->input_semantic_index, interpMode, - input_flags, /* outputs */ fs_num_outputs, outputMapping, fs_output_semantic_name, - fs_output_semantic_index, - output_flags ); + fs_output_semantic_index, FALSE ); + stfp->state.tokens = ureg_get_tokens( ureg, NULL ); + ureg_destroy( ureg ); stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index e2e5eddef22..6b9a9226df5 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -64,41 +64,73 @@ struct st_fragment_program struct pipe_shader_state state; void *driver_shader; - GLuint param_state; - - /** List of vertex programs which have been translated such that their - * outputs match this fragment program's inputs. - */ - struct translated_vertex_program *vertex_programs; - /** Program prefixed with glBitmap prologue */ struct st_fragment_program *bitmap_program; uint bitmap_sampler; }; + +struct st_vp_varient_key +{ + boolean passthrough_edgeflags; +}; + + +/** + * This represents a vertex program, especially translated to match + * the inputs of a particular fragment shader. + */ +struct st_vp_varient +{ + /* Parameters which generated this translated version of a vertex + * shader: + */ + struct st_vp_varient_key key; + + /** TGSI tokens -- why? + */ + struct pipe_shader_state state; + + /** Driver's compiled shader */ + void *driver_shader; + + /** For using our private draw module (glRasterPos) */ + struct draw_vertex_shader *draw_shader; + + /** Next in linked list */ + struct st_vp_varient *next; + + /** similar to that in st_vertex_program, but with information about edgeflags too */ + GLuint num_inputs; +}; + + + + /** * Derived from Mesa gl_fragment_program: */ struct st_vertex_program { struct gl_vertex_program Base; /**< The Mesa vertex program */ - GLuint serialNo; + GLuint serialNo, lastSerialNo; /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */ GLuint input_to_index[VERT_ATTRIB_MAX]; /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */ GLuint index_to_input[PIPE_MAX_SHADER_INPUTS]; - GLuint num_inputs; - struct pipe_shader_state state; - void *driver_shader; + /** Maps VERT_RESULT_x to slot */ + GLuint result_to_output[VERT_RESULT_MAX]; + ubyte output_semantic_name[VERT_RESULT_MAX]; + ubyte output_semantic_index[VERT_RESULT_MAX]; + GLuint num_outputs; - /** For using our private draw module (glRasterPos) */ - struct draw_vertex_shader *draw_shader; - - GLuint param_state; + /** List of translated varients of this vertex program. + */ + struct st_vp_varient *varients; }; @@ -143,13 +175,21 @@ st_translate_fragment_program(struct st_context *st, const GLuint inputMapping[]); +/* Called after program string change, discard all previous + * compilation results. + */ extern void +st_prepare_vertex_program(struct st_context *st, + struct st_vertex_program *stvp); + +extern struct st_vp_varient * st_translate_vertex_program(struct st_context *st, - struct st_vertex_program *vp, - const GLuint vert_output_to_slot[], - const ubyte *fs_input_semantic_name, - const ubyte *fs_input_semantic_index); + struct st_vertex_program *stvp, + const struct st_vp_varient_key *key); +void +st_vp_release_varients( struct st_context *st, + struct st_vertex_program *stvp ); extern void st_print_shaders(GLcontext *ctx); diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index a5fdac32d1f..98c19817c87 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -56,15 +56,19 @@ struct pipe_surface; struct pipe_texture; +PUBLIC struct st_context *st_create_context(struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share); +PUBLIC void st_destroy_context( struct st_context *st ); +PUBLIC void st_copy_context_state(struct st_context *dst, struct st_context *src, uint mask); +PUBLIC struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, @@ -72,50 +76,67 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, uint width, uint height, void *privateData); +PUBLIC void st_resize_framebuffer( struct st_framebuffer *stfb, uint width, uint height ); +PUBLIC void st_set_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf); +PUBLIC void st_get_framebuffer_dimensions( struct st_framebuffer *stfb, uint *width, uint *height); +PUBLIC int st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface); +PUBLIC int st_get_framebuffer_texture(struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture); +PUBLIC void *st_framebuffer_private( struct st_framebuffer *stfb ); +PUBLIC void st_unreference_framebuffer( struct st_framebuffer *stfb ); +PUBLIC GLboolean st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); +PUBLIC struct st_context *st_get_current(void); +PUBLIC void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ); +PUBLIC void st_finish( struct st_context *st ); +PUBLIC void st_notify_swapbuffers(struct st_framebuffer *stfb); +PUBLIC void st_swapbuffers(struct st_framebuffer *stfb, struct pipe_surface **front_left, struct pipe_surface **front_right); +PUBLIC int st_bind_texture_surface(struct pipe_surface *ps, int target, int level, enum pipe_format format); +PUBLIC int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level); /** Redirect rendering into stfb's surface to a texture image */ +PUBLIC int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level); /** Undo surface-to-texture binding */ +PUBLIC int st_release_teximage(struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level); @@ -123,6 +144,7 @@ int st_release_teximage(struct st_framebuffer *stfb, uint surfIndex, /** Generic function type */ typedef void (*st_proc)(); +PUBLIC st_proc st_get_proc_address(const char *procname); diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 3945822f663..8a3e4cd3ac3 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -43,7 +43,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" +#include "util/u_format.h" #include "util/u_rect.h" +#include "util/u_math.h" #define DBG if(0) printf @@ -100,10 +102,9 @@ st_texture_create(struct st_context *st, pt.target = target; pt.format = format; pt.last_level = last_level; - pt.width[0] = width0; - pt.height[0] = height0; - pt.depth[0] = depth0; - pf_get_block(format, &pt.block); + pt.width0 = width0; + pt.height0 = height0; + pt.depth0 = depth0; pt.tex_usage = usage; newtex = screen->texture_create(screen, &pt); @@ -135,9 +136,9 @@ st_texture_match_image(const struct pipe_texture *pt, /* Test if this image's size matches what's expected in the * established texture. */ - if (image->Width != pt->width[level] || - image->Height != pt->height[level] || - image->Depth != pt->depth[level]) + if (image->Width != u_minify(pt->width0, level) || + image->Height != u_minify(pt->height0, level) || + image->Depth != u_minify(pt->depth0, level)) return GL_FALSE; return GL_TRUE; @@ -241,8 +242,9 @@ st_surface_data(struct pipe_context *pipe, struct pipe_screen *screen = pipe->screen; void *map = screen->transfer_map(screen, dst); + assert(dst->texture); util_copy_rect(map, - &dst->block, + dst->texture->format, dst->stride, dstx, dsty, width, height, @@ -265,7 +267,7 @@ st_texture_image_data(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - GLuint depth = dst->depth[level]; + GLuint depth = u_minify(dst->depth0, level); GLuint i; const GLubyte *srcUB = src; struct pipe_transfer *dst_transfer; @@ -275,15 +277,16 @@ st_texture_image_data(struct st_context *st, for (i = 0; i < depth; i++) { dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i, PIPE_TRANSFER_WRITE, 0, 0, - dst->width[level], - dst->height[level]); + u_minify(dst->width0, level), + u_minify(dst->height0, level)); st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ - dst->width[level], dst->height[level]); /* width, height */ + u_minify(dst->width0, level), + u_minify(dst->height0, level)); /* width, height */ screen->tex_transfer_destroy(dst_transfer); @@ -301,9 +304,9 @@ st_texture_image_copy(struct pipe_context *pipe, GLuint face) { struct pipe_screen *screen = pipe->screen; - GLuint width = dst->width[dstLevel]; - GLuint height = dst->height[dstLevel]; - GLuint depth = dst->depth[dstLevel]; + GLuint width = u_minify(dst->width0, dstLevel); + GLuint height = u_minify(dst->height0, dstLevel); + GLuint depth = u_minify(dst->depth0, dstLevel); struct pipe_surface *src_surface; struct pipe_surface *dst_surface; GLuint i; @@ -313,13 +316,13 @@ st_texture_image_copy(struct pipe_context *pipe, /* find src texture level of needed size */ for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) { - if (src->width[srcLevel] == width && - src->height[srcLevel] == height) { + if (u_minify(src->width0, srcLevel) == width && + u_minify(src->height0, srcLevel) == height) { break; } } - assert(src->width[srcLevel] == width); - assert(src->height[srcLevel] == height); + assert(u_minify(src->width0, srcLevel) == width); + assert(u_minify(src->height0, srcLevel) == height); #if 0 { @@ -403,7 +406,7 @@ st_bind_texture_surface(struct pipe_surface *ps, int target, int level, } /* map pipe format to base format for now */ - if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0) + if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0) internalFormat = GL_RGBA; else internalFormat = GL_RGB; @@ -588,5 +591,5 @@ st_teximage_flush_before_map(struct st_context *st, if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || (usage & PIPE_TRANSFER_WRITE))) - st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); + st->pipe->flush(st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); } |