diff options
Diffstat (limited to 'mesalib/src')
41 files changed, 1745 insertions, 1697 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.c b/mesalib/src/gallium/auxiliary/util/u_draw.c index d16575b73..5b3c41231 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw.c +++ b/mesalib/src/gallium/auxiliary/util/u_draw.c @@ -44,7 +44,6 @@ unsigned util_draw_max_index( const struct pipe_vertex_buffer *vertex_buffers, - unsigned nr_vertex_buffers, const struct pipe_vertex_element *vertex_elements, unsigned nr_vertex_elements, const struct pipe_draw_info *info) @@ -62,6 +61,10 @@ util_draw_max_index( const struct util_format_description *format_desc; unsigned format_size; + if (!buffer->buffer) { + continue; + } + assert(buffer->buffer->height0 == 1); assert(buffer->buffer->depth0 == 1); buffer_size = buffer->buffer->width0; diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.h b/mesalib/src/gallium/auxiliary/util/u_draw.h index 69cf25aff..3dc69181c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw.h +++ b/mesalib/src/gallium/auxiliary/util/u_draw.h @@ -1,158 +1,157 @@ -/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-#ifndef U_DRAW_H
-#define U_DRAW_H
-
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-static INLINE void
-util_draw_init_info(struct pipe_draw_info *info)
-{
- memset(info, 0, sizeof(*info));
- info->instance_count = 1;
- info->max_index = 0xffffffff;
-}
-
-
-static INLINE void
-util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.min_index = start;
- info.max_index = start + count - 1;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_elements(struct pipe_context *pipe, int index_bias,
- uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_arrays_instanced(struct pipe_context *pipe,
- uint mode, uint start, uint count,
- uint start_instance,
- uint instance_count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.start_instance = start_instance;
- info.instance_count = instance_count;
- info.min_index = start;
- info.max_index = start + count - 1;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_elements_instanced(struct pipe_context *pipe,
- int index_bias,
- uint mode, uint start, uint count,
- uint start_instance,
- uint instance_count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
- info.start_instance = start_instance;
- info.instance_count = instance_count;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-static INLINE void
-util_draw_range_elements(struct pipe_context *pipe,
- int index_bias,
- uint min_index,
- uint max_index,
- uint mode, uint start, uint count)
-{
- struct pipe_draw_info info;
-
- util_draw_init_info(&info);
- info.indexed = TRUE;
- info.mode = mode;
- info.start = start;
- info.count = count;
- info.index_bias = index_bias;
- info.min_index = min_index;
- info.max_index = max_index;
-
- pipe->draw_vbo(pipe, &info);
-}
-
-
-unsigned
-util_draw_max_index(
- const struct pipe_vertex_buffer *vertex_buffers,
- unsigned nr_vertex_buffers,
- const struct pipe_vertex_element *vertex_elements,
- unsigned nr_vertex_elements,
- const struct pipe_draw_info *info);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !U_DRAW_H */
+/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef U_DRAW_H +#define U_DRAW_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +static INLINE void +util_draw_init_info(struct pipe_draw_info *info) +{ + memset(info, 0, sizeof(*info)); + info->instance_count = 1; + info->max_index = 0xffffffff; +} + + +static INLINE void +util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements(struct pipe_context *pipe, int index_bias, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_arrays_instanced(struct pipe_context *pipe, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.start_instance = start_instance; + info.instance_count = instance_count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements_instanced(struct pipe_context *pipe, + int index_bias, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.start_instance = start_instance; + info.instance_count = instance_count; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_range_elements(struct pipe_context *pipe, + int index_bias, + uint min_index, + uint max_index, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.min_index = min_index; + info.max_index = max_index; + + pipe->draw_vbo(pipe, &info); +} + + +unsigned +util_draw_max_index( + const struct pipe_vertex_buffer *vertex_buffers, + const struct pipe_vertex_element *vertex_elements, + unsigned nr_vertex_elements, + const struct pipe_draw_info *info); + + +#ifdef __cplusplus +} +#endif + +#endif /* !U_DRAW_H */ diff --git a/mesalib/src/gallium/auxiliary/util/u_draw_quad.c b/mesalib/src/gallium/auxiliary/util/u_draw_quad.c index 590fa0c36..469c87498 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw_quad.c +++ b/mesalib/src/gallium/auxiliary/util/u_draw_quad.c @@ -69,6 +69,27 @@ util_draw_vertex_buffer(struct pipe_context *pipe, } +/** + * Draw a simple vertex buffer / primitive. + * Limited to float[4] vertex attribs, tightly packed. + */ +void +util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer, + uint prim_type, uint num_verts, uint num_attribs) +{ + struct pipe_vertex_buffer vbuffer = {0}; + + assert(num_attribs <= PIPE_MAX_ATTRIBS); + + vbuffer.user_buffer = buffer; + vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */ + + /* note: vertex elements already set by caller */ + + cso_set_vertex_buffers(cso, 1, &vbuffer); + cso_draw_arrays(cso, prim_type, 0, num_verts); +} + /** * Draw screen-aligned textured quad. @@ -118,10 +139,11 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, v[28] = 0.0; v[29] = 1.0; - vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes, - PIPE_BIND_VERTEX_BUFFER); + vbuf = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, + PIPE_USAGE_STAGING, vertexBytes); if (!vbuf) goto out; + pipe_buffer_write(pipe, vbuf, 0, vertexBytes, v); util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2); diff --git a/mesalib/src/gallium/auxiliary/util/u_draw_quad.h b/mesalib/src/gallium/auxiliary/util/u_draw_quad.h index 997bbf060..2834a4a81 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw_quad.h +++ b/mesalib/src/gallium/auxiliary/util/u_draw_quad.h @@ -1,61 +1,64 @@ -/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-#ifndef U_DRAWQUAD_H
-#define U_DRAWQUAD_H
-
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_context.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct pipe_resource;
-struct cso_context;
-
-#include "util/u_draw.h"
-
-extern void
-util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
- struct pipe_resource *vbuf, uint offset,
- uint num_attribs, uint num_verts, uint prim_type);
-
-
-extern void
-util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
- float x0, float y0, float x1, float y1, float z);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
+/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef U_DRAWQUAD_H +#define U_DRAWQUAD_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_resource; +struct cso_context; + +#include "util/u_draw.h" + +extern void +util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso, + struct pipe_resource *vbuf, uint offset, + uint num_attribs, uint num_verts, uint prim_type); + +void +util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer, + uint prim_type, uint num_verts, uint num_attribs); + +extern void +util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, + float x0, float y0, float x1, float y1, float z); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_index_modify.c b/mesalib/src/gallium/auxiliary/util/u_index_modify.c index 38e9b3700..5e3fd463e 100644 --- a/mesalib/src/gallium/auxiliary/util/u_index_modify.c +++ b/mesalib/src/gallium/auxiliary/util/u_index_modify.c @@ -1,182 +1,203 @@ -/*
- * Copyright 2010 Marek Olšák <maraeo@gmail.com>
- *
- * 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
- * on 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 AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "pipe/p_context.h"
-#include "util/u_index_modify.h"
-#include "util/u_inlines.h"
-
-/* Ubyte indices. */
-
-void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start,
- unsigned count,
- void *out)
-{
- struct pipe_transfer *src_transfer;
- unsigned char *in_map;
- unsigned short *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &src_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned short)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, src_transfer);
-}
-
-void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start,
- unsigned count)
-{
- struct pipe_resource* new_elts;
- unsigned short *out_map;
- struct pipe_transfer *dst_transfer;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
- &dst_transfer);
- util_shorten_ubyte_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, dst_transfer);
-
- *elts = new_elts;
-}
-
-
-/* Ushort indices. */
-
-void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out)
-{
- struct pipe_transfer *in_transfer = NULL;
- unsigned short *in_map;
- unsigned short *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned short)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, in_transfer);
-}
-
-void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count)
-{
- struct pipe_transfer *out_transfer = NULL;
- struct pipe_resource *new_elts;
- unsigned short *out_map;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts,
- PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_ushort_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, out_transfer);
-
- *elts = new_elts;
-}
-
-
-/* Uint indices. */
-
-void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out)
-{
- struct pipe_transfer *in_transfer = NULL;
- unsigned int *in_map;
- unsigned int *out_map = out;
- unsigned i;
-
- in_map = pipe_buffer_map(context, elts,
- PIPE_TRANSFER_READ |
- PIPE_TRANSFER_UNSYNCHRONIZED,
- &in_transfer);
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned int)(*in_map + index_bias);
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, in_transfer);
-}
-
-void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count)
-{
- struct pipe_transfer *out_transfer = NULL;
- struct pipe_resource *new_elts;
- unsigned int *out_map;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- PIPE_USAGE_STATIC,
- 2 * count);
-
- out_map = pipe_buffer_map(context, new_elts,
- PIPE_TRANSFER_WRITE, &out_transfer);
- util_rebuild_uint_elts_to_userptr(context, *elts, index_bias,
- start, count, out_map);
- pipe_buffer_unmap(context, out_transfer);
-
- *elts = new_elts;
-}
+/* + * Copyright 2010 Marek Olšák <maraeo@gmail.com> + * + * 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 + * on 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 AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "pipe/p_context.h" +#include "util/u_index_modify.h" +#include "util/u_inlines.h" + +/* Ubyte indices. */ + +void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, + unsigned count, + void *out) +{ + struct pipe_transfer *src_transfer = NULL; + const unsigned char *in_map; + unsigned short *out_map = out; + unsigned i; + + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &src_transfer); + } + in_map += start; + + for (i = 0; i < count; i++) { + *out_map = (unsigned short)(*in_map + index_bias); + in_map++; + out_map++; + } + + if (src_transfer) + pipe_buffer_unmap(context, src_transfer); +} + +void util_shorten_ubyte_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, + unsigned count) +{ + struct pipe_resource* new_elts; + unsigned short *out_map; + struct pipe_transfer *dst_transfer; + + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + PIPE_USAGE_STATIC, + 2 * count); + + out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, + &dst_transfer); + util_shorten_ubyte_elts_to_userptr(context, ib, index_bias, + start, count, out_map); + pipe_buffer_unmap(context, dst_transfer); + + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; +} + + +/* Ushort indices. */ + +void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, unsigned count, + void *out) +{ + struct pipe_transfer *in_transfer = NULL; + const unsigned short *in_map; + unsigned short *out_map = out; + unsigned i; + + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &in_transfer); + } + in_map += start; + + for (i = 0; i < count; i++) { + *out_map = (unsigned short)(*in_map + index_bias); + in_map++; + out_map++; + } + + if (in_transfer) + pipe_buffer_unmap(context, in_transfer); +} + +void util_rebuild_ushort_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, unsigned count) +{ + struct pipe_transfer *out_transfer = NULL; + struct pipe_resource *new_elts; + unsigned short *out_map; + + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + PIPE_USAGE_STATIC, + 2 * count); + + out_map = pipe_buffer_map(context, new_elts, + PIPE_TRANSFER_WRITE, &out_transfer); + util_rebuild_ushort_elts_to_userptr(context, ib, index_bias, + start, count, out_map); + pipe_buffer_unmap(context, out_transfer); + + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; +} + + +/* Uint indices. */ + +void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, unsigned count, + void *out) +{ + struct pipe_transfer *in_transfer = NULL; + const unsigned int *in_map; + unsigned int *out_map = out; + unsigned i; + + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &in_transfer); + } + in_map += start; + + for (i = 0; i < count; i++) { + *out_map = (unsigned int)(*in_map + index_bias); + in_map++; + out_map++; + } + + if (in_transfer) + pipe_buffer_unmap(context, in_transfer); +} + +void util_rebuild_uint_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, unsigned count) +{ + struct pipe_transfer *out_transfer = NULL; + struct pipe_resource *new_elts; + unsigned int *out_map; + + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + PIPE_USAGE_STATIC, + 2 * count); + + out_map = pipe_buffer_map(context, new_elts, + PIPE_TRANSFER_WRITE, &out_transfer); + util_rebuild_uint_elts_to_userptr(context, ib, index_bias, + start, count, out_map); + pipe_buffer_unmap(context, out_transfer); + + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; +} diff --git a/mesalib/src/gallium/auxiliary/util/u_index_modify.h b/mesalib/src/gallium/auxiliary/util/u_index_modify.h index 3e5520b18..6afce50b9 100644 --- a/mesalib/src/gallium/auxiliary/util/u_index_modify.h +++ b/mesalib/src/gallium/auxiliary/util/u_index_modify.h @@ -1,68 +1,72 @@ -/*
- * Copyright 2010 Marek Olšák <maraeo@gmail.com>
- *
- * 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
- * on 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 AUTHOR(S) AND/OR THEIR 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 UTIL_INDEX_MODIFY_H
-#define UTIL_INDEX_MODIFY_H
-
-struct pipe_context;
-struct pipe_resource;
-
-void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start,
- unsigned count,
- void *out);
-
-void util_shorten_ubyte_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start,
- unsigned count);
-
-
-
-void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out);
-
-void util_rebuild_ushort_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count);
-
-
-
-void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
- struct pipe_resource *elts,
- int index_bias,
- unsigned start, unsigned count,
- void *out);
-
-void util_rebuild_uint_elts(struct pipe_context *context,
- struct pipe_resource **elts,
- int index_bias,
- unsigned start, unsigned count);
-
-#endif
+/* + * Copyright 2010 Marek Olšák <maraeo@gmail.com> + * + * 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 + * on 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 AUTHOR(S) AND/OR THEIR 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 UTIL_INDEX_MODIFY_H +#define UTIL_INDEX_MODIFY_H + +struct pipe_context; +struct pipe_resource; +struct pipe_index_buffer; + +void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, + unsigned count, + void *out); + +void util_shorten_ubyte_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, + unsigned count); + + + +void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, unsigned count, + void *out); + +void util_rebuild_ushort_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, unsigned count); + + + +void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, + struct pipe_index_buffer *ib, + int index_bias, + unsigned start, unsigned count, + void *out); + +void util_rebuild_uint_elts(struct pipe_context *context, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, + int index_bias, + unsigned start, unsigned count); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index 49b4531db..2ec153c58 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -233,14 +233,6 @@ pipe_buffer_create( struct pipe_screen *screen, return screen->resource_create(screen, &buffer); } - -static INLINE struct pipe_resource * -pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size, - unsigned usage ) -{ - return screen->user_buffer_create(screen, ptr, size, usage); -} - static INLINE void * pipe_buffer_map_range(struct pipe_context *pipe, struct pipe_resource *buffer, @@ -376,6 +368,19 @@ pipe_buffer_write_nooverlap(struct pipe_context *pipe, 0, 0); } +static INLINE struct pipe_resource * +pipe_buffer_create_with_data(struct pipe_context *pipe, + unsigned bind, + unsigned usage, + unsigned size, + void *ptr) +{ + struct pipe_resource *res = pipe_buffer_create(pipe->screen, + bind, usage, size); + pipe_buffer_write_nooverlap(pipe, res, 0, size, ptr); + return res; +} + static INLINE void pipe_buffer_read(struct pipe_context *pipe, struct pipe_resource *buf, @@ -437,6 +442,22 @@ pipe_transfer_destroy( struct pipe_context *context, context->transfer_destroy(context, transfer); } +static INLINE void +pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + struct pipe_resource *buf) +{ + if (buf) { + struct pipe_constant_buffer cb; + cb.buffer = buf; + cb.buffer_offset = 0; + cb.buffer_size = buf->width0; + cb.user_buffer = NULL; + pipe->set_constant_buffer(pipe, shader, index, &cb); + } else { + pipe->set_constant_buffer(pipe, shader, index, NULL); + } +} + static INLINE boolean util_get_offset( const struct pipe_rasterizer_state *templ, diff --git a/mesalib/src/gallium/auxiliary/util/u_pstipple.c b/mesalib/src/gallium/auxiliary/util/u_pstipple.c index ac0df8c1a..3a91b1da1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_pstipple.c +++ b/mesalib/src/gallium/auxiliary/util/u_pstipple.c @@ -298,12 +298,13 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, /* declare new position input reg */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_POSITION; decl.Semantic.Index = 0; decl.Range.First = decl.Range.Last = wincoordInput; + decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; ctx->emit_declaration(ctx, &decl); } diff --git a/mesalib/src/gallium/auxiliary/util/u_slab.h b/mesalib/src/gallium/auxiliary/util/u_slab.h index f49dca27d..3ed8b12d3 100644 --- a/mesalib/src/gallium/auxiliary/util/u_slab.h +++ b/mesalib/src/gallium/auxiliary/util/u_slab.h @@ -1,87 +1,87 @@ -/*
- * Copyright 2010 Marek Olšák <maraeo@gmail.com>
- *
- * 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
- * on 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 AUTHOR(S) AND/OR THEIR 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. */
-
-/**
- * @file
- * Simple slab allocator for equally sized memory allocations.
- * util_slab_alloc and util_slab_free have time complexity in O(1).
- *
- * Good for allocations which have very low lifetime and are allocated
- * and freed very often. Use a profiler first to know if it's worth using it!
- *
- * Candidates: get_transfer, user_buffer_create
- *
- * @author Marek Olšák
- */
-
-#ifndef U_SLAB_H
-#define U_SLAB_H
-
-#include "os/os_thread.h"
-
-enum util_slab_threading {
- UTIL_SLAB_SINGLETHREADED = FALSE,
- UTIL_SLAB_MULTITHREADED = TRUE
-};
-
-/* The page is an array of blocks (allocations). */
-struct util_slab_page {
- /* The header (linked-list pointers). */
- struct util_slab_page *prev, *next;
-
- /* Memory after the last member is dedicated to the page itself.
- * The allocated size is always larger than this structure. */
-};
-
-struct util_slab_mempool {
- /* Public members. */
- void *(*alloc)(struct util_slab_mempool *pool);
- void (*free)(struct util_slab_mempool *pool, void *ptr);
-
- /* Private members. */
- struct util_slab_block *first_free;
-
- struct util_slab_page list;
-
- unsigned block_size;
- unsigned page_size;
- unsigned num_blocks;
- unsigned num_pages;
- enum util_slab_threading threading;
-
- pipe_mutex mutex;
-};
-
-void util_slab_create(struct util_slab_mempool *pool,
- unsigned item_size,
- unsigned num_blocks,
- enum util_slab_threading threading);
-
-void util_slab_destroy(struct util_slab_mempool *pool);
-
-void util_slab_set_thread_safety(struct util_slab_mempool *pool,
- enum util_slab_threading threading);
-
-#define util_slab_alloc(pool) (pool)->alloc(pool)
-#define util_slab_free(pool, ptr) (pool)->free(pool, ptr)
-
-#endif
+/* + * Copyright 2010 Marek Olšák <maraeo@gmail.com> + * + * 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 + * on 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 AUTHOR(S) AND/OR THEIR 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. */ + +/** + * @file + * Simple slab allocator for equally sized memory allocations. + * util_slab_alloc and util_slab_free have time complexity in O(1). + * + * Good for allocations which have very low lifetime and are allocated + * and freed very often. Use a profiler first to know if it's worth using it! + * + * Candidates: get_transfer + * + * @author Marek Olšák + */ + +#ifndef U_SLAB_H +#define U_SLAB_H + +#include "os/os_thread.h" + +enum util_slab_threading { + UTIL_SLAB_SINGLETHREADED = FALSE, + UTIL_SLAB_MULTITHREADED = TRUE +}; + +/* The page is an array of blocks (allocations). */ +struct util_slab_page { + /* The header (linked-list pointers). */ + struct util_slab_page *prev, *next; + + /* Memory after the last member is dedicated to the page itself. + * The allocated size is always larger than this structure. */ +}; + +struct util_slab_mempool { + /* Public members. */ + void *(*alloc)(struct util_slab_mempool *pool); + void (*free)(struct util_slab_mempool *pool, void *ptr); + + /* Private members. */ + struct util_slab_block *first_free; + + struct util_slab_page list; + + unsigned block_size; + unsigned page_size; + unsigned num_blocks; + unsigned num_pages; + enum util_slab_threading threading; + + pipe_mutex mutex; +}; + +void util_slab_create(struct util_slab_mempool *pool, + unsigned item_size, + unsigned num_blocks, + enum util_slab_threading threading); + +void util_slab_destroy(struct util_slab_mempool *pool); + +void util_slab_set_thread_safety(struct util_slab_mempool *pool, + enum util_slab_threading threading); + +#define util_slab_alloc(pool) (pool)->alloc(pool) +#define util_slab_free(pool, ptr) (pool)->free(pool, ptr) + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_string.h b/mesalib/src/gallium/auxiliary/util/u_string.h index 52e380698..ed15981f1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_string.h +++ b/mesalib/src/gallium/auxiliary/util/u_string.h @@ -1,220 +1,232 @@ -/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-/**
- * @file
- * Platform independent functions for string manipulation.
- *
- * @author Jose Fonseca <jrfonseca@tungstengraphics.com>
- */
-
-#ifndef U_STRING_H_
-#define U_STRING_H_
-
-#if !defined(WIN32) && !defined(XF86_LIBC_H)
-#include <stdio.h>
-#endif
-#include <stddef.h>
-#include <stdarg.h>
-
-#include "pipe/p_compiler.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef WIN32
-
-int util_vsnprintf(char *, size_t, const char *, va_list);
-int util_snprintf(char *str, size_t size, const char *format, ...);
-
-static INLINE void
-util_vsprintf(char *str, const char *format, va_list ap)
-{
- util_vsnprintf(str, (size_t)-1, format, ap);
-}
-
-static INLINE void
-util_sprintf(char *str, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- util_vsnprintf(str, (size_t)-1, format, ap);
- va_end(ap);
-}
-
-static INLINE char *
-util_strchr(const char *s, char c)
-{
- while(*s) {
- if(*s == c)
- return (char *)s;
- ++s;
- }
- return NULL;
-}
-
-static INLINE char*
-util_strncat(char *dst, const char *src, size_t n)
-{
- char *p = dst + strlen(dst);
- const char *q = src;
- size_t i;
-
- for (i = 0; i < n && *q != '\0'; ++i)
- *p++ = *q++;
- *p = '\0';
-
- return dst;
-}
-
-static INLINE int
-util_strcmp(const char *s1, const char *s2)
-{
- unsigned char u1, u2;
-
- while (1) {
- u1 = (unsigned char) *s1++;
- u2 = (unsigned char) *s2++;
- if (u1 != u2)
- return u1 - u2;
- if (u1 == '\0')
- return 0;
- }
- return 0;
-}
-
-static INLINE int
-util_strncmp(const char *s1, const char *s2, size_t n)
-{
- unsigned char u1, u2;
-
- while (n-- > 0) {
- u1 = (unsigned char) *s1++;
- u2 = (unsigned char) *s2++;
- if (u1 != u2)
- return u1 - u2;
- if (u1 == '\0')
- return 0;
- }
- return 0;
-}
-
-static INLINE char *
-util_strstr(const char *haystack, const char *needle)
-{
- const char *p = haystack;
- size_t len = strlen(needle);
-
- for (; (p = util_strchr(p, *needle)) != 0; p++) {
- if (util_strncmp(p, needle, len) == 0) {
- return (char *)p;
- }
- }
- return NULL;
-}
-
-static INLINE void *
-util_memmove(void *dest, const void *src, size_t n)
-{
- char *p = (char *)dest;
- const char *q = (const char *)src;
- if (dest < src) {
- while (n--)
- *p++ = *q++;
- }
- else
- {
- p += n;
- q += n;
- while (n--)
- *--p = *--q;
- }
- return dest;
-}
-
-
-#else
-
-#define util_vsnprintf vsnprintf
-#define util_snprintf snprintf
-#define util_vsprintf vsprintf
-#define util_sprintf sprintf
-#define util_strchr strchr
-#define util_strcmp strcmp
-#define util_strncmp strncmp
-#define util_strncat strncat
-#define util_strstr strstr
-#define util_memmove memmove
-
-#endif
-
-
-/**
- * Printable string buffer
- */
-struct util_strbuf
-{
- char *str;
- char *ptr;
- size_t left;
-};
-
-
-static INLINE void
-util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size)
-{
- sbuf->str = str;
- sbuf->str[0] = 0;
- sbuf->ptr = sbuf->str;
- sbuf->left = size;
-}
-
-
-static INLINE void
-util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...)
-{
- if(sbuf->left > 1) {
- size_t written;
- va_list ap;
- va_start(ap, format);
- written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap);
- va_end(ap);
- sbuf->ptr += written;
- sbuf->left -= written;
- }
-}
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* U_STRING_H_ */
+/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * @file + * Platform independent functions for string manipulation. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + +#ifndef U_STRING_H_ +#define U_STRING_H_ + +#if !defined(WIN32) && !defined(XF86_LIBC_H) +#include <stdio.h> +#endif +#include <stddef.h> +#include <stdarg.h> + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _GNU_SOURCE + +#define util_strchrnul strchrnul + +#else + +static INLINE char * +util_strchrnul(const char *s, char c) +{ + for (; *s && *s != c; ++s); + + return (char *)s; +} + +#endif + +#ifdef WIN32 + +int util_vsnprintf(char *, size_t, const char *, va_list); +int util_snprintf(char *str, size_t size, const char *format, ...); + +static INLINE void +util_vsprintf(char *str, const char *format, va_list ap) +{ + util_vsnprintf(str, (size_t)-1, format, ap); +} + +static INLINE void +util_sprintf(char *str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + util_vsnprintf(str, (size_t)-1, format, ap); + va_end(ap); +} + +static INLINE char * +util_strchr(const char *s, char c) +{ + char *p = util_strchrnul(s, c); + + return *p ? p : NULL; +} + +static INLINE char* +util_strncat(char *dst, const char *src, size_t n) +{ + char *p = dst + strlen(dst); + const char *q = src; + size_t i; + + for (i = 0; i < n && *q != '\0'; ++i) + *p++ = *q++; + *p = '\0'; + + return dst; +} + +static INLINE int +util_strcmp(const char *s1, const char *s2) +{ + unsigned char u1, u2; + + while (1) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE int +util_strncmp(const char *s1, const char *s2, size_t n) +{ + unsigned char u1, u2; + + while (n-- > 0) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE char * +util_strstr(const char *haystack, const char *needle) +{ + const char *p = haystack; + size_t len = strlen(needle); + + for (; (p = util_strchr(p, *needle)) != 0; p++) { + if (util_strncmp(p, needle, len) == 0) { + return (char *)p; + } + } + return NULL; +} + +static INLINE void * +util_memmove(void *dest, const void *src, size_t n) +{ + char *p = (char *)dest; + const char *q = (const char *)src; + if (dest < src) { + while (n--) + *p++ = *q++; + } + else + { + p += n; + q += n; + while (n--) + *--p = *--q; + } + return dest; +} + + +#else + +#define util_vsnprintf vsnprintf +#define util_snprintf snprintf +#define util_vsprintf vsprintf +#define util_sprintf sprintf +#define util_strchr strchr +#define util_strcmp strcmp +#define util_strncmp strncmp +#define util_strncat strncat +#define util_strstr strstr +#define util_memmove memmove + +#endif + + +/** + * Printable string buffer + */ +struct util_strbuf +{ + char *str; + char *ptr; + size_t left; +}; + + +static INLINE void +util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size) +{ + sbuf->str = str; + sbuf->str[0] = 0; + sbuf->ptr = sbuf->str; + sbuf->left = size; +} + + +static INLINE void +util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...) +{ + if(sbuf->left > 1) { + size_t written; + va_list ap; + va_start(ap, format); + written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap); + va_end(ap); + sbuf->ptr += written; + sbuf->left -= written; + } +} + + + +#ifdef __cplusplus +} +#endif + +#endif /* U_STRING_H_ */ diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.c b/mesalib/src/gallium/auxiliary/util/u_transfer.c index 673a984fc..0b2679ffd 100644 --- a/mesalib/src/gallium/auxiliary/util/u_transfer.c +++ b/mesalib/src/gallium/auxiliary/util/u_transfer.c @@ -125,11 +125,3 @@ void u_default_transfer_destroy(struct pipe_context *pipe, { FREE(transfer); } - -void u_default_redefine_user_buffer(struct pipe_context *ctx, - struct pipe_resource *resource, - unsigned offset, - unsigned size) -{ - resource->width0 = MAX2(resource->width0, offset + size); -} diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.h b/mesalib/src/gallium/auxiliary/util/u_transfer.h index 79e2d13a4..f4fdf9a48 100644 --- a/mesalib/src/gallium/auxiliary/util/u_transfer.h +++ b/mesalib/src/gallium/auxiliary/util/u_transfer.h @@ -1,132 +1,127 @@ -
-#ifndef U_TRANSFER_H
-#define U_TRANSFER_H
-
-/* Fallback implementations for inline read/writes which just go back
- * to the regular transfer behaviour.
- */
-#include "pipe/p_state.h"
-
-struct pipe_context;
-struct winsys_handle;
-
-boolean u_default_resource_get_handle(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle);
-
-void u_default_transfer_inline_write( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-
-void u_default_transfer_flush_region( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box);
-
-struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box);
-
-void u_default_transfer_unmap( struct pipe_context *pipe,
- struct pipe_transfer *transfer );
-
-void u_default_transfer_destroy(struct pipe_context *pipe,
- struct pipe_transfer *transfer);
-
-
-
-/* Useful helper to allow >1 implementation of resource functionality
- * to exist in a single driver. This is intended to be transitionary!
- */
-struct u_resource_vtbl {
-
- boolean (*resource_get_handle)(struct pipe_screen *,
- struct pipe_resource *tex,
- struct winsys_handle *handle);
-
- void (*resource_destroy)(struct pipe_screen *,
- struct pipe_resource *pt);
-
- struct pipe_transfer *(*get_transfer)(struct pipe_context *,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *);
-
- void (*transfer_destroy)(struct pipe_context *,
- struct pipe_transfer *);
-
- void *(*transfer_map)( struct pipe_context *,
- struct pipe_transfer *transfer );
-
- void (*transfer_flush_region)( struct pipe_context *,
- struct pipe_transfer *transfer,
- const struct pipe_box *);
-
- void (*transfer_unmap)( struct pipe_context *,
- struct pipe_transfer *transfer );
-
- void (*transfer_inline_write)( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-};
-
-
-struct u_resource {
- struct pipe_resource b;
- const struct u_resource_vtbl *vtbl;
-};
-
-
-boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle);
-
-void u_resource_destroy_vtbl(struct pipe_screen *screen,
- struct pipe_resource *resource);
-
-struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box);
-
-void u_transfer_destroy_vtbl(struct pipe_context *pipe,
- struct pipe_transfer *transfer);
-
-void *u_transfer_map_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer );
-
-void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box);
-
-void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx,
- struct pipe_transfer *transfer );
-
-void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride);
-
-void u_default_redefine_user_buffer(struct pipe_context *ctx,
- struct pipe_resource *resource,
- unsigned offset,
- unsigned size);
-
-#endif
+ +#ifndef U_TRANSFER_H +#define U_TRANSFER_H + +/* Fallback implementations for inline read/writes which just go back + * to the regular transfer behaviour. + */ +#include "pipe/p_state.h" + +struct pipe_context; +struct winsys_handle; + +boolean u_default_resource_get_handle(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle); + +void u_default_transfer_inline_write( struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride); + +void u_default_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box); + +struct pipe_transfer * u_default_get_transfer(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box); + +void u_default_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ); + +void u_default_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer); + + + +/* Useful helper to allow >1 implementation of resource functionality + * to exist in a single driver. This is intended to be transitionary! + */ +struct u_resource_vtbl { + + boolean (*resource_get_handle)(struct pipe_screen *, + struct pipe_resource *tex, + struct winsys_handle *handle); + + void (*resource_destroy)(struct pipe_screen *, + struct pipe_resource *pt); + + struct pipe_transfer *(*get_transfer)(struct pipe_context *, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *); + + void (*transfer_destroy)(struct pipe_context *, + struct pipe_transfer *); + + void *(*transfer_map)( struct pipe_context *, + struct pipe_transfer *transfer ); + + void (*transfer_flush_region)( struct pipe_context *, + struct pipe_transfer *transfer, + const struct pipe_box *); + + void (*transfer_unmap)( struct pipe_context *, + struct pipe_transfer *transfer ); + + void (*transfer_inline_write)( struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride); +}; + + +struct u_resource { + struct pipe_resource b; + const struct u_resource_vtbl *vtbl; +}; + + +boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle); + +void u_resource_destroy_vtbl(struct pipe_screen *screen, + struct pipe_resource *resource); + +struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box); + +void u_transfer_destroy_vtbl(struct pipe_context *pipe, + struct pipe_transfer *transfer); + +void *u_transfer_map_vtbl( struct pipe_context *pipe, + struct pipe_transfer *transfer ); + +void u_transfer_flush_region_vtbl( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box); + +void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx, + struct pipe_transfer *transfer ); + +void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c index 401c8a4a8..4141ba536 100644 --- a/mesalib/src/gallium/auxiliary/util/u_vbuf.c +++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c @@ -277,8 +277,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, unsigned offset = vb->buffer_offset + vb->stride * start_vertex; uint8_t *map; - if (vb->buffer->user_ptr) { - map = vb->buffer->user_ptr + offset; + if (vb->user_buffer) { + map = (uint8_t*)vb->user_buffer + offset; } else { unsigned size = vb->stride ? num_vertices * vb->stride : sizeof(double)*4; @@ -307,10 +307,10 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, unsigned offset = ib->offset + start_index * ib->index_size; uint8_t *map; - assert(ib->buffer && ib->index_size); + assert((ib->buffer || ib->user_buffer) && ib->index_size); - if (ib->buffer->user_ptr) { - map = ib->buffer->user_ptr + offset; + if (ib->user_buffer) { + map = (uint8_t*)ib->user_buffer + offset; } else { map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset, num_indices * ib->index_size, @@ -713,15 +713,17 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i]; pipe_resource_reference(&orig_vb->buffer, vb->buffer); + orig_vb->user_buffer = vb->user_buffer; real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset; real_vb->stride = orig_vb->stride = vb->stride; + real_vb->user_buffer = NULL; if (vb->stride) { mgr->nonzero_stride_vb_mask |= 1 << i; } - if (!vb->buffer) { + if (!vb->buffer && !vb->user_buffer) { pipe_resource_reference(&real_vb->buffer, NULL); continue; } @@ -733,13 +735,14 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, continue; } - if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) { + if (!mgr->caps.user_vertex_buffers && vb->user_buffer) { mgr->user_vb_mask |= 1 << i; pipe_resource_reference(&real_vb->buffer, NULL); continue; } pipe_resource_reference(&real_vb->buffer, vb->buffer); + real_vb->user_buffer = vb->user_buffer; } for (i = count; i < mgr->nr_vertex_buffers; i++) { @@ -759,11 +762,10 @@ void u_vbuf_set_index_buffer(struct u_vbuf *mgr, { struct pipe_context *pipe = mgr->pipe; - if (ib && ib->buffer) { + if (ib) { assert(ib->offset % ib->index_size == 0); pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); - mgr->index_buffer.offset = ib->offset; - mgr->index_buffer.index_size = ib->index_size; + memcpy(&mgr->index_buffer, ib, sizeof(*ib)); } else { pipe_resource_reference(&mgr->index_buffer.buffer, NULL); } @@ -798,9 +800,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, continue; } - assert(vb->buffer); - - if (!vb->buffer->user_ptr) { + if (!vb->user_buffer) { continue; } @@ -837,7 +837,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, for (i = 0; i < nr_vbufs; i++) { unsigned start, end = end_offset[i]; struct pipe_vertex_buffer *real_vb; - uint8_t *ptr; + const uint8_t *ptr; if (!end) { continue; @@ -847,7 +847,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, assert(start < end); real_vb = &mgr->real_vertex_buffer[i]; - ptr = mgr->vertex_buffer[i].buffer->user_ptr; + ptr = mgr->vertex_buffer[i].user_buffer; u_upload_data(mgr->uploader, start, end - start, ptr + start, &real_vb->buffer_offset, &real_vb->buffer); @@ -888,8 +888,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, unsigned i; unsigned restart_index = info->restart_index; - if (ib->buffer->user_ptr) { - indices = ib->buffer->user_ptr + + if (ib->user_buffer) { + indices = (uint8_t*)ib->user_buffer + ib->offset + info->start * ib->index_size; } else { indices = pipe_buffer_map_range(pipe, ib->buffer, diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index 5621e42b2..fba03604c 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -51,6 +51,7 @@ LIBGLSL_CXX_FILES := \ loop_unroll.cpp \ lower_clip_distance.cpp \ lower_discard.cpp \ + lower_discard_flow.cpp \ lower_if_to_cond_assign.cpp \ lower_instructions.cpp \ lower_jumps.cpp \ @@ -72,7 +73,6 @@ LIBGLSL_CXX_FILES := \ opt_dead_code.cpp \ opt_dead_code_local.cpp \ opt_dead_functions.cpp \ - opt_discard_simplification.cpp \ opt_function_inlining.cpp \ opt_if_simplification.cpp \ opt_noop_swizzle.cpp \ diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 6f1c86b43..46f21dd07 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -1044,7 +1044,6 @@ do_common_optimization(exec_list *ir, bool linked, progress = do_structure_splitting(ir) || progress; } progress = do_if_simplification(ir) || progress; - progress = do_discard_simplification(ir) || progress; progress = do_copy_propagation(ir) || progress; progress = do_copy_propagation_elements(ir) || progress; if (linked) diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 356783583..c435d7717 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -66,6 +66,7 @@ bool do_tree_grafting(exec_list *instructions); bool do_vec_index_to_cond_assign(exec_list *instructions); bool do_vec_index_to_swizzle(exec_list *instructions); bool lower_discard(exec_list *instructions); +void lower_discard_flow(exec_list *instructions); bool lower_instructions(exec_list *instructions, unsigned what_to_lower); bool lower_noise(exec_list *instructions); bool lower_variable_index_to_cond_assign(exec_list *instructions, diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 6ba297237..bdab499f0 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -2296,6 +2296,17 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) prog->LinkStatus = true; } + /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do + * it before optimization because we want most of the checks to get + * dropped thanks to constant propagation. + */ + if (max_version >= 130) { + struct gl_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; + if (sh) { + lower_discard_flow(sh->ir); + } + } + /* Do common optimization before assigning storage for attributes, * uniforms, and varyings. Later optimization could possibly make * some of that unused. diff --git a/mesalib/src/glsl/lower_discard_flow.cpp b/mesalib/src/glsl/lower_discard_flow.cpp new file mode 100644 index 000000000..d385c1435 --- /dev/null +++ b/mesalib/src/glsl/lower_discard_flow.cpp @@ -0,0 +1,144 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/** @file lower_discard_flow.cpp + * + * Implements the GLSL 1.30 revision 9 rule for fragment shader + * discard handling: + * + * "Control flow exits the shader, and subsequent implicit or + * explicit derivatives are undefined when this control flow is + * non-uniform (meaning different fragments within the primitive + * take different control paths)." + * + * There seem to be two conflicting things here. "Control flow exits + * the shader" sounds like the discarded fragments should effectively + * jump to the end of the shader, but that breaks derivatives in the + * case of uniform control flow and causes rendering failure in the + * bushes in Unigine Tropics. + * + * The question, then, is whether the intent was "loops stop at the + * point that the only active channels left are discarded pixels" or + * "discarded pixels become inactive at the point that control flow + * returns to the top of a loop". This implements the second + * interpretation. + */ + +#include "glsl_types.h" +#include "ir.h" +#include "program/hash_table.h" + +class lower_discard_flow_visitor : public ir_hierarchical_visitor { +public: + lower_discard_flow_visitor(ir_variable *discarded) + : discarded(discarded) + { + mem_ctx = ralloc_parent(discarded); + } + + ~lower_discard_flow_visitor() + { + } + + ir_visitor_status visit_enter(ir_discard *ir); + ir_visitor_status visit_enter(ir_loop_jump *ir); + ir_visitor_status visit_enter(ir_loop *ir); + ir_visitor_status visit_enter(ir_function_signature *ir); + + ir_if *generate_discard_break(); + + ir_variable *discarded; + void *mem_ctx; +}; + +ir_visitor_status +lower_discard_flow_visitor::visit_enter(ir_loop_jump *ir) +{ + if (ir->mode != ir_loop_jump::jump_continue) + return visit_continue; + + ir->insert_before(generate_discard_break()); + + return visit_continue; +} + +ir_visitor_status +lower_discard_flow_visitor::visit_enter(ir_discard *ir) +{ + ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded); + ir_rvalue *rhs = new(mem_ctx) ir_constant(true); + ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs); + ir->insert_before(assign); + + return visit_continue; +} + +ir_visitor_status +lower_discard_flow_visitor::visit_enter(ir_loop *ir) +{ + ir->body_instructions.push_tail(generate_discard_break()); + + return visit_continue; +} + +ir_visitor_status +lower_discard_flow_visitor::visit_enter(ir_function_signature *ir) +{ + if (strcmp(ir->function_name(), "main") != 0) + return visit_continue; + + ir_dereference *lhs = new(mem_ctx) ir_dereference_variable(discarded); + ir_rvalue *rhs = new(mem_ctx) ir_constant(false); + ir_assignment *assign = new(mem_ctx) ir_assignment(lhs, rhs); + ir->body.push_head(assign); + + return visit_continue; +} + +ir_if * +lower_discard_flow_visitor::generate_discard_break() +{ + ir_rvalue *if_condition = new(mem_ctx) ir_dereference_variable(discarded); + ir_if *if_inst = new(mem_ctx) ir_if(if_condition); + + ir_instruction *br = new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); + if_inst->then_instructions.push_tail(br); + + return if_inst; +} + +void +lower_discard_flow(exec_list *ir) +{ + void *mem_ctx = ir; + + ir_variable *var = new(mem_ctx) ir_variable(glsl_type::bool_type, + "discarded", + ir_var_temporary); + + ir->push_head(var); + + lower_discard_flow_visitor v(var); + + visit_list_elements(&v, ir); +} diff --git a/mesalib/src/glsl/opt_discard_simplification.cpp b/mesalib/src/glsl/opt_discard_simplification.cpp deleted file mode 100644 index ba4981bae..000000000 --- a/mesalib/src/glsl/opt_discard_simplification.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - */ - -/** - * \file opt_discard_simplification.cpp - * - * This pass simplifies if-statements and loops containing unconditional - * discards. - * - * Case 1: Both branches contain unconditional discards: - * ----------------------------------------------------- - * - * if (cond) { - * s1; - * discard; - * s2; - * } else { - * s3; - * discard; - * s4; - * } - * - * becomes: - * - * discard - * - * Case 2: The "then" clause contains an unconditional discard: - * ------------------------------------------------------------ - * - * if (cond) { - * s1; - * discard; - * s2; - * } else { - * s3; - * } - * - * becomes: - * - * if (cond) { - * discard; - * } else { - * s3; - * } - * - * Case 3: The "else" clause contains an unconditional discard: - * ------------------------------------------------------------ - * - * if (cond) { - * s1; - * } else { - * s2; - * discard; - * s3; - * } - * - * becomes: - * - * if (cond) { - * s1; - * } else { - * discard; - * } - */ - -#include "glsl_types.h" -#include "ir.h" - -class discard_simplifier : public ir_hierarchical_visitor { -public: - discard_simplifier() - { - this->progress = false; - } - - ir_visitor_status visit_enter(ir_if *); - ir_visitor_status visit_enter(ir_loop *); - ir_visitor_status visit_enter(ir_assignment *); - - bool progress; -}; - -static ir_discard * -find_unconditional_discard(exec_list &instructions) -{ - foreach_list(n, &instructions) { - ir_instruction *ir = (ir_instruction *)n; - - if (ir->ir_type == ir_type_return || - ir->ir_type == ir_type_loop_jump) - return NULL; - - /* So far, this code doesn't know how to look inside of flow - * control to see if a discard later on at this level is - * unconditional. - */ - if (ir->ir_type == ir_type_if || - ir->ir_type == ir_type_loop) - return NULL; - - ir_discard *discard = ir->as_discard(); - if (discard != NULL && discard->condition == NULL) - return discard; - } - return NULL; -} - -static bool -is_only_instruction(ir_discard *discard) -{ - return (discard->prev->is_head_sentinel() && - discard->next->is_tail_sentinel()); -} - -/* We only care about the top level instructions, so don't descend - * into expressions. - */ -ir_visitor_status -discard_simplifier::visit_enter(ir_assignment *ir) -{ - (void) ir; - return visit_continue_with_parent; -} - -ir_visitor_status -discard_simplifier::visit_enter(ir_if *ir) -{ - ir_discard *then_discard = find_unconditional_discard(ir->then_instructions); - ir_discard *else_discard = find_unconditional_discard(ir->else_instructions); - - if (then_discard == NULL && else_discard == NULL) - return visit_continue; - - /* If both branches result in discard, replace whole if with discard. */ - if (then_discard != NULL && else_discard != NULL) { - this->progress = true; - ir->replace_with(then_discard); - return visit_continue_with_parent; - } - - /* Otherwise, one branch has a discard. */ - if (then_discard != NULL && !is_only_instruction(then_discard)) { - this->progress = true; - ir->then_instructions.make_empty(); - ir->then_instructions.push_tail(then_discard); - } else if (else_discard != NULL && !is_only_instruction(else_discard)) { - this->progress = true; - ir->else_instructions.make_empty(); - ir->else_instructions.push_tail(else_discard); - } - - visit_list_elements(this, &ir->then_instructions); - return visit_continue_with_parent; -} - -ir_visitor_status -discard_simplifier::visit_enter(ir_loop *ir) -{ - ir_discard *discard = find_unconditional_discard(ir->body_instructions); - - if (discard) { - ir->replace_with(discard); - return visit_continue_with_parent; - } - - return visit_continue; -} - -bool -do_discard_simplification(exec_list *instructions) -{ - /* Look for a top-level unconditional discard */ - ir_discard *discard = find_unconditional_discard(*instructions); - if (discard != NULL) { - instructions->make_empty(); - instructions->push_tail(discard); - return true; - } - - discard_simplifier v; - - visit_list_elements(&v, instructions); - - return v.progress; -} diff --git a/mesalib/src/glsl/test_optpass.cpp b/mesalib/src/glsl/test_optpass.cpp index 6abafb5d3..31f65c3d2 100644 --- a/mesalib/src/glsl/test_optpass.cpp +++ b/mesalib/src/glsl/test_optpass.cpp @@ -98,8 +98,6 @@ do_optimization(struct exec_list *ir, const char *optimization) return do_lower_texture_projection(ir); } else if (strcmp(optimization, "do_if_simplification") == 0) { return do_if_simplification(ir); - } else if (strcmp(optimization, "do_discard_simplification") == 0) { - return do_discard_simplification(ir); } else if (sscanf(optimization, "lower_if_to_cond_assign ( %d ) ", &int_0) == 1) { return lower_if_to_cond_assign(ir, int_0); diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 7e2ac98b9..bafd250a1 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1635,6 +1635,7 @@ _mesa_record_error(struct gl_context *ctx, GLenum error) void _mesa_finish(struct gl_context *ctx) { + FLUSH_VERTICES( ctx, 0 ); FLUSH_CURRENT( ctx, 0 ); if (ctx->Driver.Finish) { ctx->Driver.Finish(ctx); @@ -1648,6 +1649,7 @@ _mesa_finish(struct gl_context *ctx) void _mesa_flush(struct gl_context *ctx) { + FLUSH_VERTICES( ctx, 0 ); FLUSH_CURRENT( ctx, 0 ); if (ctx->Driver.Flush) { ctx->Driver.Flush(ctx); @@ -1666,7 +1668,7 @@ void GLAPIENTRY _mesa_Finish(void) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); _mesa_finish(ctx); } @@ -1681,7 +1683,7 @@ void GLAPIENTRY _mesa_Flush(void) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); _mesa_flush(ctx); } diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c index f7b1f71f4..62b8e00c1 100644 --- a/mesalib/src/mesa/main/debug.c +++ b/mesalib/src/mesa/main/debug.c @@ -149,21 +149,19 @@ void _mesa_print_info( void ) /** - * Set the debugging flags. - * - * \param debug debug string - * - * If compiled with debugging support then search for keywords in \p debug and - * enables the verbose debug output of the respective feature. + * Set verbose logging flags. When these flags are set, GL API calls + * in the various categories will be printed to stderr. + * \param str a comma-separated list of keywords */ -static void add_debug_flags( const char *debug ) +static void +set_verbose_flags(const char *str) { #ifdef DEBUG - struct debug_option { + struct option { const char *name; GLbitfield flag; }; - static const struct debug_option debug_opt[] = { + static const struct option opts[] = { { "varray", VERBOSE_VARRAY }, { "tex", VERBOSE_TEXTURE }, { "mat", VERBOSE_MATERIAL }, @@ -179,34 +177,59 @@ static void add_debug_flags( const char *debug ) }; GLuint i; + if (!str) + return; + MESA_VERBOSE = 0x0; - for (i = 0; i < Elements(debug_opt); i++) { - if (strstr(debug, debug_opt[i].name) || strcmp(debug, "all") == 0) - MESA_VERBOSE |= debug_opt[i].flag; + for (i = 0; i < Elements(opts); i++) { + if (strstr(str, opts[i].name) || strcmp(str, "all") == 0) + MESA_VERBOSE |= opts[i].flag; } +#endif +} - /* Debug flag: - */ - if (strstr(debug, "flush")) - MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH; -#else - (void) debug; +/** + * Set debugging flags. When these flags are set, Mesa will do additional + * debug checks or actions. + * \param str a comma-separated list of keywords + */ +static void +set_debug_flags(const char *str) +{ +#ifdef DEBUG + struct option { + const char *name; + GLbitfield flag; + }; + static const struct option opts[] = { + { "silent", DEBUG_SILENT }, /* turn off debug messages */ + { "flush", DEBUG_ALWAYS_FLUSH }, /* flush after each drawing command */ + { "incomplete_tex", DEBUG_INCOMPLETE_TEXTURE }, + { "incomplete_fbo", DEBUG_INCOMPLETE_FBO } + }; + GLuint i; + + if (!str) + return; + + MESA_DEBUG_FLAGS = 0x0; + for (i = 0; i < Elements(opts); i++) { + if (strstr(str, opts[i].name)) + MESA_DEBUG_FLAGS |= opts[i].flag; + } #endif } +/** + * Initialize debugging variables from env vars. + */ void _mesa_init_debug( struct gl_context *ctx ) { - char *c; - c = _mesa_getenv("MESA_DEBUG"); - if (c) - add_debug_flags(c); - - c = _mesa_getenv("MESA_VERBOSE"); - if (c) - add_debug_flags(c); + set_debug_flags(_mesa_getenv("MESA_DEBUG")); + set_verbose_flags(_mesa_getenv("MESA_VERBOSE")); } diff --git a/mesalib/src/mesa/main/drawpix.c b/mesalib/src/mesa/main/drawpix.c index c2f7db2e8..def55dddd 100644 --- a/mesalib/src/mesa/main/drawpix.c +++ b/mesalib/src/mesa/main/drawpix.c @@ -180,6 +180,10 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -280,6 +284,10 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, end: _mesa_set_vp_override(ctx, GL_FALSE); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -354,6 +362,10 @@ _mesa_Bitmap( GLsizei width, GLsizei height, /* update raster position */ ctx->Current.RasterPos[0] += xmove; ctx->Current.RasterPos[1] += ymove; + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 4a187b7b0..69dbb65cf 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -802,21 +802,20 @@ output_if_debug(const char *prefixString, const char *outputString, { static int debug = -1; - /* Check the MESA_DEBUG environment variable if it hasn't - * been checked yet. We only have to check it once... + /* Init the local 'debug' var once. + * Note: the _mesa_init_debug() function should have been called + * by now so MESA_DEBUG_FLAGS will be initialized. */ if (debug == -1) { - char *env = _mesa_getenv("MESA_DEBUG"); - - /* In a debug build, we print warning messages *unless* - * MESA_DEBUG is 0. In a non-debug build, we don't - * print warning messages *unless* MESA_DEBUG is - * set *to any value*. - */ #ifdef DEBUG - debug = (env != NULL && atoi(env) == 0) ? 0 : 1; + /* in debug builds, print messages unless MESA_DEBUG="silent" */ + if (MESA_DEBUG_FLAGS & DEBUG_SILENT) + debug = 0; + else + debug = 1; #else - debug = (env != NULL) ? 1 : 0; + /* in release builds, be silent unless MESA_DEBUG is set */ + debug = _mesa_getenv("MESA_DEBUG") != NULL; #endif } diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index f56369483..777783eb7 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -49,9 +49,6 @@ #include "texobj.h" -/** Set this to 1 to help debug FBO incompleteness problems */ -#define DEBUG_FBO 0 - /** Set this to 1 to debug/log glBlitFramebuffer() calls */ #define DEBUG_BLIT 0 @@ -462,11 +459,9 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) static void att_incomplete(const char *msg) { -#if DEBUG_FBO - _mesa_debug(NULL, "attachment incomplete: %s\n", msg); -#else - (void) msg; -#endif + if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) { + _mesa_debug(NULL, "attachment incomplete: %s\n", msg); + } } @@ -476,12 +471,9 @@ att_incomplete(const char *msg) static void fbo_incomplete(const char *msg, int index) { -#if DEBUG_FBO - _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index); -#else - (void) msg; - (void) index; -#endif + if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) { + _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index); + } } diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c index 7bc22e2fa..38ec1b6e8 100644 --- a/mesalib/src/mesa/main/light.c +++ b/mesalib/src/mesa/main/light.c @@ -728,6 +728,8 @@ _mesa_ColorMaterial( GLenum face, GLenum mode ) _mesa_lookup_enum_by_nr(mode)); bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial"); + if (bitmask == 0) + return; /* error was recorded */ if (ctx->Light.ColorMaterialBitmask == bitmask && ctx->Light.ColorMaterialFace == face && diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 06ca0d5df..c306ac6b9 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -3522,7 +3522,10 @@ enum _verbose /** The MESA_DEBUG_FLAGS var is a bitmask of these flags */ enum _debug { - DEBUG_ALWAYS_FLUSH = 0x1 + DEBUG_SILENT = (1 << 0), + DEBUG_ALWAYS_FLUSH = (1 << 1), + DEBUG_INCOMPLETE_TEXTURE = (1 << 2), + DEBUG_INCOMPLETE_FBO = (1 << 3) }; diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index e2bdaca01..66a0c8895 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -35,6 +35,9 @@ #include "mtypes.h" #include "formats.h" +#ifdef __cplusplus +extern "C" { +#endif /** Is the given value one of the 6 cube faces? */ static inline GLboolean @@ -287,4 +290,8 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); /*@}*/ +#ifdef __cplusplus +} +#endif + #endif diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 155b255a7..365169ddd 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -410,16 +410,17 @@ static void incomplete(struct gl_texture_object *t, enum base_mipmap bm, const char *fmt, ...) { -#if 0 - va_list args; - char s[100]; + if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) { + va_list args; + char s[100]; - va_start(args, fmt); - vsnprintf(s, sizeof(s), fmt, args); - va_end(args); + va_start(args, fmt); + vsnprintf(s, sizeof(s), fmt, args); + va_end(args); + + _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s); + } - printf("Texture Obj %d incomplete because: %s\n", t->Name, s); -#endif if (bm == BASE) t->_BaseComplete = GL_FALSE; t->_MipmapComplete = GL_FALSE; diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index da41ee84c..08d330a52 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -782,6 +782,16 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, return; } + /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. + * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */ + if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2) { + if (transpose) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUniformMatrix(matrix transpose is not GL_FALSE)"); + return; + } + } + if (ctx->Shader.Flags & GLSL_UNIFORMS) { log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, bool(transpose), shProg, location, uni); diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 09a930cf2..d2e34ca1e 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -259,7 +259,11 @@ compute_version_es1(struct gl_context *ctx) ctx->VersionString = (char *) malloc(max); if (ctx->VersionString) { _mesa_snprintf(ctx->VersionString, max, - "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING, + "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING +#ifdef MESA_GIT_SHA1 + " (" MESA_GIT_SHA1 ")" +#endif + , ctx->VersionMinor); } } @@ -289,7 +293,11 @@ compute_version_es2(struct gl_context *ctx) ctx->VersionString = (char *) malloc(max); if (ctx->VersionString) { _mesa_snprintf(ctx->VersionString, max, - "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING); + "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING +#ifdef MESA_GIT_SHA1 + " (" MESA_GIT_SHA1 ")" +#endif + ); } } diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c index 87a479a22..fd9228583 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c +++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c @@ -1,170 +1,177 @@ -/**************************************************************************
- *
- * 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/imports.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "st_debug.h"
-#include "st_context.h"
-#include "st_atom.h"
-#include "st_atom_constbuf.h"
-#include "st_program.h"
-
-
-/**
- * Pass the given program parameters to the graphics pipe as a
- * constant buffer.
- * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
- */
-void st_upload_constants( struct st_context *st,
- struct gl_program_parameter_list *params,
- unsigned shader_type)
-{
- struct pipe_context *pipe = st->pipe;
-
- assert(shader_type == PIPE_SHADER_VERTEX ||
- shader_type == PIPE_SHADER_FRAGMENT ||
- shader_type == PIPE_SHADER_GEOMETRY);
-
- /* update constants */
- if (params && params->NumParameters) {
- struct pipe_resource *cbuf;
- const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
-
- /* Update the constants which come from fixed-function state, such as
- * transformation matrices, fog factors, etc. The rest of the values in
- * the parameters list are explicitly set by the user with glUniform,
- * glProgramParameter(), etc.
- */
- _mesa_load_state_parameters(st->ctx, params);
-
- /* We always need to get a new buffer, to keep the drivers simple and
- * avoid gratuitous rendering synchronization.
- * Let's use a user buffer to avoid an unnecessary copy.
- */
- cbuf = pipe_user_buffer_create(pipe->screen,
- params->ParameterValues,
- paramBytes,
- PIPE_BIND_CONSTANT_BUFFER);
-
- if (ST_DEBUG & DEBUG_CONSTANTS) {
- debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
- __FUNCTION__, shader_type, params->NumParameters,
- params->StateFlags);
- _mesa_print_parameter_list(params);
- }
-
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
- pipe_resource_reference(&cbuf, NULL);
-
- st->state.constants[shader_type].ptr = params->ParameterValues;
- st->state.constants[shader_type].size = paramBytes;
- }
- else if (st->state.constants[shader_type].ptr) {
- st->state.constants[shader_type].ptr = NULL;
- st->state.constants[shader_type].size = 0;
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
- }
-}
-
-
-/**
- * Vertex shader:
- */
-static void update_vs_constants(struct st_context *st )
-{
- struct st_vertex_program *vp = st->vp;
- struct gl_program_parameter_list *params = vp->Base.Base.Parameters;
-
- st_upload_constants( st, params, PIPE_SHADER_VERTEX );
-}
-
-
-const struct st_tracked_state st_update_vs_constants = {
- "st_update_vs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_VERTEX_PROGRAM, /* st */
- },
- update_vs_constants /* update */
-};
-
-
-
-/**
- * Fragment shader:
- */
-static void update_fs_constants(struct st_context *st )
-{
- struct st_fragment_program *fp = st->fp;
- struct gl_program_parameter_list *params = fp->Base.Base.Parameters;
-
- st_upload_constants( st, params, PIPE_SHADER_FRAGMENT );
-}
-
-
-const struct st_tracked_state st_update_fs_constants = {
- "st_update_fs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_FRAGMENT_PROGRAM, /* st */
- },
- update_fs_constants /* update */
-};
-
-/* Geometry shader:
- */
-static void update_gs_constants(struct st_context *st )
-{
- struct st_geometry_program *gp = st->gp;
- struct gl_program_parameter_list *params;
-
- if (gp) {
- params = gp->Base.Base.Parameters;
- st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
- }
-}
-
-const struct st_tracked_state st_update_gs_constants = {
- "st_update_gs_constants", /* name */
- { /* dirty */
- (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */
- ST_NEW_GEOMETRY_PROGRAM, /* st */
- },
- update_gs_constants /* 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/imports.h" +#include "program/prog_parameter.h" +#include "program/prog_print.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "util/u_upload_mgr.h" + +#include "st_debug.h" +#include "st_context.h" +#include "st_atom.h" +#include "st_atom_constbuf.h" +#include "st_program.h" + + +/** + * Pass the given program parameters to the graphics pipe as a + * constant buffer. + * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT + */ +void st_upload_constants( struct st_context *st, + struct gl_program_parameter_list *params, + unsigned shader_type) +{ + assert(shader_type == PIPE_SHADER_VERTEX || + shader_type == PIPE_SHADER_FRAGMENT || + shader_type == PIPE_SHADER_GEOMETRY); + + /* update constants */ + if (params && params->NumParameters) { + struct pipe_constant_buffer cb; + const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; + + /* Update the constants which come from fixed-function state, such as + * transformation matrices, fog factors, etc. The rest of the values in + * the parameters list are explicitly set by the user with glUniform, + * glProgramParameter(), etc. + */ + _mesa_load_state_parameters(st->ctx, params); + + /* We always need to get a new buffer, to keep the drivers simple and + * avoid gratuitous rendering synchronization. + * Let's use a user buffer to avoid an unnecessary copy. + */ + if (st->constbuf_uploader) { + cb.buffer = NULL; + cb.user_buffer = NULL; + u_upload_data(st->constbuf_uploader, 0, paramBytes, + params->ParameterValues, &cb.buffer_offset, &cb.buffer); + u_upload_unmap(st->constbuf_uploader); + } else { + cb.buffer = NULL; + cb.user_buffer = params->ParameterValues; + cb.buffer_offset = 0; + } + cb.buffer_size = paramBytes; + + if (ST_DEBUG & DEBUG_CONSTANTS) { + debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", + __FUNCTION__, shader_type, params->NumParameters, + params->StateFlags); + _mesa_print_parameter_list(params); + } + + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb); + pipe_resource_reference(&cb.buffer, NULL); + + st->state.constants[shader_type].ptr = params->ParameterValues; + st->state.constants[shader_type].size = paramBytes; + } + else if (st->state.constants[shader_type].ptr) { + st->state.constants[shader_type].ptr = NULL; + st->state.constants[shader_type].size = 0; + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL); + } +} + + +/** + * Vertex shader: + */ +static void update_vs_constants(struct st_context *st ) +{ + struct st_vertex_program *vp = st->vp; + struct gl_program_parameter_list *params = vp->Base.Base.Parameters; + + st_upload_constants( st, params, PIPE_SHADER_VERTEX ); +} + + +const struct st_tracked_state st_update_vs_constants = { + "st_update_vs_constants", /* name */ + { /* dirty */ + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ + ST_NEW_VERTEX_PROGRAM, /* st */ + }, + update_vs_constants /* update */ +}; + + + +/** + * Fragment shader: + */ +static void update_fs_constants(struct st_context *st ) +{ + struct st_fragment_program *fp = st->fp; + struct gl_program_parameter_list *params = fp->Base.Base.Parameters; + + st_upload_constants( st, params, PIPE_SHADER_FRAGMENT ); +} + + +const struct st_tracked_state st_update_fs_constants = { + "st_update_fs_constants", /* name */ + { /* dirty */ + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ + ST_NEW_FRAGMENT_PROGRAM, /* st */ + }, + update_fs_constants /* update */ +}; + +/* Geometry shader: + */ +static void update_gs_constants(struct st_context *st ) +{ + struct st_geometry_program *gp = st->gp; + struct gl_program_parameter_list *params; + + if (gp) { + params = gp->Base.Base.Parameters; + st_upload_constants( st, params, PIPE_SHADER_GEOMETRY ); + } +} + +const struct st_tracked_state st_update_gs_constants = { + "st_update_gs_constants", /* name */ + { /* dirty */ + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ + ST_NEW_GEOMETRY_PROGRAM, /* st */ + }, + update_gs_constants /* update */ +}; diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index ce7dbb3f3..b44976525 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -65,7 +65,6 @@ #include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" -#include "util/u_vbuf.h" DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE) @@ -112,32 +111,12 @@ st_get_msaa(void) } -static void st_init_vbuf(struct st_context *st) -{ - struct u_vbuf_caps caps; - - u_vbuf_get_caps(st->pipe->screen, &caps); - - /* Create u_vbuf if there is anything unsupported. */ - if (!caps.buffer_offset_unaligned || - !caps.buffer_stride_unaligned || - !caps.velem_src_offset_unaligned || - !caps.format_fixed32 || - !caps.format_float16 || - !caps.format_float64 || - !caps.format_norm32 || - !caps.format_scaled32 || - !caps.user_vertex_buffers) { - /* XXX user vertex buffers are always uploaded regardless of the CAP. */ - st->vbuf = u_vbuf_create(st->pipe, &caps); - cso_install_vbuf(st->cso_context, st->vbuf); - } -} static struct st_context * st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) { + struct pipe_screen *screen = pipe->screen; uint i; struct st_context *st = ST_CALLOC_STRUCT( st_context ); @@ -156,9 +135,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) st->dirty.st = ~0; st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); + + if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) { + st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4, + PIPE_BIND_INDEX_BUFFER); + } + + if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) { + unsigned alignment = + screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); + + st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment, + PIPE_BIND_CONSTANT_BUFFER); + } + st->cso_context = cso_create_context(pipe); - st_init_vbuf(st); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); @@ -254,11 +246,6 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_drawpix(st); st_destroy_drawtex(st); - /* Unreference any user vertex buffers. */ - 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++) { pipe_sampler_view_reference(&st->state.sampler_views[i], NULL); } @@ -269,6 +256,12 @@ static void st_destroy_context_priv( struct st_context *st ) } u_upload_destroy(st->uploader); + if (st->indexbuf_uploader) { + u_upload_destroy(st->indexbuf_uploader); + } + if (st->constbuf_uploader) { + u_upload_destroy(st->constbuf_uploader); + } free( st ); } @@ -276,7 +269,6 @@ static void st_destroy_context_priv( struct st_context *st ) void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; - struct u_vbuf *vbuf = st->vbuf; struct cso_context *cso = st->cso_context; struct gl_context *ctx = st->ctx; GLuint i; @@ -312,9 +304,6 @@ void st_destroy_context( struct st_context *st ) st_destroy_context_priv(st); st = NULL; - if (vbuf) - u_vbuf_destroy(vbuf); - cso_destroy_context(cso); pipe->destroy( pipe ); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 4786ed22f..00a405b69 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -41,7 +41,6 @@ struct gen_mipmap_state; struct st_context; struct st_fragment_program; struct u_upload_mgr; -struct u_vbuf; #define ST_NEW_MESA (1 << 0) /* Mesa state has changed */ @@ -74,8 +73,7 @@ struct st_context struct pipe_context *pipe; - struct u_upload_mgr *uploader; - struct u_vbuf *vbuf; + struct u_upload_mgr *uploader, *indexbuf_uploader, *constbuf_uploader; struct draw_context *draw; /**< For selection/feedback/rastpos only */ struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ @@ -191,18 +189,6 @@ struct st_context int force_msaa; void *winsys_drawable_handle; - /* User vertex buffers. */ - struct { - struct pipe_resource *buffer; - - /** Element size */ - GLuint element_size; - - /** Attribute stride */ - GLsizei stride; - } user_attrib[PIPE_MAX_ATTRIBS]; - unsigned num_user_attribs; - /* Active render condition. */ struct pipe_query *render_condition; unsigned condition_mode; diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 42dc37576..a8c20f45a 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -61,6 +61,7 @@ #include "util/u_format.h" #include "util/u_prim.h" #include "util/u_draw_quad.h" +#include "util/u_upload_mgr.h" #include "draw/draw_context.h" #include "cso_cache/cso_context.h" @@ -402,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx, const struct st_vp_variant *vpv, const struct gl_client_array **arrays, struct pipe_vertex_buffer *vbuffer, - struct pipe_vertex_element velements[], - unsigned max_index, - unsigned num_instances) + struct pipe_vertex_element velements[]) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; GLuint attr; const GLubyte *low_addr = NULL; GLboolean usingVBO; /* all arrays in a VBO? */ struct gl_buffer_object *bufobj; - GLuint user_buffer_size = 0; - GLuint vertex_size = 0; /* bytes per vertex, in bytes */ GLsizei stride; /* Find the lowest address of the arrays we're drawing, @@ -464,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx, array->Normalized, array->Integer); assert(velements[attr].src_format); - - if (!usingVBO) { - /* how many bytes referenced by this attribute array? */ - uint divisor = array->InstanceDivisor; - uint last_index = divisor ? num_instances / divisor : max_index; - uint bytes = src_offset + stride * last_index + element_size; - - user_buffer_size = MAX2(user_buffer_size, bytes); - - /* update vertex size */ - vertex_size = MAX2(vertex_size, src_offset + element_size); - } } /* @@ -484,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx, if (vpv->num_inputs == 0) { /* just defensive coding here */ vbuffer->buffer = NULL; + vbuffer->user_buffer = NULL; vbuffer->buffer_offset = 0; vbuffer->stride = 0; - st->num_user_attribs = 0; } else if (usingVBO) { /* all interleaved arrays in a VBO */ @@ -497,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx, return GL_FALSE; } - vbuffer->buffer = NULL; - pipe_resource_reference(&vbuffer->buffer, stobj->buffer); + vbuffer->buffer = stobj->buffer; + vbuffer->user_buffer = NULL; vbuffer->buffer_offset = pointer_to_offset(low_addr); vbuffer->stride = stride; - st->num_user_attribs = 0; } else { /* all interleaved arrays in user memory */ - vbuffer->buffer = pipe_user_buffer_create(pipe->screen, - (void*) low_addr, - user_buffer_size, - PIPE_BIND_VERTEX_BUFFER); + vbuffer->buffer = NULL; + vbuffer->user_buffer = low_addr; vbuffer->buffer_offset = 0; vbuffer->stride = stride; - - /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer); - st->user_attrib[0].element_size = vertex_size; - st->user_attrib[0].stride = stride; - st->num_user_attribs = 1; } return GL_TRUE; @@ -536,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx, const struct st_vp_variant *vpv, const struct gl_client_array **arrays, struct pipe_vertex_buffer vbuffer[], - struct pipe_vertex_element velements[], - unsigned max_index, - unsigned num_instances) + struct pipe_vertex_element velements[]) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; GLuint attr; for (attr = 0; attr < vpv->num_inputs; attr++) { 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)); + assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type)); if (_mesa_is_bufferobj(bufobj)) { /* Attribute data is in a VBO. @@ -565,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx, return GL_FALSE; } - vbuffer[attr].buffer = NULL; - pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer); + vbuffer[attr].buffer = stobj->buffer; + vbuffer[attr].user_buffer = NULL; vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr); } else { /* wrap user data */ - uint bytes; void *ptr; if (array->Ptr) { - 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 = element_size = sizeof(ctx->Current.Attrib[0]); ptr = (void *) ctx->Current.Attrib[mesaAttr]; stride = 0; } assert(ptr); - assert(bytes); - - vbuffer[attr].buffer = - pipe_user_buffer_create(pipe->screen, ptr, bytes, - PIPE_BIND_VERTEX_BUFFER); + vbuffer[attr].buffer = NULL; + vbuffer[attr].user_buffer = ptr; vbuffer[attr].buffer_offset = 0; - - /* Track user vertex buffers. */ - 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); - - if (!vbuffer[attr].buffer) { - /* probably ran out of memory */ - return GL_FALSE; - } } /* common-case setup */ @@ -629,34 +577,31 @@ setup_non_interleaved_attribs(struct gl_context *ctx, static void -setup_index_buffer(struct gl_context *ctx, +setup_index_buffer(struct st_context *st, const struct _mesa_index_buffer *ib, struct pipe_index_buffer *ibuffer) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; + struct gl_buffer_object *bufobj = ib->obj; - memset(ibuffer, 0, sizeof(*ibuffer)); - if (ib) { - struct gl_buffer_object *bufobj = ib->obj; - - ibuffer->index_size = vbo_sizeof_ib_type(ib->type); + ibuffer->index_size = vbo_sizeof_ib_type(ib->type); - /* get/create the index buffer object */ - if (_mesa_is_bufferobj(bufobj)) { - /* elements/indexes are in a real VBO */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - pipe_resource_reference(&ibuffer->buffer, stobj->buffer); - ibuffer->offset = pointer_to_offset(ib->ptr); - } - else { - /* element/indicies are in user space memory */ - ibuffer->buffer = - pipe_user_buffer_create(pipe->screen, (void *) ib->ptr, - ib->count * ibuffer->index_size, - PIPE_BIND_INDEX_BUFFER); - } + /* get/create the index buffer object */ + if (_mesa_is_bufferobj(bufobj)) { + /* indices are in a real VBO */ + ibuffer->buffer = st_buffer_object(bufobj)->buffer; + ibuffer->offset = pointer_to_offset(ib->ptr); } + else if (st->indexbuf_uploader) { + u_upload_data(st->indexbuf_uploader, 0, ib->count * ibuffer->index_size, + ib->ptr, &ibuffer->offset, &ibuffer->buffer); + u_upload_unmap(st->indexbuf_uploader); + } + else { + /* indices are in user space memory */ + ibuffer->user_buffer = ib->ptr; + } + + cso_set_index_buffer(st->cso_context, ibuffer); } @@ -811,10 +756,10 @@ handle_fallback_primitive_restart(struct cso_context *cso, unsigned num_sub_prims; assert(info.indexed); - assert(ibuffer->buffer); + assert(ibuffer->buffer || ibuffer->user_buffer); assert(ib); - if (!ibuffer->buffer || !ib) + if (!ibuffer->buffer || !ibuffer->user_buffer || !ib) return; info.primitive_restart = FALSE; @@ -894,9 +839,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim) */ static GLboolean st_validate_varrays(struct gl_context *ctx, - const struct gl_client_array **arrays, - unsigned max_index, - unsigned num_instances) + const struct gl_client_array **arrays) { struct st_context *st = st_context(ctx); const struct st_vertex_program *vp; @@ -904,8 +847,6 @@ st_validate_varrays(struct gl_context *ctx, struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; - GLuint attr; - unsigned i; /* must get these after state validation! */ vp = st->vp; @@ -913,18 +854,12 @@ 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_attribs; i++) { - pipe_resource_reference(&st->user_attrib[i].buffer, NULL); - } - st->num_user_attribs = 0; - /* * Setup the vbuffer[] and velements[] arrays. */ if (is_interleaved_arrays(vp, vpv, arrays)) { - if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements, - max_index, num_instances)) { + if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, + velements)) { return GL_FALSE; } @@ -935,8 +870,7 @@ st_validate_varrays(struct gl_context *ctx, } else { if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays, - vbuffer, velements, max_index, - num_instances)) { + vbuffer, velements)) { return GL_FALSE; } @@ -947,14 +881,6 @@ st_validate_varrays(struct gl_context *ctx, cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer); cso_set_vertex_elements(st->cso_context, num_velements, velements); - /* unreference buffers (frees wrapped user-space buffer objects) - * This is OK, because the pipe driver should reference buffers by itself - * in set_vertex_buffers. */ - for (attr = 0; attr < num_vbuffers; attr++) { - pipe_resource_reference(&vbuffer[attr].buffer, NULL); - assert(!vbuffer[attr].buffer); - } - return GL_TRUE; } @@ -976,11 +902,10 @@ st_draw_vbo(struct gl_context *ctx, { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; - struct pipe_index_buffer ibuffer; + struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; - unsigned i, num_instances = 1; - unsigned max_index_plus_base; + unsigned i; GLboolean new_array; /* Mesa core state should have been validated already */ @@ -994,43 +919,6 @@ st_draw_vbo(struct gl_context *ctx, (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) || (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; - if (ib) { - int max_base_vertex = 0; - - /* Gallium probably doesn't want this in some cases. */ - if (!index_bounds_valid) - if (!all_varyings_in_vbos(arrays)) - vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, - nr_prims); - - for (i = 0; i < nr_prims; i++) { - num_instances = MAX2(num_instances, prims[i].num_instances); - max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex); - } - - /* Compute the sum of max_index and max_base_vertex. That's the value - * we need to use when creating buffers. - */ - if (max_index == ~0) - max_index_plus_base = max_index; - else - max_index_plus_base = max_index + max_base_vertex; - } - else { - /* Get min/max index for non-indexed drawing. */ - min_index = ~0; - max_index = 0; - - for (i = 0; i < nr_prims; i++) { - min_index = MIN2(min_index, prims[i].start); - max_index = MAX2(max_index, prims[i].start + prims[i].count - 1); - num_instances = MAX2(num_instances, prims[i].num_instances); - } - - /* The base vertex offset only applies to indexed drawing */ - max_index_plus_base = max_index; - } - /* Validate state. */ if (st->dirty.st) { GLboolean vertDataEdgeFlags; @@ -1045,8 +933,7 @@ st_draw_vbo(struct gl_context *ctx, st_validate_state(st); if (new_array) { - if (!st_validate_varrays(ctx, arrays, max_index_plus_base, - num_instances)) { + if (!st_validate_varrays(ctx, arrays)) { /* probably out of memory, no-op the draw call */ return; } @@ -1061,31 +948,16 @@ st_draw_vbo(struct gl_context *ctx, #endif } - /* Notify the driver that the content of user buffers may have been - * changed. */ - 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_plus_base * stride + element_size; - - assert(max_offset > min_offset); - - pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer, - min_offset, - max_offset - min_offset); - } - } - } - - setup_index_buffer(ctx, ib, &ibuffer); - cso_set_index_buffer(st->cso_context, &ibuffer); - util_draw_init_info(&info); if (ib) { + /* Get index bounds for user buffers. */ + if (!index_bounds_valid) + if (!all_varyings_in_vbos(arrays)) + vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, + nr_prims); + + setup_index_buffer(st, ib, &ibuffer); + info.indexed = TRUE; if (min_index != ~0 && max_index != ~0) { info.min_index = min_index; @@ -1098,10 +970,12 @@ st_draw_vbo(struct gl_context *ctx, info.primitive_restart = ctx->Array.PrimitiveRestart; info.restart_index = ctx->Array.RestartIndex; } - - /* Set info.count_from_stream_output. */ - if (tfb_vertcount) { - st_transform_feedback_draw_init(tfb_vertcount, &info); + else { + /* Transform feedback drawing is always non-indexed. */ + /* Set info.count_from_stream_output. */ + if (tfb_vertcount) { + st_transform_feedback_draw_init(tfb_vertcount, &info); + } } /* do actual drawing */ @@ -1134,7 +1008,9 @@ st_draw_vbo(struct gl_context *ctx, cso_draw_vbo(st->cso_context, &info); } - pipe_resource_reference(&ibuffer.buffer, NULL); + if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) { + pipe_resource_reference(&ibuffer.buffer, NULL); + } } diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c index 257618aa9..4209fb214 100644 --- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c +++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c @@ -107,7 +107,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; struct pipe_index_buffer ibuffer; - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *ib_transfer = NULL; const struct gl_client_array **arrays = ctx->Array._DrawArrays; GLuint attr, i; @@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx, assert(stobj->buffer); vbuffers[attr].buffer = NULL; + vbuffers[attr].user_buffer = NULL; pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer); vbuffers[attr].buffer_offset = pointer_to_offset(low_addr); velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr; + + /* map the attrib buffer */ + map = pipe_buffer_map(pipe, vbuffers[attr].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[attr]); + draw_set_mapped_vertex_buffer(draw, attr, map); } else { - /* attribute data is in user-space memory, not a VBO */ - uint bytes = (arrays[mesaAttr]->Size - * _mesa_sizeof_type(arrays[mesaAttr]->Type) - * (max_index + 1)); - - /* wrap user data */ - vbuffers[attr].buffer - = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr, - bytes, - PIPE_BIND_VERTEX_BUFFER); + vbuffers[attr].buffer = NULL; + vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr; vbuffers[attr].buffer_offset = 0; velements[attr].src_offset = 0; + + draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer); } /* common-case setup */ @@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, #if 0 draw_set_vertex_buffer(draw, attr, &vbuffer[attr]); #endif - - /* map the attrib buffer */ - map = pipe_buffer_map(pipe, vbuffers[attr].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[attr]); - draw_set_mapped_vertex_buffer(draw, attr, map); } draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers); @@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, out_unref_vertex: for (attr = 0; attr < vp->num_inputs; attr++) { - pipe_buffer_unmap(pipe, vb_transfer[attr]); + if (vb_transfer[attr]) + pipe_buffer_unmap(pipe, vb_transfer[attr]); draw_set_mapped_vertex_buffer(draw, attr, NULL); pipe_resource_reference(&vbuffers[attr].buffer, NULL); } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index eecabb3e6..60a4e2831 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -3961,7 +3961,7 @@ dst_register(struct st_translate *t, case PROGRAM_TEMPORARY: if (ureg_dst_is_undef(t->temps[index])) - t->temps[index] = ureg_DECL_temporary(t->ureg); + t->temps[index] = ureg_DECL_local_temporary(t->ureg); return t->temps[index]; @@ -4002,7 +4002,7 @@ src_register(struct st_translate *t, assert(index >= 0); assert(index < Elements(t->temps)); if (ureg_dst_is_undef(t->temps[index])) - t->temps[index] = ureg_DECL_temporary(t->ureg); + t->temps[index] = ureg_DECL_local_temporary(t->ureg); return ureg_src(t->temps[index]); case PROGRAM_NAMED_PARAM: @@ -4259,7 +4259,7 @@ emit_wpos_adjustment( struct st_translate *t, * or not, which is determined by testing against the inversion * state variable used below, which will be either +1 or -1. */ - struct ureg_dst adj_temp = ureg_DECL_temporary(ureg); + struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg); ureg_CMP(ureg, adj_temp, ureg_scalar(wpostrans, invert ? 2 : 0), @@ -4622,7 +4622,7 @@ st_translate_program( */ for (i = 0; i < (unsigned)program->next_temp; i++) { /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ - t->temps[i] = ureg_DECL_temporary(t->ureg); + t->temps[i] = ureg_DECL_local_temporary(t->ureg); } } diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h index 0bf5c9165..d3fc77eef 100644 --- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h +++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h @@ -792,63 +792,6 @@ TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v) } - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* Colormaterial conflicts are dealt with later. - */ -static void GLAPIENTRY -TAG(Materialfv)(GLenum face, GLenum pname, - const GLfloat * params) -{ - GET_CURRENT_CONTEXT(ctx); - - if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { - _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)"); - return; - } - - switch (pname) { - case GL_EMISSION: - MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params); - break; - case GL_AMBIENT: - MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params); - break; - case GL_DIFFUSE: - MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params); - break; - case GL_SPECULAR: - MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params); - break; - case GL_SHININESS: - if (*params < 0 || *params > ctx->Const.MaxShininess) - _mesa_error(ctx, GL_INVALID_VALUE, - "glMaterial(invalid shininess: %f out range [0, %f])", - *params, ctx->Const.MaxShininess); - else - MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params); - break; - case GL_COLOR_INDEXES: - MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params); - MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params); - break; - default: - ERROR(GL_INVALID_ENUM); - return; - } -} - static void GLAPIENTRY TAG(VertexP2ui)(GLenum type, GLuint value) { @@ -1145,4 +1088,3 @@ TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, #undef ATTR_UI #undef MAT -#undef MAT_ATTR diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index b87da18f3..28d2c4de9 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -433,6 +433,101 @@ do { \ #include "vbo_attrib_tmp.h" + +/** + * Execute a glMaterial call. Note that if GL_COLOR_MATERIAL is enabled, + * this may be a (partial) no-op. + */ +static void GLAPIENTRY +vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params) +{ + GLbitfield updateMats; + GET_CURRENT_CONTEXT(ctx); + + /* This function should be a no-op when it tries to update material + * attributes which are currently tracking glColor via glColorMaterial. + * The updateMats var will be a mask of the MAT_BIT_FRONT/BACK_x bits + * indicating which material attributes can actually be updated below. + */ + if (ctx->Light.ColorMaterialEnabled) { + updateMats = ~ctx->Light.ColorMaterialBitmask; + } + else { + /* GL_COLOR_MATERIAL is disabled so don't skip any material updates */ + updateMats = ALL_MATERIAL_BITS; + } + + if (face == GL_FRONT) { + updateMats &= FRONT_MATERIAL_BITS; + } + else if (face == GL_BACK) { + updateMats &= BACK_MATERIAL_BITS; + } + else if (face != GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)"); + return; + } + + switch (pname) { + case GL_EMISSION: + if (updateMats & MAT_BIT_FRONT_EMISSION) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, params); + if (updateMats & MAT_BIT_BACK_EMISSION) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_EMISSION, 4, params); + break; + case GL_AMBIENT: + if (updateMats & MAT_BIT_FRONT_AMBIENT) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params); + if (updateMats & MAT_BIT_BACK_AMBIENT) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params); + break; + case GL_DIFFUSE: + if (updateMats & MAT_BIT_FRONT_DIFFUSE) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params); + if (updateMats & MAT_BIT_BACK_DIFFUSE) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params); + break; + case GL_SPECULAR: + if (updateMats & MAT_BIT_FRONT_SPECULAR) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, params); + if (updateMats & MAT_BIT_BACK_SPECULAR) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_SPECULAR, 4, params); + break; + case GL_SHININESS: + if (*params < 0 || *params > ctx->Const.MaxShininess) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glMaterial(invalid shininess: %f out range [0, %f])", + *params, ctx->Const.MaxShininess); + return; + } + if (updateMats & MAT_BIT_FRONT_SHININESS) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, params); + if (updateMats & MAT_BIT_BACK_SHININESS) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_SHININESS, 1, params); + break; + case GL_COLOR_INDEXES: + if (updateMats & MAT_BIT_FRONT_INDEXES) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, params); + if (updateMats & MAT_BIT_BACK_INDEXES) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_INDEXES, 3, params); + break; + case GL_AMBIENT_AND_DIFFUSE: + if (updateMats & MAT_BIT_FRONT_AMBIENT) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params); + if (updateMats & MAT_BIT_FRONT_DIFFUSE) + MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params); + if (updateMats & MAT_BIT_BACK_AMBIENT) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params); + if (updateMats & MAT_BIT_BACK_DIFFUSE) + MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glMaterialfv(pname)"); + return; + } +} + + /** * Flush (draw) vertices. * \param unmap - leave VBO unmapped after flushing? @@ -767,6 +862,10 @@ static void GLAPIENTRY vbo_exec_End( void ) } else _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index cc94e761b..9303ad719 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -614,6 +614,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, GL_TRUE, start, start + count - 1, NULL); } + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -803,6 +807,10 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims( ctx, prim, 1, &ib, index_bounds_valid, start, end, NULL ); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -1127,6 +1135,10 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } free(prim); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } @@ -1201,6 +1213,10 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, prim, 1, NULL, GL_TRUE, 0, 0, obj); + + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { + _mesa_flush(ctx); + } } /** diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 74f5dc9ce..f202375ca 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -724,6 +724,63 @@ do { \ +#define MAT( ATTR, N, face, params ) \ +do { \ + if (face != GL_BACK) \ + MAT_ATTR( ATTR, N, params ); /* front */ \ + if (face != GL_FRONT) \ + MAT_ATTR( ATTR + 1, N, params ); /* back */ \ +} while (0) + + +/** + * Save a glMaterial call found between glBegin/End. + * glMaterial calls outside Begin/End are handled in dlist.c. + */ +static void GLAPIENTRY +_save_Materialfv(GLenum face, GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + + if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { + _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)"); + return; + } + + switch (pname) { + case GL_EMISSION: + MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params); + break; + case GL_AMBIENT: + MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params); + break; + case GL_DIFFUSE: + MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params); + break; + case GL_SPECULAR: + MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params); + break; + case GL_SHININESS: + if (*params < 0 || *params > ctx->Const.MaxShininess) { + _mesa_compile_error(ctx, GL_INVALID_VALUE, "glMaterial(shininess)"); + } + else { + MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params); + } + break; + case GL_COLOR_INDEXES: + MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params); + break; + case GL_AMBIENT_AND_DIFFUSE: + MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params); + MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params); + break; + default: + _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)"); + return; + } +} + /* Cope with EvalCoord/CallList called within a begin/end object: * -- Flush current buffer |