aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/main/context.c6
-rw-r--r--mesalib/src/mesa/main/debug.c75
-rw-r--r--mesalib/src/mesa/main/drawpix.c12
-rw-r--r--mesalib/src/mesa/main/errors.c21
-rw-r--r--mesalib/src/mesa/main/fbobject.c20
-rw-r--r--mesalib/src/mesa/main/light.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h5
-rw-r--r--mesalib/src/mesa/main/teximage.h7
-rw-r--r--mesalib/src/mesa/main/texobj.c17
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp10
-rw-r--r--mesalib/src/mesa/main/version.c12
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c347
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c53
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h16
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c240
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw_feedback.c32
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp8
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h58
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c99
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c16
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c57
21 files changed, 570 insertions, 543 deletions
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