diff options
Diffstat (limited to 'mesalib/src/mesa')
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 |