From 4d2c16e77fd64dce6899269e007053396c454bdb Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 20 Dec 2012 14:20:13 -0500 Subject: [PATCH] mesa-9.0.1-22-gd0a9ab2.patch: Sync with git - Build with -fno-rtti -fno-exceptions, modest size and speed win - mesa-9.0.1-less-cxx-please.patch: Remove the only use of typeid() so the above works. --- mesa-9.0.1-22-gd0a9ab2.patch | 1834 ++++++++++++++++++++++++++++++++++ 1 file changed, 1834 insertions(+) create mode 100644 mesa-9.0.1-22-gd0a9ab2.patch diff --git a/mesa-9.0.1-22-gd0a9ab2.patch b/mesa-9.0.1-22-gd0a9ab2.patch new file mode 100644 index 0000000..fb10a04 --- /dev/null +++ b/mesa-9.0.1-22-gd0a9ab2.patch @@ -0,0 +1,1834 @@ +diff --git a/configs/current.in b/configs/current.in +index 1802271..62edfa5 100644 +--- a/configs/current.in ++++ b/configs/current.in +@@ -144,7 +144,7 @@ GLAPI_LIB_DEPS = @GLAPI_LIB_DEPS@ + DRI_LIB_DEPS = @DRI_LIB_DEPS@ + GALLIUM_DRI_LIB_DEPS = @GALLIUM_DRI_LIB_DEPS@ + LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +-LIBDRM_LIB = @LIBDRM_LIBS@ ++LIBDRM_LIBS = @LIBDRM_LIBS@ + DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ + GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ + EXPAT_INCLUDES = @EXPAT_INCLUDES@ +diff --git a/docs/GL3.txt b/docs/GL3.txt +index 24b70a1..9035779 100644 +--- a/docs/GL3.txt ++++ b/docs/GL3.txt +@@ -34,8 +34,7 @@ sRGB framebuffer format (GL_EXT_framebuffer_sRGB) DONE (i965, r600) + glClearBuffer commands DONE + glGetStringi command DONE + glTexParameterI, glGetTexParameterI commands DONE +-glVertexAttribI commands ~50% done (converts int +- values to floats) ++glVertexAttribI commands DONE + Depth format cube textures DONE + GLX_ARB_create_context (GLX 1.4 is required) DONE + +diff --git a/docs/news.html b/docs/news.html +index 26e648b..399a537 100644 +--- a/docs/news.html ++++ b/docs/news.html +@@ -9,6 +9,14 @@ + +

News

+ ++

November 16, 2012

++ ++

++Mesa 9.0.1 is released. ++This is a bug fix release. ++

++ ++ +

October 8, 2012

+ +

+diff --git a/docs/relnotes-9.0.1.html b/docs/relnotes-9.0.1.html +index 8a354b0..ed8f1a7 100644 +--- a/docs/relnotes-9.0.1.html ++++ b/docs/relnotes-9.0.1.html +@@ -7,7 +7,7 @@ + + + +-

Mesa 9.0.1 Release Notes / November 14th, 2012

++

Mesa 9.0.1 Release Notes / November 16th, 2012

+ +

+ Mesa 9.0.1 is a bug fix release which fixes bugs found since the 9.0 release. +@@ -23,7 +23,9 @@ because GL_ARB_compatibility is not supported. + +

MD5 checksums

+
+-TBD.
++97d6554c05ea7449398afe3a0ede7018  MesaLib-9.0.1.tar.bz2
++fd0fd5a6e56bc3dd210c80e42baef975  MesaLib-9.0.1.tar.gz
++c2683d957acd530a00f747f50317186f  MesaLib-9.0.1.zip
+ 
+ +

New features

+diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h +index e63cf5f..c87c3d8 100644 +--- a/src/gallium/auxiliary/draw/draw_vertex.h ++++ b/src/gallium/auxiliary/draw/draw_vertex.h +@@ -42,6 +42,7 @@ + #include "pipe/p_compiler.h" + #include "pipe/p_state.h" + #include "util/u_debug.h" ++#include "util/u_memory.h" + + + /** +@@ -87,7 +88,7 @@ struct vertex_info + unsigned interp_mode:4; /**< INTERP_x */ + unsigned emit:4; /**< EMIT_x */ + unsigned src_index:8; /**< map to post-xform attribs */ +- } attrib[PIPE_MAX_SHADER_INPUTS]; ++ } attrib[PIPE_MAX_SHADER_OUTPUTS]; + }; + + static INLINE size_t +@@ -127,7 +128,7 @@ draw_emit_vertex_attr(struct vertex_info *vinfo, + uint src_index) + { + const uint n = vinfo->num_attribs; +- assert(n < PIPE_MAX_SHADER_INPUTS); ++ assert(n < Elements(vinfo->attrib)); + vinfo->attrib[n].emit = emit; + vinfo->attrib[n].interp_mode = interp; + vinfo->attrib[n].src_index = src_index; +diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c +index 3fe78e0..3c2a923 100644 +--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c ++++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c +@@ -73,7 +73,7 @@ struct ureg_tokens { + + #define UREG_MAX_INPUT PIPE_MAX_ATTRIBS + #define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS +-#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS ++#define UREG_MAX_OUTPUT PIPE_MAX_SHADER_OUTPUTS + #define UREG_MAX_CONSTANT_RANGE 32 + #define UREG_MAX_IMMEDIATE 256 + #define UREG_MAX_ADDR 2 +diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp +index 071674b..e73c804 100644 +--- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp ++++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp +@@ -257,7 +257,7 @@ unsigned int Instruction::srcMask(unsigned int s) const + mask &= 0x9; + break; + case TGSI_TEXTURE_SHADOW1D: +- mask &= 0x5; ++ mask &= 0xd; + break; + case TGSI_TEXTURE_1D_ARRAY: + case TGSI_TEXTURE_2D: +diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c +index 3d510ea..982948e 100644 +--- a/src/gallium/drivers/nv50/nv50_screen.c ++++ b/src/gallium/drivers/nv50/nv50_screen.c +@@ -454,6 +454,18 @@ nv50_screen_init_hwctx(struct nv50_screen *screen) + PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); + PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); + ++ /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */ ++ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); ++ PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX); ++ BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); ++ PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9)); ++ PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9)); ++ + /* max TIC (bits 4:8) & TSC bindings, per program type */ + for (i = 0; i < 3; ++i) { + BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); +diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c +index b021f2e..9c43ae6 100644 +--- a/src/gallium/drivers/nvc0/nvc0_context.c ++++ b/src/gallium/drivers/nvc0/nvc0_context.c +@@ -183,6 +183,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text); + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniform_bo); + BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc); ++ BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->poly_cache); + + flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR; + +diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c +index eb74e95..8bb9ff6 100644 +--- a/src/gallium/drivers/nvc0/nvc0_screen.c ++++ b/src/gallium/drivers/nvc0/nvc0_screen.c +@@ -589,7 +589,7 @@ nvc0_screen_create(struct nouveau_device *dev) + + for (i = 0; i < 5; ++i) { + /* TIC and TSC entries for each unit (nve4+ only) */ +- /* auxiliary constants (6 user clip planes, base instance id */ ++ /* auxiliary constants (6 user clip planes, base instance id) */ + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); + PUSH_DATA (push, 512); + PUSH_DATAh(push, screen->uniform_bo->offset + (5 << 16) + (i << 9)); +@@ -610,6 +610,21 @@ nvc0_screen_create(struct nouveau_device *dev) + BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1); + PUSH_DATA (push, 0); + ++ /* return { 0.0, 0.0, 0.0, 0.0 } for out-of-bounds vtxbuf access */ ++ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); ++ PUSH_DATA (push, 256); ++ PUSH_DATAh(push, screen->uniform_bo->offset + (5 << 16) + (6 << 9)); ++ PUSH_DATA (push, screen->uniform_bo->offset + (5 << 16) + (6 << 9)); ++ BEGIN_1IC0(push, NVC0_3D(CB_POS), 5); ++ PUSH_DATA (push, 0); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ PUSH_DATAf(push, 0.0f); ++ BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); ++ PUSH_DATAh(push, screen->uniform_bo->offset + (5 << 16) + (6 << 9)); ++ PUSH_DATA (push, screen->uniform_bo->offset + (5 << 16) + (6 << 9)); ++ + /* max MPs * max warps per MP (TODO: ask kernel) */ + if (screen->eng3d->oclass >= NVE4_3D_CLASS) + screen->tls_size = 8 * 64; +@@ -734,10 +749,6 @@ nvc0_screen_create(struct nouveau_device *dev) + + IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1); + +- BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); +- PUSH_DATA (push, 0xab); +- PUSH_DATA (push, 0x00000000); +- + PUSH_KICK (push); + + screen->tic.entries = CALLOC(4096, sizeof(void *)); +diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c +index 940179c..3ccf396 100644 +--- a/src/gallium/drivers/r300/r300_state_derived.c ++++ b/src/gallium/drivers/r300/r300_state_derived.c +@@ -655,6 +655,12 @@ static uint32_t r300_get_border_color(enum pipe_format format, + case PIPE_FORMAT_LATC2_UNORM: + util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc); + return uc.ui; ++ case PIPE_FORMAT_DXT1_SRGB: ++ case PIPE_FORMAT_DXT1_SRGBA: ++ case PIPE_FORMAT_DXT3_SRGBA: ++ case PIPE_FORMAT_DXT5_SRGBA: ++ util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_SRGB, &uc); ++ return uc.ui; + default: + util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); + return uc.ui; +@@ -685,10 +691,18 @@ static uint32_t r300_get_border_color(enum pipe_format format, + + default: + case 8: +- if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) +- util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc); +- else +- util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc); ++ if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { ++ util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc); ++ } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { ++ if (desc->nr_channels == 2) { ++ border_swizzled[3] = border_swizzled[1]; ++ util_pack_color(border_swizzled, PIPE_FORMAT_L8A8_SRGB, &uc); ++ } else { ++ util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SRGB, &uc); ++ } ++ } else { ++ util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc); ++ } + break; + + case 10: +diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c +index 7b7b6b1..af27fd9 100644 +--- a/src/gallium/drivers/r600/r600_hw_context.c ++++ b/src/gallium/drivers/r600/r600_hw_context.c +@@ -1080,13 +1080,14 @@ void r600_context_streamout_begin(struct r600_context *ctx) + unsigned *stride_in_dw = ctx->vs_shader->so.stride; + unsigned buffer_en, i, update_flags = 0; + uint64_t va; ++ unsigned num_cs_dw_streamout_end; + + buffer_en = (ctx->num_so_targets >= 1 && t[0] ? 1 : 0) | + (ctx->num_so_targets >= 2 && t[1] ? 2 : 0) | + (ctx->num_so_targets >= 3 && t[2] ? 4 : 0) | + (ctx->num_so_targets >= 4 && t[3] ? 8 : 0); + +- ctx->num_cs_dw_streamout_end = ++ num_cs_dw_streamout_end = + 12 + /* flush_vgt_streamout */ + util_bitcount(buffer_en) * 8 + /* STRMOUT_BUFFER_UPDATE */ + 3 /* set_streamout_enable(0) */; +@@ -1095,11 +1096,15 @@ void r600_context_streamout_begin(struct r600_context *ctx) + 12 + /* flush_vgt_streamout */ + 6 + /* set_streamout_enable */ + util_bitcount(buffer_en) * 7 + /* SET_CONTEXT_REG */ +- (ctx->chip_class == R700 ? util_bitcount(buffer_en) * 5 : 0) + /* STRMOUT_BASE_UPDATE */ ++ (ctx->family >= CHIP_RS780 && ++ ctx->family <= CHIP_RV740 ? util_bitcount(buffer_en) * 5 : 0) + /* STRMOUT_BASE_UPDATE */ + util_bitcount(buffer_en & ctx->streamout_append_bitmask) * 8 + /* STRMOUT_BUFFER_UPDATE */ + util_bitcount(buffer_en & ~ctx->streamout_append_bitmask) * 6 + /* STRMOUT_BUFFER_UPDATE */ +- (ctx->family > CHIP_R600 && ctx->family < CHIP_RV770 ? 2 : 0) + /* SURFACE_BASE_UPDATE */ +- ctx->num_cs_dw_streamout_end, TRUE); ++ (ctx->family > CHIP_R600 && ctx->family < CHIP_RS780 ? 2 : 0) + /* SURFACE_BASE_UPDATE */ ++ num_cs_dw_streamout_end, TRUE); ++ ++ /* This must be set after r600_need_cs_space. */ ++ ctx->num_cs_dw_streamout_end = num_cs_dw_streamout_end; + + if (ctx->chip_class >= EVERGREEN) { + evergreen_flush_vgt_streamout(ctx); +@@ -1133,7 +1138,7 @@ void r600_context_streamout_begin(struct r600_context *ctx) + + /* R7xx requires this packet after updating BUFFER_BASE. + * Without this, R7xx locks up. */ +- if (ctx->chip_class == R700) { ++ if (ctx->family >= CHIP_RS780 && ctx->family <= CHIP_RV740) { + cs->buf[cs->cdw++] = PKT3(PKT3_STRMOUT_BASE_UPDATE, 1, 0); + cs->buf[cs->cdw++] = i; + cs->buf[cs->cdw++] = va >> 8; +@@ -1173,7 +1178,7 @@ void r600_context_streamout_begin(struct r600_context *ctx) + } + } + +- if (ctx->family > CHIP_R600 && ctx->family < CHIP_RV770) { ++ if (ctx->family > CHIP_R600 && ctx->family < CHIP_RS780) { + cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); + cs->buf[cs->cdw++] = update_flags; + } +diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c +index 286c676..be30c7e 100644 +--- a/src/gallium/drivers/r600/r600_pipe.c ++++ b/src/gallium/drivers/r600/r600_pipe.c +@@ -443,7 +443,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) + return rscreen->has_streamout ? 1 : 0; + case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: + case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: +- return 16*4; ++ return 32*4; + + /* Texturing. */ + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: +@@ -933,13 +933,19 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) + /* Figure out streamout kernel support. */ + switch (rscreen->chip_class) { + case R600: +- case EVERGREEN: +- case CAYMAN: +- rscreen->has_streamout = rscreen->info.drm_minor >= 14; ++ if (rscreen->family < CHIP_RS780) { ++ rscreen->has_streamout = rscreen->info.drm_minor >= 14; ++ } else { ++ rscreen->has_streamout = rscreen->info.drm_minor >= 23; ++ } + break; + case R700: + rscreen->has_streamout = rscreen->info.drm_minor >= 17; + break; ++ case EVERGREEN: ++ case CAYMAN: ++ rscreen->has_streamout = rscreen->info.drm_minor >= 14; ++ break; + } + + if (r600_init_tiling(rscreen)) { +diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c +index 21019b7..1f8ab2b 100644 +--- a/src/gallium/drivers/r600/r600_shader.c ++++ b/src/gallium/drivers/r600/r600_shader.c +@@ -4012,6 +4012,23 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) + if (r) + return r; + } ++ ++ /* for cube forms of lod and bias we need to route the lod ++ value into Z */ ++ if (inst->Instruction.Opcode == TGSI_OPCODE_TXB || ++ inst->Instruction.Opcode == TGSI_OPCODE_TXL) { ++ memset(&alu, 0, sizeof(struct r600_bytecode_alu)); ++ alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); ++ r600_bytecode_src(&alu.src[0], &ctx->src[0], 3); ++ alu.dst.sel = ctx->temp_reg; ++ alu.dst.chan = 2; ++ alu.last = 1; ++ alu.dst.write = 1; ++ r = r600_bytecode_add_alu(ctx->bc, &alu); ++ if (r) ++ return r; ++ } ++ + src_loaded = TRUE; + src_gpr = ctx->temp_reg; + } +@@ -4087,17 +4104,12 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) + tex.src_rel = ctx->src[0].rel; + } + +- if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) { +- tex.src_sel_x = 1; +- tex.src_sel_y = 0; +- tex.src_sel_z = 3; +- tex.src_sel_w = 1; +- } +- if (inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) { ++ if (inst->Texture.Texture == TGSI_TEXTURE_CUBE || ++ inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) { + tex.src_sel_x = 1; + tex.src_sel_y = 0; + tex.src_sel_z = 3; +- tex.src_sel_w = 2; /* route Z compare value into W */ ++ tex.src_sel_w = 2; /* route Z compare or Lod value into W */ + } + + if (inst->Texture.Texture != TGSI_TEXTURE_RECT && +diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h +index 9ea9c0e..a67c43e 100644 +--- a/src/gallium/include/pipe/p_state.h ++++ b/src/gallium/include/pipe/p_state.h +@@ -59,7 +59,7 @@ extern "C" { + #define PIPE_MAX_CONSTANT_BUFFERS 32 + #define PIPE_MAX_SAMPLERS 16 + #define PIPE_MAX_SHADER_INPUTS 32 +-#define PIPE_MAX_SHADER_OUTPUTS 32 ++#define PIPE_MAX_SHADER_OUTPUTS 48 /* 32 GENERICs + POS, PSIZE, FOG, etc. */ + #define PIPE_MAX_SHADER_SAMPLER_VIEWS 32 + #define PIPE_MAX_SHADER_RESOURCES 32 + #define PIPE_MAX_TEXTURE_LEVELS 16 +@@ -145,7 +145,7 @@ struct pipe_rasterizer_state + unsigned line_stipple_factor:8; /**< [1..256] actually */ + unsigned line_stipple_pattern:16; + +- unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS; ++ unsigned sprite_coord_enable; /* bitfield referring to 32 GENERIC inputs */ + + float line_width; + float point_size; /**< used when no per-vertex size */ +diff --git a/src/gallium/targets/dri-i915/Makefile b/src/gallium/targets/dri-i915/Makefile +index ddebff2..a835ee7 100644 +--- a/src/gallium/targets/dri-i915/Makefile ++++ b/src/gallium/targets/dri-i915/Makefile +@@ -28,6 +28,6 @@ endif + + include ../Makefile.dri + +-GALLIUM_DRI_LIB_DEPS += -ldrm_intel ++GALLIUM_DRI_LIB_DEPS += $(INTEL_LIBS) + + symlinks: +diff --git a/src/gallium/targets/dri-r300/Makefile b/src/gallium/targets/dri-r300/Makefile +index 256aa23..63a2956 100644 +--- a/src/gallium/targets/dri-r300/Makefile ++++ b/src/gallium/targets/dri-r300/Makefile +@@ -21,6 +21,6 @@ DRIVER_DEFINES = \ + + include ../Makefile.dri + +-GALLIUM_DRI_LIB_DEPS += -ldrm_radeon ++GALLIUM_DRI_LIB_DEPS += $(RADEON_LIBS) + + symlinks: +diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile +index 7402750..2499ede 100644 +--- a/src/gallium/targets/dri-r600/Makefile ++++ b/src/gallium/targets/dri-r600/Makefile +@@ -21,6 +21,6 @@ DRIVER_DEFINES = \ + + include ../Makefile.dri + +-GALLIUM_DRI_LIB_DEPS += -ldrm_radeon ++GALLIUM_DRI_LIB_DEPS += $(RADEON_LIBS) + + symlinks: +diff --git a/src/gallium/targets/dri-radeonsi/Makefile b/src/gallium/targets/dri-radeonsi/Makefile +index b45f243..588946e 100644 +--- a/src/gallium/targets/dri-radeonsi/Makefile ++++ b/src/gallium/targets/dri-radeonsi/Makefile +@@ -21,6 +21,6 @@ DRIVER_DEFINES = \ + + include ../Makefile.dri + +-GALLIUM_DRI_LIB_DEPS += -ldrm_radeon ++GALLIUM_DRI_LIB_DEPS += $(RADEON_LIBS) + + symlinks: +diff --git a/src/gallium/targets/egl-static/Makefile b/src/gallium/targets/egl-static/Makefile +index f05c81d..08626a9 100644 +--- a/src/gallium/targets/egl-static/Makefile ++++ b/src/gallium/targets/egl-static/Makefile +@@ -48,17 +48,17 @@ egl_SYS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) -lEGL -lm -lpthread + ifneq ($(findstring x11, $(EGL_PLATFORMS)),) + egl_CPPFLAGS += $(LIBDRM_CFLAGS) + egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a +-egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIB) ++egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIBS) + endif + ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) + egl_CPPFLAGS += $(LIBDRM_CFLAGS) + egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a + egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/.libs/libwayland-drm.a +-egl_SYS += $(LIBDRM_LIB) $(WAYLAND_LIBS) ++egl_SYS += $(LIBDRM_LIBS) $(WAYLAND_LIBS) + endif + ifneq ($(findstring drm, $(EGL_PLATFORMS)),) + egl_CPPFLAGS += $(LIBDRM_CFLAGS) +-egl_SYS += $(LIBDRM_LIB) -lgbm ++egl_SYS += $(LIBDRM_LIBS) -lgbm + endif + ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) + egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a +@@ -93,7 +93,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_I915=1 + egl_LIBS += \ + $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a +-egl_SYS += -ldrm_intel ++egl_SYS += $(INTEL_LIBS) + endif + + # nouveau +@@ -105,7 +105,7 @@ egl_LIBS += \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a +-egl_SYS += -ldrm_nouveau ++egl_SYS += $(NOUVEAU_LIBS) + endif + + # r300 +@@ -115,7 +115,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_R300=1 + egl_LIBS += \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a +-egl_SYS += -ldrm_radeon ++egl_SYS += $(RADEON_LIBS) + endif + endif + +@@ -126,7 +126,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_R600=1 + egl_LIBS += \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r600/libr600.a +-egl_SYS += -ldrm_radeon ++egl_SYS += $(RADEON_LIBS) + endif + endif + +@@ -137,7 +137,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_RADEONSI=1 + egl_LIBS += \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/radeonsi/libradeonsi.a +-egl_SYS += -ldrm_radeon ++egl_SYS += $(RADEON_LIBS) + endif + endif + +diff --git a/src/gallium/targets/gbm/Makefile b/src/gallium/targets/gbm/Makefile +index 423debf..17d5648 100644 +--- a/src/gallium/targets/gbm/Makefile ++++ b/src/gallium/targets/gbm/Makefile +@@ -14,7 +14,7 @@ GBM_INCLUDES = \ + -I$(TOP)/src/gallium/winsys \ + -I$(TOP)/src/gallium/include + +-GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) -lm \ ++GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIBS) -lm \ + $(TOP)/src/gallium/state_trackers/gbm/libgbm.a \ + $(GALLIUM_PIPE_LOADER_LIBS) $(GALLIUM_AUXILIARIES) + +diff --git a/src/gallium/targets/pipe-loader/Makefile b/src/gallium/targets/pipe-loader/Makefile +index 596539c..f15cd25 100644 +--- a/src/gallium/targets/pipe-loader/Makefile ++++ b/src/gallium/targets/pipe-loader/Makefile +@@ -24,7 +24,7 @@ PIPE_LIBS = \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(GALLIUM_AUXILIARIES) + +-PIPE_SYS = $(LIBDRM_LIB) -lm -lpthread $(DLOPEN_LIBS) ++PIPE_SYS = $(LIBDRM_LIBS) -lm -lpthread $(DLOPEN_LIBS) + + PIPE_CFLAGS = $(LIBDRM_CFLAGS) + +@@ -34,7 +34,7 @@ PIPE_LDFLAGS = -Wl,--no-undefined + i915_LIBS = \ + $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a +-i915_SYS = -ldrm_intel ++i915_SYS = $(INTEL_LIBS) + + # nouveau pipe driver + nouveau_LIBS = \ +@@ -43,25 +43,25 @@ nouveau_LIBS = \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a +-nouveau_SYS = -ldrm_nouveau ++nouveau_SYS = $(NOUVEAU_LIBS) + + # r300 pipe driver + r300_LIBS = \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a +-r300_SYS += -ldrm_radeon ++r300_SYS += $(RADEON_LIBS) + + # r600 pipe driver + r600_LIBS = \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r600/libr600.a +-r600_SYS += -ldrm_radeon ++r600_SYS += $(RADEON_LIBS) + + # radeonsi pipe driver + radeonsi_LIBS = \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/radeonsi/libradeonsi.a +-radeonsi_SYS += -ldrm_radeon ++radeonsi_SYS += $(RADEON_LIBS) + + # vmwgfx pipe driver + vmwgfx_LIBS = \ +diff --git a/src/gallium/targets/vdpau-r300/Makefile b/src/gallium/targets/vdpau-r300/Makefile +index 1ada550..e79c920 100644 +--- a/src/gallium/targets/vdpau-r300/Makefile ++++ b/src/gallium/targets/vdpau-r300/Makefile +@@ -21,7 +21,7 @@ C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon ++DRIVER_LIBS = $(LIBDRM_LIBS) $(RADEON_LIBS) -lXfixes + + include ../Makefile.vdpau + +diff --git a/src/gallium/targets/vdpau-r600/Makefile b/src/gallium/targets/vdpau-r600/Makefile +index 05e0b4f..6ef7f90 100644 +--- a/src/gallium/targets/vdpau-r600/Makefile ++++ b/src/gallium/targets/vdpau-r600/Makefile +@@ -17,7 +17,7 @@ C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon ++DRIVER_LIBS = $(LIBDRM_LIBS) $(RADEON_LIBS) -lXfixes + + include ../Makefile.vdpau + +diff --git a/src/gallium/targets/vdpau-radeonsi/Makefile b/src/gallium/targets/vdpau-radeonsi/Makefile +index 6dd2be9..4ff6743 100644 +--- a/src/gallium/targets/vdpau-radeonsi/Makefile ++++ b/src/gallium/targets/vdpau-radeonsi/Makefile +@@ -23,7 +23,7 @@ C_SOURCES = \ + DRIVER_DEFINES = \ + -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_NOOP + +-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon ++DRIVER_LIBS = $(LIBDRM_LIBS) $(RADEON_LIBS) -lXfixes + + include ../Makefile.vdpau + +diff --git a/src/gallium/targets/xvmc-r300/Makefile b/src/gallium/targets/xvmc-r300/Makefile +index 800f8d5..d2ab488 100644 +--- a/src/gallium/targets/xvmc-r300/Makefile ++++ b/src/gallium/targets/xvmc-r300/Makefile +@@ -17,7 +17,7 @@ C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon ++DRIVER_LIBS = $(LIBDRM_LIBS) $(RADEON_LIBS) -lXfixes + + include ../Makefile.xvmc + +diff --git a/src/gallium/targets/xvmc-r600/Makefile b/src/gallium/targets/xvmc-r600/Makefile +index d9ce72f..3ef5b1a 100644 +--- a/src/gallium/targets/xvmc-r600/Makefile ++++ b/src/gallium/targets/xvmc-r600/Makefile +@@ -17,7 +17,7 @@ C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon ++DRIVER_LIBS = $(LIBDRM_LIBS) $(RADEON_LIBS) -lXfixes + + include ../Makefile.xvmc + +diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c +index 37f7577..288b510 100644 +--- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c ++++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c +@@ -369,7 +369,7 @@ get_last_level(struct gl_texture_object *t) + t->Sampler.MinFilter == GL_LINEAR || !base) + return t->BaseLevel; + else +- return MIN2(t->BaseLevel + base->MaxLog2, t->MaxLevel); ++ return MIN2(t->BaseLevel + base->MaxNumLevels - 1, t->MaxLevel); + } + + static void +diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +index 8901090..f4fb3a5 100644 +--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c ++++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +@@ -270,7 +270,7 @@ static void calculate_min_max_lod(struct gl_sampler_object *samp, struct gl_text + minLod = MIN2(minLod, tObj->MaxLevel); + maxLod = tObj->BaseLevel + (GLint)(samp->MaxLod + 0.5); + maxLod = MIN2(maxLod, tObj->MaxLevel); +- maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxLog2 + minLod); ++ maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxNumLevels - 1 + minLod); + maxLod = MAX2(maxLod, minLod); /* need at least one level */ + } + break; +@@ -329,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g + + mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; + firstImage = texObj->Image[0][texObj->BaseLevel]; +- numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); ++ numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxNumLevels); + + if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { + fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); +@@ -378,7 +378,7 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) + } + + +- numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1); ++ numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxNumLevels); + + t->mt = radeon_miptree_create(rmesa, t->base.Target, + texImg->TexFormat, texObj->BaseLevel, +diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h +index ead1d32..3572ae8 100644 +--- a/src/mesa/main/config.h ++++ b/src/mesa/main/config.h +@@ -187,7 +187,7 @@ + #define MAX_PROGRAM_CALL_DEPTH 8 + #define MAX_PROGRAM_TEMPS 256 + #define MAX_PROGRAM_ADDRESS_REGS 2 +-#define MAX_VARYING 16 /**< number of float[4] vectors */ ++#define MAX_VARYING 32 /**< number of float[4] vectors */ + #define MAX_SAMPLERS MAX_TEXTURE_IMAGE_UNITS + #define MAX_PROGRAM_INPUTS 32 + #define MAX_PROGRAM_OUTPUTS 64 +diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c +index a21ae10..de385cd 100644 +--- a/src/mesa/main/context.c ++++ b/src/mesa/main/context.c +@@ -624,7 +624,7 @@ _mesa_init_constants(struct gl_context *ctx) + #if FEATURE_ARB_vertex_shader + ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; +- ctx->Const.MaxVarying = MAX_VARYING; ++ ctx->Const.MaxVarying = 16; /* old limit not to break tnl and swrast */ + #endif + #if FEATURE_ARB_geometry_shader4 + ctx->Const.MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS; +diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h +index 551aea7..4b74f70 100644 +--- a/src/mesa/main/imports.h ++++ b/src/mesa/main/imports.h +@@ -81,7 +81,7 @@ extern "C" { + * these casts generate warnings. + * The following union typedef is used to solve that. + */ +-typedef union { GLfloat f; GLint i; } fi_type; ++typedef union { GLfloat f; GLint i; GLuint u; } fi_type; + + + +diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h +index 5af9487..e7ef877 100644 +--- a/src/mesa/main/macros.h ++++ b/src/mesa/main/macros.h +@@ -171,6 +171,20 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; + ub = ((GLubyte) F_TO_I((f) * 255.0F)) + #endif + ++static inline GLfloat INT_AS_FLT(GLint i) ++{ ++ fi_type tmp; ++ tmp.i = i; ++ return tmp.f; ++} ++ ++static inline GLfloat UINT_AS_FLT(GLuint u) ++{ ++ fi_type tmp; ++ tmp.u = u; ++ return tmp.f; ++} ++ + /*@}*/ + + +@@ -573,6 +587,31 @@ do { \ + + /*@}*/ + ++/** Copy \p sz elements into a homegeneous (4-element) vector, giving ++ * default values to the remaining components. ++ * The default values are chosen based on \p type. ++ */ ++static inline void ++COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat src[4], ++ GLenum type) ++{ ++ switch (type) { ++ case GL_FLOAT: ++ ASSIGN_4V(dst, 0, 0, 0, 1); ++ break; ++ case GL_INT: ++ ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0), ++ INT_AS_FLT(0), INT_AS_FLT(1)); ++ break; ++ case GL_UNSIGNED_INT: ++ ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0), ++ UINT_AS_FLT(0), UINT_AS_FLT(1)); ++ break; ++ default: ++ ASSERT(0); ++ } ++ COPY_SZ_4V(dst, sz, src); ++} + + /** \name Linear interpolation functions */ + /*@{*/ +diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h +index f185ffd..6fce70f 100644 +--- a/src/mesa/main/mtypes.h ++++ b/src/mesa/main/mtypes.h +@@ -1205,7 +1205,8 @@ struct gl_texture_image + GLuint WidthLog2; /**< = log2(Width2) */ + GLuint HeightLog2; /**< = log2(Height2) */ + GLuint DepthLog2; /**< = log2(Depth2) */ +- GLuint MaxLog2; /**< = MAX(WidthLog2, HeightLog2) */ ++ GLuint MaxNumLevels; /**< = maximum possible number of mipmap ++ levels, computed from the dimensions */ + + struct gl_texture_object *TexObject; /**< Pointer back to parent object */ + GLuint Level; /**< Which mipmap level am I? */ +diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c +index 38fa9fa..9edd4d8 100644 +--- a/src/mesa/main/teximage.c ++++ b/src/mesa/main/teximage.c +@@ -1002,6 +1002,43 @@ _mesa_get_texture_dimensions(GLenum target) + } + + ++/** ++ * Return the maximum number of mipmap levels for the given target ++ * and the dimensions. ++ * The dimensions are expected not to include the border. ++ */ ++GLsizei ++_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, ++ GLsizei depth) ++{ ++ GLsizei size; ++ ++ switch (target) { ++ case GL_TEXTURE_1D: ++ case GL_TEXTURE_1D_ARRAY: ++ size = width; ++ break; ++ case GL_TEXTURE_CUBE_MAP: ++ case GL_TEXTURE_CUBE_MAP_ARRAY: ++ ASSERT(width == height); ++ size = width; ++ break; ++ case GL_TEXTURE_2D: ++ case GL_TEXTURE_2D_ARRAY: ++ size = MAX2(width, height); ++ break; ++ case GL_TEXTURE_3D: ++ size = MAX3(width, height, depth); ++ break; ++ case GL_TEXTURE_RECTANGLE: ++ return 1; ++ default: ++ assert(0); ++ return 1; ++ } ++ ++ return _mesa_logbase2(size) + 1; ++} + + + #if 000 /* not used anymore */ +@@ -1187,7 +1224,9 @@ _mesa_init_teximage_fields(struct gl_context *ctx, + target); + } + +- img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); ++ img->MaxNumLevels = ++ _mesa_get_tex_max_num_levels(target, ++ img->Width2, img->Height2, img->Depth2); + img->TexFormat = format; + } + +diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h +index 36fd1c2..a2565ec 100644 +--- a/src/mesa/main/teximage.h ++++ b/src/mesa/main/teximage.h +@@ -138,6 +138,10 @@ _mesa_tex_target_to_face(GLenum target); + extern GLint + _mesa_get_texture_dimensions(GLenum target); + ++extern GLsizei ++_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, ++ GLsizei depth); ++ + extern GLenum + _mesa_es_error_check_format_and_type(GLenum format, GLenum type, + unsigned dimensions); +diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c +index f8a9397..b4dd13e 100644 +--- a/src/mesa/main/texstorage.c ++++ b/src/mesa/main/texstorage.c +@@ -244,7 +244,6 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, + GLsizei width, GLsizei height, GLsizei depth) + { + struct gl_texture_object *texObj; +- GLuint maxDim; + GLboolean legalFormat; + + /* check internal format - note that only sized formats are allowed */ +@@ -324,8 +323,7 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, + } + + /* check levels against width/height/depth */ +- maxDim = MAX3(width, height, depth); +- if (levels > _mesa_logbase2(maxDim) + 1) { ++ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexStorage%uD(too many levels for max texture dimension)", + dims); +diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c +index bc5dc58..887f020 100644 +--- a/src/mesa/program/prog_print.c ++++ b/src/mesa/program/prog_print.c +@@ -164,7 +164,23 @@ arb_input_attrib_string(GLint index, GLenum progType) + "fragment.varying[12]", + "fragment.varying[13]", + "fragment.varying[14]", +- "fragment.varying[15]" /* MAX_VARYING = 16 */ ++ "fragment.varying[15]", ++ "fragment.varying[16]", ++ "fragment.varying[17]", ++ "fragment.varying[18]", ++ "fragment.varying[19]", ++ "fragment.varying[20]", ++ "fragment.varying[21]", ++ "fragment.varying[22]", ++ "fragment.varying[23]", ++ "fragment.varying[24]", ++ "fragment.varying[25]", ++ "fragment.varying[26]", ++ "fragment.varying[27]", ++ "fragment.varying[28]", ++ "fragment.varying[29]", ++ "fragment.varying[30]", ++ "fragment.varying[31]", /* MAX_VARYING = 32 */ + }; + + /* sanity checks */ +@@ -268,7 +284,23 @@ arb_output_attrib_string(GLint index, GLenum progType) + "result.varying[12]", + "result.varying[13]", + "result.varying[14]", +- "result.varying[15]" /* MAX_VARYING = 16 */ ++ "result.varying[15]", ++ "result.varying[16]", ++ "result.varying[17]", ++ "result.varying[18]", ++ "result.varying[19]", ++ "result.varying[20]", ++ "result.varying[21]", ++ "result.varying[22]", ++ "result.varying[23]", ++ "result.varying[24]", ++ "result.varying[25]", ++ "result.varying[26]", ++ "result.varying[27]", ++ "result.varying[28]", ++ "result.varying[29]", ++ "result.varying[30]", ++ "result.varying[31]", /* MAX_VARYING = 32 */ + }; + static const char *const fragResults[] = { + "result.depth", /* FRAG_RESULT_DEPTH */ +diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c +index adcc7b5..3eba5b1 100644 +--- a/src/mesa/state_tracker/st_atom_sampler.c ++++ b/src/mesa/state_tracker/st_atom_sampler.c +@@ -34,6 +34,7 @@ + + #include "main/macros.h" + #include "main/mtypes.h" ++#include "main/glformats.h" + #include "main/samplerobj.h" + #include "main/texobj.h" + +@@ -172,12 +173,17 @@ convert_sampler(struct st_context *st, + msamp->BorderColor.ui[2] || + msamp->BorderColor.ui[3]) { + struct gl_texture_image *teximg; ++ GLboolean is_integer = GL_FALSE; + + teximg = texobj->Image[0][texobj->BaseLevel]; + +- st_translate_color(msamp->BorderColor.f, +- teximg ? teximg->_BaseFormat : GL_RGBA, +- sampler->border_color.f); ++ if (teximg) { ++ is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat); ++ } ++ ++ st_translate_color(&msamp->BorderColor, ++ &sampler->border_color, ++ teximg ? teximg->_BaseFormat : GL_RGBA, is_integer); + } + + sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? +diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c +index e731b6b..90eb0af 100644 +--- a/src/mesa/state_tracker/st_cb_clear.c ++++ b/src/mesa/state_tracker/st_cb_clear.c +@@ -37,6 +37,7 @@ + #include "main/accum.h" + #include "main/formats.h" + #include "main/macros.h" ++#include "main/glformats.h" + #include "program/prog_instruction.h" + #include "st_context.h" + #include "st_atom.h" +@@ -301,9 +302,13 @@ clear_with_quad(struct gl_context *ctx, + cso_set_geometry_shader_handle(st->cso_context, NULL); + + if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { +- st_translate_color(ctx->Color.ClearColor.f, +- ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, +- clearColor.f); ++ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; ++ GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); ++ ++ st_translate_color(&ctx->Color.ClearColor, ++ &clearColor, ++ ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, ++ is_integer); + } + + /* draw quad matching scissor rect */ +@@ -540,9 +545,13 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) + clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + + if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { +- st_translate_color(ctx->Color.ClearColor.f, ++ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; ++ GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); ++ ++ st_translate_color(&ctx->Color.ClearColor, ++ &clearColor, + ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, +- clearColor.f); ++ is_integer); + } + + st->pipe->clear(st->pipe, clear_buffers, &clearColor, +diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c +index b8e2538..923a8c9 100644 +--- a/src/mesa/state_tracker/st_cb_texture.c ++++ b/src/mesa/state_tracker/st_cb_texture.c +@@ -237,36 +237,6 @@ default_bindings(struct st_context *st, enum pipe_format format) + } + + +-/** Return number of image dimensions (1, 2 or 3) for a texture target. */ +-static GLuint +-get_texture_dims(GLenum target) +-{ +- switch (target) { +- case GL_TEXTURE_1D: +- case GL_TEXTURE_1D_ARRAY_EXT: +- case GL_TEXTURE_BUFFER: +- return 1; +- case GL_TEXTURE_2D: +- case GL_TEXTURE_CUBE_MAP_ARB: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: +- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: +- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: +- case GL_TEXTURE_RECTANGLE_NV: +- case GL_TEXTURE_2D_ARRAY_EXT: +- case GL_TEXTURE_EXTERNAL_OES: +- return 2; +- case GL_TEXTURE_3D: +- return 3; +- default: +- assert(0 && "invalid texture target in get_texture_dims()"); +- return 1; +- } +-} +- +- + /** + * Given the size of a mipmap image, try to compute the size of the level=0 + * mipmap image. +@@ -281,32 +251,57 @@ guess_base_level_size(GLenum target, + GLuint width, GLuint height, GLuint depth, GLuint level, + GLuint *width0, GLuint *height0, GLuint *depth0) + { +- const GLuint dims = get_texture_dims(target); +- + assert(width >= 1); + assert(height >= 1); + assert(depth >= 1); + + if (level > 0) { +- /* Depending on the image's size, we can't always make a guess here */ +- if ((dims >= 1 && width == 1) || +- (dims >= 2 && height == 1) || +- (dims >= 3 && depth == 1)) { +- /* we can't determine the image size at level=0 */ +- return GL_FALSE; +- } ++ /* Guess the size of the base level. ++ * Depending on the image's size, we can't always make a guess here. ++ */ ++ switch (target) { ++ case GL_TEXTURE_1D: ++ case GL_TEXTURE_1D_ARRAY: ++ width <<= level; ++ break; ++ ++ case GL_TEXTURE_2D: ++ case GL_TEXTURE_2D_ARRAY: ++ /* We can't make a good guess here, because the base level dimensions ++ * can be non-square. ++ */ ++ if (width == 1 || height == 1) { ++ return GL_FALSE; ++ } ++ width <<= level; ++ height <<= level; ++ break; ++ ++ case GL_TEXTURE_CUBE_MAP: ++ case GL_TEXTURE_CUBE_MAP_ARRAY: ++ width <<= level; ++ height <<= level; ++ break; ++ ++ case GL_TEXTURE_3D: ++ /* We can't make a good guess here, because the base level dimensions ++ * can be non-cube. ++ */ ++ if (width == 1 || height == 1 || depth == 1) { ++ return GL_FALSE; ++ } ++ width <<= level; ++ height <<= level; ++ depth <<= level; ++ break; ++ ++ case GL_TEXTURE_RECTANGLE: ++ break; + +- /* grow the image size until we hit level = 0 */ +- while (level > 0) { +- if (width > 1) +- width <<= 1; +- if (height > 1) +- height <<= 1; +- if (depth > 1) +- depth <<= 1; +- level--; ++ default: ++ assert(0); + } +- } ++ } + + *width0 = width; + *height0 = height; +@@ -371,10 +366,8 @@ guess_and_alloc_texture(struct st_context *st, + } + else { + /* alloc space for a full mipmap */ +- GLuint l2width = util_logbase2(width); +- GLuint l2height = util_logbase2(height); +- GLuint l2depth = util_logbase2(depth); +- lastLevel = MAX2(MAX2(l2width, l2height), l2depth); ++ lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target, ++ width, height, depth) - 1; + } + + /* Save the level=0 dimensions */ +diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c +index 302b58c..75602e5 100644 +--- a/src/mesa/state_tracker/st_format.c ++++ b/src/mesa/state_tracker/st_format.c +@@ -1699,44 +1699,92 @@ st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2) + * Similarly for texture border colors. + */ + void +-st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, +- GLfloat colorOut[4]) ++st_translate_color(union gl_color_union *colorIn, ++ union pipe_color_union *colorOut, ++ GLenum baseFormat, GLboolean is_integer) + { +- switch (baseFormat) { +- case GL_RED: +- colorOut[0] = colorIn[0]; +- colorOut[1] = 0.0F; +- colorOut[2] = 0.0F; +- colorOut[3] = 1.0F; +- break; +- case GL_RG: +- colorOut[0] = colorIn[0]; +- colorOut[1] = colorIn[1]; +- colorOut[2] = 0.0F; +- colorOut[3] = 1.0F; +- break; +- case GL_RGB: +- colorOut[0] = colorIn[0]; +- colorOut[1] = colorIn[1]; +- colorOut[2] = colorIn[2]; +- colorOut[3] = 1.0F; +- break; +- case GL_ALPHA: +- colorOut[0] = colorOut[1] = colorOut[2] = 0.0; +- colorOut[3] = colorIn[3]; +- break; +- case GL_LUMINANCE: +- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0]; +- colorOut[3] = 1.0; +- break; +- case GL_LUMINANCE_ALPHA: +- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0]; +- colorOut[3] = colorIn[3]; +- break; +- case GL_INTENSITY: +- colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0]; +- break; +- default: +- COPY_4V(colorOut, colorIn); ++ if (is_integer) { ++ int *in = colorIn->i; ++ int *out = colorOut->i; ++ ++ switch (baseFormat) { ++ case GL_RED: ++ out[0] = in[0]; ++ out[1] = 0; ++ out[2] = 0; ++ out[3] = 1; ++ break; ++ case GL_RG: ++ out[0] = in[0]; ++ out[1] = in[1]; ++ out[2] = 0; ++ out[3] = 1; ++ break; ++ case GL_RGB: ++ out[0] = in[0]; ++ out[1] = in[1]; ++ out[2] = in[2]; ++ out[3] = 1; ++ break; ++ case GL_ALPHA: ++ out[0] = out[1] = out[2] = 0; ++ out[3] = in[3]; ++ break; ++ case GL_LUMINANCE: ++ out[0] = out[1] = out[2] = in[0]; ++ out[3] = 1; ++ break; ++ case GL_LUMINANCE_ALPHA: ++ out[0] = out[1] = out[2] = in[0]; ++ out[3] = in[3]; ++ break; ++ case GL_INTENSITY: ++ out[0] = out[1] = out[2] = out[3] = in[0]; ++ break; ++ default: ++ COPY_4V(out, in); ++ } ++ } ++ else { ++ float *in = colorIn->f; ++ float *out = colorOut->f; ++ ++ switch (baseFormat) { ++ case GL_RED: ++ out[0] = in[0]; ++ out[1] = 0.0F; ++ out[2] = 0.0F; ++ out[3] = 1.0F; ++ break; ++ case GL_RG: ++ out[0] = in[0]; ++ out[1] = in[1]; ++ out[2] = 0.0F; ++ out[3] = 1.0F; ++ break; ++ case GL_RGB: ++ out[0] = in[0]; ++ out[1] = in[1]; ++ out[2] = in[2]; ++ out[3] = 1.0F; ++ break; ++ case GL_ALPHA: ++ out[0] = out[1] = out[2] = 0.0F; ++ out[3] = in[3]; ++ break; ++ case GL_LUMINANCE: ++ out[0] = out[1] = out[2] = in[0]; ++ out[3] = 1.0F; ++ break; ++ case GL_LUMINANCE_ALPHA: ++ out[0] = out[1] = out[2] = in[0]; ++ out[3] = in[3]; ++ break; ++ case GL_INTENSITY: ++ out[0] = out[1] = out[2] = out[3] = in[0]; ++ break; ++ default: ++ COPY_4V(out, in); ++ } + } + } +diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h +index 2eef2c0..39397b1 100644 +--- a/src/mesa/state_tracker/st_format.h ++++ b/src/mesa/state_tracker/st_format.h +@@ -75,7 +75,8 @@ st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2); + + + extern void +-st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, +- GLfloat colorOut[4]); ++st_translate_color(union gl_color_union *colorIn, ++ union pipe_color_union *colorOut, ++ GLenum baseFormat, GLboolean is_integer); + + #endif /* ST_FORMAT_H */ +diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c +index 8892006..c092613 100644 +--- a/src/mesa/state_tracker/st_gen_mipmap.c ++++ b/src/mesa/state_tracker/st_gen_mipmap.c +@@ -121,30 +121,16 @@ compute_num_levels(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target) + { +- if (target == GL_TEXTURE_RECTANGLE_ARB) { +- return 1; +- } +- else { +- const struct gl_texture_image *baseImage = +- _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel); +- GLuint size, numLevels; ++ const struct gl_texture_image *baseImage; ++ GLuint numLevels; + +- size = MAX2(baseImage->Width2, baseImage->Height2); +- size = MAX2(size, baseImage->Depth2); ++ baseImage = _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel); + +- numLevels = texObj->BaseLevel; +- +- while (size > 0) { +- numLevels++; +- size >>= 1; +- } ++ numLevels = texObj->BaseLevel + baseImage->MaxNumLevels; ++ numLevels = MIN2(numLevels, texObj->MaxLevel + 1); ++ assert(numLevels >= 1); + +- numLevels = MIN2(numLevels, texObj->MaxLevel + 1); +- +- assert(numLevels >= 1); +- +- return numLevels; +- } ++ return numLevels; + } + + +diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h +index d3fc77e..b4a6d73 100644 +--- a/src/mesa/vbo/vbo_attrib_tmp.h ++++ b/src/mesa/vbo/vbo_attrib_tmp.h +@@ -26,38 +26,46 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. + **************************************************************************/ + + /* float */ +-#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 ) +-#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) +-#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) +-#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) ++#define ATTR1FV( A, V ) ATTR( A, 1, GL_FLOAT, (V)[0], 0, 0, 1 ) ++#define ATTR2FV( A, V ) ATTR( A, 2, GL_FLOAT, (V)[0], (V)[1], 0, 1 ) ++#define ATTR3FV( A, V ) ATTR( A, 3, GL_FLOAT, (V)[0], (V)[1], (V)[2], 1 ) ++#define ATTR4FV( A, V ) ATTR( A, 4, GL_FLOAT, (V)[0], (V)[1], (V)[2], (V)[3] ) + +-#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 ) +-#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) +-#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) +-#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) ++#define ATTR1F( A, X ) ATTR( A, 1, GL_FLOAT, X, 0, 0, 1 ) ++#define ATTR2F( A, X, Y ) ATTR( A, 2, GL_FLOAT, X, Y, 0, 1 ) ++#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, GL_FLOAT, X, Y, Z, 1 ) ++#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, GL_FLOAT, X, Y, Z, W ) + + /* int */ +-#define ATTR2IV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) +-#define ATTR3IV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) +-#define ATTR4IV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) ++#define ATTRI( A, N, X, Y, Z, W) ATTR( A, N, GL_INT, \ ++ INT_AS_FLT(X), INT_AS_FLT(Y), \ ++ INT_AS_FLT(Z), INT_AS_FLT(W) ) + +-#define ATTR1I( A, X ) ATTR( A, 1, X, 0, 0, 1 ) +-#define ATTR2I( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) +-#define ATTR3I( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) +-#define ATTR4I( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) ++#define ATTR2IV( A, V ) ATTRI( A, 2, (V)[0], (V)[1], 0, 1 ) ++#define ATTR3IV( A, V ) ATTRI( A, 3, (V)[0], (V)[1], (V)[2], 1 ) ++#define ATTR4IV( A, V ) ATTRI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) ++ ++#define ATTR1I( A, X ) ATTRI( A, 1, X, 0, 0, 1 ) ++#define ATTR2I( A, X, Y ) ATTRI( A, 2, X, Y, 0, 1 ) ++#define ATTR3I( A, X, Y, Z ) ATTRI( A, 3, X, Y, Z, 1 ) ++#define ATTR4I( A, X, Y, Z, W ) ATTRI( A, 4, X, Y, Z, W ) + + + /* uint */ +-#define ATTR2UIV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) +-#define ATTR3UIV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) +-#define ATTR4UIV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) ++#define ATTRUI( A, N, X, Y, Z, W) ATTR( A, N, GL_UNSIGNED_INT, \ ++ UINT_AS_FLT(X), UINT_AS_FLT(Y), \ ++ UINT_AS_FLT(Z), UINT_AS_FLT(W) ) ++ ++#define ATTR2UIV( A, V ) ATTRUI( A, 2, (V)[0], (V)[1], 0, 1 ) ++#define ATTR3UIV( A, V ) ATTRUI( A, 3, (V)[0], (V)[1], (V)[2], 1 ) ++#define ATTR4UIV( A, V ) ATTRUI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) + +-#define ATTR1UI( A, X ) ATTR( A, 1, X, 0, 0, 1 ) +-#define ATTR2UI( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) +-#define ATTR3UI( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) +-#define ATTR4UI( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) ++#define ATTR1UI( A, X ) ATTRUI( A, 1, X, 0, 0, 1 ) ++#define ATTR2UI( A, X, Y ) ATTRUI( A, 2, X, Y, 0, 1 ) ++#define ATTR3UI( A, X, Y, Z ) ATTRUI( A, 3, X, Y, Z, 1 ) ++#define ATTR4UI( A, X, Y, Z, W ) ATTRUI( A, 4, X, Y, Z, W ) + +-#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] ) ++#define MAT_ATTR( A, N, V ) ATTR( A, N, GL_FLOAT, (V)[0], (V)[1], (V)[2], (V)[3] ) + + static inline float conv_ui10_to_norm_float(unsigned ui10) + { +@@ -69,20 +77,20 @@ static inline float conv_ui2_to_norm_float(unsigned ui2) + return (float)(ui2) / 3.0; + } + +-#define ATTRUI10_1( A, UI ) ATTR( A, 1, (UI) & 0x3ff, 0, 0, 1 ) +-#define ATTRUI10_2( A, UI ) ATTR( A, 2, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, 0, 1 ) +-#define ATTRUI10_3( A, UI ) ATTR( A, 3, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, 1 ) +-#define ATTRUI10_4( A, UI ) ATTR( A, 4, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, ((UI) >> 30) & 0x3 ) ++#define ATTRUI10_1( A, UI ) ATTR( A, 1, GL_FLOAT, (UI) & 0x3ff, 0, 0, 1 ) ++#define ATTRUI10_2( A, UI ) ATTR( A, 2, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, 0, 1 ) ++#define ATTRUI10_3( A, UI ) ATTR( A, 3, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, 1 ) ++#define ATTRUI10_4( A, UI ) ATTR( A, 4, GL_FLOAT, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, ((UI) >> 30) & 0x3 ) + +-#define ATTRUI10N_1( A, UI ) ATTR( A, 1, conv_ui10_to_norm_float((UI) & 0x3ff), 0, 0, 1 ) +-#define ATTRUI10N_2( A, UI ) ATTR( A, 2, \ ++#define ATTRUI10N_1( A, UI ) ATTR( A, 1, GL_FLOAT, conv_ui10_to_norm_float((UI) & 0x3ff), 0, 0, 1 ) ++#define ATTRUI10N_2( A, UI ) ATTR( A, 2, GL_FLOAT, \ + conv_ui10_to_norm_float((UI) & 0x3ff), \ + conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), 0, 1 ) +-#define ATTRUI10N_3( A, UI ) ATTR( A, 3, \ ++#define ATTRUI10N_3( A, UI ) ATTR( A, 3, GL_FLOAT, \ + conv_ui10_to_norm_float((UI) & 0x3ff), \ + conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \ + conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), 1 ) +-#define ATTRUI10N_4( A, UI ) ATTR( A, 4, \ ++#define ATTRUI10N_4( A, UI ) ATTR( A, 4, GL_FLOAT, \ + conv_ui10_to_norm_float((UI) & 0x3ff), \ + conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \ + conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), \ +@@ -119,30 +127,30 @@ static inline float conv_i2_to_norm_float(int i2) + return (float)val.x; + } + +-#define ATTRI10_1( A, I10 ) ATTR( A, 1, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 ) +-#define ATTRI10_2( A, I10 ) ATTR( A, 2, \ ++#define ATTRI10_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 ) ++#define ATTRI10_2( A, I10 ) ATTR( A, 2, GL_FLOAT, \ + conv_i10_to_i((I10) & 0x3ff), \ + conv_i10_to_i(((I10) >> 10) & 0x3ff), 0, 1 ) +-#define ATTRI10_3( A, I10 ) ATTR( A, 3, \ ++#define ATTRI10_3( A, I10 ) ATTR( A, 3, GL_FLOAT, \ + conv_i10_to_i((I10) & 0x3ff), \ + conv_i10_to_i(((I10) >> 10) & 0x3ff), \ + conv_i10_to_i(((I10) >> 20) & 0x3ff), 1 ) +-#define ATTRI10_4( A, I10 ) ATTR( A, 4, \ ++#define ATTRI10_4( A, I10 ) ATTR( A, 4, GL_FLOAT, \ + conv_i10_to_i((I10) & 0x3ff), \ + conv_i10_to_i(((I10) >> 10) & 0x3ff), \ + conv_i10_to_i(((I10) >> 20) & 0x3ff), \ + conv_i2_to_i(((I10) >> 30) & 0x3)) + + +-#define ATTRI10N_1( A, I10 ) ATTR( A, 1, conv_i10_to_norm_float((I10) & 0x3ff), 0, 0, 1 ) +-#define ATTRI10N_2( A, I10 ) ATTR( A, 2, \ ++#define ATTRI10N_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_norm_float((I10) & 0x3ff), 0, 0, 1 ) ++#define ATTRI10N_2( A, I10 ) ATTR( A, 2, GL_FLOAT, \ + conv_i10_to_norm_float((I10) & 0x3ff), \ + conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), 0, 1 ) +-#define ATTRI10N_3( A, I10 ) ATTR( A, 3, \ ++#define ATTRI10N_3( A, I10 ) ATTR( A, 3, GL_FLOAT, \ + conv_i10_to_norm_float((I10) & 0x3ff), \ + conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), 1 ) +-#define ATTRI10N_4( A, I10 ) ATTR( A, 4, \ ++#define ATTRI10N_4( A, I10 ) ATTR( A, 4, GL_FLOAT, \ + conv_i10_to_norm_float((I10) & 0x3ff), \ + conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), \ +diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h +index 1c49de0..6fcd47f 100644 +--- a/src/mesa/vbo/vbo_context.h ++++ b/src/mesa/vbo/vbo_context.h +@@ -151,4 +151,47 @@ vbo_draw_method(struct vbo_context *vbo, enum draw_method method) + } + } + ++/** ++ * Return if format is integer. The immediate mode commands only emit floats ++ * for non-integer types, thus everything else is integer. ++ */ ++static inline GLboolean ++vbo_attrtype_to_integer_flag(GLenum format) ++{ ++ switch (format) { ++ case GL_FLOAT: ++ return GL_FALSE; ++ case GL_INT: ++ case GL_UNSIGNED_INT: ++ return GL_TRUE; ++ default: ++ ASSERT(0); ++ return GL_FALSE; ++ } ++} ++ ++ ++/** ++ * Return default component values for the given format. ++ * The return type is an array of floats, because that's how we declare ++ * the vertex storage despite the fact we sometimes store integers in there. ++ */ ++static inline const GLfloat * ++vbo_get_default_vals_as_float(GLenum format) ++{ ++ static const GLfloat default_float[4] = { 0, 0, 0, 1 }; ++ static const GLint default_int[4] = { 0, 0, 0, 1 }; ++ ++ switch (format) { ++ case GL_FLOAT: ++ return default_float; ++ case GL_INT: ++ case GL_UNSIGNED_INT: ++ return (const GLfloat*)default_int; ++ default: ++ ASSERT(0); ++ return NULL; ++ } ++} ++ + #endif +diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h +index 4ac7d16..34a6fe7 100644 +--- a/src/mesa/vbo/vbo_exec.h ++++ b/src/mesa/vbo/vbo_exec.h +@@ -102,6 +102,7 @@ struct vbo_exec_context + struct vbo_exec_copied_vtx copied; + + GLubyte attrsz[VBO_ATTRIB_MAX]; ++ GLenum attrtype[VBO_ATTRIB_MAX]; + GLubyte active_sz[VBO_ATTRIB_MAX]; + + GLfloat *attrptr[VBO_ATTRIB_MAX]; +diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c +index 781e360..64762c7 100644 +--- a/src/mesa/vbo/vbo_exec_api.c ++++ b/src/mesa/vbo/vbo_exec_api.c +@@ -157,11 +157,13 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) + GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + GLfloat tmp[4]; + +- COPY_CLEAN_4V(tmp, +- exec->vtx.attrsz[i], +- exec->vtx.attrptr[i]); ++ COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, ++ exec->vtx.attrsz[i], ++ exec->vtx.attrptr[i], ++ exec->vtx.attrtype[i]); + +- if (memcmp(current, tmp, sizeof(tmp)) != 0) { ++ if (exec->vtx.attrtype[i] != vbo->currval[i].Type || ++ memcmp(current, tmp, sizeof(tmp)) != 0) { + memcpy(current, tmp, sizeof(tmp)); + + /* Given that we explicitly state size here, there is no need +@@ -170,8 +172,10 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec ) + * directly. + */ + vbo->currval[i].Size = exec->vtx.attrsz[i]; +- assert(vbo->currval[i].Type == GL_FLOAT); + vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat); ++ vbo->currval[i].Type = exec->vtx.attrtype[i]; ++ vbo->currval[i].Integer = ++ vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]); + + /* This triggers rather too much recalculation of Mesa state + * that doesn't get used (eg light positions). +@@ -324,7 +328,9 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec, + if (j == attr) { + if (oldSize) { + GLfloat tmp[4]; +- COPY_CLEAN_4V(tmp, oldSize, data + old_offset); ++ COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, oldSize, ++ data + old_offset, ++ exec->vtx.attrtype[j]); + COPY_SZ_4V(dest + new_offset, newSize, tmp); + } else { + GLfloat *current = (GLfloat *)vbo->currval[j].Ptr; +@@ -365,8 +371,9 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize) + vbo_exec_wrap_upgrade_vertex( exec, attr, newSize ); + } + else if (newSize < exec->vtx.active_sz[attr]) { +- static const GLfloat id[4] = { 0, 0, 0, 1 }; + GLuint i; ++ const GLfloat *id = ++ vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]); + + /* New size is smaller - just need to fill in some + * zeros. Don't need to flush or wrap. +@@ -390,7 +397,7 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize) + * This macro is used to implement all the glVertex, glColor, glTexCoord, + * glVertexAttrib, etc functions. + */ +-#define ATTR( A, N, V0, V1, V2, V3 ) \ ++#define ATTR( A, N, T, V0, V1, V2, V3 ) \ + do { \ + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; \ + \ +@@ -406,6 +413,7 @@ do { \ + if (N>1) dest[1] = V1; \ + if (N>2) dest[2] = V2; \ + if (N>3) dest[3] = V3; \ ++ exec->vtx.attrtype[A] = T; \ + } \ + \ + if ((A) == 0) { \ +@@ -1192,6 +1200,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { + ASSERT(i < Elements(exec->vtx.attrsz)); + exec->vtx.attrsz[i] = 0; ++ ASSERT(i < Elements(exec->vtx.attrtype)); ++ exec->vtx.attrtype[i] = GL_FLOAT; + ASSERT(i < Elements(exec->vtx.active_sz)); + exec->vtx.active_sz[i] = 0; + } +@@ -1328,6 +1338,7 @@ static void reset_attrfv( struct vbo_exec_context *exec ) + + for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) { + exec->vtx.attrsz[i] = 0; ++ exec->vtx.attrtype[i] = GL_FLOAT; + exec->vtx.active_sz[i] = 0; + } + +@@ -1382,7 +1393,7 @@ VertexAttrib4f_nopos(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) + { + GET_CURRENT_CONTEXT(ctx); + if (index < MAX_VERTEX_GENERIC_ATTRIBS) +- ATTR(VBO_ATTRIB_GENERIC0 + index, 4, x, y, z, w); ++ ATTR(VBO_ATTRIB_GENERIC0 + index, 4, GL_FLOAT, x, y, z, w); + else + ERROR(GL_INVALID_VALUE); + } +diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c +index 77db8ec..14d22ee 100644 +--- a/src/mesa/vbo/vbo_exec_draw.c ++++ b/src/mesa/vbo/vbo_exec_draw.c +@@ -215,9 +215,6 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) + assert(0); + } + +- /* Make all active attributes (including edgeflag) available as +- * arrays of floats. +- */ + for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) { + const GLuint src = map[attr]; + +@@ -243,7 +240,9 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) + arrays[attr].Size = exec->vtx.attrsz[src]; + arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); + arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); +- arrays[attr].Type = GL_FLOAT; ++ arrays[attr].Type = exec->vtx.attrtype[src]; ++ arrays[attr].Integer = ++ vbo_attrtype_to_integer_flag(exec->vtx.attrtype[src]); + arrays[attr].Format = GL_RGBA; + arrays[attr].Enabled = 1; + arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat); +diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h +index 0b4d563..9aadde4 100644 +--- a/src/mesa/vbo/vbo_save.h ++++ b/src/mesa/vbo/vbo_save.h +@@ -63,6 +63,7 @@ struct vbo_save_copied_vtx { + */ + struct vbo_save_vertex_list { + GLubyte attrsz[VBO_ATTRIB_MAX]; ++ GLenum attrtype[VBO_ATTRIB_MAX]; + GLuint vertex_size; + + /* Copy of the final vertex from node->vertex_store->bufferobj. +@@ -127,6 +128,7 @@ struct vbo_save_context { + const struct gl_client_array *inputs[VBO_ATTRIB_MAX]; + + GLubyte attrsz[VBO_ATTRIB_MAX]; ++ GLenum attrtype[VBO_ATTRIB_MAX]; + GLubyte active_sz[VBO_ATTRIB_MAX]; + GLuint vertex_size; + +diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c +index a02a13d..1386d71 100644 +--- a/src/mesa/vbo/vbo_save_api.c ++++ b/src/mesa/vbo/vbo_save_api.c +@@ -327,6 +327,7 @@ _save_compile_vertex_list(struct gl_context *ctx) + /* Duplicate our template, increment refcounts to the storage structs: + */ + memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); ++ memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype)); + node->vertex_size = save->vertex_size; + node->buffer_offset = + (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); +@@ -513,7 +514,8 @@ _save_copy_to_current(struct gl_context *ctx) + for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) { + if (save->attrsz[i]) { + save->currentsz[i][0] = save->attrsz[i]; +- COPY_CLEAN_4V(save->current[i], save->attrsz[i], save->attrptr[i]); ++ COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i], ++ save->attrptr[i], save->attrtype[i]); + } + } + } +@@ -615,7 +617,8 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz) + if (save->attrsz[j]) { + if (j == attr) { + if (oldsz) { +- COPY_CLEAN_4V(dest, oldsz, data); ++ COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data, ++ save->attrtype[j]); + data += oldsz; + dest += newsz; + } +@@ -652,8 +655,8 @@ save_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz) + _save_upgrade_vertex(ctx, attr, sz); + } + else if (sz < save->active_sz[attr]) { +- static GLfloat id[4] = { 0, 0, 0, 1 }; + GLuint i; ++ const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]); + + /* New size is equal or smaller - just need to fill in some + * zeros. +@@ -691,7 +694,7 @@ _save_reset_vertex(struct gl_context *ctx) + * 3f version won't otherwise set color[3] to 1.0 -- this is the job + * of the chooser function when switching between Color4f and Color3f. + */ +-#define ATTR(A, N, V0, V1, V2, V3) \ ++#define ATTR(A, N, T, V0, V1, V2, V3) \ + do { \ + struct vbo_save_context *save = &vbo_context(ctx)->save; \ + \ +@@ -704,6 +707,7 @@ do { \ + if (N>1) dest[1] = V1; \ + if (N>2) dest[2] = V2; \ + if (N>3) dest[3] = V3; \ ++ save->attrtype[A] = T; \ + } \ + \ + if ((A) == 0) { \ +diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c +index c6425ab..8e70dbd 100644 +--- a/src/mesa/vbo/vbo_save_draw.c ++++ b/src/mesa/vbo/vbo_save_draw.c +@@ -82,16 +82,20 @@ _playback_copy_to_current(struct gl_context *ctx, + GLfloat *current = (GLfloat *)vbo->currval[i].Ptr; + GLfloat tmp[4]; + +- COPY_CLEAN_4V(tmp, +- node->attrsz[i], +- data); ++ COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, ++ node->attrsz[i], ++ data, ++ node->attrtype[i]); + +- if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) { ++ if (node->attrtype[i] != vbo->currval[i].Type || ++ memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) { + memcpy(current, tmp, 4 * sizeof(GLfloat)); + + vbo->currval[i].Size = node->attrsz[i]; +- assert(vbo->currval[i].Type == GL_FLOAT); + vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat); ++ vbo->currval[i].Type = node->attrtype[i]; ++ vbo->currval[i].Integer = ++ vbo_attrtype_to_integer_flag(node->attrtype[i]); + + if (i >= VBO_ATTRIB_FIRST_MATERIAL && + i <= VBO_ATTRIB_LAST_MATERIAL) +@@ -137,9 +141,11 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, + const GLuint *map; + GLuint attr; + GLubyte node_attrsz[VBO_ATTRIB_MAX]; /* copy of node->attrsz[] */ ++ GLenum node_attrtype[VBO_ATTRIB_MAX]; /* copy of node->attrtype[] */ + GLbitfield64 varying_inputs = 0x0; + + memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz)); ++ memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype)); + + /* Install the default (ie Current) attributes first, then overlay + * all active ones. +@@ -178,6 +184,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, + (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) { + save->inputs[VERT_ATTRIB_GENERIC0] = save->inputs[0]; + node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0]; ++ node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0]; + node_attrsz[0] = 0; + } + break; +@@ -196,7 +203,9 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, + arrays[attr].Size = node_attrsz[src]; + arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); + arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); +- arrays[attr].Type = GL_FLOAT; ++ arrays[attr].Type = node_attrtype[src]; ++ arrays[attr].Integer = ++ vbo_attrtype_to_integer_flag(node_attrtype[src]); + arrays[attr].Format = GL_RGBA; + arrays[attr].Enabled = 1; + arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);