diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_sampler.c | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_texture.c | 650 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.c | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.h | 13 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_draw.c | 78 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_draw.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_draw_feedback.c | 15 |
7 files changed, 399 insertions, 374 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c index d1ab1ac3e..48b94500d 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c +++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c @@ -166,12 +166,11 @@ update_samplers(struct st_context *st) sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias +
texobj->LodBias;
- sampler->min_lod = texobj->BaseLevel + texobj->MinLod;
- if (sampler->min_lod < texobj->BaseLevel)
- sampler->min_lod = texobj->BaseLevel;
-
- sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel,
- (texobj->MaxLod + texobj->BaseLevel));
+ sampler->min_lod = CLAMP(texobj->MinLod,
+ 0.0f,
+ (GLfloat) texobj->MaxLevel - texobj->BaseLevel);
+ sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel,
+ texobj->MaxLod);
if (sampler->max_lod < sampler->min_lod) {
/* The GL spec doesn't seem to specify what to do in this case.
* Swap the values.
diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index fd03669e6..04825ba4a 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -1,324 +1,326 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell <keith@tungstengraphics.com> - * Brian Paul - */ - - -#include "main/macros.h" -#include "program/prog_instruction.h" - -#include "st_context.h" -#include "st_atom.h" -#include "st_texture.h" -#include "st_format.h" -#include "st_cb_texture.h" -#include "pipe/p_context.h" -#include "util/u_format.h" -#include "util/u_inlines.h" -#include "cso_cache/cso_context.h" - - -/** - * Combine depth texture mode with "swizzle" so that depth mode swizzling - * takes place before texture swizzling, and return the resulting swizzle. - * If the format is not a depth format, return "swizzle" unchanged. - * - * \param format PIPE_FORMAT_*. - * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4. - * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA, GL_RED. - */ -static GLuint -apply_depthmode(enum pipe_format format, GLuint swizzle, GLenum depthmode) -{ - const struct util_format_description *desc = - util_format_description(format); - unsigned char swiz[4]; - unsigned i; - - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS || - desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) { - /* Not a depth format. */ - return swizzle; - } - - for (i = 0; i < 4; i++) - swiz[i] = GET_SWZ(swizzle, i); - - switch (depthmode) { - case GL_LUMINANCE: - /* Rewrite reads from W to ONE, and reads from XYZ to XXX. */ - for (i = 0; i < 4; i++) - if (swiz[i] == SWIZZLE_W) - swiz[i] = SWIZZLE_ONE; - else if (swiz[i] < SWIZZLE_W) - swiz[i] = SWIZZLE_X; - break; - - case GL_INTENSITY: - /* Rewrite reads from XYZW to XXXX. */ - for (i = 0; i < 4; i++) - if (swiz[i] <= SWIZZLE_W) - swiz[i] = SWIZZLE_X; - break; - - case GL_ALPHA: - /* Rewrite reads from W to X, and reads from XYZ to 000. */ - for (i = 0; i < 4; i++) - if (swiz[i] == SWIZZLE_W) - swiz[i] = SWIZZLE_X; - else if (swiz[i] < SWIZZLE_W) - swiz[i] = SWIZZLE_ZERO; - break; - case GL_RED: - /* Rewrite reads W to 1, XYZ to X00 */ - for (i = 0; i < 4; i++) - if (swiz[i] == SWIZZLE_W) - swiz[i] = SWIZZLE_ONE; - else if (swiz[i] == SWIZZLE_Y || swiz[i] == SWIZZLE_Z) - swiz[i] = SWIZZLE_ZERO; - break; - } - - return MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]); -} - - -/** - * Return TRUE if the swizzling described by "swizzle" and - * "depthmode" (for depth textures only) is different from the swizzling - * set in the given sampler view. - * - * \param sv A sampler view. - * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4. - * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA. - */ -static boolean -check_sampler_swizzle(struct pipe_sampler_view *sv, - GLuint swizzle, GLenum depthmode) -{ - swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode); - - if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) || - (sv->swizzle_g != GET_SWZ(swizzle, 1)) || - (sv->swizzle_b != GET_SWZ(swizzle, 2)) || - (sv->swizzle_a != GET_SWZ(swizzle, 3))) - return TRUE; - return FALSE; -} - - -static INLINE struct pipe_sampler_view * -st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe, - struct st_texture_object *stObj, - enum pipe_format format) -{ - struct pipe_sampler_view templ; - GLuint swizzle = apply_depthmode(stObj->pt->format, - stObj->base._Swizzle, - stObj->base.DepthMode); - - u_sampler_view_default_template(&templ, - stObj->pt, - format); - - if (swizzle != SWIZZLE_NOOP) { - templ.swizzle_r = GET_SWZ(swizzle, 0); - templ.swizzle_g = GET_SWZ(swizzle, 1); - templ.swizzle_b = GET_SWZ(swizzle, 2); - templ.swizzle_a = GET_SWZ(swizzle, 3); - } - - return pipe->create_sampler_view(pipe, stObj->pt, &templ); -} - - -static INLINE struct pipe_sampler_view * -st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, - struct pipe_context *pipe, - enum pipe_format format) -{ - if (!stObj || !stObj->pt) { - return NULL; - } - - if (!stObj->sampler_view) { - stObj->sampler_view = - st_create_texture_sampler_view_from_stobj(pipe, stObj, format); - } - - return stObj->sampler_view; -} - - -static void -update_textures(struct st_context *st) -{ - struct pipe_context *pipe = st->pipe; - struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; - const GLbitfield samplersUsed = (vprog->Base.SamplersUsed | - fprog->Base.SamplersUsed); - GLuint su; - - st->state.num_textures = 0; - - /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { - struct pipe_sampler_view *sampler_view = NULL; - enum pipe_format st_view_format; - if (samplersUsed & (1 << su)) { - struct gl_texture_object *texObj; - struct st_texture_object *stObj; - GLboolean retval; - GLuint texUnit; - - if (fprog->Base.SamplersUsed & (1 << su)) - texUnit = fprog->Base.SamplerUnits[su]; - else - texUnit = vprog->Base.SamplerUnits[su]; - - texObj = st->ctx->Texture.Unit[texUnit]._Current; - - if (!texObj) { - texObj = st_get_default_texture(st); - } - stObj = st_texture_object(texObj); - - retval = st_finalize_texture(st->ctx, st->pipe, texObj); - if (!retval) { - /* out of mem */ - continue; - } - - /* Determine the format of the texture sampler view */ - st_view_format = stObj->pt->format; - { - const struct st_texture_image *firstImage = - st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); - const gl_format texFormat = firstImage->base.TexFormat; - enum pipe_format firstImageFormat = - st_mesa_format_to_pipe_format(texFormat); - - if ((stObj->base.sRGBDecode == GL_SKIP_DECODE_EXT) && - (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) { - /* don't do sRGB->RGB conversion. Interpret the texture - * texture data as linear values. - */ - const gl_format linearFormat = - _mesa_get_srgb_format_linear(texFormat); - firstImageFormat = st_mesa_format_to_pipe_format(linearFormat); - } - - if (firstImageFormat != stObj->pt->format) - st_view_format = firstImageFormat; - } - - st->state.num_textures = su + 1; - - /* if sampler view has changed dereference it */ - if (stObj->sampler_view) - if (check_sampler_swizzle(stObj->sampler_view, - stObj->base._Swizzle, - stObj->base.DepthMode) || - (st_view_format != stObj->sampler_view->format)) - pipe_sampler_view_reference(&stObj->sampler_view, NULL); - - sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, st_view_format); - } - pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view); - } - - cso_set_fragment_sampler_views(st->cso_context, - st->state.num_textures, - st->state.sampler_views); - if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { - cso_set_vertex_sampler_views(st->cso_context, - MIN2(st->state.num_textures, - st->ctx->Const.MaxVertexTextureImageUnits), - st->state.sampler_views); - } -} - - -const struct st_tracked_state st_update_texture = { - "st_update_texture", /* name */ - { /* dirty */ - _NEW_TEXTURE, /* mesa */ - ST_NEW_FRAGMENT_PROGRAM, /* st */ - }, - update_textures /* update */ -}; - - - - -static void -finalize_textures(struct st_context *st) -{ - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; - const GLboolean prev_missing_textures = st->missing_textures; - GLuint su; - - st->missing_textures = GL_FALSE; - - for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) { - if (fprog->Base.SamplersUsed & (1 << su)) { - const GLuint texUnit = fprog->Base.SamplerUnits[su]; - struct gl_texture_object *texObj - = st->ctx->Texture.Unit[texUnit]._Current; - - if (texObj) { - GLboolean retval; - - retval = st_finalize_texture(st->ctx, st->pipe, texObj); - if (!retval) { - /* out of mem */ - st->missing_textures = GL_TRUE; - continue; - } - } - } - } - - if (prev_missing_textures != st->missing_textures) - st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; -} - - - -const struct st_tracked_state st_finalize_textures = { - "st_finalize_textures", /* name */ - { /* dirty */ - _NEW_TEXTURE, /* mesa */ - 0, /* st */ - }, - finalize_textures /* update */ -}; +/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Brian Paul
+ */
+
+
+#include "main/macros.h"
+#include "program/prog_instruction.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_texture.h"
+#include "st_format.h"
+#include "st_cb_texture.h"
+#include "pipe/p_context.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "cso_cache/cso_context.h"
+
+
+/**
+ * Combine depth texture mode with "swizzle" so that depth mode swizzling
+ * takes place before texture swizzling, and return the resulting swizzle.
+ * If the format is not a depth format, return "swizzle" unchanged.
+ *
+ * \param format PIPE_FORMAT_*.
+ * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA, GL_RED.
+ */
+static GLuint
+apply_depthmode(enum pipe_format format, GLuint swizzle, GLenum depthmode)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ unsigned char swiz[4];
+ unsigned i;
+
+ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
+ desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
+ /* Not a depth format. */
+ return swizzle;
+ }
+
+ for (i = 0; i < 4; i++)
+ swiz[i] = GET_SWZ(swizzle, i);
+
+ switch (depthmode) {
+ case GL_LUMINANCE:
+ /* Rewrite reads from W to ONE, and reads from XYZ to XXX. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] == SWIZZLE_W)
+ swiz[i] = SWIZZLE_ONE;
+ else if (swiz[i] < SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ break;
+
+ case GL_INTENSITY:
+ /* Rewrite reads from XYZW to XXXX. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] <= SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ break;
+
+ case GL_ALPHA:
+ /* Rewrite reads from W to X, and reads from XYZ to 000. */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] == SWIZZLE_W)
+ swiz[i] = SWIZZLE_X;
+ else if (swiz[i] < SWIZZLE_W)
+ swiz[i] = SWIZZLE_ZERO;
+ break;
+ case GL_RED:
+ /* Rewrite reads W to 1, XYZ to X00 */
+ for (i = 0; i < 4; i++)
+ if (swiz[i] == SWIZZLE_W)
+ swiz[i] = SWIZZLE_ONE;
+ else if (swiz[i] == SWIZZLE_Y || swiz[i] == SWIZZLE_Z)
+ swiz[i] = SWIZZLE_ZERO;
+ break;
+ }
+
+ return MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
+}
+
+
+/**
+ * Return TRUE if the swizzling described by "swizzle" and
+ * "depthmode" (for depth textures only) is different from the swizzling
+ * set in the given sampler view.
+ *
+ * \param sv A sampler view.
+ * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
+ */
+static boolean
+check_sampler_swizzle(struct pipe_sampler_view *sv,
+ GLuint swizzle, GLenum depthmode)
+{
+ swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
+
+ if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
+ (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
+ (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
+ (sv->swizzle_a != GET_SWZ(swizzle, 3)))
+ return TRUE;
+ return FALSE;
+}
+
+
+static INLINE struct pipe_sampler_view *
+st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
+ struct st_texture_object *stObj,
+ enum pipe_format format)
+{
+ struct pipe_sampler_view templ;
+ GLuint swizzle = apply_depthmode(stObj->pt->format,
+ stObj->base._Swizzle,
+ stObj->base.DepthMode);
+
+ u_sampler_view_default_template(&templ,
+ stObj->pt,
+ format);
+ templ.u.tex.first_level = stObj->base.BaseLevel;
+
+ if (swizzle != SWIZZLE_NOOP) {
+ templ.swizzle_r = GET_SWZ(swizzle, 0);
+ templ.swizzle_g = GET_SWZ(swizzle, 1);
+ templ.swizzle_b = GET_SWZ(swizzle, 2);
+ templ.swizzle_a = GET_SWZ(swizzle, 3);
+ }
+
+ return pipe->create_sampler_view(pipe, stObj->pt, &templ);
+}
+
+
+static INLINE struct pipe_sampler_view *
+st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
+ struct pipe_context *pipe,
+ enum pipe_format format)
+{
+ if (!stObj || !stObj->pt) {
+ return NULL;
+ }
+
+ if (!stObj->sampler_view) {
+ stObj->sampler_view =
+ st_create_texture_sampler_view_from_stobj(pipe, stObj, format);
+ }
+
+ return stObj->sampler_view;
+}
+
+
+static void
+update_textures(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+ struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
+ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
+ fprog->Base.SamplersUsed);
+ GLuint su;
+
+ st->state.num_textures = 0;
+
+ /* loop over sampler units (aka tex image units) */
+ for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
+ struct pipe_sampler_view *sampler_view = NULL;
+ enum pipe_format st_view_format;
+ if (samplersUsed & (1 << su)) {
+ struct gl_texture_object *texObj;
+ struct st_texture_object *stObj;
+ GLboolean retval;
+ GLuint texUnit;
+
+ if (fprog->Base.SamplersUsed & (1 << su))
+ texUnit = fprog->Base.SamplerUnits[su];
+ else
+ texUnit = vprog->Base.SamplerUnits[su];
+
+ texObj = st->ctx->Texture.Unit[texUnit]._Current;
+
+ if (!texObj) {
+ texObj = st_get_default_texture(st);
+ }
+ stObj = st_texture_object(texObj);
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj);
+ if (!retval) {
+ /* out of mem */
+ continue;
+ }
+
+ /* Determine the format of the texture sampler view */
+ st_view_format = stObj->pt->format;
+ {
+ const struct st_texture_image *firstImage =
+ st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+ const gl_format texFormat = firstImage->base.TexFormat;
+ enum pipe_format firstImageFormat =
+ st_mesa_format_to_pipe_format(texFormat);
+
+ if ((stObj->base.sRGBDecode == GL_SKIP_DECODE_EXT) &&
+ (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) {
+ /* don't do sRGB->RGB conversion. Interpret the texture
+ * texture data as linear values.
+ */
+ const gl_format linearFormat =
+ _mesa_get_srgb_format_linear(texFormat);
+ firstImageFormat = st_mesa_format_to_pipe_format(linearFormat);
+ }
+
+ if (firstImageFormat != stObj->pt->format)
+ st_view_format = firstImageFormat;
+ }
+
+ st->state.num_textures = su + 1;
+
+ /* if sampler view has changed dereference it */
+ if (stObj->sampler_view)
+ if (check_sampler_swizzle(stObj->sampler_view,
+ stObj->base._Swizzle,
+ stObj->base.DepthMode) ||
+ (st_view_format != stObj->sampler_view->format) ||
+ stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level)
+ pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+
+ sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, st_view_format);
+ }
+ pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view);
+ }
+
+ cso_set_fragment_sampler_views(st->cso_context,
+ st->state.num_textures,
+ st->state.sampler_views);
+ if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+ cso_set_vertex_sampler_views(st->cso_context,
+ MIN2(st->state.num_textures,
+ st->ctx->Const.MaxVertexTextureImageUnits),
+ st->state.sampler_views);
+ }
+}
+
+
+const struct st_tracked_state st_update_texture = {
+ "st_update_texture", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ ST_NEW_FRAGMENT_PROGRAM, /* st */
+ },
+ update_textures /* update */
+};
+
+
+
+
+static void
+finalize_textures(struct st_context *st)
+{
+ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLboolean prev_missing_textures = st->missing_textures;
+ GLuint su;
+
+ st->missing_textures = GL_FALSE;
+
+ for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
+ if (fprog->Base.SamplersUsed & (1 << su)) {
+ const GLuint texUnit = fprog->Base.SamplerUnits[su];
+ struct gl_texture_object *texObj
+ = st->ctx->Texture.Unit[texUnit]._Current;
+
+ if (texObj) {
+ GLboolean retval;
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj);
+ if (!retval) {
+ /* out of mem */
+ st->missing_textures = GL_TRUE;
+ continue;
+ }
+ }
+ }
+ }
+
+ if (prev_missing_textures != st->missing_textures)
+ st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+
+const struct st_tracked_state st_finalize_textures = {
+ "st_finalize_textures", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ 0, /* st */
+ },
+ finalize_textures /* update */
+};
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index afd85f0de..458968486 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -206,8 +206,8 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_drawtex(st);
/* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_vbs; i++) {
- pipe_resource_reference(&st->user_vb[i], NULL);
+ for (i = 0; i < st->num_user_attribs; i++) {
+ pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
}
for (i = 0; i < Elements(st->state.sampler_views); i++) {
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index ef54fd7cd..a35439741 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -187,9 +187,16 @@ struct st_context void *winsys_drawable_handle;
/* User vertex buffers. */
- struct pipe_resource *user_vb[PIPE_MAX_ATTRIBS];
- unsigned user_vb_stride[PIPE_MAX_ATTRIBS];
- unsigned num_user_vbs;
+ struct {
+ struct pipe_resource *buffer;
+
+ /** Element size */
+ GLuint element_size;
+
+ /** Attribute stride */
+ GLsizei stride;
+ } user_attrib[PIPE_MAX_ATTRIBS];
+ unsigned num_user_attribs;
};
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 52e46d628..61e127776 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -329,8 +329,12 @@ setup_interleaved_attribs(struct gl_context *ctx, const struct gl_client_array *array = arrays[mesaAttr];
struct gl_buffer_object *bufobj = array->BufferObj;
struct st_buffer_object *stobj = st_buffer_object(bufobj);
+ unsigned src_offset = (unsigned) (array->Ptr - low_addr);
+ GLuint element_size = array->_ElementSize;
GLsizei stride = array->StrideB;
+ assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+
if (attr == 0) {
if (bufobj && bufobj->Name) {
vbuffer->buffer = NULL;
@@ -339,22 +343,25 @@ setup_interleaved_attribs(struct gl_context *ctx, }
else {
uint divisor = array->InstanceDivisor;
- uint length = (divisor ? num_instances / divisor : max_index) + 1;
+ uint last_index = divisor ? num_instances / divisor : max_index;
+ uint bytes = src_offset + stride * last_index + element_size;
+
vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
(void*) low_addr,
- stride * length,
+ bytes,
PIPE_BIND_VERTEX_BUFFER);
vbuffer->buffer_offset = 0;
/* Track user vertex buffers. */
- pipe_resource_reference(&st->user_vb[0], vbuffer->buffer);
- st->user_vb_stride[0] = stride;
- st->num_user_vbs = 1;
+ pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
+ st->user_attrib[0].element_size = element_size;
+ st->user_attrib[0].stride = stride;
+ st->num_user_attribs = 1;
}
vbuffer->stride = stride; /* in bytes */
}
- velements[attr].src_offset = (unsigned) (array->Ptr - low_addr);
+ velements[attr].src_offset = src_offset;
velements[attr].instance_divisor = array->InstanceDivisor;
velements[attr].vertex_buffer_index = 0;
velements[attr].src_format = st_pipe_vertex_format(array->Type,
@@ -390,8 +397,11 @@ setup_non_interleaved_attribs(struct gl_context *ctx, const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
struct gl_buffer_object *bufobj = array->BufferObj;
+ GLuint element_size = array->_ElementSize;
GLsizei stride = array->StrideB;
+ assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+
if (bufobj && bufobj->Name) {
/* Attribute data is in a VBO.
* Recall that for VBOs, the gl_client_array->Ptr field is
@@ -410,20 +420,16 @@ setup_non_interleaved_attribs(struct gl_context *ctx, void *ptr;
if (array->Ptr) {
- if (stride == 0) {
- bytes = _mesa_sizeof_type(array->Type) * array->Size;
- }
- else {
- uint divisor = array->InstanceDivisor;
- uint length = (divisor ? num_instances / divisor : max_index) + 1;
- bytes = stride * length;
- }
+ uint divisor = array->InstanceDivisor;
+ uint last_index = divisor ? num_instances / divisor : max_index;
+
+ bytes = stride * last_index + element_size;
ptr = (void *) array->Ptr;
}
else {
/* no array, use ctx->Current.Attrib[] value */
- bytes = sizeof(ctx->Current.Attrib[0]);
+ bytes = element_size = sizeof(ctx->Current.Attrib[0]);
ptr = (void *) ctx->Current.Attrib[mesaAttr];
stride = 0;
}
@@ -438,9 +444,10 @@ setup_non_interleaved_attribs(struct gl_context *ctx, vbuffer[attr].buffer_offset = 0;
/* Track user vertex buffers. */
- pipe_resource_reference(&st->user_vb[attr], vbuffer[attr].buffer);
- st->user_vb_stride[attr] = stride;
- st->num_user_vbs = MAX2(st->num_user_vbs, attr+1);
+ pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer);
+ st->user_attrib[attr].element_size = element_size;
+ st->user_attrib[attr].stride = stride;
+ st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1);
}
/* common-case setup */
@@ -583,10 +590,10 @@ st_validate_varrays(struct gl_context *ctx, memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
/* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_vbs; i++) {
- pipe_resource_reference(&st->user_vb[i], NULL);
+ for (i = 0; i < st->num_user_attribs; i++) {
+ pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
}
- st->num_user_vbs = 0;
+ st->num_user_attribs = 0;
/*
* Setup the vbuffer[] and velements[] arrays.
@@ -700,21 +707,20 @@ st_draw_vbo(struct gl_context *ctx, /* Notify the driver that the content of user buffers may have been
* changed. */
- if (!new_array && st->num_user_vbs) {
- for (i = 0; i < st->num_user_vbs; i++) {
- if (st->user_vb[i]) {
- unsigned stride = st->user_vb_stride[i];
-
- if (stride) {
- pipe->redefine_user_buffer(pipe, st->user_vb[i],
- min_index * stride,
- (max_index + 1 - min_index) * stride);
- }
- else {
- /* stride == 0 */
- pipe->redefine_user_buffer(pipe, st->user_vb[i],
- 0, st->user_vb[i]->width0);
- }
+ assert(max_index >= min_index);
+ if (!new_array && st->num_user_attribs) {
+ for (i = 0; i < st->num_user_attribs; i++) {
+ if (st->user_attrib[i].buffer) {
+ unsigned element_size = st->user_attrib[i].element_size;
+ unsigned stride = st->user_attrib[i].stride;
+ unsigned min_offset = min_index * stride;
+ unsigned max_offset = max_index * stride + element_size;
+
+ assert(max_offset > min_offset);
+
+ pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer,
+ min_offset,
+ max_offset - min_offset);
}
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h index 6c8b78c76..23e1c7821 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.h +++ b/mesalib/src/mesa/state_tracker/st_draw.h @@ -69,7 +69,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* Internal function:
*/
-extern GLuint
+extern enum pipe_format
st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
GLboolean normalized);
diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c index f0734eae0..bbf2ef67e 100644 --- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c +++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c @@ -111,6 +111,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer = NULL;
GLuint attr, i;
+ const GLubyte *low_addr = NULL;
const void *mapped_indices = NULL;
assert(draw);
@@ -141,6 +142,16 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_bind_vertex_shader(draw, st->vp_variant->draw_shader);
set_feedback_vertex_format(ctx);
+ /* Find the lowest address of the arrays we're drawing */
+ if (vp->num_inputs) {
+ low_addr = arrays[vp->index_to_input[0]]->Ptr;
+
+ for (attr = 1; attr < vp->num_inputs; attr++) {
+ const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr;
+ low_addr = MIN2(low_addr, start);
+ }
+ }
+
/* loop over TGSI shader inputs to determine vertex buffer
* and attribute info
*/
@@ -159,8 +170,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, vbuffers[attr].buffer = NULL;
pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer);
- vbuffers[attr].buffer_offset = pointer_to_offset(arrays[0]->Ptr);
- velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
+ vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
+ velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
}
else {
/* attribute data is in user-space memory, not a VBO */
|