From a0b4a1330be6a36ad095222d2ea83927cd33514d Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 25 Nov 2011 08:22:48 +0100 Subject: mesa xserver pixman git update 25 nov 2011 --- mesalib/Android.common.mk | 6 + mesalib/include/EGL/eglext.h | 1 - mesalib/src/gallium/auxiliary/util/u_caps.c | 539 +++++++------ mesalib/src/gallium/auxiliary/util/u_caps.h | 142 ++-- mesalib/src/gallium/auxiliary/util/u_vbuf.c | 868 +++++++++++++++++++++ mesalib/src/gallium/auxiliary/util/u_vbuf.h | 145 ++++ mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.c | 849 -------------------- mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.h | 145 ---- mesalib/src/glsl/ast_to_hir.cpp | 10 +- mesalib/src/glsl/glcpp/glcpp-parse.y | 2 +- mesalib/src/glsl/glsl_lexer.ll | 1 + mesalib/src/glsl/glsl_parser.yy | 9 +- mesalib/src/glsl/glsl_parser_extras.cpp | 4 +- mesalib/src/glsl/link_uniforms.cpp | 10 +- mesalib/src/mesa/main/extensions.c | 4 +- mesalib/src/mesa/main/format_unpack.c | 14 +- mesalib/src/mesa/main/formats.c | 12 +- mesalib/src/mesa/main/mtypes.h | 2 +- mesalib/src/mesa/main/readpix.c | 4 +- mesalib/src/mesa/main/texformat.c | 12 + mesalib/src/mesa/main/teximage.c | 11 +- mesalib/src/mesa/main/texparam.c | 119 +-- mesalib/src/mesa/main/texstore.c | 7 +- mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 7 + mesalib/src/mesa/state_tracker/st_cb_fbo.c | 14 +- mesalib/src/mesa/state_tracker/st_extensions.c | 46 +- mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 16 +- mesalib/src/mesa/swrast/s_texcombine.c | 23 +- mesalib/src/mesa/vbo/vbo_noop.h | 6 + 29 files changed, 1568 insertions(+), 1460 deletions(-) create mode 100644 mesalib/src/gallium/auxiliary/util/u_vbuf.c create mode 100644 mesalib/src/gallium/auxiliary/util/u_vbuf.h delete mode 100644 mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.c delete mode 100644 mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.h (limited to 'mesalib') diff --git a/mesalib/Android.common.mk b/mesalib/Android.common.mk index 83177a0cb..f28ddc2ef 100644 --- a/mesalib/Android.common.mk +++ b/mesalib/Android.common.mk @@ -24,6 +24,12 @@ LOCAL_C_INCLUDES += \ $(MESA_TOP)/include +# define ANDROID_VERSION (e.g., 4.0.x => 0x0400) +major := $(word 1, $(subst ., , $(PLATFORM_VERSION))) +minor := $(word 2, $(subst ., , $(PLATFORM_VERSION))) +LOCAL_CFLAGS += \ + -DANDROID_VERSION=0x0$(major)0$(minor) + LOCAL_CFLAGS += \ -DPTHREADS \ -fvisibility=hidden \ diff --git a/mesalib/include/EGL/eglext.h b/mesalib/include/EGL/eglext.h index 0449ae2cd..9484b83c6 100644 --- a/mesalib/include/EGL/eglext.h +++ b/mesalib/include/EGL/eglext.h @@ -392,7 +392,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 -struct android_native_buffer_t; #define EGL_NATIVE_BUFFER_ANDROID 0x3140 /* eglCreateImageKHR target */ #endif diff --git a/mesalib/src/gallium/auxiliary/util/u_caps.c b/mesalib/src/gallium/auxiliary/util/u_caps.c index fbe265d0e..623070755 100644 --- a/mesalib/src/gallium/auxiliary/util/u_caps.c +++ b/mesalib/src/gallium/auxiliary/util/u_caps.c @@ -1,270 +1,269 @@ -/************************************************************************** - * - * Copyright 2010 Vmware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE 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. - * - **************************************************************************/ - -#include "pipe/p_screen.h" -#include "util/u_format.h" -#include "util/u_debug.h" -#include "u_caps.h" - -/** - * Iterates over a list of caps checks as defined in u_caps.h. Should - * all checks pass returns TRUE and out is set to the last element of - * the list (TERMINATE). Should any check fail returns FALSE and set - * out to the index of the start of the first failing check. - */ -boolean -util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) -{ - int i, tmpi; - float tmpf; - - for (i = 0; list[i];) { - switch(list[i++]) { - case UTIL_CAPS_CHECK_CAP: - if (!screen->get_param(screen, list[i++])) { - *out = i - 2; - return FALSE; - } - break; - case UTIL_CAPS_CHECK_INT: - tmpi = screen->get_param(screen, list[i++]); - if (tmpi < (int)list[i++]) { - *out = i - 3; - return FALSE; - } - break; - case UTIL_CAPS_CHECK_FLOAT: - tmpf = screen->get_paramf(screen, list[i++]); - if (tmpf < (float)list[i++]) { - *out = i - 3; - return FALSE; - } - break; - case UTIL_CAPS_CHECK_FORMAT: - if (!screen->is_format_supported(screen, - list[i++], - PIPE_TEXTURE_2D, - 0, - PIPE_BIND_SAMPLER_VIEW)) { - *out = i - 2; - return FALSE; - } - break; - case UTIL_CAPS_CHECK_SHADER: - tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1)); - ++i; - if (tmpi < (int)list[i++]) { - *out = i - 3; - return FALSE; - } - break; - case UTIL_CAPS_CHECK_UNIMPLEMENTED: - *out = i - 1; - return FALSE; - default: - assert(!"Unsupported check"); - return FALSE; - } - } - - *out = i; - return TRUE; -} - -/** - * Iterates over a list of caps checks as defined in u_caps.h. - * Returns TRUE if all caps checks pass returns FALSE otherwise. - */ -boolean -util_check_caps(struct pipe_screen *screen, const unsigned *list) -{ - int out; - return util_check_caps_out(screen, list, &out); -} - - -/* - * Below follows some demo lists. - * - * None of these lists are exhausting lists of what is - * actually needed to support said API and more here for - * as example on how to uses the above functions. Especially - * for DX10 and DX11 where Gallium is missing features. - */ - -/* DX 9_1 */ -static unsigned caps_dx_9_1[] = { - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), - UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ - UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ - UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ - UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 2), - UTIL_CHECK_TERMINATE -}; - -/* DX 9_2 */ -static unsigned caps_dx_9_2[] = { - UTIL_CHECK_CAP(OCCLUSION_QUERY), - UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), - UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ - UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ - UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ - UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), - UTIL_CHECK_TERMINATE -}; - -/* DX 9_3 */ -static unsigned caps_dx_9_3[] = { - UTIL_CHECK_CAP(SM3), - //UTIL_CHECK_CAP(INSTANCING), - UTIL_CHECK_CAP(OCCLUSION_QUERY), - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4), - UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */ - UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ - UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ - UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), - UTIL_CHECK_TERMINATE -}; - -/* DX 10 */ -static unsigned caps_dx_10[] = { - UTIL_CHECK_CAP(SM3), - //UTIL_CHECK_CAP(INSTANCING), - UTIL_CHECK_CAP(OCCLUSION_QUERY), - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), - UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 8192 */ - UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ - UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 8192 */ - UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), - UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ - UTIL_CHECK_TERMINATE -}; - -/* DX11 */ -static unsigned caps_dx_11[] = { - UTIL_CHECK_CAP(SM3), - //UTIL_CHECK_CAP(INSTANCING), - UTIL_CHECK_CAP(OCCLUSION_QUERY), - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), - UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 16384 */ - UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ - UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 16384 */ - UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), - UTIL_CHECK_FORMAT(B8G8R8A8_UNORM), - UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ - UTIL_CHECK_TERMINATE -}; - -/* OpenGL 2.1 */ -static unsigned caps_opengl_2_1[] = { - UTIL_CHECK_CAP(GLSL), - UTIL_CHECK_CAP(OCCLUSION_QUERY), - UTIL_CHECK_CAP(TWO_SIDED_STENCIL), - UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), - UTIL_CHECK_INT(MAX_RENDER_TARGETS, 2), - UTIL_CHECK_TERMINATE -}; - -/* OpenGL 3.0 */ -/* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */ - -/* Shader Model 3 */ -static unsigned caps_sm3[] = { - UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512), - UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10), - UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32), - UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1), - UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224), - - UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512), - UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), - UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32), - UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2), - UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256), - - UTIL_CHECK_TERMINATE -}; - -/** - * Demo function which checks against theoretical caps needed for different APIs. - */ -void util_caps_demo_print(struct pipe_screen *screen) -{ - struct { - char* name; - unsigned *list; - } list[] = { - {"DX 9.1", caps_dx_9_1}, - {"DX 9.2", caps_dx_9_2}, - {"DX 9.3", caps_dx_9_3}, - {"DX 10", caps_dx_10}, - {"DX 11", caps_dx_11}, - {"OpenGL 2.1", caps_opengl_2_1}, -/* {"OpenGL 3.0", caps_opengl_3_0},*/ - {"SM3", caps_sm3}, - {NULL, NULL} - }; - int i, out = 0; - - for (i = 0; list[i].name; i++) { - if (util_check_caps_out(screen, list[i].list, &out)) { - debug_printf("%s: %s yes\n", __FUNCTION__, list[i].name); - continue; - } - switch (list[i].list[out]) { - case UTIL_CAPS_CHECK_CAP: - debug_printf("%s: %s no (cap %u not supported)\n", __FUNCTION__, - list[i].name, - list[i].list[out + 1]); - break; - case UTIL_CAPS_CHECK_INT: - debug_printf("%s: %s no (cap %u less then %u)\n", __FUNCTION__, - list[i].name, - list[i].list[out + 1], - list[i].list[out + 2]); - break; - case UTIL_CAPS_CHECK_FLOAT: - debug_printf("%s: %s no (cap %u less then %f)\n", __FUNCTION__, - list[i].name, - list[i].list[out + 1], - (double)(int)list[i].list[out + 2]); - break; - case UTIL_CAPS_CHECK_FORMAT: - debug_printf("%s: %s no (format %s not supported)\n", __FUNCTION__, - list[i].name, - util_format_name(list[i].list[out + 1]) + 12); - break; - case UTIL_CAPS_CHECK_UNIMPLEMENTED: - debug_printf("%s: %s no (not implemented in gallium or state tracker)\n", - __FUNCTION__, list[i].name); - break; - default: - assert(!"Unsupported check"); - } - } -} +/************************************************************************** + * + * Copyright 2010 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE 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. + * + **************************************************************************/ + +#include "pipe/p_screen.h" +#include "util/u_format.h" +#include "util/u_debug.h" +#include "u_caps.h" + +/** + * Iterates over a list of caps checks as defined in u_caps.h. Should + * all checks pass returns TRUE and out is set to the last element of + * the list (TERMINATE). Should any check fail returns FALSE and set + * out to the index of the start of the first failing check. + */ +boolean +util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) +{ + int i, tmpi; + float tmpf; + + for (i = 0; list[i];) { + switch(list[i++]) { + case UTIL_CAPS_CHECK_CAP: + if (!screen->get_param(screen, list[i++])) { + *out = i - 2; + return FALSE; + } + break; + case UTIL_CAPS_CHECK_INT: + tmpi = screen->get_param(screen, list[i++]); + if (tmpi < (int)list[i++]) { + *out = i - 3; + return FALSE; + } + break; + case UTIL_CAPS_CHECK_FLOAT: + tmpf = screen->get_paramf(screen, list[i++]); + if (tmpf < (float)list[i++]) { + *out = i - 3; + return FALSE; + } + break; + case UTIL_CAPS_CHECK_FORMAT: + if (!screen->is_format_supported(screen, + list[i++], + PIPE_TEXTURE_2D, + 0, + PIPE_BIND_SAMPLER_VIEW)) { + *out = i - 2; + return FALSE; + } + break; + case UTIL_CAPS_CHECK_SHADER: + tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1)); + ++i; + if (tmpi < (int)list[i++]) { + *out = i - 3; + return FALSE; + } + break; + case UTIL_CAPS_CHECK_UNIMPLEMENTED: + *out = i - 1; + return FALSE; + default: + assert(!"Unsupported check"); + return FALSE; + } + } + + *out = i; + return TRUE; +} + +/** + * Iterates over a list of caps checks as defined in u_caps.h. + * Returns TRUE if all caps checks pass returns FALSE otherwise. + */ +boolean +util_check_caps(struct pipe_screen *screen, const unsigned *list) +{ + int out; + return util_check_caps_out(screen, list, &out); +} + + +/* + * Below follows some demo lists. + * + * None of these lists are exhausting lists of what is + * actually needed to support said API and more here for + * as example on how to uses the above functions. Especially + * for DX10 and DX11 where Gallium is missing features. + */ + +/* DX 9_1 */ +static unsigned caps_dx_9_1[] = { + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), + UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ + UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ + UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ + UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 2), + UTIL_CHECK_TERMINATE +}; + +/* DX 9_2 */ +static unsigned caps_dx_9_2[] = { + UTIL_CHECK_CAP(OCCLUSION_QUERY), + UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), + UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ + UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ + UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ + UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), + UTIL_CHECK_TERMINATE +}; + +/* DX 9_3 */ +static unsigned caps_dx_9_3[] = { + UTIL_CHECK_CAP(SM3), + //UTIL_CHECK_CAP(INSTANCING), + UTIL_CHECK_CAP(OCCLUSION_QUERY), + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4), + UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */ + UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ + UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ + UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), + UTIL_CHECK_TERMINATE +}; + +/* DX 10 */ +static unsigned caps_dx_10[] = { + UTIL_CHECK_CAP(SM3), + //UTIL_CHECK_CAP(INSTANCING), + UTIL_CHECK_CAP(OCCLUSION_QUERY), + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), + UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 8192 */ + UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ + UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 8192 */ + UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), + UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ + UTIL_CHECK_TERMINATE +}; + +/* DX11 */ +static unsigned caps_dx_11[] = { + UTIL_CHECK_CAP(SM3), + //UTIL_CHECK_CAP(INSTANCING), + UTIL_CHECK_CAP(OCCLUSION_QUERY), + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), + UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 16384 */ + UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ + UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 16384 */ + UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), + UTIL_CHECK_FORMAT(B8G8R8A8_UNORM), + UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ + UTIL_CHECK_TERMINATE +}; + +/* OpenGL 2.1 */ +static unsigned caps_opengl_2_1[] = { + UTIL_CHECK_CAP(OCCLUSION_QUERY), + UTIL_CHECK_CAP(TWO_SIDED_STENCIL), + UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), + UTIL_CHECK_INT(MAX_RENDER_TARGETS, 2), + UTIL_CHECK_TERMINATE +}; + +/* OpenGL 3.0 */ +/* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */ + +/* Shader Model 3 */ +static unsigned caps_sm3[] = { + UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512), + UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10), + UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32), + UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1), + UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224), + + UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512), + UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), + UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32), + UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2), + UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256), + + UTIL_CHECK_TERMINATE +}; + +/** + * Demo function which checks against theoretical caps needed for different APIs. + */ +void util_caps_demo_print(struct pipe_screen *screen) +{ + struct { + char* name; + unsigned *list; + } list[] = { + {"DX 9.1", caps_dx_9_1}, + {"DX 9.2", caps_dx_9_2}, + {"DX 9.3", caps_dx_9_3}, + {"DX 10", caps_dx_10}, + {"DX 11", caps_dx_11}, + {"OpenGL 2.1", caps_opengl_2_1}, +/* {"OpenGL 3.0", caps_opengl_3_0},*/ + {"SM3", caps_sm3}, + {NULL, NULL} + }; + int i, out = 0; + + for (i = 0; list[i].name; i++) { + if (util_check_caps_out(screen, list[i].list, &out)) { + debug_printf("%s: %s yes\n", __FUNCTION__, list[i].name); + continue; + } + switch (list[i].list[out]) { + case UTIL_CAPS_CHECK_CAP: + debug_printf("%s: %s no (cap %u not supported)\n", __FUNCTION__, + list[i].name, + list[i].list[out + 1]); + break; + case UTIL_CAPS_CHECK_INT: + debug_printf("%s: %s no (cap %u less then %u)\n", __FUNCTION__, + list[i].name, + list[i].list[out + 1], + list[i].list[out + 2]); + break; + case UTIL_CAPS_CHECK_FLOAT: + debug_printf("%s: %s no (cap %u less then %f)\n", __FUNCTION__, + list[i].name, + list[i].list[out + 1], + (double)(int)list[i].list[out + 2]); + break; + case UTIL_CAPS_CHECK_FORMAT: + debug_printf("%s: %s no (format %s not supported)\n", __FUNCTION__, + list[i].name, + util_format_name(list[i].list[out + 1]) + 12); + break; + case UTIL_CAPS_CHECK_UNIMPLEMENTED: + debug_printf("%s: %s no (not implemented in gallium or state tracker)\n", + __FUNCTION__, list[i].name); + break; + default: + assert(!"Unsupported check"); + } + } +} diff --git a/mesalib/src/gallium/auxiliary/util/u_caps.h b/mesalib/src/gallium/auxiliary/util/u_caps.h index 32a3aca5c..038efc9f1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_caps.h +++ b/mesalib/src/gallium/auxiliary/util/u_caps.h @@ -1,71 +1,71 @@ -/************************************************************************** - * - * Copyright 2010 Vmware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef U_CAPS_H -#define U_CAPS_H - -#include "pipe/p_compiler.h" - -struct pipe_screen; - -enum u_caps_check_enum { - UTIL_CAPS_CHECK_TERMINATE = 0, - UTIL_CAPS_CHECK_CAP, - UTIL_CAPS_CHECK_INT, - UTIL_CAPS_CHECK_FLOAT, - UTIL_CAPS_CHECK_FORMAT, - UTIL_CAPS_CHECK_SHADER, - UTIL_CAPS_CHECK_UNIMPLEMENTED, -}; - -#define UTIL_CHECK_CAP(cap) \ - UTIL_CAPS_CHECK_CAP, PIPE_CAP_##cap - -#define UTIL_CHECK_INT(cap, higher) \ - UTIL_CAPS_CHECK_INT, PIPE_CAP_##cap, (unsigned)(higher) - -/* Floats currently lose precision */ -#define UTIL_CHECK_FLOAT(cap, higher) \ - UTIL_CAPS_CHECK_FLOAT, PIPE_CAP_##cap, (unsigned)(int)(higher) - -#define UTIL_CHECK_FORMAT(format) \ - UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format - -#define UTIL_CHECK_SHADER(shader, cap, higher) \ - UTIL_CAPS_CHECK_SHADER, (PIPE_SHADER_##shader << 24) | PIPE_SHADER_CAP_##cap, (unsigned)(higher) - -#define UTIL_CHECK_UNIMPLEMENTED \ - UTIL_CAPS_CHECK_UNIMPLEMENTED - -#define UTIL_CHECK_TERMINATE \ - UTIL_CAPS_CHECK_TERMINATE - -boolean util_check_caps(struct pipe_screen *screen, const unsigned *list); -boolean util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out); -void util_caps_demo_print(struct pipe_screen *screen); - -#endif +/************************************************************************** + * + * Copyright 2010 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_CAPS_H +#define U_CAPS_H + +#include "pipe/p_compiler.h" + +struct pipe_screen; + +enum u_caps_check_enum { + UTIL_CAPS_CHECK_TERMINATE = 0, + UTIL_CAPS_CHECK_CAP, + UTIL_CAPS_CHECK_INT, + UTIL_CAPS_CHECK_FLOAT, + UTIL_CAPS_CHECK_FORMAT, + UTIL_CAPS_CHECK_SHADER, + UTIL_CAPS_CHECK_UNIMPLEMENTED, +}; + +#define UTIL_CHECK_CAP(cap) \ + UTIL_CAPS_CHECK_CAP, PIPE_CAP_##cap + +#define UTIL_CHECK_INT(cap, higher) \ + UTIL_CAPS_CHECK_INT, PIPE_CAP_##cap, (unsigned)(higher) + +/* Floats currently lose precision */ +#define UTIL_CHECK_FLOAT(cap, higher) \ + UTIL_CAPS_CHECK_FLOAT, PIPE_CAPF_##cap, (unsigned)(int)(higher) + +#define UTIL_CHECK_FORMAT(format) \ + UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format + +#define UTIL_CHECK_SHADER(shader, cap, higher) \ + UTIL_CAPS_CHECK_SHADER, (PIPE_SHADER_##shader << 24) | PIPE_SHADER_CAP_##cap, (unsigned)(higher) + +#define UTIL_CHECK_UNIMPLEMENTED \ + UTIL_CAPS_CHECK_UNIMPLEMENTED + +#define UTIL_CHECK_TERMINATE \ + UTIL_CAPS_CHECK_TERMINATE + +boolean util_check_caps(struct pipe_screen *screen, const unsigned *list); +boolean util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out); +void util_caps_demo_print(struct pipe_screen *screen); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c new file mode 100644 index 000000000..f6da91203 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c @@ -0,0 +1,868 @@ +/************************************************************************** + * + * Copyright 2011 Marek Olšák + * 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 AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_vbuf.h" + +#include "util/u_format.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_upload_mgr.h" +#include "translate/translate.h" +#include "translate/translate_cache.h" + +struct u_vbuf_elements { + unsigned count; + struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; + + unsigned src_format_size[PIPE_MAX_ATTRIBS]; + + /* If (velem[i].src_format != native_format[i]), the vertex buffer + * referenced by the vertex element cannot be used for rendering and + * its vertex data must be translated to native_format[i]. */ + enum pipe_format native_format[PIPE_MAX_ATTRIBS]; + unsigned native_format_size[PIPE_MAX_ATTRIBS]; + + /* This might mean two things: + * - src_format != native_format, as discussed above. + * - src_offset % 4 != 0 (if the caps don't allow such an offset). */ + boolean incompatible_layout; + /* Per-element flags. */ + boolean incompatible_layout_elem[PIPE_MAX_ATTRIBS]; +}; + +struct u_vbuf_priv { + struct u_vbuf b; + struct pipe_context *pipe; + struct translate_cache *translate_cache; + + /* Vertex element state bound by the state tracker. */ + void *saved_ve; + /* and its associated helper structure for this module. */ + struct u_vbuf_elements *ve; + + /* Vertex elements used for the translate fallback. */ + struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; + /* If non-NULL, this is a vertex element state used for the translate + * fallback and therefore used for rendering too. */ + void *fallback_ve; + /* The vertex buffer slot index where translated vertices have been + * stored in. */ + unsigned fallback_vb_slot; + /* When binding the fallback vertex element state, we don't want to + * change saved_ve and ve. This is set to TRUE in such cases. */ + boolean ve_binding_lock; + + /* Whether there is any user buffer. */ + boolean any_user_vbs; + /* Whether there is a buffer with a non-native layout. */ + boolean incompatible_vb_layout; + /* Per-buffer flags. */ + boolean incompatible_vb[PIPE_MAX_ATTRIBS]; +}; + +static void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr) +{ + struct pipe_screen *screen = mgr->pipe->screen; + + mgr->b.caps.format_fixed32 = + screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER); + + mgr->b.caps.format_float16 = + screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER); + + mgr->b.caps.format_float64 = + screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER); + + mgr->b.caps.format_norm32 = + screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER) && + screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER); + + mgr->b.caps.format_scaled32 = + screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER) && + screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER, + 0, PIPE_BIND_VERTEX_BUFFER); +} + +struct u_vbuf * +u_vbuf_create(struct pipe_context *pipe, + unsigned upload_buffer_size, + unsigned upload_buffer_alignment, + unsigned upload_buffer_bind, + enum u_fetch_alignment fetch_alignment) +{ + struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv); + + mgr->pipe = pipe; + mgr->translate_cache = translate_cache_create(); + mgr->fallback_vb_slot = ~0; + + mgr->b.uploader = u_upload_create(pipe, upload_buffer_size, + upload_buffer_alignment, + upload_buffer_bind); + + mgr->b.caps.fetch_dword_unaligned = + fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED; + + u_vbuf_init_format_caps(mgr); + + return &mgr->b; +} + +void u_vbuf_destroy(struct u_vbuf *mgrb) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + unsigned i; + + for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); + } + for (i = 0; i < mgr->b.nr_real_vertex_buffers; i++) { + pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); + } + + translate_cache_destroy(mgr->translate_cache); + u_upload_destroy(mgr->b.uploader); + FREE(mgr); +} + + +static unsigned u_vbuf_get_free_real_vb_slot(struct u_vbuf_priv *mgr) +{ + unsigned i, nr = mgr->ve->count; + boolean used_vb[PIPE_MAX_ATTRIBS] = {0}; + + for (i = 0; i < nr; i++) { + if (!mgr->ve->incompatible_layout_elem[i]) { + unsigned index = mgr->ve->ve[i].vertex_buffer_index; + + if (!mgr->incompatible_vb[index]) { + used_vb[index] = TRUE; + } + } + } + + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (!used_vb[i]) { + if (i >= mgr->b.nr_real_vertex_buffers) { + mgr->b.nr_real_vertex_buffers = i+1; + } + return i; + } + } + return ~0; +} + +static void +u_vbuf_translate_begin(struct u_vbuf_priv *mgr, + int min_index, int max_index) +{ + struct translate_key key; + struct translate_element *te; + unsigned tr_elem_index[PIPE_MAX_ATTRIBS]; + struct translate *tr; + boolean vb_translated[PIPE_MAX_ATTRIBS] = {0}; + uint8_t *out_map; + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; + struct pipe_resource *out_buffer = NULL; + unsigned i, num_verts, out_offset; + boolean upload_flushed = FALSE; + + memset(&key, 0, sizeof(key)); + memset(tr_elem_index, 0xff, sizeof(tr_elem_index)); + + /* Get a new vertex buffer slot. */ + mgr->fallback_vb_slot = u_vbuf_get_free_real_vb_slot(mgr); + + if (mgr->fallback_vb_slot == ~0) { + return; /* XXX error, not enough attribs */ + } + + /* Initialize the description of how vertices should be translated. */ + for (i = 0; i < mgr->ve->count; i++) { + enum pipe_format output_format = mgr->ve->native_format[i]; + unsigned output_format_size = mgr->ve->native_format_size[i]; + + /* Check for support. */ + if (!mgr->ve->incompatible_layout_elem[i] && + !mgr->incompatible_vb[mgr->ve->ve[i].vertex_buffer_index]) { + continue; + } + + /* Workaround for translate: output floats instead of halfs. */ + switch (output_format) { + case PIPE_FORMAT_R16_FLOAT: + output_format = PIPE_FORMAT_R32_FLOAT; + output_format_size = 4; + break; + case PIPE_FORMAT_R16G16_FLOAT: + output_format = PIPE_FORMAT_R32G32_FLOAT; + output_format_size = 8; + break; + case PIPE_FORMAT_R16G16B16_FLOAT: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + output_format_size = 12; + break; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + output_format_size = 16; + break; + default:; + } + + /* Add this vertex element. */ + te = &key.element[key.nr_elements]; + te->type = TRANSLATE_ELEMENT_NORMAL; + te->instance_divisor = 0; + te->input_buffer = mgr->ve->ve[i].vertex_buffer_index; + te->input_format = mgr->ve->ve[i].src_format; + te->input_offset = mgr->ve->ve[i].src_offset; + te->output_format = output_format; + te->output_offset = key.output_stride; + + key.output_stride += output_format_size; + vb_translated[mgr->ve->ve[i].vertex_buffer_index] = TRUE; + tr_elem_index[i] = key.nr_elements; + key.nr_elements++; + } + + /* Get a translate object. */ + tr = translate_cache_find(mgr->translate_cache, &key); + + /* Map buffers we want to translate. */ + for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + if (vb_translated[i]) { + struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i]; + + uint8_t *map = pipe_buffer_map(mgr->pipe, vb->buffer, + PIPE_TRANSFER_READ, &vb_transfer[i]); + + tr->set_buffer(tr, i, + map + vb->buffer_offset + vb->stride * min_index, + vb->stride, ~0); + } + } + + /* Create and map the output buffer. */ + num_verts = max_index + 1 - min_index; + + u_upload_alloc(mgr->b.uploader, + key.output_stride * min_index, + key.output_stride * num_verts, + &out_offset, &out_buffer, &upload_flushed, + (void**)&out_map); + + out_offset -= key.output_stride * min_index; + + /* Translate. */ + tr->run(tr, 0, num_verts, 0, out_map); + + /* Unmap all buffers. */ + for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + if (vb_translated[i]) { + pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); + } + } + + /* Setup the new vertex buffer. */ + mgr->b.real_vertex_buffer[mgr->fallback_vb_slot].buffer_offset = out_offset; + mgr->b.real_vertex_buffer[mgr->fallback_vb_slot].stride = key.output_stride; + + /* Move the buffer reference. */ + pipe_resource_reference( + &mgr->b.real_vertex_buffer[mgr->fallback_vb_slot].buffer, NULL); + mgr->b.real_vertex_buffer[mgr->fallback_vb_slot].buffer = out_buffer; + out_buffer = NULL; + + /* Setup new vertex elements. */ + for (i = 0; i < mgr->ve->count; i++) { + if (tr_elem_index[i] < key.nr_elements) { + te = &key.element[tr_elem_index[i]]; + mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor; + mgr->fallback_velems[i].src_format = te->output_format; + mgr->fallback_velems[i].src_offset = te->output_offset; + mgr->fallback_velems[i].vertex_buffer_index = mgr->fallback_vb_slot; + } else { + memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i], + sizeof(struct pipe_vertex_element)); + } + } + + + mgr->fallback_ve = + mgr->pipe->create_vertex_elements_state(mgr->pipe, mgr->ve->count, + mgr->fallback_velems); + + /* Preserve saved_ve. */ + mgr->ve_binding_lock = TRUE; + mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->fallback_ve); + mgr->ve_binding_lock = FALSE; +} + +static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) +{ + if (mgr->fallback_ve == NULL) { + return; + } + + /* Restore vertex elements. */ + /* Note that saved_ve will be overwritten in bind_vertex_elements_state. */ + mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->saved_ve); + mgr->pipe->delete_vertex_elements_state(mgr->pipe, mgr->fallback_ve); + mgr->fallback_ve = NULL; + + /* Delete the now-unused VBO. */ + pipe_resource_reference(&mgr->b.real_vertex_buffer[mgr->fallback_vb_slot].buffer, + NULL); + mgr->fallback_vb_slot = ~0; + mgr->b.nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; +} + +#define FORMAT_REPLACE(what, withwhat) \ + case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break + +struct u_vbuf_elements * +u_vbuf_create_vertex_elements(struct u_vbuf *mgrb, + unsigned count, + const struct pipe_vertex_element *attribs, + struct pipe_vertex_element *native_attribs) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + unsigned i; + struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); + + ve->count = count; + + if (!count) { + return ve; + } + + memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); + memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count); + + /* Set the best native format in case the original format is not + * supported. */ + for (i = 0; i < count; i++) { + enum pipe_format format = ve->ve[i].src_format; + + ve->src_format_size[i] = util_format_get_blocksize(format); + + /* Choose a native format. + * For now we don't care about the alignment, that's going to + * be sorted out later. */ + if (!mgr->b.caps.format_fixed32) { + switch (format) { + FORMAT_REPLACE(R32_FIXED, R32_FLOAT); + FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT); + FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT); + FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT); + default:; + } + } + if (!mgr->b.caps.format_float16) { + switch (format) { + FORMAT_REPLACE(R16_FLOAT, R32_FLOAT); + FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT); + FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT); + FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT); + default:; + } + } + if (!mgr->b.caps.format_float64) { + switch (format) { + FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); + FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); + FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); + FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); + default:; + } + } + if (!mgr->b.caps.format_norm32) { + switch (format) { + FORMAT_REPLACE(R32_UNORM, R32_FLOAT); + FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); + FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); + FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); + FORMAT_REPLACE(R32_SNORM, R32_FLOAT); + FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); + FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); + FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); + default:; + } + } + if (!mgr->b.caps.format_scaled32) { + switch (format) { + FORMAT_REPLACE(R32_USCALED, R32_FLOAT); + FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); + FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); + FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); + FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); + FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); + FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); + FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); + default:; + } + } + + native_attribs[i].src_format = format; + ve->native_format[i] = format; + ve->native_format_size[i] = + util_format_get_blocksize(ve->native_format[i]); + + ve->incompatible_layout_elem[i] = + ve->ve[i].src_format != ve->native_format[i] || + (!mgr->b.caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0); + ve->incompatible_layout = + ve->incompatible_layout || + ve->incompatible_layout_elem[i]; + } + + /* Align the formats to the size of DWORD if needed. */ + if (!mgr->b.caps.fetch_dword_unaligned) { + for (i = 0; i < count; i++) { + ve->native_format_size[i] = align(ve->native_format_size[i], 4); + } + } + + return ve; +} + +void u_vbuf_bind_vertex_elements(struct u_vbuf *mgrb, + void *cso, + struct u_vbuf_elements *ve) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + + if (!cso) { + return; + } + + if (!mgr->ve_binding_lock) { + mgr->saved_ve = cso; + mgr->ve = ve; + } +} + +void u_vbuf_destroy_vertex_elements(struct u_vbuf *mgr, + struct u_vbuf_elements *ve) +{ + FREE(ve); +} + +void u_vbuf_set_vertex_buffers(struct u_vbuf *mgrb, + unsigned count, + const struct pipe_vertex_buffer *bufs) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + unsigned i; + + mgr->any_user_vbs = FALSE; + mgr->incompatible_vb_layout = FALSE; + memset(mgr->incompatible_vb, 0, sizeof(mgr->incompatible_vb)); + + if (!mgr->b.caps.fetch_dword_unaligned) { + /* Check if the strides and offsets are aligned to the size of DWORD. */ + for (i = 0; i < count; i++) { + if (bufs[i].buffer) { + if (bufs[i].stride % 4 != 0 || + bufs[i].buffer_offset % 4 != 0) { + mgr->incompatible_vb_layout = TRUE; + mgr->incompatible_vb[i] = TRUE; + } + } + } + } + + for (i = 0; i < count; i++) { + const struct pipe_vertex_buffer *vb = &bufs[i]; + + pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer); + + mgr->b.real_vertex_buffer[i].buffer_offset = + mgr->b.vertex_buffer[i].buffer_offset = vb->buffer_offset; + + mgr->b.real_vertex_buffer[i].stride = + mgr->b.vertex_buffer[i].stride = vb->stride; + + if (!vb->buffer || + mgr->incompatible_vb[i]) { + pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); + continue; + } + + if (u_vbuf_resource(vb->buffer)->user_ptr) { + pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); + mgr->any_user_vbs = TRUE; + continue; + } + + pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, vb->buffer); + } + + for (i = count; i < mgr->b.nr_vertex_buffers; i++) { + pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); + } + for (i = count; i < mgr->b.nr_real_vertex_buffers; i++) { + pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); + } + + mgr->b.nr_vertex_buffers = count; + mgr->b.nr_real_vertex_buffers = count; +} + +void u_vbuf_set_index_buffer(struct u_vbuf *mgr, + const struct pipe_index_buffer *ib) +{ + if (ib && ib->buffer) { + assert(ib->offset % ib->index_size == 0); + pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); + mgr->index_buffer.offset = ib->offset; + mgr->index_buffer.index_size = ib->index_size; + } else { + pipe_resource_reference(&mgr->index_buffer.buffer, NULL); + } +} + +static void +u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, + int min_index, int max_index, + unsigned instance_count) +{ + unsigned i; + unsigned count = max_index + 1 - min_index; + unsigned nr_velems = mgr->ve->count; + unsigned nr_vbufs = mgr->b.nr_vertex_buffers; + struct pipe_vertex_element *velems = + mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; + unsigned start_offset[PIPE_MAX_ATTRIBS]; + unsigned end_offset[PIPE_MAX_ATTRIBS] = {0}; + + /* Determine how much data needs to be uploaded. */ + for (i = 0; i < nr_velems; i++) { + struct pipe_vertex_element *velem = &velems[i]; + unsigned index = velem->vertex_buffer_index; + struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index]; + unsigned instance_div, first, size; + + /* Skip the buffer generated by translate. */ + if (index == mgr->fallback_vb_slot) { + continue; + } + + assert(vb->buffer); + + if (!u_vbuf_resource(vb->buffer)->user_ptr) { + continue; + } + + instance_div = velem->instance_divisor; + first = vb->buffer_offset + velem->src_offset; + + if (!vb->stride) { + /* Constant attrib. */ + size = mgr->ve->src_format_size[i]; + } else if (instance_div) { + /* Per-instance attrib. */ + unsigned count = (instance_count + instance_div - 1) / instance_div; + size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; + } else { + /* Per-vertex attrib. */ + first += vb->stride * min_index; + size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; + } + + /* Update offsets. */ + if (!end_offset[index]) { + start_offset[index] = first; + end_offset[index] = first + size; + } else { + if (first < start_offset[index]) + start_offset[index] = first; + if (first + size > end_offset[index]) + end_offset[index] = first + size; + } + } + + /* Upload buffers. */ + for (i = 0; i < nr_vbufs; i++) { + unsigned start, end = end_offset[i]; + boolean flushed; + struct pipe_vertex_buffer *real_vb; + uint8_t *ptr; + + if (!end) { + continue; + } + + start = start_offset[i]; + assert(start < end); + + real_vb = &mgr->b.real_vertex_buffer[i]; + ptr = u_vbuf_resource(mgr->b.vertex_buffer[i].buffer)->user_ptr; + + u_upload_data(mgr->b.uploader, start, end - start, ptr + start, + &real_vb->buffer_offset, &real_vb->buffer, &flushed); + + real_vb->buffer_offset -= start; + } +} + +unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf *mgrb) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + unsigned i, nr = mgr->ve->count; + struct pipe_vertex_element *velems = + mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; + unsigned result = ~0; + + for (i = 0; i < nr; i++) { + struct pipe_vertex_buffer *vb = + &mgr->b.real_vertex_buffer[velems[i].vertex_buffer_index]; + unsigned size, max_count, value; + + /* We're not interested in constant and per-instance attribs. */ + if (!vb->buffer || + !vb->stride || + velems[i].instance_divisor) { + continue; + } + + size = vb->buffer->width0; + + /* Subtract buffer_offset. */ + value = vb->buffer_offset; + if (value >= size) { + return 0; + } + size -= value; + + /* Subtract src_offset. */ + value = velems[i].src_offset; + if (value >= size) { + return 0; + } + size -= value; + + /* Subtract format_size. */ + value = mgr->ve->native_format_size[i]; + if (value >= size) { + return 0; + } + size -= value; + + /* Compute the max count. */ + max_count = 1 + size / vb->stride; + result = MIN2(result, max_count); + } + return result; +} + +static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) +{ + unsigned i, nr = mgr->ve->count; + + for (i = 0; i < nr; i++) { + struct pipe_vertex_buffer *vb; + unsigned index; + + /* Per-instance attribs don't need min/max_index. */ + if (mgr->ve->ve[i].instance_divisor) { + continue; + } + + index = mgr->ve->ve[i].vertex_buffer_index; + vb = &mgr->b.vertex_buffer[index]; + + /* Constant attribs don't need min/max_index. */ + if (!vb->stride) { + continue; + } + + /* Per-vertex attribs need min/max_index. */ + if (u_vbuf_resource(vb->buffer)->user_ptr || + mgr->ve->incompatible_layout_elem[i] || + mgr->incompatible_vb[index]) { + return TRUE; + } + } + + return FALSE; +} + +static void u_vbuf_get_minmax_index(struct pipe_context *pipe, + struct pipe_index_buffer *ib, + const struct pipe_draw_info *info, + int *out_min_index, + int *out_max_index) +{ + struct pipe_transfer *transfer = NULL; + const void *indices; + unsigned i; + unsigned restart_index = info->restart_index; + + if (u_vbuf_resource(ib->buffer)->user_ptr) { + indices = u_vbuf_resource(ib->buffer)->user_ptr + + ib->offset + info->start * ib->index_size; + } else { + indices = pipe_buffer_map_range(pipe, ib->buffer, + ib->offset + info->start * ib->index_size, + info->count * ib->index_size, + PIPE_TRANSFER_READ, &transfer); + } + + switch (ib->index_size) { + case 4: { + const unsigned *ui_indices = (const unsigned*)indices; + unsigned max_ui = 0; + unsigned min_ui = ~0U; + if (info->primitive_restart) { + for (i = 0; i < info->count; i++) { + if (ui_indices[i] != restart_index) { + if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; + if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; + } + } + } + else { + for (i = 0; i < info->count; i++) { + if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; + if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; + } + } + *out_min_index = min_ui; + *out_max_index = max_ui; + break; + } + case 2: { + const unsigned short *us_indices = (const unsigned short*)indices; + unsigned max_us = 0; + unsigned min_us = ~0U; + if (info->primitive_restart) { + for (i = 0; i < info->count; i++) { + if (us_indices[i] != restart_index) { + if (us_indices[i] > max_us) max_us = us_indices[i]; + if (us_indices[i] < min_us) min_us = us_indices[i]; + } + } + } + else { + for (i = 0; i < info->count; i++) { + if (us_indices[i] > max_us) max_us = us_indices[i]; + if (us_indices[i] < min_us) min_us = us_indices[i]; + } + } + *out_min_index = min_us; + *out_max_index = max_us; + break; + } + case 1: { + const unsigned char *ub_indices = (const unsigned char*)indices; + unsigned max_ub = 0; + unsigned min_ub = ~0U; + if (info->primitive_restart) { + for (i = 0; i < info->count; i++) { + if (ub_indices[i] != restart_index) { + if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; + if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; + } + } + } + else { + for (i = 0; i < info->count; i++) { + if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; + if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; + } + } + *out_min_index = min_ub; + *out_max_index = max_ub; + break; + } + default: + assert(0); + } + + if (transfer) { + pipe_buffer_unmap(pipe, transfer); + } +} + +enum u_vbuf_return_flags +u_vbuf_draw_begin(struct u_vbuf *mgrb, + const struct pipe_draw_info *info) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + int min_index, max_index; + + if (!mgr->incompatible_vb_layout && + !mgr->ve->incompatible_layout && + !mgr->any_user_vbs) { + return 0; + } + + if (info->indexed) { + if (info->max_index != ~0) { + min_index = info->min_index + info->index_bias; + max_index = info->max_index + info->index_bias; + } else if (u_vbuf_need_minmax_index(mgr)) { + u_vbuf_get_minmax_index(mgr->pipe, &mgr->b.index_buffer, info, + &min_index, &max_index); + min_index += info->index_bias; + max_index += info->index_bias; + } else { + min_index = 0; + max_index = 0; + } + } else { + min_index = info->start; + max_index = info->start + info->count - 1; + } + + /* Translate vertices with non-native layouts or formats. */ + if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) { + u_vbuf_translate_begin(mgr, min_index, max_index); + } + + /* Upload user buffers. */ + if (mgr->any_user_vbs) { + u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count); + } + return U_VBUF_BUFFERS_UPDATED; +} + +void u_vbuf_draw_end(struct u_vbuf *mgrb) +{ + struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; + + if (mgr->fallback_ve) { + u_vbuf_translate_end(mgr); + } +} diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.h b/mesalib/src/gallium/auxiliary/util/u_vbuf.h new file mode 100644 index 000000000..57b93ddea --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.h @@ -0,0 +1,145 @@ +/************************************************************************** + * + * Copyright 2011 Marek Olšák + * 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 AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_VBUF_MGR_H +#define U_VBUF_MGR_H + +/* This module builds upon u_upload_mgr and translate_cache and takes care of + * user buffer uploads and vertex format fallbacks. It's designed + * for the drivers which don't always use the Draw module. (e.g. for HWTCL) + */ + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "util/u_transfer.h" + +/* Hardware vertex fetcher limitations can be described by this structure. */ +struct u_vbuf_caps { + /* Vertex format CAPs. */ + /* TRUE if hardware supports it. */ + unsigned format_fixed32:1; /* PIPE_FORMAT_*32*_FIXED */ + unsigned format_float16:1; /* PIPE_FORMAT_*16*_FLOAT */ + unsigned format_float64:1; /* PIPE_FORMAT_*64*_FLOAT */ + unsigned format_norm32:1; /* PIPE_FORMAT_*32*NORM */ + unsigned format_scaled32:1; /* PIPE_FORMAT_*32*SCALED */ + + /* Whether vertex fetches don't have to be dword-aligned. */ + /* TRUE if hardware supports it. */ + unsigned fetch_dword_unaligned:1; +}; + +/* The manager. + * This structure should also be used to access vertex buffers + * from a driver. */ +struct u_vbuf { + /* This is what was set in set_vertex_buffers. + * May contain user buffers. */ + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + + /* Contains only real vertex buffers. + * Hardware drivers should use real_vertex_buffers[i] + * instead of vertex_buffers[i].buffer. */ + struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS]; + int nr_real_vertex_buffers; + + /* The index buffer. */ + struct pipe_index_buffer index_buffer; + + /* This uploader can optionally be used by the driver. + * + * Allowed functions: + * - u_upload_alloc + * - u_upload_data + * - u_upload_buffer + * - u_upload_flush */ + struct u_upload_mgr *uploader; + + struct u_vbuf_caps caps; +}; + +struct u_vbuf_resource { + struct u_resource b; + uint8_t *user_ptr; +}; + +/* Opaque type containing information about vertex elements for the manager. */ +struct u_vbuf_elements; + +enum u_fetch_alignment { + U_VERTEX_FETCH_BYTE_ALIGNED, + U_VERTEX_FETCH_DWORD_ALIGNED +}; + +enum u_vbuf_return_flags { + U_VBUF_BUFFERS_UPDATED = 1 +}; + + +struct u_vbuf * +u_vbuf_create(struct pipe_context *pipe, + unsigned upload_buffer_size, + unsigned upload_buffer_alignment, + unsigned upload_buffer_bind, + enum u_fetch_alignment fetch_alignment); + +void u_vbuf_destroy(struct u_vbuf *mgr); + +struct u_vbuf_elements * +u_vbuf_create_vertex_elements(struct u_vbuf *mgr, + unsigned count, + const struct pipe_vertex_element *attrs, + struct pipe_vertex_element *native_attrs); + +void u_vbuf_bind_vertex_elements(struct u_vbuf *mgr, + void *cso, + struct u_vbuf_elements *ve); + +void u_vbuf_destroy_vertex_elements(struct u_vbuf *mgr, + struct u_vbuf_elements *ve); + +void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, + unsigned count, + const struct pipe_vertex_buffer *bufs); + +void u_vbuf_set_index_buffer(struct u_vbuf *mgr, + const struct pipe_index_buffer *ib); + +enum u_vbuf_return_flags u_vbuf_draw_begin(struct u_vbuf *mgr, + const struct pipe_draw_info *info); + +unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf *mgr); + +void u_vbuf_draw_end(struct u_vbuf *mgr); + + +static INLINE struct u_vbuf_resource *u_vbuf_resource(struct pipe_resource *r) +{ + return (struct u_vbuf_resource*)r; +} + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.c b/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.c deleted file mode 100644 index 7e36018a0..000000000 --- a/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.c +++ /dev/null @@ -1,849 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Marek Olšák - * 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 AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "util/u_vbuf_mgr.h" - -#include "util/u_format.h" -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_upload_mgr.h" -#include "translate/translate.h" -#include "translate/translate_cache.h" - -struct u_vbuf_elements { - unsigned count; - struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; - - unsigned src_format_size[PIPE_MAX_ATTRIBS]; - - /* If (velem[i].src_format != native_format[i]), the vertex buffer - * referenced by the vertex element cannot be used for rendering and - * its vertex data must be translated to native_format[i]. */ - enum pipe_format native_format[PIPE_MAX_ATTRIBS]; - unsigned native_format_size[PIPE_MAX_ATTRIBS]; - - /* This might mean two things: - * - src_format != native_format, as discussed above. - * - src_offset % 4 != 0 (if the caps don't allow such an offset). */ - boolean incompatible_layout; - /* Per-element flags. */ - boolean incompatible_layout_elem[PIPE_MAX_ATTRIBS]; -}; - -struct u_vbuf_priv { - struct u_vbuf_mgr b; - struct pipe_context *pipe; - struct translate_cache *translate_cache; - - /* Whether there is any user buffer. */ - boolean any_user_vbs; - - /* Vertex element state bound by the state tracker. */ - void *saved_ve; - /* and its associated helper structure for this module. */ - struct u_vbuf_elements *ve; - - /* Vertex elements used for the translate fallback. */ - struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; - /* If non-NULL, this is a vertex element state used for the translate - * fallback and therefore used for rendering too. */ - void *fallback_ve; - /* The vertex buffer slot index where translated vertices have been - * stored in. */ - unsigned translate_vb_slot; - /* When binding the fallback vertex element state, we don't want to - * change saved_ve and ve. This is set to TRUE in such cases. */ - boolean ve_binding_lock; - - /* Whether there is a buffer with a non-native layout. */ - boolean incompatible_vb_layout; - /* Per-buffer flags. */ - boolean incompatible_vb[PIPE_MAX_ATTRIBS]; -}; - -static void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr) -{ - struct pipe_screen *screen = mgr->pipe->screen; - - mgr->b.caps.format_fixed32 = - screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER); - - mgr->b.caps.format_float16 = - screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER); - - mgr->b.caps.format_float64 = - screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER); - - mgr->b.caps.format_norm32 = - screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER) && - screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER); - - mgr->b.caps.format_scaled32 = - screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER) && - screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER); -} - -struct u_vbuf_mgr * -u_vbuf_create(struct pipe_context *pipe, - unsigned upload_buffer_size, - unsigned upload_buffer_alignment, - unsigned upload_buffer_bind, - enum u_fetch_alignment fetch_alignment) -{ - struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv); - - mgr->pipe = pipe; - mgr->translate_cache = translate_cache_create(); - mgr->translate_vb_slot = ~0; - - mgr->b.uploader = u_upload_create(pipe, upload_buffer_size, - upload_buffer_alignment, - upload_buffer_bind); - - mgr->b.caps.fetch_dword_unaligned = - fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED; - - u_vbuf_init_format_caps(mgr); - - return &mgr->b; -} - -void u_vbuf_destroy(struct u_vbuf_mgr *mgrb) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - unsigned i; - - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); - } - for (i = 0; i < mgr->b.nr_real_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); - } - - translate_cache_destroy(mgr->translate_cache); - u_upload_destroy(mgr->b.uploader); - FREE(mgr); -} - - -static void -u_vbuf_translate_begin(struct u_vbuf_priv *mgr, - int min_index, int max_index) -{ - struct translate_key key; - struct translate_element *te; - unsigned tr_elem_index[PIPE_MAX_ATTRIBS]; - struct translate *tr; - boolean vb_translated[PIPE_MAX_ATTRIBS] = {0}; - uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map; - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; - struct pipe_resource *out_buffer = NULL; - unsigned i, num_verts, out_offset; - boolean upload_flushed = FALSE; - - memset(&key, 0, sizeof(key)); - memset(tr_elem_index, 0xff, sizeof(tr_elem_index)); - - /* Initialize the translate key, i.e. the recipe how vertices should be - * translated. */ - memset(&key, 0, sizeof key); - for (i = 0; i < mgr->ve->count; i++) { - enum pipe_format output_format = mgr->ve->native_format[i]; - unsigned output_format_size = mgr->ve->native_format_size[i]; - - /* Check for support. */ - if (!mgr->ve->incompatible_layout_elem[i] && - !mgr->incompatible_vb[mgr->ve->ve[i].vertex_buffer_index]) { - continue; - } - - /* Workaround for translate: output floats instead of halfs. */ - switch (output_format) { - case PIPE_FORMAT_R16_FLOAT: - output_format = PIPE_FORMAT_R32_FLOAT; - output_format_size = 4; - break; - case PIPE_FORMAT_R16G16_FLOAT: - output_format = PIPE_FORMAT_R32G32_FLOAT; - output_format_size = 8; - break; - case PIPE_FORMAT_R16G16B16_FLOAT: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - output_format_size = 12; - break; - case PIPE_FORMAT_R16G16B16A16_FLOAT: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - output_format_size = 16; - break; - default:; - } - - /* Add this vertex element. */ - te = &key.element[key.nr_elements]; - /*te->type; - te->instance_divisor;*/ - te->input_buffer = mgr->ve->ve[i].vertex_buffer_index; - te->input_format = mgr->ve->ve[i].src_format; - te->input_offset = mgr->ve->ve[i].src_offset; - te->output_format = output_format; - te->output_offset = key.output_stride; - - key.output_stride += output_format_size; - vb_translated[mgr->ve->ve[i].vertex_buffer_index] = TRUE; - tr_elem_index[i] = key.nr_elements; - key.nr_elements++; - } - - /* Get a translate object. */ - tr = translate_cache_find(mgr->translate_cache, &key); - - /* Map buffers we want to translate. */ - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { - if (vb_translated[i]) { - struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i]; - - vb_map[i] = pipe_buffer_map(mgr->pipe, vb->buffer, - PIPE_TRANSFER_READ, &vb_transfer[i]); - - tr->set_buffer(tr, i, - vb_map[i] + vb->buffer_offset + vb->stride * min_index, - vb->stride, ~0); - } - } - - /* Create and map the output buffer. */ - num_verts = max_index + 1 - min_index; - - u_upload_alloc(mgr->b.uploader, - key.output_stride * min_index, - key.output_stride * num_verts, - &out_offset, &out_buffer, &upload_flushed, - (void**)&out_map); - - out_offset -= key.output_stride * min_index; - - /* Translate. */ - tr->run(tr, 0, num_verts, 0, out_map); - - /* Unmap all buffers. */ - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { - if (vb_translated[i]) { - pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); - } - } - - /* Setup the new vertex buffer in the first free slot. */ - mgr->translate_vb_slot = ~0; - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (!mgr->b.vertex_buffer[i].buffer) { - mgr->translate_vb_slot = i; - - if (i >= mgr->b.nr_vertex_buffers) { - mgr->b.nr_real_vertex_buffers = i+1; - } - break; - } - } - - if (mgr->translate_vb_slot != ~0) { - /* Setup the new vertex buffer. */ - pipe_resource_reference( - &mgr->b.real_vertex_buffer[mgr->translate_vb_slot].buffer, out_buffer); - mgr->b.real_vertex_buffer[mgr->translate_vb_slot].buffer_offset = out_offset; - mgr->b.real_vertex_buffer[mgr->translate_vb_slot].stride = key.output_stride; - - /* Setup new vertex elements. */ - for (i = 0; i < mgr->ve->count; i++) { - if (tr_elem_index[i] < key.nr_elements) { - te = &key.element[tr_elem_index[i]]; - mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor; - mgr->fallback_velems[i].src_format = te->output_format; - mgr->fallback_velems[i].src_offset = te->output_offset; - mgr->fallback_velems[i].vertex_buffer_index = mgr->translate_vb_slot; - } else { - memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i], - sizeof(struct pipe_vertex_element)); - } - } - - mgr->fallback_ve = - mgr->pipe->create_vertex_elements_state(mgr->pipe, mgr->ve->count, - mgr->fallback_velems); - - /* Preserve saved_ve. */ - mgr->ve_binding_lock = TRUE; - mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->fallback_ve); - mgr->ve_binding_lock = FALSE; - } - - pipe_resource_reference(&out_buffer, NULL); -} - -static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) -{ - if (mgr->fallback_ve == NULL) { - return; - } - - /* Restore vertex elements. */ - /* Note that saved_ve will be overwritten in bind_vertex_elements_state. */ - mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->saved_ve); - mgr->pipe->delete_vertex_elements_state(mgr->pipe, mgr->fallback_ve); - mgr->fallback_ve = NULL; - - /* Delete the now-unused VBO. */ - pipe_resource_reference(&mgr->b.real_vertex_buffer[mgr->translate_vb_slot].buffer, - NULL); - mgr->translate_vb_slot = ~0; - mgr->b.nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; -} - -#define FORMAT_REPLACE(what, withwhat) \ - case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break - -struct u_vbuf_elements * -u_vbuf_create_vertex_elements(struct u_vbuf_mgr *mgrb, - unsigned count, - const struct pipe_vertex_element *attribs, - struct pipe_vertex_element *native_attribs) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - unsigned i; - struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); - - ve->count = count; - - if (!count) { - return ve; - } - - memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); - memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count); - - /* Set the best native format in case the original format is not - * supported. */ - for (i = 0; i < count; i++) { - enum pipe_format format = ve->ve[i].src_format; - - ve->src_format_size[i] = util_format_get_blocksize(format); - - /* Choose a native format. - * For now we don't care about the alignment, that's going to - * be sorted out later. */ - if (!mgr->b.caps.format_fixed32) { - switch (format) { - FORMAT_REPLACE(R32_FIXED, R32_FLOAT); - FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT); - default:; - } - } - if (!mgr->b.caps.format_float16) { - switch (format) { - FORMAT_REPLACE(R16_FLOAT, R32_FLOAT); - FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT); - FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT); - FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT); - default:; - } - } - if (!mgr->b.caps.format_float64) { - switch (format) { - FORMAT_REPLACE(R64_FLOAT, R32_FLOAT); - FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT); - FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT); - FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT); - default:; - } - } - if (!mgr->b.caps.format_norm32) { - switch (format) { - FORMAT_REPLACE(R32_UNORM, R32_FLOAT); - FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT); - FORMAT_REPLACE(R32_SNORM, R32_FLOAT); - FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT); - default:; - } - } - if (!mgr->b.caps.format_scaled32) { - switch (format) { - FORMAT_REPLACE(R32_USCALED, R32_FLOAT); - FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); - FORMAT_REPLACE(R32_SSCALED, R32_FLOAT); - FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT); - FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT); - FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); - default:; - } - } - - native_attribs[i].src_format = format; - ve->native_format[i] = format; - ve->native_format_size[i] = - util_format_get_blocksize(ve->native_format[i]); - - ve->incompatible_layout_elem[i] = - ve->ve[i].src_format != ve->native_format[i] || - (!mgr->b.caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0); - ve->incompatible_layout = - ve->incompatible_layout || - ve->incompatible_layout_elem[i]; - } - - /* Align the formats to the size of DWORD if needed. */ - if (!mgr->b.caps.fetch_dword_unaligned) { - for (i = 0; i < count; i++) { - ve->native_format_size[i] = align(ve->native_format_size[i], 4); - } - } - - return ve; -} - -void u_vbuf_bind_vertex_elements(struct u_vbuf_mgr *mgrb, - void *cso, - struct u_vbuf_elements *ve) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - - if (!cso) { - return; - } - - if (!mgr->ve_binding_lock) { - mgr->saved_ve = cso; - mgr->ve = ve; - } -} - -void u_vbuf_destroy_vertex_elements(struct u_vbuf_mgr *mgr, - struct u_vbuf_elements *ve) -{ - FREE(ve); -} - -void u_vbuf_set_vertex_buffers(struct u_vbuf_mgr *mgrb, - unsigned count, - const struct pipe_vertex_buffer *bufs) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - unsigned i; - - mgr->any_user_vbs = FALSE; - mgr->incompatible_vb_layout = FALSE; - memset(mgr->incompatible_vb, 0, sizeof(mgr->incompatible_vb)); - - if (!mgr->b.caps.fetch_dword_unaligned) { - /* Check if the strides and offsets are aligned to the size of DWORD. */ - for (i = 0; i < count; i++) { - if (bufs[i].buffer) { - if (bufs[i].stride % 4 != 0 || - bufs[i].buffer_offset % 4 != 0) { - mgr->incompatible_vb_layout = TRUE; - mgr->incompatible_vb[i] = TRUE; - } - } - } - } - - for (i = 0; i < count; i++) { - const struct pipe_vertex_buffer *vb = &bufs[i]; - - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer); - - mgr->b.real_vertex_buffer[i].buffer_offset = - mgr->b.vertex_buffer[i].buffer_offset = vb->buffer_offset; - - mgr->b.real_vertex_buffer[i].stride = - mgr->b.vertex_buffer[i].stride = vb->stride; - - if (!vb->buffer) { - pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); - continue; - } - - if (u_vbuf_resource(vb->buffer)->user_ptr) { - pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); - mgr->any_user_vbs = TRUE; - continue; - } - - pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, vb->buffer); - } - - for (i = count; i < mgr->b.nr_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); - } - for (i = count; i < mgr->b.nr_real_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.real_vertex_buffer[i].buffer, NULL); - } - - mgr->b.nr_vertex_buffers = count; - mgr->b.nr_real_vertex_buffers = count; -} - -void u_vbuf_set_index_buffer(struct u_vbuf_mgr *mgr, - const struct pipe_index_buffer *ib) -{ - if (ib && ib->buffer) { - assert(ib->offset % ib->index_size == 0); - pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); - mgr->index_buffer.offset = ib->offset; - mgr->index_buffer.index_size = ib->index_size; - } else { - pipe_resource_reference(&mgr->index_buffer.buffer, NULL); - } -} - -static void -u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, - int min_index, int max_index, - unsigned instance_count) -{ - unsigned i; - unsigned count = max_index + 1 - min_index; - unsigned nr_velems = mgr->ve->count; - unsigned nr_vbufs = mgr->b.nr_vertex_buffers; - struct pipe_vertex_element *velems = - mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; - unsigned start_offset[PIPE_MAX_ATTRIBS]; - unsigned end_offset[PIPE_MAX_ATTRIBS] = {0}; - - /* Determine how much data needs to be uploaded. */ - for (i = 0; i < nr_velems; i++) { - struct pipe_vertex_element *velem = &velems[i]; - unsigned index = velem->vertex_buffer_index; - struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index]; - unsigned instance_div, first, size; - - /* Skip the buffer generated by translate. */ - if (index == mgr->translate_vb_slot) { - continue; - } - - assert(vb->buffer); - - if (!u_vbuf_resource(vb->buffer)->user_ptr) { - continue; - } - - instance_div = velem->instance_divisor; - first = vb->buffer_offset + velem->src_offset; - - if (!vb->stride) { - /* Constant attrib. */ - size = mgr->ve->src_format_size[i]; - } else if (instance_div) { - /* Per-instance attrib. */ - unsigned count = (instance_count + instance_div - 1) / instance_div; - size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; - } else { - /* Per-vertex attrib. */ - first += vb->stride * min_index; - size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; - } - - /* Update offsets. */ - if (!end_offset[index]) { - start_offset[index] = first; - end_offset[index] = first + size; - } else { - if (first < start_offset[index]) - start_offset[index] = first; - if (first + size > end_offset[index]) - end_offset[index] = first + size; - } - } - - /* Upload buffers. */ - for (i = 0; i < nr_vbufs; i++) { - unsigned start, end = end_offset[i]; - boolean flushed; - struct pipe_vertex_buffer *real_vb; - uint8_t *ptr; - - if (!end) { - continue; - } - - start = start_offset[i]; - assert(start < end); - - real_vb = &mgr->b.real_vertex_buffer[i]; - ptr = u_vbuf_resource(mgr->b.vertex_buffer[i].buffer)->user_ptr; - - u_upload_data(mgr->b.uploader, start, end - start, ptr + start, - &real_vb->buffer_offset, &real_vb->buffer, &flushed); - - real_vb->buffer_offset -= start; - } -} - -unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf_mgr *mgrb) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - unsigned i, nr = mgr->ve->count; - struct pipe_vertex_element *velems = - mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; - unsigned result = ~0; - - for (i = 0; i < nr; i++) { - struct pipe_vertex_buffer *vb = - &mgr->b.real_vertex_buffer[velems[i].vertex_buffer_index]; - unsigned size, max_count, value; - - /* We're not interested in constant and per-instance attribs. */ - if (!vb->buffer || - !vb->stride || - velems[i].instance_divisor) { - continue; - } - - size = vb->buffer->width0; - - /* Subtract buffer_offset. */ - value = vb->buffer_offset; - if (value >= size) { - return 0; - } - size -= value; - - /* Subtract src_offset. */ - value = velems[i].src_offset; - if (value >= size) { - return 0; - } - size -= value; - - /* Subtract format_size. */ - value = mgr->ve->native_format_size[i]; - if (value >= size) { - return 0; - } - size -= value; - - /* Compute the max count. */ - max_count = 1 + size / vb->stride; - result = MIN2(result, max_count); - } - return result; -} - -static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) -{ - unsigned i, nr = mgr->ve->count; - - for (i = 0; i < nr; i++) { - struct pipe_vertex_buffer *vb; - unsigned index; - - /* Per-instance attribs don't need min/max_index. */ - if (mgr->ve->ve[i].instance_divisor) { - continue; - } - - index = mgr->ve->ve[i].vertex_buffer_index; - vb = &mgr->b.vertex_buffer[index]; - - /* Constant attribs don't need min/max_index. */ - if (!vb->stride) { - continue; - } - - /* Per-vertex attribs need min/max_index. */ - if (u_vbuf_resource(vb->buffer)->user_ptr || - mgr->ve->incompatible_layout_elem[i] || - mgr->incompatible_vb[index]) { - return TRUE; - } - } - - return FALSE; -} - -static void u_vbuf_get_minmax_index(struct pipe_context *pipe, - struct pipe_index_buffer *ib, - const struct pipe_draw_info *info, - int *out_min_index, - int *out_max_index) -{ - struct pipe_transfer *transfer = NULL; - const void *indices; - unsigned i; - unsigned restart_index = info->restart_index; - - if (u_vbuf_resource(ib->buffer)->user_ptr) { - indices = u_vbuf_resource(ib->buffer)->user_ptr + - ib->offset + info->start * ib->index_size; - } else { - indices = pipe_buffer_map_range(pipe, ib->buffer, - ib->offset + info->start * ib->index_size, - info->count * ib->index_size, - PIPE_TRANSFER_READ, &transfer); - } - - switch (ib->index_size) { - case 4: { - const unsigned *ui_indices = (const unsigned*)indices; - unsigned max_ui = 0; - unsigned min_ui = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { - if (ui_indices[i] != restart_index) { - if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; - if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; - } - } - } - else { - for (i = 0; i < info->count; i++) { - if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; - if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; - } - } - *out_min_index = min_ui; - *out_max_index = max_ui; - break; - } - case 2: { - const unsigned short *us_indices = (const unsigned short*)indices; - unsigned max_us = 0; - unsigned min_us = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { - if (us_indices[i] != restart_index) { - if (us_indices[i] > max_us) max_us = us_indices[i]; - if (us_indices[i] < min_us) min_us = us_indices[i]; - } - } - } - else { - for (i = 0; i < info->count; i++) { - if (us_indices[i] > max_us) max_us = us_indices[i]; - if (us_indices[i] < min_us) min_us = us_indices[i]; - } - } - *out_min_index = min_us; - *out_max_index = max_us; - break; - } - case 1: { - const unsigned char *ub_indices = (const unsigned char*)indices; - unsigned max_ub = 0; - unsigned min_ub = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { - if (ub_indices[i] != restart_index) { - if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; - if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; - } - } - } - else { - for (i = 0; i < info->count; i++) { - if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; - if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; - } - } - *out_min_index = min_ub; - *out_max_index = max_ub; - break; - } - default: - assert(0); - } - - if (transfer) { - pipe_buffer_unmap(pipe, transfer); - } -} - -enum u_vbuf_return_flags -u_vbuf_draw_begin(struct u_vbuf_mgr *mgrb, - const struct pipe_draw_info *info) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - int min_index, max_index; - - if (!mgr->incompatible_vb_layout && - !mgr->ve->incompatible_layout && - !mgr->any_user_vbs) { - return 0; - } - - if (info->indexed) { - if (info->max_index != ~0) { - min_index = info->min_index + info->index_bias; - max_index = info->max_index + info->index_bias; - } else if (u_vbuf_need_minmax_index(mgr)) { - u_vbuf_get_minmax_index(mgr->pipe, &mgr->b.index_buffer, info, - &min_index, &max_index); - min_index += info->index_bias; - max_index += info->index_bias; - } else { - min_index = 0; - max_index = 0; - } - } else { - min_index = info->start; - max_index = info->start + info->count - 1; - } - - /* Translate vertices with non-native layouts or formats. */ - if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) { - u_vbuf_translate_begin(mgr, min_index, max_index); - } - - /* Upload user buffers. */ - if (mgr->any_user_vbs) { - u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count); - } - return U_VBUF_BUFFERS_UPDATED; -} - -void u_vbuf_draw_end(struct u_vbuf_mgr *mgrb) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - - if (mgr->fallback_ve) { - u_vbuf_translate_end(mgr); - } -} diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.h b/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.h deleted file mode 100644 index 42ca0ac35..000000000 --- a/mesalib/src/gallium/auxiliary/util/u_vbuf_mgr.h +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Marek Olšák - * 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 AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef U_VBUF_MGR_H -#define U_VBUF_MGR_H - -/* This module builds upon u_upload_mgr and translate_cache and takes care of - * user buffer uploads and vertex format fallbacks. It's designed - * for the drivers which don't always use the Draw module. (e.g. for HWTCL) - */ - -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_transfer.h" - -/* Hardware vertex fetcher limitations can be described by this structure. */ -struct u_vbuf_caps { - /* Vertex format CAPs. */ - /* TRUE if hardware supports it. */ - unsigned format_fixed32:1; /* PIPE_FORMAT_*32*_FIXED */ - unsigned format_float16:1; /* PIPE_FORMAT_*16*_FLOAT */ - unsigned format_float64:1; /* PIPE_FORMAT_*64*_FLOAT */ - unsigned format_norm32:1; /* PIPE_FORMAT_*32*NORM */ - unsigned format_scaled32:1; /* PIPE_FORMAT_*32*SCALED */ - - /* Whether vertex fetches don't have to be dword-aligned. */ - /* TRUE if hardware supports it. */ - unsigned fetch_dword_unaligned:1; -}; - -/* The manager. - * This structure should also be used to access vertex buffers - * from a driver. */ -struct u_vbuf_mgr { - /* This is what was set in set_vertex_buffers. - * May contain user buffers. */ - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_buffers; - - /* Contains only real vertex buffers. - * Hardware drivers should use real_vertex_buffers[i] - * instead of vertex_buffers[i].buffer. */ - struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS]; - int nr_real_vertex_buffers; - - /* The index buffer. */ - struct pipe_index_buffer index_buffer; - - /* This uploader can optionally be used by the driver. - * - * Allowed functions: - * - u_upload_alloc - * - u_upload_data - * - u_upload_buffer - * - u_upload_flush */ - struct u_upload_mgr *uploader; - - struct u_vbuf_caps caps; -}; - -struct u_vbuf_resource { - struct u_resource b; - uint8_t *user_ptr; -}; - -/* Opaque type containing information about vertex elements for the manager. */ -struct u_vbuf_elements; - -enum u_fetch_alignment { - U_VERTEX_FETCH_BYTE_ALIGNED, - U_VERTEX_FETCH_DWORD_ALIGNED -}; - -enum u_vbuf_return_flags { - U_VBUF_BUFFERS_UPDATED = 1 -}; - - -struct u_vbuf_mgr * -u_vbuf_create(struct pipe_context *pipe, - unsigned upload_buffer_size, - unsigned upload_buffer_alignment, - unsigned upload_buffer_bind, - enum u_fetch_alignment fetch_alignment); - -void u_vbuf_destroy(struct u_vbuf_mgr *mgr); - -struct u_vbuf_elements * -u_vbuf_create_vertex_elements(struct u_vbuf_mgr *mgr, - unsigned count, - const struct pipe_vertex_element *attrs, - struct pipe_vertex_element *native_attrs); - -void u_vbuf_bind_vertex_elements(struct u_vbuf_mgr *mgr, - void *cso, - struct u_vbuf_elements *ve); - -void u_vbuf_destroy_vertex_elements(struct u_vbuf_mgr *mgr, - struct u_vbuf_elements *ve); - -void u_vbuf_set_vertex_buffers(struct u_vbuf_mgr *mgr, - unsigned count, - const struct pipe_vertex_buffer *bufs); - -void u_vbuf_set_index_buffer(struct u_vbuf_mgr *mgr, - const struct pipe_index_buffer *ib); - -enum u_vbuf_return_flags u_vbuf_draw_begin(struct u_vbuf_mgr *mgr, - const struct pipe_draw_info *info); - -unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf_mgr *mgr); - -void u_vbuf_draw_end(struct u_vbuf_mgr *mgr); - - -static INLINE struct u_vbuf_resource *u_vbuf_resource(struct pipe_resource *r) -{ - return (struct u_vbuf_resource*)r; -} - -#endif diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index ac090c315..d5b04e9d7 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2090,6 +2090,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, * The following extension do not allow the deprecated keywords: * * GL_AMD_conservative_depth + * GL_ARB_conservative_depth * GL_ARB_gpu_shader5 * GL_ARB_separate_shader_objects * GL_ARB_tesselation_shader @@ -2122,9 +2123,11 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, + qual->flags.q.depth_less + qual->flags.q.depth_unchanged; if (depth_layout_count > 0 - && !state->AMD_conservative_depth_enable) { + && !state->AMD_conservative_depth_enable + && !state->ARB_conservative_depth_enable) { _mesa_glsl_error(loc, state, - "extension GL_AMD_conservative_depth must be enabled " + "extension GL_AMD_conservative_depth or " + "GL_ARB_conservative_depth must be enabled " "to use depth layout qualifiers"); } else if (depth_layout_count > 0 && strcmp(var->name, "gl_FragDepth") != 0) { @@ -2237,7 +2240,8 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, earlier->interpolation = var->interpolation; /* Layout qualifiers for gl_FragDepth. */ - } else if (state->AMD_conservative_depth_enable + } else if ((state->AMD_conservative_depth_enable || + state->ARB_conservative_depth_enable) && strcmp(var->name, "gl_FragDepth") == 0 && earlier->type == var->type && earlier->mode == var->mode) { diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index c0457b057..2b7e65cd4 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1135,7 +1135,7 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_draw_instanced) add_builtin_define(parser, "GL_ARB_draw_instanced", 1); - if (extensions->AMD_conservative_depth) { + if (extensions->ARB_conservative_depth) { add_builtin_define(parser, "GL_AMD_conservative_depth", 1); add_builtin_define(parser, "GL_ARB_conservative_depth", 1); } diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index 49f3bc82e..c7cfedd42 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -310,6 +310,7 @@ void return VOID_TOK; layout { if ((yyextra->language_version >= 140) || yyextra->AMD_conservative_depth_enable + || yyextra->ARB_conservative_depth_enable || yyextra->ARB_explicit_attrib_location_enable || yyextra->ARB_fragment_coord_conventions_enable) { return LAYOUT_TOK; diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 836390453..71ab039d6 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1124,7 +1124,9 @@ layout_qualifier_id: } /* Layout qualifiers for AMD/ARB_conservative_depth. */ - if (!got_one && state->AMD_conservative_depth_enable) { + if (!got_one && + (state->AMD_conservative_depth_enable || + state->ARB_conservative_depth_enable)) { if (strcmp($1, "depth_any") == 0) { got_one = true; $$.flags.q.depth_any = 1; @@ -1140,6 +1142,11 @@ layout_qualifier_id: } if (got_one && state->AMD_conservative_depth_warn) { + _mesa_glsl_warning(& @1, state, + "GL_AMD_conservative_depth " + "layout qualifier `%s' is used\n", $1); + } + if (got_one && state->ARB_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, "GL_ARB_conservative_depth " "layout qualifier `%s' is used\n", $1); diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 23aadb143..0b4ccac53 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -256,7 +256,7 @@ struct _mesa_glsl_extension { static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { /* target availability API availability */ /* name VS GS FS GL ES supported flag */ - EXT(ARB_conservative_depth, true, false, true, true, false, AMD_conservative_depth), + EXT(ARB_conservative_depth, false, false, true, true, false, ARB_conservative_depth), EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), @@ -265,7 +265,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), - EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth), + EXT(AMD_conservative_depth, false, false, true, true, false, ARB_conservative_depth), EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external), diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index ca5da3040..c7de480a5 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -114,7 +114,7 @@ class count_uniform_size : public uniform_field_visitor { public: count_uniform_size(struct string_to_uint_map *map) : num_active_uniforms(0), num_values(0), num_shader_samplers(0), - num_shader_uniforms(0), map(map) + num_shader_uniform_components(0), map(map) { /* empty */ } @@ -122,7 +122,7 @@ public: void start_shader() { this->num_shader_samplers = 0; - this->num_shader_uniforms = 0; + this->num_shader_uniform_components = 0; } /** @@ -143,7 +143,7 @@ public: /** * Number of uniforms used in the current shader */ - unsigned num_shader_uniforms; + unsigned num_shader_uniform_components; private: virtual void visit_field(const glsl_type *type, const char *name) @@ -165,7 +165,7 @@ private: * Note that samplers do not count against this limit because they * don't use any storage on current hardware. */ - this->num_shader_uniforms += values; + this->num_shader_uniform_components += values; } /* If the uniform is already in the map, there's nothing more to do. @@ -321,7 +321,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog) prog->_LinkedShaders[i]->num_samplers = uniform_size.num_shader_samplers; prog->_LinkedShaders[i]->num_uniform_components = - uniform_size.num_shader_uniforms * 4; + uniform_size.num_shader_uniform_components; } const unsigned num_user_uniforms = uniform_size.num_active_uniforms; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index d5a891435..8ebc05139 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -81,7 +81,7 @@ static const struct extension extension_table[] = { { "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 }, { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 }, { "GL_ARB_copy_buffer", o(ARB_copy_buffer), GL, 2008 }, - { "GL_ARB_conservative_depth", o(AMD_conservative_depth), GL, 2011 }, + { "GL_ARB_conservative_depth", o(ARB_conservative_depth), GL, 2011 }, { "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL, 2008 }, { "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL, 2003 }, { "GL_ARB_depth_texture", o(ARB_depth_texture), GL, 2001 }, @@ -257,7 +257,7 @@ static const struct extension extension_table[] = { /* Vendor extensions */ { "GL_3DFX_texture_compression_FXT1", o(TDFX_texture_compression_FXT1), GL, 1999 }, - { "GL_AMD_conservative_depth", o(AMD_conservative_depth), GL, 2009 }, + { "GL_AMD_conservative_depth", o(ARB_conservative_depth), GL, 2009 }, { "GL_AMD_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 }, { "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 }, { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index 6e2ce7a05..080392f2b 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -936,7 +936,7 @@ unpack_INTENSITY_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = - dst[i][ACOMP] = s[i]; + dst[i][ACOMP] = _mesa_half_to_float(s[i]); } } @@ -1750,6 +1750,12 @@ unpack_float_z_Z32(GLuint n, const void *src, GLfloat *dst) } } +static void +unpack_float_z_Z32F(GLuint n, const void *src, GLfloat *dst) +{ + memcpy(dst, src, n * sizeof(float)); +} + static void unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) { @@ -1783,6 +1789,9 @@ _mesa_unpack_float_z_row(gl_format format, GLuint n, case MESA_FORMAT_Z32: unpack = unpack_float_z_Z32; break; + case MESA_FORMAT_Z32_FLOAT: + unpack = unpack_float_z_Z32F; + break; case MESA_FORMAT_Z32_FLOAT_X24S8: unpack = unpack_float_z_Z32X24S8; break; @@ -1959,7 +1968,8 @@ _mesa_unpack_uint_24_8_depth_stencil_row(gl_format format, GLuint n, unpack_uint_24_8_depth_stencil_S8_Z24(src, dst, n); break; default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", + _mesa_problem(NULL, + "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", _mesa_get_format_name(format)); return; } diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index c6febb0e5..b934bd4d8 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -414,7 +414,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_Z24_S8, /* Name */ "MESA_FORMAT_Z24_S8", /* StrName */ GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 4 /* BlockWidth/Height,Bytes */ @@ -423,7 +423,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_S8_Z24, /* Name */ "MESA_FORMAT_S8_Z24", /* StrName */ GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 4 /* BlockWidth/Height,Bytes */ @@ -432,7 +432,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_Z16, /* Name */ "MESA_FORMAT_Z16", /* StrName */ GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 16, 0, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 2 /* BlockWidth/Height,Bytes */ @@ -441,7 +441,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_X8_Z24, /* Name */ "MESA_FORMAT_X8_Z24", /* StrName */ GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 4 /* BlockWidth/Height,Bytes */ @@ -450,7 +450,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_Z24_X8, /* Name */ "MESA_FORMAT_Z24_X8", /* StrName */ GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 4 /* BlockWidth/Height,Bytes */ @@ -459,7 +459,7 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = MESA_FORMAT_Z32, /* Name */ "MESA_FORMAT_Z32", /* StrName */ GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ + GL_UNSIGNED_NORMALIZED, /* DataType */ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */ 1, 1, 4 /* BlockWidth/Height,Bytes */ diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index b3427dac1..96a44266c 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2844,6 +2844,7 @@ struct gl_extensions GLboolean ARB_ES2_compatibility; GLboolean ARB_blend_func_extended; GLboolean ARB_color_buffer_float; + GLboolean ARB_conservative_depth; GLboolean ARB_copy_buffer; GLboolean ARB_depth_buffer_float; GLboolean ARB_depth_clamp; @@ -2942,7 +2943,6 @@ struct gl_extensions GLboolean EXT_vertex_array_bgra; GLboolean OES_standard_derivatives; /* vendor extensions */ - GLboolean AMD_conservative_depth; GLboolean AMD_seamless_cubemap_per_texture; GLboolean APPLE_packed_pixels; GLboolean APPLE_vertex_array_object; diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 8048a7286..a7b7ed7f2 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -60,7 +60,7 @@ fast_read_depth_pixels( struct gl_context *ctx, if (packing->SwapBytes) return GL_FALSE; - if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_INT) + if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) || @@ -381,7 +381,7 @@ fast_read_depth_stencil_pixels_separate(struct gl_context *ctx, GLubyte *depthMap, *stencilMap; int depthStride, stencilStride, i, j; - if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_INT) + if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c index aebe38ee0..ee9552bc0 100644 --- a/mesalib/src/mesa/main/texformat.c +++ b/mesalib/src/mesa/main/texformat.c @@ -326,6 +326,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, case GL_ALPHA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_LUMINANCE16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT16); @@ -335,6 +337,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, case GL_LUMINANCE32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_LUMINANCE_ALPHA16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16); @@ -344,6 +348,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, case GL_LUMINANCE_ALPHA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_INTENSITY16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT16); @@ -353,15 +359,20 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, case GL_INTENSITY32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RGB16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); break; case GL_RGB32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; case GL_RGBA16F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); @@ -369,6 +380,7 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, break; case GL_RGBA32F_ARB: RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); + RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); break; default: ; /* fallthrough */ diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index c8ea4329f..56335ad10 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1021,15 +1021,8 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format) /** - * Reset the fields of a gl_texture_image struct to zero. - * - * \param img texture image structure. - * - * This is called when a proxy texture test fails, we set all the - * image members (except DriverData) to zero. - * It's also used in glTexImage[123]D as a safeguard to be sure all - * required fields get initialized properly by the Driver.TexImage[123]D - * functions. + * Set the size and format-related fields of a gl_texture_image struct + * to zero. This is used when a proxy texture test fails. */ static void clear_teximage_fields(struct gl_texture_image *img) diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 17eac5fc9..0081c3b52 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -884,6 +884,70 @@ _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) } +static GLboolean +base_format_has_channel(GLenum base_format, GLenum pname) +{ + switch (pname) { + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_RED_TYPE: + if (base_format == GL_RED || + base_format == GL_RG || + base_format == GL_RGB || + base_format == GL_RGBA) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_GREEN_TYPE: + if (base_format == GL_RG || + base_format == GL_RGB || + base_format == GL_RGBA) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_BLUE_TYPE: + if (base_format == GL_RGB || + base_format == GL_RGBA) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_ALPHA_SIZE: + case GL_TEXTURE_ALPHA_TYPE: + if (base_format == GL_RGBA || + base_format == GL_ALPHA || + base_format == GL_LUMINANCE_ALPHA) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_LUMINANCE_SIZE: + case GL_TEXTURE_LUMINANCE_TYPE: + if (base_format == GL_LUMINANCE || + base_format == GL_LUMINANCE_ALPHA) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_INTENSITY_SIZE: + case GL_TEXTURE_INTENSITY_TYPE: + if (base_format == GL_INTENSITY) { + return GL_TRUE; + } + return GL_FALSE; + case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_DEPTH_TYPE: + if (base_format == GL_DEPTH_STENCIL || + base_format == GL_DEPTH_COMPONENT) { + return GL_TRUE; + } + return GL_FALSE; + default: + _mesa_warning(NULL, "%s: Unexpected channel token 0x%x\n", + __FUNCTION__, pname); + return GL_FALSE; + } + + return GL_FALSE; +} void GLAPIENTRY @@ -981,27 +1045,10 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->Border; break; case GL_TEXTURE_RED_SIZE: - if (img->_BaseFormat == GL_RED) { - *params = _mesa_get_format_bits(texFormat, pname); - break; - } - /* FALLTHROUGH */ case GL_TEXTURE_GREEN_SIZE: - if (img->_BaseFormat == GL_RG) { - *params = _mesa_get_format_bits(texFormat, pname); - break; - } - /* FALLTHROUGH */ case GL_TEXTURE_BLUE_SIZE: - if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) - *params = _mesa_get_format_bits(texFormat, pname); - else - *params = 0; - break; case GL_TEXTURE_ALPHA_SIZE: - if (img->_BaseFormat == GL_ALPHA || - img->_BaseFormat == GL_LUMINANCE_ALPHA || - img->_BaseFormat == GL_RGBA) + if (base_format_has_channel(img->_BaseFormat, pname)) *params = _mesa_get_format_bits(texFormat, pname); else *params = 0; @@ -1067,46 +1114,18 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, /* GL_ARB_texture_float */ case GL_TEXTURE_RED_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_GREEN_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_BLUE_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_ALPHA_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_LUMINANCE_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_INTENSITY_TYPE_ARB: - if (!ctx->Extensions.ARB_texture_float) - goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; - break; case GL_TEXTURE_DEPTH_TYPE_ARB: if (!ctx->Extensions.ARB_texture_float) goto invalid_pname; - *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ? - _mesa_get_format_datatype(texFormat) : GL_NONE; + if (base_format_has_channel(img->_BaseFormat, pname)) + *params = _mesa_get_format_datatype(texFormat); + else + *params = GL_NONE; break; default: diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 05c1964d6..aae6b4b3b 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -986,12 +986,17 @@ _mesa_texstore_z32(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffffff; const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); - const GLenum dstType = _mesa_get_format_datatype(dstFormat); + GLenum dstType; (void) dims; ASSERT(dstFormat == MESA_FORMAT_Z32 || dstFormat == MESA_FORMAT_Z32_FLOAT); ASSERT(texelBytes == sizeof(GLuint)); + if (dstFormat == MESA_FORMAT_Z32) + dstType = GL_UNSIGNED_INT; + else + dstType = GL_FLOAT; + if (ctx->Pixel.DepthScale == 1.0f && ctx->Pixel.DepthBias == 0.0f && !srcPacking->SwapBytes && diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 95805fd3c..912241b35 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -1441,6 +1441,13 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (type == GL_DEPTH_STENCIL) { + /* XXX make this more efficient */ + st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL); + st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH); + return; + } + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index a351d1197..1e8ec0556 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -75,8 +75,18 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, enum pipe_format format; struct pipe_surface surf_tmpl; - format = st_choose_renderbuffer_format(screen, internalFormat, - rb->NumSamples); + if (internalFormat == GL_RGBA16_SNORM && strb->software) { + /* Special case for software accum buffers. Otherwise, if the + * call to st_choose_renderbuffer_format() fails (because the + * driver doesn't support signed 16-bit/channel colors) we'd + * just return without allocating the software accum buffer. + */ + format = PIPE_FORMAT_R16G16B16A16_SNORM; + } + else { + format = st_choose_renderbuffer_format(screen, internalFormat, + rb->NumSamples); + } if (format == PIPE_FORMAT_NONE) { return FALSE; diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 3563e1d9b..25a6cdc75 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -113,14 +113,18 @@ void st_init_limits(struct st_context *st) 1, MAX_DRAW_BUFFERS); c->MaxLineWidth - = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH)); + = _maxf(1.0f, screen->get_paramf(screen, + PIPE_CAPF_MAX_LINE_WIDTH)); c->MaxLineWidthAA - = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_LINE_WIDTH_AA)); + = _maxf(1.0f, screen->get_paramf(screen, + PIPE_CAPF_MAX_LINE_WIDTH_AA)); c->MaxPointSize - = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH)); + = _maxf(1.0f, screen->get_paramf(screen, + PIPE_CAPF_MAX_POINT_WIDTH)); c->MaxPointSizeAA - = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA)); + = _maxf(1.0f, screen->get_paramf(screen, + PIPE_CAPF_MAX_POINT_WIDTH_AA)); /* called after _mesa_create_context/_mesa_init_point, fix default user * settable max point size up */ @@ -132,10 +136,11 @@ void st_init_limits(struct st_context *st) c->MinPointSizeAA = 0.0f; c->MaxTextureMaxAnisotropy - = _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY)); + = _maxf(2.0f, screen->get_paramf(screen, + PIPE_CAPF_MAX_TEXTURE_ANISOTROPY)); c->MaxTextureLodBias - = screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_LOD_BIAS); + = screen->get_paramf(screen, PIPE_CAPF_MAX_TEXTURE_LOD_BIAS); c->MaxDrawBuffers = CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS), @@ -213,15 +218,10 @@ void st_init_limits(struct st_context *st) c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS) - 2; c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); - /* XXX we'll need a better query here someday */ - if (screen->get_param(screen, PIPE_CAP_GLSL)) { - c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); - c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); + c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); + c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); - c->GLSLVersion = 120; - _mesa_override_glsl_version(st->ctx); - c->UniformBooleanTrue = ~0; - } + c->UniformBooleanTrue = ~0; c->StripTextureBorder = GL_TRUE; } @@ -249,16 +249,23 @@ void st_init_extensions(struct st_context *st) struct gl_context *ctx = st->ctx; int i; + ctx->Const.GLSLVersion = 120; + _mesa_override_glsl_version(st->ctx); + /* * Extensions that are supported by all Gallium drivers: */ ctx->Extensions.ARB_copy_buffer = GL_TRUE; ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE; + ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE; ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.ARB_fragment_program = GL_TRUE; + ctx->Extensions.ARB_fragment_shader = GL_TRUE; ctx->Extensions.ARB_half_float_pixel = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; ctx->Extensions.ARB_sampler_objects = GL_TRUE; + ctx->Extensions.ARB_shader_objects = GL_TRUE; + ctx->Extensions.ARB_shading_language_100 = GL_TRUE; ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */ ctx->Extensions.ARB_texture_cube_map = GL_TRUE; ctx->Extensions.ARB_texture_env_combine = GL_TRUE; @@ -267,6 +274,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.ARB_texture_storage = GL_TRUE; ctx->Extensions.ARB_vertex_array_object = GL_TRUE; ctx->Extensions.ARB_vertex_program = GL_TRUE; + ctx->Extensions.ARB_vertex_shader = GL_TRUE; ctx->Extensions.ARB_window_pos = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; @@ -281,6 +289,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_point_parameters = GL_TRUE; ctx->Extensions.EXT_provoking_vertex = GL_TRUE; ctx->Extensions.EXT_secondary_color = GL_TRUE; + ctx->Extensions.EXT_separate_shader_objects = GL_TRUE; ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; @@ -317,15 +326,6 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_texture_swizzle = GL_TRUE; } - if (screen->get_param(screen, PIPE_CAP_GLSL)) { - ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_vertex_shader = GL_TRUE; - ctx->Extensions.ARB_shader_objects = GL_TRUE; - ctx->Extensions.ARB_shading_language_100 = GL_TRUE; - ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE; - ctx->Extensions.EXT_separate_shader_objects = GL_TRUE; - } - if (screen->get_param(screen, PIPE_CAP_BLEND_EQUATION_SEPARATE)) { ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; } 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 929c7af01..74b8fa7c7 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -4803,6 +4803,8 @@ get_mesa_program(struct gl_context *ctx, { glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor(); struct gl_program *prog; + struct pipe_screen * screen = st_context(ctx)->pipe->screen; + unsigned pipe_shader_type; GLenum target; const char *target_string; bool progress; @@ -4813,14 +4815,17 @@ get_mesa_program(struct gl_context *ctx, case GL_VERTEX_SHADER: target = GL_VERTEX_PROGRAM_ARB; target_string = "vertex"; + pipe_shader_type = PIPE_SHADER_VERTEX; break; case GL_FRAGMENT_SHADER: target = GL_FRAGMENT_PROGRAM_ARB; target_string = "fragment"; + pipe_shader_type = PIPE_SHADER_FRAGMENT; break; case GL_GEOMETRY_SHADER: target = GL_GEOMETRY_PROGRAM_NV; target_string = "geometry"; + pipe_shader_type = PIPE_SHADER_GEOMETRY; break; default: assert(!"should not be reached"); @@ -4889,10 +4894,13 @@ get_mesa_program(struct gl_context *ctx, } #endif - /* Remove reads to output registers, and to varyings in vertex shaders. */ - v->remove_output_reads(PROGRAM_OUTPUT); - if (target == GL_VERTEX_PROGRAM_ARB) - v->remove_output_reads(PROGRAM_VARYING); + if (!screen->get_shader_param(screen, pipe_shader_type, + PIPE_SHADER_CAP_OUTPUT_READ)) { + /* Remove reads to output registers, and to varyings in vertex shaders. */ + v->remove_output_reads(PROGRAM_OUTPUT); + if (target == GL_VERTEX_PROGRAM_ARB) + v->remove_output_reads(PROGRAM_VARYING); + } /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */ v->simplify_cmp(); diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c index a7cbb4424..1fce5c565 100644 --- a/mesalib/src/mesa/swrast/s_texcombine.c +++ b/mesalib/src/mesa/swrast/s_texcombine.c @@ -69,17 +69,18 @@ get_texel_array(SWcontext *swrast, GLuint unit) * * \param ctx rendering context * \param unit the texture combiner unit - * \param n number of fragments to process (span width) * \param primary_rgba incoming fragment color array * \param texelBuffer pointer to texel colors for all texture units * - * \param rgba incoming/result fragment colors + * \param span two fields are used in this function: + * span->end: number of fragments to process + * span->array->rgba: incoming/result fragment colors */ static void -texture_combine( struct gl_context *ctx, GLuint unit, GLuint n, +texture_combine( struct gl_context *ctx, GLuint unit, const float4_array primary_rgba, const GLfloat *texelBuffer, - GLchan (*rgbaChan)[4] ) + SWspan *span ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); @@ -92,6 +93,8 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n, const GLuint numArgsA = combine->_NumArgsA; float4_array ccolor[4], rgba; GLuint i, term; + GLuint n = span->end; + GLchan (*rgbaChan)[4] = span->array->rgba; /* alloc temp pixel buffers */ rgba = (float4_array) malloc(4 * n * sizeof(GLfloat)); @@ -542,6 +545,10 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n, UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]); UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]); } + /* The span->array->rgba values are of CHAN type so set + * span->array->ChanType field accordingly. + */ + span->array->ChanType = CHAN_TYPE; end: for (i = 0; i < numArgsRGB || i < numArgsA; i++) { @@ -764,12 +771,8 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span ) * We modify the span->color.rgba values. */ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - texture_combine( ctx, unit, span->end, - primary_rgba, - swrast->TexelBuffer, - span->array->rgba ); - } + if (ctx->Texture.Unit[unit]._ReallyEnabled) + texture_combine(ctx, unit, primary_rgba, swrast->TexelBuffer, span); } free(primary_rgba); diff --git a/mesalib/src/mesa/vbo/vbo_noop.h b/mesalib/src/mesa/vbo/vbo_noop.h index f9180374f..92f61d356 100644 --- a/mesalib/src/mesa/vbo/vbo_noop.h +++ b/mesalib/src/mesa/vbo/vbo_noop.h @@ -38,6 +38,12 @@ _mesa_noop_vtxfmt_init(GLvertexformat *vfmt); extern GLboolean _mesa_using_noop_vtxfmt(const struct _glapi_table *dispatch); +#else + +static inline void +_mesa_noop_vtxfmt_init(GLvertexformat *vfmt) +{ +} #endif /* FEATURE_beginend */ -- cgit v1.2.3