diff --git a/configure.ac b/configure.ac index 4a98996..1c9d606 100644 --- a/configure.ac +++ b/configure.ac @@ -452,6 +452,9 @@ if test "x$enable_asm" = xyes; then linux* | *freebsd* | dragonfly* | *netbsd*) test "x$enable_64bit" = xyes && asm_arch=x86_64 || asm_arch=x86 ;; + gnu*) + asm_arch=x86 + ;; esac ;; x86_64) @@ -826,20 +829,6 @@ if test "x$enable_dri" = xyes; then fi fi -dnl Find out if X is available. -PKG_CHECK_MODULES([X11], [x11], [no_x=no], [no_x=yes]) - -dnl Try to tell the user that the --x-* options are only used when -dnl pkg-config is not available. This must be right after AC_PATH_XTRA. -m4_divert_once([HELP_BEGIN], -[These options are only used when the X libraries cannot be found by the -pkg-config utility.]) - -dnl We need X for xlib and dri, so bomb now if it's not found -if test "x$enable_glx" = xyes -a "x$no_x" = xyes; then - AC_MSG_ERROR([X11 development libraries needed for GLX]) -fi - dnl Direct rendering or just indirect rendering case "$host_os" in gnu*) diff --git a/docs/relnotes-9.1.1.html b/docs/relnotes-9.1.1.html index 8921c8f..a73c974 100644 --- a/docs/relnotes-9.1.1.html +++ b/docs/relnotes-9.1.1.html @@ -30,6 +30,9 @@ because GL_ARB_compatibility is not supported.

MD5 checksums

+6508d9882d8dce7106717f365632700c  MesaLib-9.1.1.tar.gz
+6ea2bdc3b7ecfb4257b39814b4182580  MesaLib-9.1.1.tar.bz2
+3434c0eb47849a08c53cd32833d10d13  MesaLib-9.1.1.zip
 

New features

diff --git a/include/c99_compat.h b/include/c99_compat.h new file mode 100644 index 0000000..3a9f502 --- /dev/null +++ b/include/c99_compat.h @@ -0,0 +1,147 @@ +/************************************************************************** + * + * Copyright 2007-2013 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 _C99_COMPAT_H_ +#define _C99_COMPAT_H_ + + +/* + * MSVC hacks. + */ +#if defined(_MSC_VER) + /* + * Visual Studio 2012 will complain if we define the `inline` keyword, but + * actually it only supports the keyword on C++. + * + * We could skip this check by defining _ALLOW_KEYWORD_MACROS, but there is + * probably value in checking this for other keywords. So simply include + * the checking before we define it below. + */ +# if _MSC_VER >= 1700 +# include +# endif + + /* + * XXX: MSVC has a `__restrict` keyword, but it also has a + * `__declspec(restrict)` modifier, so it is impossible to define a + * `restrict` macro without interfering with the latter. Furthermore the + * MSVC standard library uses __declspec(restrict) under the _CRTRESTRICT + * macro. For now resolve this issue by redefining _CRTRESTRICT, but going + * forward we should probably should stop using restrict, especially + * considering that our code does not obbey strict aliasing rules any way. + */ +# include +# undef _CRTRESTRICT +# define _CRTRESTRICT +#endif + + +/* + * C99 inline keyword + */ +#ifndef inline +# ifdef __cplusplus + /* C++ supports inline keyword */ +# elif defined(__GNUC__) +# define inline __inline__ +# elif defined(_MSC_VER) +# define inline __inline +# elif defined(__ICL) +# define inline __inline +# elif defined(__INTEL_COMPILER) + /* Intel compiler supports inline keyword */ +# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) +# define inline __inline +# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) + /* C99 supports inline keyword */ +# elif (__STDC_VERSION__ >= 199901L) + /* C99 supports inline keyword */ +# else +# define inline +# endif +#endif + + +/* + * C99 restrict keyword + * + * See also: + * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html + */ +#ifndef restrict +# if (__STDC_VERSION__ >= 199901L) + /* C99 */ +# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) + /* C99 */ +# elif defined(__GNUC__) +# define restrict __restrict__ +# elif defined(_MSC_VER) +# define restrict __restrict +# else +# define restrict /* */ +# endif +#endif + + +/* + * C99 __func__ macro + */ +#ifndef __func__ +# if (__STDC_VERSION__ >= 199901L) + /* C99 */ +# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) + /* C99 */ +# elif defined(__GNUC__) +# if __GNUC__ >= 2 +# define __func__ __FUNCTION__ +# else +# define __func__ "" +# endif +# elif defined(_MSC_VER) +# if _MSC_VER >= 1300 +# define __func__ __FUNCTION__ +# else +# define __func__ "" +# endif +# else +# define __func__ "" +# endif +#endif + + +/* Simple test case for debugging */ +#if 0 +static inline const char * +test_c99_compat_h(const void * restrict a, + const void * restrict b) +{ + return __func__; +} +#endif + + +#endif /* _C99_COMPAT_H_ */ diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h index 9823693..2499172 100644 --- a/src/egl/main/eglcompiler.h +++ b/src/egl/main/eglcompiler.h @@ -31,6 +31,9 @@ #define EGLCOMPILER_INCLUDED +#include "c99_compat.h" /* inline, __func__, etc. */ + + /** * Get standard integer types */ @@ -62,30 +65,7 @@ #endif -/** - * Function inlining - */ -#ifndef inline -# ifdef __cplusplus - /* C++ supports inline keyword */ -# elif defined(__GNUC__) -# define inline __inline__ -# elif defined(_MSC_VER) -# define inline __inline -# elif defined(__ICL) -# define inline __inline -# elif defined(__INTEL_COMPILER) - /* Intel compiler supports inline keyword */ -# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) -# define inline __inline -# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) - /* C99 supports inline keyword */ -# elif (__STDC_VERSION__ >= 199901L) - /* C99 supports inline keyword */ -# else -# define inline -# endif -#endif +/* XXX: Use standard `inline` keyword instead */ #ifndef INLINE # define INLINE inline #endif @@ -104,21 +84,9 @@ # endif #endif -/** - * The __FUNCTION__ gcc variable is generally only used for debugging. - * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. - * Don't define it if using a newer Windows compiler. - */ +/* XXX: Use standard `__func__` instead */ #ifndef __FUNCTION__ -# if (!defined __GNUC__) && (!defined __xlC__) && \ - (!defined(_MSC_VER) || _MSC_VER < 1300) -# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ - (defined(__SUNPRO_C) && defined(__C99FEATURES__)) -# define __FUNCTION__ __func__ -# else -# define __FUNCTION__ "" -# endif -# endif +# define __FUNCTION__ __func__ #endif #endif /* EGLCOMPILER_INCLUDED */ diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am index a4eee47..f14279b 100644 --- a/src/gallium/auxiliary/Makefile.am +++ b/src/gallium/auxiliary/Makefile.am @@ -7,7 +7,10 @@ noinst_LTLIBRARIES = libgallium.la AM_CFLAGS = \ -I$(top_srcdir)/src/gallium/auxiliary/util \ - $(GALLIUM_CFLAGS) + $(GALLIUM_CFLAGS) \ + $(VISIBILITY_CFLAGS) + +AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS) libgallium_la_SOURCES = \ $(C_SOURCES) \ @@ -18,7 +21,7 @@ if HAVE_MESA_LLVM AM_CFLAGS += \ $(LLVM_CFLAGS) -AM_CXXFLAGS = \ +AM_CXXFLAGS += \ $(GALLIUM_CFLAGS) \ $(LLVM_CXXFLAGS) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 4898849..5fb4a11 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -240,6 +240,7 @@ struct lp_exec_mask { struct lp_build_context *bld; boolean has_mask; + boolean ret_in_main; LLVMTypeRef int_vec_type; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 0621fb4..413a918 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -73,6 +73,7 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context mask->bld = bld; mask->has_mask = FALSE; + mask->ret_in_main = FALSE; mask->cond_stack_size = 0; mask->loop_stack_size = 0; mask->call_stack_size = 0; @@ -108,7 +109,7 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask) } else mask->exec_mask = mask->cond_mask; - if (mask->call_stack_size) { + if (mask->call_stack_size || mask->ret_in_main) { mask->exec_mask = LLVMBuildAnd(builder, mask->exec_mask, mask->ret_mask, @@ -117,7 +118,8 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask) mask->has_mask = (mask->cond_stack_size > 0 || mask->loop_stack_size > 0 || - mask->call_stack_size > 0); + mask->call_stack_size > 0 || + mask->ret_in_main); } static void lp_exec_mask_cond_push(struct lp_exec_mask *mask, @@ -348,11 +350,23 @@ static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc) LLVMBuilderRef builder = mask->bld->gallivm->builder; LLVMValueRef exec_mask; - if (mask->call_stack_size == 0) { + if (mask->cond_stack_size == 0 && + mask->loop_stack_size == 0 && + mask->call_stack_size == 0) { /* returning from main() */ *pc = -1; return; } + + if (mask->call_stack_size == 0) { + /* + * This requires special handling since we need to ensure + * we don't drop the mask even if we have no call stack + * (e.g. after a ret in a if clause after the endif) + */ + mask->ret_in_main = TRUE; + } + exec_mask = LLVMBuildNot(builder, mask->exec_mask, "ret"); diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 1267e79..dc3a5fb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -1569,7 +1569,7 @@ tgsi_text_translate( struct tgsi_token *tokens, uint num_tokens ) { - struct translate_ctx ctx; + struct translate_ctx ctx = {0}; ctx.text = text; ctx.cur = text; diff --git a/src/gallium/drivers/Makefile.am b/src/gallium/drivers/Makefile.am index 25d9533..3477fee 100644 --- a/src/gallium/drivers/Makefile.am +++ b/src/gallium/drivers/Makefile.am @@ -1,6 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ -I$(top_srcdir)/src/gallium/include \ -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_srcdir)/src/gallium/drivers \ diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 328c0f7..e145391 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -64,6 +64,28 @@ lp_scene_create( struct pipe_context *pipe ) pipe_mutex_init(scene->mutex); +#ifdef DEBUG + /* Do some scene limit sanity checks here */ + { + size_t maxBins = TILES_X * TILES_Y; + size_t maxCommandBytes = sizeof(struct cmd_block) * maxBins; + size_t maxCommandPlusData = maxCommandBytes + DATA_BLOCK_SIZE; + /* We'll need at least one command block per bin. Make sure that's + * less than the max allowed scene size. + */ + assert(maxCommandBytes < LP_SCENE_MAX_SIZE); + /* We'll also need space for at least one other data block */ + assert(maxCommandPlusData <= LP_SCENE_MAX_SIZE); + + /* Ideally, the size of a cmd_block object will be a power of two + * in order to avoid wasting space when we allocation them from + * data blocks (which are power of two also). + */ + assert(sizeof(struct cmd_block) == + util_next_power_of_two(sizeof(struct cmd_block))); + } +#endif + return scene; } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index b1db61b..801829d 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -49,12 +49,18 @@ struct lp_rast_state; #define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE) -#define CMD_BLOCK_MAX 128 +/* Commands per command block (ideally so sizeof(cmd_block) is a power of + * two in size.) + */ +#define CMD_BLOCK_MAX 29 + +/* Bytes per data block. + */ #define DATA_BLOCK_SIZE (64 * 1024) /* Scene temporary storage is clamped to this size: */ -#define LP_SCENE_MAX_SIZE (4*1024*1024) +#define LP_SCENE_MAX_SIZE (9*1024*1024) /* The maximum amount of texture storage referenced by a scene is * clamped ot this size: diff --git a/src/gallium/drivers/nv50/nv50_blit.h b/src/gallium/drivers/nv50/nv50_blit.h index d409f21..bdd6a63 100644 --- a/src/gallium/drivers/nv50/nv50_blit.h +++ b/src/gallium/drivers/nv50/nv50_blit.h @@ -180,4 +180,44 @@ nv50_blit_eng2d_get_mask(const struct pipe_blit_info *info) return mask; } +#if NOUVEAU_DRIVER == 0xc0 +# define nv50_format_table nvc0_format_table +#endif + +/* return TRUE for formats that can be converted among each other by NVC0_2D */ +static INLINE boolean +nv50_2d_dst_format_faithful(enum pipe_format format) +{ + const uint64_t mask = + NV50_ENG2D_SUPPORTED_FORMATS & + ~NV50_ENG2D_NOCONVERT_FORMATS; + uint8_t id = nv50_format_table[format].rt; + return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0))); +} +static INLINE boolean +nv50_2d_src_format_faithful(enum pipe_format format) +{ + const uint64_t mask = + NV50_ENG2D_SUPPORTED_FORMATS & + ~(NV50_ENG2D_LUMINANCE_FORMATS | NV50_ENG2D_INTENSITY_FORMATS); + uint8_t id = nv50_format_table[format].rt; + return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0))); +} + +static INLINE boolean +nv50_2d_format_supported(enum pipe_format format) +{ + uint8_t id = nv50_format_table[format].rt; + return (id >= 0xc0) && + (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))); +} + +static INLINE boolean +nv50_2d_dst_format_ops_supported(enum pipe_format format) +{ + uint8_t id = nv50_format_table[format].rt; + return (id >= 0xc0) && + (NV50_ENG2D_OPERATION_FORMATS & (1ULL << (id - 0xc0))); +} + #endif /* __NV50_BLIT_H__ */ diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index a95e96d..f5e7b36 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -9,6 +9,7 @@ nv50_validate_fb(struct nv50_context *nv50) struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1; + uint32_t array_size = 0xffff, array_mode = 0; nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); @@ -23,6 +24,13 @@ nv50_validate_fb(struct nv50_context *nv50) struct nv50_surface *sf = nv50_surface(fb->cbufs[i]); struct nouveau_bo *bo = mt->base.bo; + array_size = MIN2(array_size, sf->depth); + if (mt->layout_3d) + array_mode = NV50_3D_RT_ARRAY_MODE_MODE_3D; /* 1 << 16 */ + + /* can't mix 3D with ARRAY or have RTs of different depth/array_size */ + assert(mt->layout_3d || !array_mode || array_size == 1); + BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5); PUSH_DATAh(push, bo->offset + sf->offset); PUSH_DATA (push, bo->offset + sf->offset); @@ -34,7 +42,7 @@ nv50_validate_fb(struct nv50_context *nv50) PUSH_DATA (push, sf->width); PUSH_DATA (push, sf->height); BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1); - PUSH_DATA (push, sf->depth); + PUSH_DATA (push, array_mode | array_size); } else { PUSH_DATA (push, 0); PUSH_DATA (push, 0); @@ -63,7 +71,7 @@ nv50_validate_fb(struct nv50_context *nv50) struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture); struct nv50_surface *sf = nv50_surface(fb->zsbuf); struct nouveau_bo *bo = mt->base.bo; - int unk = mt->base.base.target == PIPE_TEXTURE_2D; + int unk = mt->base.base.target == PIPE_TEXTURE_3D || sf->depth == 1; BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5); PUSH_DATAh(push, bo->offset + sf->offset); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 7a0470c..3a780f6 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -35,25 +35,22 @@ #include "nv50_context.h" #include "nv50_resource.h" -#include "nv50_blit.h" #include "nv50_defs.xml.h" #include "nv50_texture.xml.h" +/* these are used in nv50_blit.h */ #define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL +#define NV50_ENG2D_NOCONVERT_FORMATS 0x0008402000000000ULL +#define NV50_ENG2D_LUMINANCE_FORMATS 0x0008402000000000ULL +#define NV50_ENG2D_INTENSITY_FORMATS 0x0000000000000000ULL +#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000608000ULL -/* return TRUE for formats that can be converted among each other by NV50_2D */ -static INLINE boolean -nv50_2d_format_faithful(enum pipe_format format) -{ - uint8_t id = nv50_format_table[format].rt; - - return (id >= 0xc0) && - (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))); -} +#define NOUVEAU_DRIVER 0x50 +#include "nv50_blit.h" static INLINE uint8_t -nv50_2d_format(enum pipe_format format) +nv50_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal) { uint8_t id = nv50_format_table[format].rt; @@ -62,6 +59,7 @@ nv50_2d_format(enum pipe_format format) */ if ((id >= 0xc0) && (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)))) return id; + assert(dst_src_equal); switch (util_format_get_blocksize(format)) { case 1: @@ -78,7 +76,7 @@ nv50_2d_format(enum pipe_format format) static int nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst, struct nv50_miptree *mt, unsigned level, unsigned layer, - enum pipe_format pformat) + enum pipe_format pformat, boolean dst_src_pformat_equal) { struct nouveau_bo *bo = mt->base.bo; uint32_t width, height, depth; @@ -86,7 +84,7 @@ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst, uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; uint32_t offset = mt->level[level].offset; - format = nv50_2d_format(pformat); + format = nv50_2d_format(pformat, dst, dst_src_pformat_equal); if (!format) { NOUVEAU_ERR("invalid/unsupported surface format: %s\n", util_format_name(pformat)); @@ -155,15 +153,16 @@ nv50_2d_texture_do_copy(struct nouveau_pushbuf *push, const enum pipe_format dfmt = dst->base.base.format; const enum pipe_format sfmt = src->base.base.format; int ret; + boolean eqfmt = dfmt == sfmt; if (!PUSH_SPACE(push, 2 * 16 + 32)) return PIPE_ERROR; - ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt); + ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt, eqfmt); if (ret) return ret; - ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt); + ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt, eqfmt); if (ret) return ret; @@ -243,8 +242,8 @@ nv50_resource_copy_region(struct pipe_context *pipe, } assert((src->format == dst->format) || - (nv50_2d_format_faithful(src->format) && - nv50_2d_format_faithful(dst->format))); + (nv50_2d_src_format_faithful(src->format) && + nv50_2d_dst_format_faithful(dst->format))); BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD); BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR); @@ -936,7 +935,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) nv50_blit_select_fp(blit, info); nv50_blitctx_pre_blit(blit); - nv50_blit_set_dst(blit, dst, info->dst.level, 0, info->dst.format); + nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format); nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format, blit->filter); @@ -977,6 +976,8 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); PUSH_DATA (push, 0); + BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); + PUSH_DATA (push, 0x1); /* Draw a large triangle in screen coordinates covering the whole * render target, with scissors defining the destination region. @@ -1059,7 +1060,8 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info) int64_t du_dx, dv_dy; int i; uint32_t mode; - const uint32_t mask = nv50_blit_eng2d_get_mask(info); + uint32_t mask = nv50_blit_eng2d_get_mask(info); + boolean b; mode = nv50_blit_get_filter(info) ? NV50_2D_BLIT_CONTROL_FILTER_BILINEAR : @@ -1070,8 +1072,9 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info) du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width; dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height; - nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format); - nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format); + b = info->dst.format == info->src.format; + nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b); + nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b); if (info->scissor_enable) { BEGIN_NV04(push, NV50_2D(CLIP_X), 5); @@ -1094,6 +1097,17 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info) PUSH_DATA (push, 0xffffffff); BEGIN_NV04(push, NV50_2D(OPERATION), 1); PUSH_DATA (push, NV50_2D_OPERATION_ROP); + } else + if (info->src.format != info->dst.format) { + if (info->src.format == PIPE_FORMAT_R8_UNORM || + info->src.format == PIPE_FORMAT_R16_UNORM || + info->src.format == PIPE_FORMAT_R16_FLOAT || + info->src.format == PIPE_FORMAT_R32_FLOAT) { + mask = 0xffff0000; /* also makes condition for OPERATION reset true */ + BEGIN_NV04(push, NV50_2D(BETA4), 2); + PUSH_DATA (push, mask); + PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT); + } } if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) { @@ -1224,10 +1238,25 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) debug_printf("blit: cannot filter array or cube textures in z direction"); } - if (!eng3d && info->dst.format != info->src.format) - if (!nv50_2d_format_faithful(info->dst.format) || - !nv50_2d_format_faithful(info->src.format)) + if (!eng3d && info->dst.format != info->src.format) { + if (!nv50_2d_dst_format_faithful(info->dst.format) || + !nv50_2d_src_format_faithful(info->src.format)) { eng3d = TRUE; + } else + if (!nv50_2d_src_format_faithful(info->src.format)) { + if (!util_format_is_luminance(info->src.format)) { + if (util_format_is_intensity(info->src.format)) + eng3d = TRUE; + else + if (!nv50_2d_dst_format_ops_supported(info->dst.format)) + eng3d = TRUE; + else + eng3d = !nv50_2d_format_supported(info->src.format); + } + } else + if (util_format_is_luminance_alpha(info->src.format)) + eng3d = TRUE; + } if (info->src.resource->nr_samples == 8 && info->dst.resource->nr_samples <= 1) diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 1cf1f96..bd3de58 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -1041,7 +1041,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VIEWPORT_TRANSFORM_EN 0x0000192c #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL 0x0000193c -#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK0 0x00000001 +#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1 0x00000001 #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__MASK 0x00000006 #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__SHIFT 1 #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK0 0x00000000 diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 281d740..66154a4 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -36,29 +36,32 @@ #include "nv50/nv50_defs.xml.h" #include "nv50/nv50_texture.xml.h" -#include "nv50/nv50_blit.h" -#define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL +/* these are used in nv50_blit.h */ +#define NV50_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL +#define NV50_ENG2D_NOCONVERT_FORMATS 0x009cc02000000000ULL +#define NV50_ENG2D_LUMINANCE_FORMATS 0x001cc02000000000ULL +#define NV50_ENG2D_INTENSITY_FORMATS 0x0080000000000000ULL +#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000638000ULL -/* return TRUE for formats that can be converted among each other by NVC0_2D */ -static INLINE boolean -nvc0_2d_format_faithful(enum pipe_format format) -{ - uint8_t id = nvc0_format_table[format].rt; - - return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))); -} +#define NOUVEAU_DRIVER 0xc0 +#include "nv50/nv50_blit.h" static INLINE uint8_t -nvc0_2d_format(enum pipe_format format) +nvc0_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal) { uint8_t id = nvc0_format_table[format].rt; + /* A8_UNORM is treated as I8_UNORM as far as the 2D engine is concerned. */ + if (!dst && unlikely(format == PIPE_FORMAT_I8_UNORM) && !dst_src_equal) + return NV50_SURFACE_FORMAT_A8_UNORM; + /* Hardware values for color formats range from 0xc0 to 0xff, * but the 2D engine doesn't support all of them. */ - if (nvc0_2d_format_faithful(format)) + if (nv50_2d_format_supported(format)) return id; + assert(dst_src_equal); switch (util_format_get_blocksize(format)) { case 1: @@ -72,6 +75,7 @@ nvc0_2d_format(enum pipe_format format) case 16: return NV50_SURFACE_FORMAT_RGBA32_FLOAT; default: + assert(0); return 0; } } @@ -79,7 +83,7 @@ nvc0_2d_format(enum pipe_format format) static int nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst, struct nv50_miptree *mt, unsigned level, unsigned layer, - enum pipe_format pformat) + enum pipe_format pformat, boolean dst_src_pformat_equal) { struct nouveau_bo *bo = mt->base.bo; uint32_t width, height, depth; @@ -87,7 +91,7 @@ nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst, uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT; uint32_t offset = mt->level[level].offset; - format = nvc0_2d_format(pformat); + format = nvc0_2d_format(pformat, dst, dst_src_pformat_equal); if (!format) { NOUVEAU_ERR("invalid/unsupported surface format: %s\n", util_format_name(pformat)); @@ -157,15 +161,16 @@ nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push, const enum pipe_format dfmt = dst->base.base.format; const enum pipe_format sfmt = src->base.base.format; int ret; + boolean eqfmt = dfmt == sfmt; if (!PUSH_SPACE(push, 2 * 16 + 32)) return PIPE_ERROR; - ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt); + ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt, eqfmt); if (ret) return ret; - ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt); + ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt, eqfmt); if (ret) return ret; @@ -243,8 +248,8 @@ nvc0_resource_copy_region(struct pipe_context *pipe, return; } - assert(nvc0_2d_format_faithful(src->format)); - assert(nvc0_2d_format_faithful(dst->format)); + assert(nv50_2d_dst_format_faithful(dst->format)); + assert(nv50_2d_src_format_faithful(src->format)); BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD); BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR); @@ -490,19 +495,19 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit) { static const uint32_t code_nvc0[] = { - 0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */ - 0xfff11c26, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/ - 0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */ - 0x13f01c26, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */ + 0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */ + 0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */ + 0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */ + 0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */ 0x00001de7, 0x80000000, /* exit */ }; static const uint32_t code_nve4[] = { 0x00000007, 0x20000000, /* sched */ - 0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */ - 0xfff11c46, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/ - 0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */ - 0x13f01c46, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */ + 0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */ + 0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */ + 0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */ + 0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */ 0x00001de7, 0x80000000, /* exit */ }; @@ -515,13 +520,13 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit) blit->vp.code = (uint32_t *)code_nvc0; /* const_cast */ blit->vp.code_size = sizeof(code_nvc0); } - blit->vp.max_gpr = 7; + blit->vp.max_gpr = 6; blit->vp.vp.edgeflag = PIPE_MAX_ATTRIBS; blit->vp.hdr[0] = 0x00020461; /* vertprog magic */ blit->vp.hdr[4] = 0x000ff000; /* no outputs read */ - blit->vp.hdr[6] = 0x0000003f; /* a[0x80], a[0x90] */ - blit->vp.hdr[13] = 0x0003f000; /* o[0x70], o[0x80] */ + blit->vp.hdr[6] = 0x00000073; /* a[0x80].xy, a[0x90].xyz */ + blit->vp.hdr[13] = 0x00073000; /* o[0x70].xy, o[0x80].xyz */ } static void @@ -820,7 +825,7 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) nvc0_blit_select_fp(blit, info); nvc0_blitctx_pre_blit(blit); - nvc0_blit_set_dst(blit, dst, info->dst.level, 0, info->dst.format); + nvc0_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format); nvc0_blit_set_src(blit, src, info->src.level, -1, info->src.format, blit->filter); @@ -859,6 +864,8 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) z += 0.5f * dz; IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0); + IMMED_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 0x2 | + NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1); BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); PUSH_DATA (push, nvc0->framebuffer.width << 16); PUSH_DATA (push, nvc0->framebuffer.height << 16); @@ -925,11 +932,14 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) if (info->dst.box.z + info->dst.box.depth - 1) IMMED_NVC0(push, NVC0_3D(LAYER), 0); - /* re-enable normally constant state */ + nvc0_blitctx_post_blit(blit); - IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); + /* restore viewport */ - nvc0_blitctx_post_blit(blit); + BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2); + PUSH_DATA (push, nvc0->framebuffer.width << 16); + PUSH_DATA (push, nvc0->framebuffer.height << 16); + IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1); } static void @@ -948,7 +958,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) int64_t du_dx, dv_dy; int i; uint32_t mode; - const uint32_t mask = nv50_blit_eng2d_get_mask(info); + uint32_t mask = nv50_blit_eng2d_get_mask(info); + boolean b; mode = nv50_blit_get_filter(info) ? NVC0_2D_BLIT_CONTROL_FILTER_BILINEAR : @@ -959,8 +970,9 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width; dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height; - nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format); - nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format); + b = info->dst.format == info->src.format; + nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b); + nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b); if (info->scissor_enable) { BEGIN_NVC0(push, NVC0_2D(CLIP_X), 5); @@ -981,6 +993,25 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info) PUSH_DATA (push, 0xffffffff); PUSH_DATA (push, 0xffffffff); IMMED_NVC0(push, NVC0_2D(OPERATION), NVC0_2D_OPERATION_ROP); + } else + if (info->src.format != info->dst.format) { + if (info->src.format == PIPE_FORMAT_R8_UNORM || + info->src.format == PIPE_FORMAT_R8_SNORM || + info->src.format == PIPE_FORMAT_R16_UNORM || + info->src.format == PIPE_FORMAT_R16_SNORM || + info->src.format == PIPE_FORMAT_R16_FLOAT || + info->src.format == PIPE_FORMAT_R32_FLOAT) { + mask = 0xffff0000; /* also makes condition for OPERATION reset true */ + BEGIN_NVC0(push, NVC0_2D(BETA4), 2); + PUSH_DATA (push, mask); + PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT); + } else + if (info->src.format == PIPE_FORMAT_A8_UNORM) { + mask = 0xff000000; + BEGIN_NVC0(push, NVC0_2D(BETA4), 2); + PUSH_DATA (push, mask); + PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT); + } } if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) { @@ -1106,10 +1137,24 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) debug_printf("blit: cannot filter array or cube textures in z direction"); } - if (!eng3d && info->dst.format != info->src.format) - if (!nvc0_2d_format_faithful(info->dst.format) || - !nvc0_2d_format_faithful(info->src.format)) + if (!eng3d && info->dst.format != info->src.format) { + if (!nv50_2d_dst_format_faithful(info->dst.format)) { + eng3d = TRUE; + } else + if (!nv50_2d_src_format_faithful(info->src.format)) { + if (!util_format_is_luminance(info->src.format)) { + if (util_format_is_intensity(info->src.format)) + eng3d = info->src.format != PIPE_FORMAT_I8_UNORM; + else + if (!nv50_2d_dst_format_ops_supported(info->dst.format)) + eng3d = TRUE; + else + eng3d = !nv50_2d_format_supported(info->src.format); + } + } else + if (util_format_is_luminance_alpha(info->src.format)) eng3d = TRUE; + } if (info->src.resource->nr_samples == 8 && info->dst.resource->nr_samples <= 1) diff --git a/src/gallium/drivers/r300/compiler/radeon_optimize.c b/src/gallium/drivers/r300/compiler/radeon_optimize.c index 734c7f2..74afd6f 100644 --- a/src/gallium/drivers/r300/compiler/radeon_optimize.c +++ b/src/gallium/drivers/r300/compiler/radeon_optimize.c @@ -708,6 +708,7 @@ static int peephole_mul_omod( struct rc_list * writer_list; struct rc_variable * var; struct peephole_mul_cb_data cb_data; + unsigned writemask_sum; for (i = 0; i < 2; i++) { unsigned int j; @@ -815,10 +816,11 @@ static int peephole_mul_omod( } /* Rewrite the instructions */ + writemask_sum = rc_variable_writemask_sum(writer_list->Item); for (var = writer_list->Item; var; var = var->Friend) { struct rc_variable * writer = var; unsigned conversion_swizzle = rc_make_conversion_swizzle( - writer->Inst->U.I.DstReg.WriteMask, + writemask_sum, inst_mul->U.I.DstReg.WriteMask); writer->Inst->U.I.Omod = omod_op; writer->Inst->U.I.DstReg.File = inst_mul->U.I.DstReg.File; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index a7973a5..80b859f 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -1157,7 +1157,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) * case were triggering lockup quickly such as : * piglit/bin/depthstencil-render-miplevels 1024 d=s=z24_s8 */ - rscreen->use_hyperz = debug_get_bool_option("R600_HYPERZ", TRUE); + rscreen->use_hyperz = debug_get_bool_option("R600_HYPERZ", FALSE); rscreen->use_hyperz = rscreen->info.drm_minor >= 26 ? rscreen->use_hyperz : FALSE; rscreen->global_pool = compute_memory_pool_new(rscreen); diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 0335189..782ad26 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -186,10 +186,11 @@ static void r600_emit_query_end(struct r600_context *ctx, struct r600_query *que case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_SO_STATISTICS: case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + va += query->buffer.results_end + query->result_size/2; cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3); - cs->buf[cs->cdw++] = query->buffer.results_end + query->result_size/2; - cs->buf[cs->cdw++] = 0; + cs->buf[cs->cdw++] = va; + cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; break; case PIPE_QUERY_TIME_ELAPSED: va += query->buffer.results_end + query->result_size/2; diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am index e6eb241..a3a7b74 100644 --- a/src/gallium/drivers/radeon/Makefile.am +++ b/src/gallium/drivers/radeon/Makefile.am @@ -1,11 +1,14 @@ include Makefile.sources include $(top_srcdir)/src/gallium/Automake.inc +LIBGALLIUM_LIBS= + if HAVE_GALLIUM_R600 if HAVE_GALLIUM_RADEONSI lib_LTLIBRARIES = libllvmradeon@VERSION@.la libllvmradeon@VERSION@_la_LDFLAGS = -Wl, -shared -avoid-version \ $(LLVM_LDFLAGS) +LIBGALLIUM_LIBS += $(top_builddir)/src/gallium/auxiliary/libgallium.la else noinst_LTLIBRARIES = libllvmradeon@VERSION@.la endif @@ -26,5 +29,6 @@ libllvmradeon@VERSION@_la_SOURCES = \ $(C_FILES) libllvmradeon@VERSION@_la_LIBADD = \ + $(LIBGALLIUM_LIBS) \ $(CLOCK_LIB) \ $(LLVM_LIBS) diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 8c35625..93766a3 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -401,6 +401,11 @@ static void si_update_derived_state(struct r600_context *rctx) } if (si_pm4_state_changed(rctx, ps) || si_pm4_state_changed(rctx, vs)) { + /* XXX: Emitting the PS state even when only the VS changed + * fixes random failures with piglit glsl-max-varyings. + * Not sure why... + */ + rctx->emitted.named.ps = NULL; si_update_spi_map(rctx); } } diff --git a/src/gallium/drivers/rbug/Makefile.am b/src/gallium/drivers/rbug/Makefile.am index 655bfe1..3c1a8b5 100644 --- a/src/gallium/drivers/rbug/Makefile.am +++ b/src/gallium/drivers/rbug/Makefile.am @@ -30,6 +30,7 @@ noinst_LTLIBRARIES = librbug.la # preprocessor is determined by the ordering of the -I flags. AM_CFLAGS = \ $(GALLIUM_CFLAGS) \ + $(VISIBILITY_CFLAGS) \ -I$(top_srcdir)/src/gallium/drivers \ -I$(top_srcdir)/include diff --git a/src/gallium/drivers/svga/Makefile.am b/src/gallium/drivers/svga/Makefile.am index fdaa3c8..7eacd90 100644 --- a/src/gallium/drivers/svga/Makefile.am +++ b/src/gallium/drivers/svga/Makefile.am @@ -29,6 +29,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ $(GALLIUM_CFLAGS) +AM_CFLAGS = $(VISIBILITY_CFLAGS) + #On some systems -std= must be added to CFLAGS to be the last -std= CFLAGS += -std=gnu99 diff --git a/src/gallium/drivers/trace/Makefile.am b/src/gallium/drivers/trace/Makefile.am index a9e1457..984ead4 100644 --- a/src/gallium/drivers/trace/Makefile.am +++ b/src/gallium/drivers/trace/Makefile.am @@ -1,7 +1,8 @@ include $(top_srcdir)/src/gallium/Automake.inc AM_CFLAGS = \ - $(GALLIUM_CFLAGS) + $(GALLIUM_CFLAGS) \ + $(VISIBILITY_CFLAGS) noinst_LTLIBRARIES = libtrace.la diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 5958333..a131969 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -29,6 +29,8 @@ #define P_COMPILER_H +#include "c99_compat.h" /* inline, __func__, etc. */ + #include "p_config.h" #include @@ -90,28 +92,7 @@ typedef unsigned char boolean; #endif #endif -/* Function inlining */ -#ifndef inline -# ifdef __cplusplus - /* C++ supports inline keyword */ -# elif defined(__GNUC__) -# define inline __inline__ -# elif defined(_MSC_VER) -# define inline __inline -# elif defined(__ICL) -# define inline __inline -# elif defined(__INTEL_COMPILER) - /* Intel compiler supports inline keyword */ -# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) -# define inline __inline -# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) - /* C99 supports inline keyword */ -# elif (__STDC_VERSION__ >= 199901L) - /* C99 supports inline keyword */ -# else -# define inline -# endif -#endif +/* XXX: Use standard `inline` keyword instead */ #ifndef INLINE # define INLINE inline #endif @@ -127,26 +108,6 @@ typedef unsigned char boolean; # endif #endif -/* - * Define the C99 restrict keyword. - * - * See also: - * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html - */ -#ifndef restrict -# if (__STDC_VERSION__ >= 199901L) - /* C99 */ -# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) - /* C99 */ -# elif defined(__GNUC__) -# define restrict __restrict__ -# elif defined(_MSC_VER) -# define restrict __restrict -# else -# define restrict /* */ -# endif -#endif - /* Function visibility */ #ifndef PUBLIC @@ -160,35 +121,10 @@ typedef unsigned char boolean; #endif -/* The __FUNCTION__ gcc variable is generally only used for debugging. - * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. - */ +/* XXX: Use standard `__func__` instead */ #ifndef __FUNCTION__ -# if !defined(__GNUC__) -# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ - (defined(__SUNPRO_C) && defined(__C99FEATURES__)) -# define __FUNCTION__ __func__ -# else -# define __FUNCTION__ "" -# endif -# endif -# if defined(_MSC_VER) && _MSC_VER < 1300 -# define __FUNCTION__ "" -# endif +# define __FUNCTION__ __func__ #endif -#ifndef __func__ -# if (__STDC_VERSION__ >= 199901L) || \ - (defined(__SUNPRO_C) && defined(__C99FEATURES__)) - /* __func__ is part of C99 */ -# elif defined(_MSC_VER) -# if _MSC_VER >= 1300 -# define __func__ __FUNCTION__ -# else -# define __func__ "" -# endif -# endif -#endif - /* This should match linux gcc cdecl semantics everywhere, so that we diff --git a/src/gallium/state_trackers/egl/Makefile.am b/src/gallium/state_trackers/egl/Makefile.am index e19e9a3..f78b36e 100644 --- a/src/gallium/state_trackers/egl/Makefile.am +++ b/src/gallium/state_trackers/egl/Makefile.am @@ -27,7 +27,7 @@ include $(top_srcdir)/src/gallium/Automake.inc AM_CFLAGS = $(GALLIUM_CFLAGS) AM_CPPFLAGS = \ -I$(top_srcdir)/src/egl/main \ - -I$(top_srcdir)/src/egl/wayland/wayland-drm/ \ + -I$(top_builddir)/src/egl/wayland/wayland-drm/ \ -I$(top_srcdir)/include noinst_LTLIBRARIES = libegl.la diff --git a/src/gallium/state_trackers/xa/Makefile.am b/src/gallium/state_trackers/xa/Makefile.am index 5b53ef9..57d55c4 100644 --- a/src/gallium/state_trackers/xa/Makefile.am +++ b/src/gallium/state_trackers/xa/Makefile.am @@ -24,7 +24,9 @@ include $(top_srcdir)/src/gallium/Automake.inc AM_CFLAGS = \ -Wall -pedantic \ - $(GALLIUM_CFLAGS) + $(GALLIUM_CFLAGS) \ + $(VISIBILITY_CFLAGS) + AM_CPPFLAGS = \ -I$(top_srcdir)/src/gallium/ \ -I$(top_srcdir)/src/gallium/winsys \ diff --git a/src/gallium/winsys/svga/drm/Makefile.am b/src/gallium/winsys/svga/drm/Makefile.am index 53bbcc2..d7ada3c 100644 --- a/src/gallium/winsys/svga/drm/Makefile.am +++ b/src/gallium/winsys/svga/drm/Makefile.am @@ -31,6 +31,8 @@ AM_CPPFLAGS = \ $(GALLIUM_CFLAGS) \ $(LIBDRM_CFLAGS) +AM_CFLAGS = $(VISIBILITY_CFLAGS) + #On some systems -std= must be added to CFLAGS to be the last -std= CFLAGS += -std=gnu99 -D_FILE_OFFSET_BITS=64 diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 02d85b8..dee9709 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -446,6 +446,8 @@ const glsl_type *glsl_type::get_scalar_type() const return int_type; case GLSL_TYPE_FLOAT: return float_type; + case GLSL_TYPE_BOOL: + return bool_type; default: /* Handle everything else */ return type; diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index d8cafd5..78ce13e 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -695,6 +695,11 @@ check_node_type(ir_instruction *ir, void *data) void validate_ir_tree(exec_list *instructions) { + /* We shouldn't have any reason to validate IR in a release build, + * and it's half composed of assert()s anyway which wouldn't do + * anything. + */ +#ifdef DEBUG ir_validate v; v.run(instructions); @@ -704,4 +709,5 @@ validate_ir_tree(exec_list *instructions) visit_tree(ir, check_node_type, NULL); } +#endif } diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 57e7a9a..cf0420c 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1067,13 +1067,11 @@ link_intrastage_shaders(void *mem_ctx, free(linking_shaders); -#ifdef DEBUG /* At this point linked should contain all of the linked IR, so * validate it to make sure nothing went wrong. */ if (linked) validate_ir_tree(linked->ir); -#endif /* Make a pass over all variable declarations to ensure that arrays with * unspecified sizes have a size specified. The size is inferred from the diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am index 4aa900a..f01709b 100644 --- a/src/glx/Makefile.am +++ b/src/glx/Makefile.am @@ -39,6 +39,7 @@ AM_CFLAGS = \ -I$(top_srcdir)/src/mapi/glapi \ -I$(top_builddir)/src/mapi \ -I$(top_builddir)/src/mapi/glapi \ + $(VISIBILITY_CFLAGS) \ $(SHARED_GLAPI_CFLAGS) \ $(EXTRA_DEFINES_XF86VIDMODE) \ -D_REENTRANT \ diff --git a/src/mapi/glapi/gen/gl_x86-64_asm.py b/src/mapi/glapi/gen/gl_x86-64_asm.py index a3548c2..19e0e15 100644 --- a/src/mapi/glapi/gen/gl_x86-64_asm.py +++ b/src/mapi/glapi/gen/gl_x86-64_asm.py @@ -181,19 +181,6 @@ class PrintGenericStubs(gl_XML.gl_print_base): def printRealFooter(self): print '' - print '#if defined(GLX_USE_TLS) && defined(__linux__)' - print ' .section ".note.ABI-tag", "a"' - print ' .p2align 2' - print ' .long 1f - 0f /* name length */' - print ' .long 3f - 2f /* data length */' - print ' .long 1 /* note length */' - print '0: .asciz "GNU" /* vendor name */' - print '1: .p2align 2' - print '2: .long 0 /* note data: the ABI tag */' - print ' .long 2,4,20 /* Minimum kernel version w/TLS */' - print '3: .p2align 2 /* pad out section */' - print '#endif /* GLX_USE_TLS */' - print '' print '#if defined (__ELF__) && defined (__linux__)' print ' .section .note.GNU-stack,"",%progbits' print '#endif' diff --git a/src/mapi/glapi/gen/gl_x86_asm.py b/src/mapi/glapi/gen/gl_x86_asm.py index 8b0f6ee..919bbc0 100644 --- a/src/mapi/glapi/gen/gl_x86_asm.py +++ b/src/mapi/glapi/gen/gl_x86_asm.py @@ -189,19 +189,6 @@ class PrintGenericStubs(gl_XML.gl_print_base): print '\t\tALIGNTEXT16' print 'GLNAME(gl_dispatch_functions_end):' print '' - print '#if defined(GLX_USE_TLS) && defined(__linux__)' - print ' .section ".note.ABI-tag", "a"' - print ' .p2align 2' - print ' .long 1f - 0f /* name length */' - print ' .long 3f - 2f /* data length */' - print ' .long 1 /* note length */' - print '0: .asciz "GNU" /* vendor name */' - print '1: .p2align 2' - print '2: .long 0 /* note data: the ABI tag */' - print ' .long 2,4,20 /* Minimum kernel version w/TLS */' - print '3: .p2align 2 /* pad out section */' - print '#endif /* GLX_USE_TLS */' - print '' print '#if defined (__ELF__) && defined (__linux__)' print ' .section .note.GNU-stack,"",%progbits' print '#endif' diff --git a/src/mapi/mapi/entry_x86-64_tls.h b/src/mapi/mapi/entry_x86-64_tls.h index 72d4125..36cad00 100644 --- a/src/mapi/mapi/entry_x86-64_tls.h +++ b/src/mapi/mapi/entry_x86-64_tls.h @@ -28,19 +28,6 @@ #include "u_macros.h" -#ifdef __linux__ -__asm__(".section .note.ABI-tag, \"a\"\n\t" - ".p2align 2\n\t" - ".long 1f - 0f\n\t" /* name length */ - ".long 3f - 2f\n\t" /* data length */ - ".long 1\n\t" /* note length */ - "0: .asciz \"GNU\"\n\t" /* vendor name */ - "1: .p2align 2\n\t" - "2: .long 0\n\t" /* note data: the ABI tag */ - ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ - "3: .p2align 2\n\t"); /* pad out section */ -#endif /* __linux__ */ - __asm__(".text\n" ".balign 32\n" "x86_64_entry_start:"); diff --git a/src/mapi/mapi/entry_x86_tls.h b/src/mapi/mapi/entry_x86_tls.h index de91812..58d09ca 100644 --- a/src/mapi/mapi/entry_x86_tls.h +++ b/src/mapi/mapi/entry_x86_tls.h @@ -29,19 +29,6 @@ #include #include "u_macros.h" -#ifdef __linux__ -__asm__(".section .note.ABI-tag, \"a\"\n\t" - ".p2align 2\n\t" - ".long 1f - 0f\n\t" /* name length */ - ".long 3f - 2f\n\t" /* data length */ - ".long 1\n\t" /* note length */ - "0: .asciz \"GNU\"\n\t" /* vendor name */ - "1: .p2align 2\n\t" - "2: .long 0\n\t" /* note data: the ABI tag */ - ".long 2,4,20\n\t" /* Minimum kernel version w/TLS */ - "3: .p2align 2\n\t"); /* pad out section */ -#endif /* __linux__ */ - __asm__(".text"); __asm__("x86_current_tls:\n\t" diff --git a/src/mapi/mapi/u_compiler.h b/src/mapi/mapi/u_compiler.h index 2b019ed..f376e97 100644 --- a/src/mapi/mapi/u_compiler.h +++ b/src/mapi/mapi/u_compiler.h @@ -1,28 +1,10 @@ #ifndef _U_COMPILER_H_ #define _U_COMPILER_H_ -/* Function inlining */ -#ifndef inline -# ifdef __cplusplus - /* C++ supports inline keyword */ -# elif defined(__GNUC__) -# define inline __inline__ -# elif defined(_MSC_VER) -# define inline __inline -# elif defined(__ICL) -# define inline __inline -# elif defined(__INTEL_COMPILER) - /* Intel compiler supports inline keyword */ -# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) -# define inline __inline -# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) - /* C99 supports inline keyword */ -# elif (__STDC_VERSION__ >= 199901L) - /* C99 supports inline keyword */ -# else -# define inline -# endif -#endif +#include "c99_compat.h" /* inline, __func__, etc. */ + + +/* XXX: Use standard `inline` keyword instead */ #ifndef INLINE # define INLINE inline #endif diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c index 53d8e54..cde1a06 100644 --- a/src/mesa/drivers/dri/i965/brw_clear.c +++ b/src/mesa/drivers/dri/i965/brw_clear.c @@ -40,6 +40,8 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" +#include "brw_context.h" + #define FILE_DEBUG_FLAG DEBUG_BLIT static const char *buffer_names[] = { @@ -219,7 +221,8 @@ brw_fast_clear_depth(struct gl_context *ctx) static void brw_clear(struct gl_context *ctx, GLbitfield mask) { - struct intel_context *intel = intel_context(ctx); + struct brw_context *brw = brw_context(ctx); + struct intel_context *intel = &brw->intel; if (!_mesa_check_conditional_render(ctx)) return; @@ -229,6 +232,7 @@ brw_clear(struct gl_context *ctx, GLbitfield mask) } intel_prepare_render(intel); + brw_workaround_depthstencil_alignment(brw); if (mask & BUFFER_BIT_DEPTH) { if (brw_fast_clear_depth(ctx)) { diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 79cc12f..4bcfb95 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -437,6 +437,7 @@ #define BRW_SURFACEFORMAT_B10G10R10A2_SSCALED 0x1B9 #define BRW_SURFACEFORMAT_B10G10R10A2_UINT 0x1BA #define BRW_SURFACEFORMAT_B10G10R10A2_SINT 0x1BB +#define BRW_SURFACEFORMAT_RAW 0x1FF #define BRW_SURFACE_FORMAT_SHIFT 18 #define BRW_SURFACE_FORMAT_MASK INTEL_MASK(26, 18) @@ -857,6 +858,7 @@ enum brw_message_target { GEN6_SFID_DATAPORT_CONSTANT_CACHE = 9, GEN7_SFID_DATAPORT_DATA_CACHE = 10, + HSW_SFID_DATAPORT_DATA_CACHE_1 = 12, }; #define GEN7_MESSAGE_TARGET_DP_DATA_CACHE 10 @@ -965,7 +967,44 @@ enum brw_message_target { /* GEN7 */ #define GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 10 +#define GEN7_DATAPORT_DC_OWORD_BLOCK_READ 0 +#define GEN7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ 1 +#define GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ 2 #define GEN7_DATAPORT_DC_DWORD_SCATTERED_READ 3 +#define GEN7_DATAPORT_DC_BYTE_SCATTERED_READ 4 +#define GEN7_DATAPORT_DC_UNTYPED_SURFACE_READ 5 +#define GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP 6 +#define GEN7_DATAPORT_DC_MEMORY_FENCE 7 +#define GEN7_DATAPORT_DC_OWORD_BLOCK_WRITE 8 +#define GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE 10 +#define GEN7_DATAPORT_DC_DWORD_SCATTERED_WRITE 11 +#define GEN7_DATAPORT_DC_BYTE_SCATTERED_WRITE 12 +#define GEN7_DATAPORT_DC_UNTYPED_SURFACE_WRITE 13 + +/* HSW */ +#define HSW_DATAPORT_DC_PORT0_OWORD_BLOCK_READ 0 +#define HSW_DATAPORT_DC_PORT0_UNALIGNED_OWORD_BLOCK_READ 1 +#define HSW_DATAPORT_DC_PORT0_OWORD_DUAL_BLOCK_READ 2 +#define HSW_DATAPORT_DC_PORT0_DWORD_SCATTERED_READ 3 +#define HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_READ 4 +#define HSW_DATAPORT_DC_PORT0_MEMORY_FENCE 7 +#define HSW_DATAPORT_DC_PORT0_OWORD_BLOCK_WRITE 8 +#define HSW_DATAPORT_DC_PORT0_OWORD_DUAL_BLOCK_WRITE 10 +#define HSW_DATAPORT_DC_PORT0_DWORD_SCATTERED_WRITE 11 +#define HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_WRITE 12 + +#define HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ 1 +#define HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP 2 +#define HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2 3 +#define HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ 4 +#define HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ 5 +#define HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP 6 +#define HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2 7 +#define HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE 9 +#define HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE 10 +#define HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP 11 +#define HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2 12 +#define HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE 13 /* dataport atomic operations. */ #define BRW_AOP_AND 1 diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index b34754a..40cae37 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -2539,15 +2539,22 @@ void brw_shader_time_add(struct brw_compile *p, brw_set_src0(p, send, brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, base_mrf, 0)); + uint32_t sfid, msg_type; + if (intel->is_haswell) { + sfid = HSW_SFID_DATAPORT_DATA_CACHE_1; + msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP; + } else { + sfid = GEN7_SFID_DATAPORT_DATA_CACHE; + msg_type = GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP; + } + bool header_present = false; bool eot = false; uint32_t mlen = 2; /* offset, value */ uint32_t rlen = 0; - brw_set_message_descriptor(p, send, - GEN7_SFID_DATAPORT_DATA_CACHE, - mlen, rlen, header_present, eot); + brw_set_message_descriptor(p, send, sfid, mlen, rlen, header_present, eot); - send->bits3.ud |= 6 << 14; /* untyped atomic op */ + send->bits3.ud |= msg_type << 14; send->bits3.ud |= 0 << 13; /* no return data */ send->bits3.ud |= 1 << 12; /* SIMD8 mode */ send->bits3.ud |= BRW_AOP_ADD << 8; diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index f80219e..4924441 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2295,7 +2295,8 @@ clear_deps_for_inst_src(fs_inst *inst, int dispatch_width, bool *deps, void fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst) { - int write_len = inst->regs_written() * dispatch_width / 8; + int reg_size = dispatch_width / 8; + int write_len = inst->regs_written() * reg_size; int first_write_grf = inst->dst.reg; bool needs_dep[BRW_MAX_MRF]; assert(write_len < (int)sizeof(needs_dep) - 1); @@ -2334,14 +2335,19 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst) * instruction but a MOV that might have left us an outstanding * dependency has more latency than a MOV. */ - if (scan_inst->dst.file == GRF && - scan_inst->dst.reg >= first_write_grf && - scan_inst->dst.reg < first_write_grf + write_len && - needs_dep[scan_inst->dst.reg - first_write_grf]) { - inst->insert_before(DEP_RESOLVE_MOV(scan_inst->dst.reg)); - needs_dep[scan_inst->dst.reg - first_write_grf] = false; - if (scan_inst_16wide) - needs_dep[scan_inst->dst.reg - first_write_grf + 1] = false; + if (scan_inst->dst.file == GRF) { + for (int i = 0; i < scan_inst->regs_written(); i++) { + int reg = scan_inst->dst.reg + i * reg_size; + + if (reg >= first_write_grf && + reg < first_write_grf + write_len && + needs_dep[reg - first_write_grf]) { + inst->insert_before(DEP_RESOLVE_MOV(reg)); + needs_dep[reg - first_write_grf] = false; + if (scan_inst_16wide) + needs_dep[reg - first_write_grf + 1] = false; + } + } } /* Clear the flag for registers that actually got read (as expected). */ @@ -2494,6 +2500,8 @@ fs_visitor::lower_uniform_pull_constant_loads() inst->insert_before(setup2); inst->opcode = FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD_GEN7; inst->src[1] = payload; + + this->live_intervals_valid = false; } else { /* Before register allocation, we didn't tell the scheduler about the * MRF we use. We know it's safe to use this MRF because nothing diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp index db8f397..4c7991d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp @@ -190,6 +190,37 @@ fs_visitor::calculate_live_intervals() int reg = inst->src[i].reg; use[reg] = ip; + + /* In most cases, a register can be written over safely by the + * same instruction that is its last use. For a single + * instruction, the sources are dereferenced before writing of the + * destination starts (naturally). This gets more complicated for + * simd16, because the instruction: + * + * mov(16) g4<1>F g4<8,8,1>F g6<8,8,1>F + * + * is actually decoded in hardware as: + * + * mov(8) g4<1>F g4<8,8,1>F g6<8,8,1>F + * mov(8) g5<1>F g5<8,8,1>F g7<8,8,1>F + * + * Which is safe. However, if we have uniform accesses + * happening, we get into trouble: + * + * mov(8) g4<1>F g4<0,1,0>F g6<8,8,1>F + * mov(8) g5<1>F g4<0,1,0>F g7<8,8,1>F + * + * Now our destination for the first instruction overwrote the + * second instruction's src0, and we get garbage for those 8 + * pixels. There's a similar issue for the pre-gen6 + * pixel_x/pixel_y, which are registers of 16-bit values and thus + * would get stomped by the first decode as well. + */ + if (dispatch_width == 16 && (inst->src[i].smear || + (this->pixel_x.reg == reg || + this->pixel_y.reg == reg))) { + use[reg]++; + } } } @@ -264,28 +295,5 @@ fs_visitor::virtual_grf_interferes(int a, int b) int start = MAX2(a_def, b_def); int end = MIN2(a_use, b_use); - /* If the register is used to store 16 values of less than float - * size (only the case for pixel_[xy]), then we can't allocate - * another dword-sized thing to that register that would be used in - * the same instruction. This is because when the GPU decodes (for - * example): - * - * (declare (in ) vec4 gl_FragCoord@0x97766a0) - * add(16) g6<1>F g6<8,8,1>UW 0.5F { align1 compr }; - * - * it's actually processed as: - * add(8) g6<1>F g6<8,8,1>UW 0.5F { align1 }; - * add(8) g7<1>F g6.8<8,8,1>UW 0.5F { align1 sechalf }; - * - * so our second half values in g6 got overwritten in the first - * half. - */ - if (dispatch_width == 16 && (this->pixel_x.reg == a || - this->pixel_x.reg == b || - this->pixel_y.reg == a || - this->pixel_y.reg == b)) { - return start <= end; - } - return start < end; } diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index ecc61c4..02ce57b 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -216,6 +216,8 @@ void gen7_set_surface_mcs_info(struct brw_context *brw, bool is_render_target); void gen7_check_surface_setup(uint32_t *surf, bool is_render_target); void gen7_init_vtable_surface_functions(struct brw_context *brw); +void gen7_create_shader_time_surface(struct brw_context *brw, + uint32_t *out_offset); /* brw_wm_sampler_state.c */ uint32_t translate_wrap_mode(GLenum wrap, bool using_nearest); diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c index 4da7eaa..2aefc0c 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -137,14 +137,11 @@ const struct brw_tracked_state brw_vs_ubo_surfaces = { static void brw_vs_upload_binding_table(struct brw_context *brw) { - struct intel_context *intel = &brw->intel; uint32_t *bind; int i; if (INTEL_DEBUG & DEBUG_SHADER_TIME) { - intel->vtbl.create_constant_surface(brw, brw->shader_time.bo, 0, - brw->shader_time.bo->size, - &brw->vs.surf_offset[SURF_INDEX_VS_SHADER_TIME]); + gen7_create_shader_time_surface(brw, &brw->vs.surf_offset[SURF_INDEX_VS_SHADER_TIME]); assert(brw->vs.prog_data->num_surfaces <= SURF_INDEX_VS_SHADER_TIME); brw->vs.prog_data->num_surfaces = SURF_INDEX_VS_SHADER_TIME; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 6ec7d71..657a56f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -770,7 +770,8 @@ brw_get_texture_swizzle(const struct gl_context *ctx, case GL_RED: case GL_RG: case GL_RGB: - swizzles[3] = SWIZZLE_ONE; + if (_mesa_get_format_bits(img->TexFormat, GL_ALPHA_BITS) > 0) + swizzles[3] = SWIZZLE_ONE; break; } @@ -1468,14 +1469,11 @@ const struct brw_tracked_state brw_wm_ubo_surfaces = { static void brw_upload_wm_binding_table(struct brw_context *brw) { - struct intel_context *intel = &brw->intel; uint32_t *bind; int i; if (INTEL_DEBUG & DEBUG_SHADER_TIME) { - intel->vtbl.create_constant_surface(brw, brw->shader_time.bo, 0, - brw->shader_time.bo->size, - &brw->wm.surf_offset[SURF_INDEX_WM_SHADER_TIME]); + gen7_create_shader_time_surface(brw, &brw->wm.surf_offset[SURF_INDEX_WM_SHADER_TIME]); } /* Might want to calculate nr_surfaces first, to avoid taking up so much diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c index d32f636..7ac5d5f 100644 --- a/src/mesa/drivers/dri/i965/gen6_cc.c +++ b/src/mesa/drivers/dri/i965/gen6_cc.c @@ -126,7 +126,7 @@ gen6_upload_blend_state(struct brw_context *brw) * not read the alpha channel, but will instead use the correct * implicit value for alpha. */ - if (!_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) + if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE)) { srcRGB = brw_fix_xRGB_alpha(srcRGB); srcA = brw_fix_xRGB_alpha(srcA); diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c index 24f1b9c..2913fc6 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -413,6 +413,46 @@ gen7_create_constant_surface(struct brw_context *brw, gen7_check_surface_setup(surf, false /* is_render_target */); } +/** + * Create a surface for shader time. + */ +void +gen7_create_shader_time_surface(struct brw_context *brw, uint32_t *out_offset) +{ + struct intel_context *intel = &brw->intel; + const int w = brw->shader_time.bo->size - 1; + + uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, + 8 * 4, 32, out_offset); + memset(surf, 0, 8 * 4); + + surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT | + BRW_SURFACEFORMAT_RAW << BRW_SURFACE_FORMAT_SHIFT | + BRW_SURFACE_RC_READ_WRITE; + + surf[1] = brw->shader_time.bo->offset; /* reloc */ + + surf[2] = SET_FIELD(w & 0x7f, GEN7_SURFACE_WIDTH) | + SET_FIELD((w >> 7) & 0x1fff, GEN7_SURFACE_HEIGHT); + surf[3] = SET_FIELD((w >> 20) & 0x7f, BRW_SURFACE_DEPTH); + + /* Unlike texture or renderbuffer surfaces, we only do untyped operations + * on the shader_time surface, so there's no need to set HSW channel + * overrides. + */ + + /* Emit relocation to surface contents. Section 5.1.1 of the gen4 + * bspec ("Data Cache") says that the data cache does not exist as + * a separate cache and is just the sampler cache. + */ + drm_intel_bo_emit_reloc(intel->batch.bo, + *out_offset + 4, + brw->shader_time.bo, 0, + I915_GEM_DOMAIN_SAMPLER, 0); + + gen7_check_surface_setup(surf, false /* is_render_target */); +} + static void gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit) { diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 5ec93f1..4173c0f 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -312,7 +312,7 @@ intel_create_image_from_name(__DRIscreen *screen, cpp = _mesa_get_format_bytes(image->format); image->region = intel_region_alloc_for_handle(intelScreen, cpp, width, height, - pitch, name, "image"); + pitch * cpp, name, "image"); if (image->region == NULL) { free(image); return NULL; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index f56b3b2..6c119d5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -69,7 +69,8 @@ nouveau_flush(struct gl_context *ctx) __DRIdri2LoaderExtension *dri2 = screen->dri2.loader; __DRIdrawable *drawable = nctx->dri_context->driDrawablePriv; - dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); + if (drawable && drawable->loaderPrivate) + dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); } } diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c index 7eda4e0..4ffc4ef 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_context.c +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -469,7 +469,7 @@ nv10_context_create(struct nouveau_screen *screen, const struct gl_config *visua goto fail; /* 3D engine. */ - if (context_chipset(ctx) >= 0x17) + if (context_chipset(ctx) >= 0x17 && context_chipset(ctx) != 0x1a) celsius_class = NV17_3D_CLASS; else if (context_chipset(ctx) >= 0x11) celsius_class = NV15_3D_CLASS; diff --git a/src/mesa/drivers/osmesa/Makefile.am b/src/mesa/drivers/osmesa/Makefile.am index c4b178b..2503401 100644 --- a/src/mesa/drivers/osmesa/Makefile.am +++ b/src/mesa/drivers/osmesa/Makefile.am @@ -24,6 +24,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/mapi \ + -I$(top_builddir)/src/mapi \ -I$(top_srcdir)/src/mesa/ \ $(DEFINES) \ $(API_DEFINES) diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index b22b994..8b23665 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -48,6 +48,8 @@ #include #include +#include "c99_compat.h" /* inline, __func__, etc. */ + #ifdef __cplusplus extern "C" { @@ -111,30 +113,7 @@ extern "C" { -/** - * Function inlining - */ -#ifndef inline -# ifdef __cplusplus - /* C++ supports inline keyword */ -# elif defined(__GNUC__) -# define inline __inline__ -# elif defined(_MSC_VER) -# define inline __inline -# elif defined(__ICL) -# define inline __inline -# elif defined(__INTEL_COMPILER) - /* Intel compiler supports inline keyword */ -# elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) -# define inline __inline -# elif defined(__SUNPRO_C) && defined(__C99FEATURES__) - /* C99 supports inline keyword */ -# elif (__STDC_VERSION__ >= 199901L) - /* C99 supports inline keyword */ -# else -# define inline -# endif -#endif +/* XXX: Use standard `inline` keyword instead */ #ifndef INLINE # define INLINE inline #endif @@ -177,35 +156,10 @@ extern "C" { # endif #endif -/** - * The __FUNCTION__ gcc variable is generally only used for debugging. - * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. - * Don't define it if using a newer Windows compiler. - */ +/* XXX: Use standard `__func__` instead */ #ifndef __FUNCTION__ -# if !defined(__GNUC__) && !defined(__xlC__) && \ - (!defined(_MSC_VER) || _MSC_VER < 1300) -# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ - (defined(__SUNPRO_C) && defined(__C99FEATURES__)) -# define __FUNCTION__ __func__ -# else -# define __FUNCTION__ "" -# endif -# endif +# define __FUNCTION__ __func__ #endif -#ifndef __func__ -# if (__STDC_VERSION__ >= 199901L) || \ - (defined(__SUNPRO_C) && defined(__C99FEATURES__)) - /* __func__ is part of C99 */ -# elif defined(_MSC_VER) -# if _MSC_VER >= 1300 -# define __func__ __FUNCTION__ -# else -# define __func__ "" -# endif -# endif -#endif - /** * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN, and CPU_TO_LE32. @@ -353,8 +307,9 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) * USE_IEEE: Determine if we're using IEEE floating point */ #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ - defined(__s390x__) || defined(__powerpc__) || \ + defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \ defined(__x86_64__) || \ + defined(__m68k__) || \ defined(ia64) || defined(__ia64__) || \ defined(__hppa__) || defined(hpux) || \ defined(__mips) || defined(_MIPS_ARCH) || \ diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 257f839..61c1151 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -3160,7 +3160,9 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, } } - if (!mask) { + if (!mask || + (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || + (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { return; } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 5f4e2fa..6fb2f5d 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -34,6 +34,7 @@ #include "state.h" #include "texcompress.h" #include "framebuffer.h" +#include "samplerobj.h" /* This is a table driven implemetation of the glGet*v() functions. * The basic idea is that most getters just look up an int somewhere @@ -823,7 +824,16 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu { struct gl_sampler_object *samp = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler; - v->value_int = samp ? samp->Name : 0; + + /* + * The sampler object may have been deleted on another context, + * so we try to lookup the sampler object before returning its Name. + */ + if (samp && _mesa_lookup_samplerobj(ctx, samp->Name)) { + v->value_int = samp->Name; + } else { + v->value_int = 0; + } } break; /* GL_ARB_uniform_buffer_object */ diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index 9aab889..15c1c4d 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -412,7 +412,7 @@ descriptor=[ [ "DEPTH_SCALE", "CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA" ], [ "DOUBLEBUFFER", "BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA" ], [ "DRAW_BUFFER", "BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA" ], - [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], + [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_flush_current" ], [ "FEEDBACK_BUFFER_SIZE", "CONTEXT_INT(Feedback.BufferSize), NO_EXTRA" ], [ "FEEDBACK_BUFFER_TYPE", "CONTEXT_ENUM(Feedback.Type), NO_EXTRA" ], [ "FOG_INDEX", "CONTEXT_FLOAT(Fog.Index), NO_EXTRA" ], diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3369623..8f906ae 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1274,6 +1274,7 @@ struct gl_texture_object GLfloat Priority; /**< in [0,1] */ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ GLint CropRect[4]; /**< GL_OES_draw_texture */ diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c index 319a444..5cff329 100644 --- a/src/mesa/main/samplerobj.c +++ b/src/mesa/main/samplerobj.c @@ -40,7 +40,7 @@ #include "main/samplerobj.h" -static struct gl_sampler_object * +struct gl_sampler_object * _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) { if (name == 0) @@ -206,9 +206,19 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) for (i = 0; i < count; i++) { if (samplers[i]) { + GLuint j; struct gl_sampler_object *sampObj = _mesa_lookup_samplerobj(ctx, samplers[i]); + if (sampObj) { + /* If the sampler is currently bound, unbind it. */ + for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) { + if (ctx->Texture.Unit[j].Sampler == sampObj) { + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL); + } + } + /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]); /* But the object exists until its reference count goes to zero */ diff --git a/src/mesa/main/samplerobj.h b/src/mesa/main/samplerobj.h index 3114257..69e3899 100644 --- a/src/mesa/main/samplerobj.h +++ b/src/mesa/main/samplerobj.h @@ -62,6 +62,8 @@ _mesa_reference_sampler_object(struct gl_context *ctx, _mesa_reference_sampler_object_(ctx, ptr, samp); } +extern struct gl_sampler_object * +_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name); extern struct gl_sampler_object * _mesa_new_sampler_object(struct gl_context *ctx, GLuint name); diff --git a/src/mesa/main/tests/hash_table/Makefile.am b/src/mesa/main/tests/hash_table/Makefile.am index 272c63a..f63841d 100644 --- a/src/mesa/main/tests/hash_table/Makefile.am +++ b/src/mesa/main/tests/hash_table/Makefile.am @@ -19,6 +19,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ -I$(top_srcdir)/src/mesa/main \ $(API_DEFINES) $(DEFINES) $(INCLUDE_DIRS) diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 7299a4b..74b09ef 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -518,6 +518,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, if (type_needs_clamping(type)) { /* the returned image type can't have negative values */ if (dataType == GL_FLOAT || + dataType == GL_HALF_FLOAT || dataType == GL_SIGNED_NORMALIZED || format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 1b9525b..1b91b89 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1362,6 +1362,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, return GL_FALSE; return GL_TRUE; + case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -3438,19 +3439,21 @@ copyteximage(struct gl_context *ctx, GLuint dims, _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border, internalFormat, texFormat); - /* Allocate texture memory (no pixel data yet) */ - ctx->Driver.AllocTextureImageBuffer(ctx, texImage); + if (width && height) { + /* Allocate texture memory (no pixel data yet) */ + ctx->Driver.AllocTextureImageBuffer(ctx, texImage); - if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, - &width, &height)) { - struct gl_renderbuffer *srcRb = - get_copy_tex_image_source(ctx, texImage->TexFormat); + if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, + &width, &height)) { + struct gl_renderbuffer *srcRb = + get_copy_tex_image_source(ctx, texImage->TexFormat); - ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ, - srcRb, srcX, srcY, width, height); - } + ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ, + srcRb, srcX, srcY, width, height); + } - check_gen_mipmap(ctx, target, texObj, level); + check_gen_mipmap(ctx, target, texObj, level); + } _mesa_update_fbo_texture(ctx, texObj, face, level); diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 6f18ec6..dd67baa 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -1432,6 +1432,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) *params = (GLfloat) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; @@ -1609,6 +1615,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = (GLint) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c index 00f19ba..675fd74 100644 --- a/src/mesa/main/texstorage.c +++ b/src/mesa/main/texstorage.c @@ -397,6 +397,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } texObj->Immutable = GL_TRUE; + texObj->ImmutableLevels = levels; } } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index efb386e..f5b5c41 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -253,7 +253,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) struct vbo_save_context *save = &vbo_context(ctx)->save; GLboolean remap_vertex_store = GL_FALSE; - if (save->vertex_store->buffer) { + if (save->vertex_store && save->vertex_store->buffer) { /* The vertex store is currently mapped but we're about to replay * a display list. This can happen when a nested display list is * being build with GL_COMPILE_AND_EXECUTE.