diff options
Diffstat (limited to 'src/mesa')
40 files changed, 1027 insertions, 430 deletions
| diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index f2868cb58a..89c815722f 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -82,6 +82,71 @@        rgba[3] = 0xff;							\     } while (0) +#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4_REV) + +/** + ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +#define INIT_MONO_PIXEL(p, color) \ +   p = PACK_COLOR_4444(color[3], color[0], color[1], color[2]) + +#define WRITE_RGBA( _x, _y, r, g, b, a )				\ +   PUT_VALUE(_x, _y, PACK_COLOR_4444(a, r, g, b))			\ + +#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p) + +#define READ_RGBA( rgba, _x, _y )					\ +   do {									\ +      GLushort p = GET_VALUE(_x, _y);					\ +      rgba[0] = ((p >> 8) & 0xf) * 0x11;				\ +      rgba[1] = ((p >> 4) & 0xf) * 0x11;				\ +      rgba[2] = ((p >> 0) & 0xf) * 0x11;				\ +      rgba[3] = ((p >> 12) & 0xf) * 0x11;				\ +   } while (0) + + +#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5_REV) + +/** + ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +#define INIT_MONO_PIXEL(p, color) \ +   p = PACK_COLOR_1555(color[3], color[0], color[1], color[2]) + +#define WRITE_RGBA( _x, _y, r, g, b, a )				\ +   PUT_VALUE(_x, _y, PACK_COLOR_1555(a, r, g, b))			\ + +#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p) + +#define READ_RGBA( rgba, _x, _y )					\ +   do {									\ +      GLushort p = GET_VALUE(_x, _y);					\ +      rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8;				\ +      rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8;				\ +      rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;				\ +      rgba[3] = ((p >> 15) & 0x1) * 0xff;				\ +   } while (0) +  #elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)  /** diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index 954a7e2af1..9f4bd1699f 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -11,7 +11,6 @@ DRIVER_SOURCES = \  	i830_metaops.c \  	i830_state.c \  	i830_texblend.c \ -	i830_tex.c \  	i830_texstate.c \  	i830_vtbl.c \  	intel_render.c \ @@ -36,7 +35,6 @@ DRIVER_SOURCES = \  	intel_buffers.c \  	intel_blit.c \  	intel_swapbuffers.c \ -	i915_tex.c \  	i915_tex_layout.c \  	i915_texstate.c \  	i915_context.c \ diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 9c540cb2bb..10b9bf371c 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -47,7 +47,6 @@ i830InitDriverFunctions(struct dd_function_table *functions)  {     intelInitDriverFunctions(functions);     i830InitStateFuncs(functions); -   i830InitTextureFuncs(functions);  }  extern const struct tnl_pipeline_stage *intel_pipeline[]; diff --git a/src/mesa/drivers/dri/i915/i830_tex.c b/src/mesa/drivers/dri/i915/i830_tex.c deleted file mode 100644 index 34ac42a78e..0000000000 --- a/src/mesa/drivers/dri/i915/i830_tex.c +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - *  - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - *  - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - *  - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - *  - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *  - **************************************************************************/ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/imports.h" -#include "main/simple_list.h" -#include "main/enums.h" -#include "main/image.h" -#include "main/mm.h" -#include "main/texstore.h" -#include "main/texformat.h" -#include "swrast/swrast.h" - -#include "texmem.h" - -#include "i830_context.h" -#include "i830_reg.h" - - - -static void -i830TexEnv(GLcontext * ctx, GLenum target, -           GLenum pname, const GLfloat * param) -{ - -   switch (pname) { -   case GL_TEXTURE_ENV_COLOR: -   case GL_TEXTURE_ENV_MODE: -   case GL_COMBINE_RGB: -   case GL_COMBINE_ALPHA: -   case GL_SOURCE0_RGB: -   case GL_SOURCE1_RGB: -   case GL_SOURCE2_RGB: -   case GL_SOURCE0_ALPHA: -   case GL_SOURCE1_ALPHA: -   case GL_SOURCE2_ALPHA: -   case GL_OPERAND0_RGB: -   case GL_OPERAND1_RGB: -   case GL_OPERAND2_RGB: -   case GL_OPERAND0_ALPHA: -   case GL_OPERAND1_ALPHA: -   case GL_OPERAND2_ALPHA: -   case GL_RGB_SCALE: -   case GL_ALPHA_SCALE: -      break; - -   case GL_TEXTURE_LOD_BIAS:{ -         struct i830_context *i830 = i830_context(ctx); -         GLuint unit = ctx->Texture.CurrentUnit; -         int b = (int) ((*param) * 16.0); -         if (b > 63) -            b = 63; -         if (b < -64) -            b = -64; -         I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); -         i830->lodbias_tm0s3[unit] = -            ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); -         break; -      } - -   default: -      break; -   } -} - - - - -void -i830InitTextureFuncs(struct dd_function_table *functions) -{ -/* -   functions->TexEnv = i830TexEnv; -*/ -} diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 1a94921078..3bf02de61f 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -26,12 +26,14 @@   **************************************************************************/  #include "glapi/glapi.h" +#include "main/texformat.h"  #include "i830_context.h"  #include "i830_reg.h"  #include "intel_batchbuffer.h"  #include "intel_regions.h"  #include "intel_tris.h" +#include "intel_fbo.h"  #include "tnl/t_context.h"  #include "tnl/t_vertex.h" @@ -614,6 +616,8 @@ i830_state_draw_region(struct intel_context *intel,  {     struct i830_context *i830 = i830_context(&intel->ctx);     GLcontext *ctx = &intel->ctx; +   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; +   struct intel_renderbuffer *irb = intel_renderbuffer(rb);     GLuint value;     ASSERT(state == &i830->state || state == &i830->meta); @@ -651,13 +655,27 @@ i830_state_draw_region(struct intel_context *intel,      */     value = (DSTORG_HORT_BIAS(0x8) |     /* .5 */              DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z);    /* .5 */ -             -   if (color_region && color_region->cpp == 4) { -      value |= DV_PF_8888; -   } -   else { -      value |= DV_PF_565; + +   if (irb != NULL) { +      switch (irb->texformat->MesaFormat) { +      case MESA_FORMAT_ARGB8888: +	 value |= DV_PF_8888; +	 break; +      case MESA_FORMAT_RGB565: +	 value |= DV_PF_565; +	 break; +      case MESA_FORMAT_ARGB1555: +	 value |= DV_PF_1555; +	 break; +      case MESA_FORMAT_ARGB4444: +	 value |= DV_PF_4444; +	 break; +      default: +	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n", +		       irb->texformat->MesaFormat); +      }     } +     if (depth_region && depth_region->cpp == 4) {        value |= DEPTH_FRMT_24_FIXED_8_OTHER;     } diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 7549029a1b..fdd2cf6109 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -83,7 +83,6 @@ i915InitDriverFunctions(struct dd_function_table *functions)  {     intelInitDriverFunctions(functions);     i915InitStateFunctions(functions); -   i915InitTextureFuncs(functions);     i915InitFragProgFuncs(functions);     functions->UpdateState = i915InvalidateState;  } diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index a5158de945..2db10c60e9 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -323,7 +323,8 @@ upload_program(struct i915_fragment_program *p)        p->ctx->FragmentProgram._Current;     const struct prog_instruction *inst = program->Base.Instructions; -/*    _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ +   if (INTEL_DEBUG & DEBUG_WM) +      _mesa_print_program(&program->Base);     /* Is this a parse-failed program?  Ensure a valid program is      * loaded, as the flagging of an error isn't sufficient to stop @@ -1049,9 +1050,6 @@ i915ProgramStringNotify(GLcontext * ctx,           _mesa_append_fog_code(ctx, &p->FragProg);           p->FragProg.FogOption = GL_NONE;        } - -      if (INTEL_DEBUG & DEBUG_STATE) -	 _mesa_print_program(prog);     }     _tnl_program_string(ctx, target, prog); diff --git a/src/mesa/drivers/dri/i915/i915_tex.c b/src/mesa/drivers/dri/i915/i915_tex.c deleted file mode 100644 index e38d8fe79d..0000000000 --- a/src/mesa/drivers/dri/i915/i915_tex.c +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** - *  - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - *  - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - *  - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - *  - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *  - **************************************************************************/ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/imports.h" -#include "main/simple_list.h" -#include "main/enums.h" -#include "main/image.h" -#include "main/mm.h" -#include "main/texstore.h" -#include "main/texformat.h" -#include "swrast/swrast.h" - -#include "texmem.h" - -#include "i915_context.h" -#include "i915_reg.h" - - - -static void -i915TexEnv(GLcontext * ctx, GLenum target, -           GLenum pname, const GLfloat * param) -{ -   struct i915_context *i915 = I915_CONTEXT(ctx); - -   switch (pname) { -   case GL_TEXTURE_LOD_BIAS:{ -         GLuint unit = ctx->Texture.CurrentUnit; -         GLint b = (int) ((*param) * 16.0); -         if (b > 255) -            b = 255; -         if (b < -256) -            b = -256; -         I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); -         i915->lodbias_ss2[unit] = -            ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); -         break; -      } - -   default: -      break; -   } -} - - -void -i915InitTextureFuncs(struct dd_function_table *functions) -{ -/* -   functions->TexEnv = i915TexEnv; -*/ -} diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 3f6d282d34..115004616f 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -32,6 +32,7 @@  #include "main/imports.h"  #include "main/macros.h"  #include "main/colormac.h" +#include "main/texformat.h"  #include "tnl/t_context.h"  #include "tnl/t_vertex.h" @@ -40,6 +41,7 @@  #include "intel_tex.h"  #include "intel_regions.h"  #include "intel_tris.h" +#include "intel_fbo.h"  #include "i915_reg.h"  #include "i915_context.h" @@ -542,6 +544,8 @@ i915_state_draw_region(struct intel_context *intel,  {     struct i915_context *i915 = i915_context(&intel->ctx);     GLcontext *ctx = &intel->ctx; +   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; +   struct intel_renderbuffer *irb = intel_renderbuffer(rb);     GLuint value;     ASSERT(state == &i915->state || state == &i915->meta); @@ -580,12 +584,26 @@ i915_state_draw_region(struct intel_context *intel,     value = (DSTORG_HORT_BIAS(0x8) |     /* .5 */              DSTORG_VERT_BIAS(0x8) |     /* .5 */              LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); -   if (color_region && color_region->cpp == 4) { -      value |= DV_PF_8888; -   } -   else { -      value |= (DITHER_FULL_ALWAYS | DV_PF_565); +   if (irb != NULL) { +      switch (irb->texformat->MesaFormat) { +      case MESA_FORMAT_ARGB8888: +	 value |= DV_PF_8888; +	 break; +      case MESA_FORMAT_RGB565: +	 value |= DV_PF_565 | DITHER_FULL_ALWAYS; +	 break; +      case MESA_FORMAT_ARGB1555: +	 value |= DV_PF_1555 | DITHER_FULL_ALWAYS; +	 break; +      case MESA_FORMAT_ARGB4444: +	 value |= DV_PF_4444 | DITHER_FULL_ALWAYS; +	 break; +      default: +	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n", +		       irb->texformat->MesaFormat); +      }     } +     if (depth_region && depth_region->cpp == 4) {        value |= DEPTH_FRMT_24_FIXED_8_OTHER;     } diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index dfab14aa74..fe1de821f0 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -353,6 +353,14 @@ update_constant_buffer(struct brw_context *brw,        map = const_buffer->virtual;        memcpy(map, params->ParameterValues, size);        dri_bo_unmap(const_buffer); + +      if (0) { +         int i; +         for (i = 0; i < params->NumParameters; i++) { +            float *p = params->ParameterValues[i]; +            printf("%d: %f %f %f %f\n", i, p[0], p[1], p[2], p[3]); +         } +      }     }  } @@ -363,6 +371,10 @@ update_vertex_constant_buffer(struct brw_context *brw)  {     struct brw_vertex_program *vp =        (struct brw_vertex_program *) brw->vertex_program; +   if (0) { +      printf("update VS constants in buffer %p\n", vp->const_buffer); +      printf("program %u\n", vp->program.Base.Id); +   }     update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer);  } diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 66f8eb840c..896e67dbfe 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -868,6 +868,7 @@ void brw_dp_READ_4( struct brw_compile *p,  void brw_dp_READ_4_vs( struct brw_compile *p,                         struct brw_reg dest,                         GLboolean relAddr, +                       struct brw_reg addrReg,                         GLuint location,                         GLuint bind_table_index ); diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index c731a93a8d..df2141660c 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -1003,15 +1003,18 @@ void brw_dp_READ_4( struct brw_compile *p,  /** - * Read float[4] constant from VS constant buffer. + * Read float[4] constant(s) from VS constant buffer. + * For relative addressing, two float[4] constants will be read into 'dest'. + * Otherwise, one float[4] constant will be read into the lower half of 'dest'.   */  void brw_dp_READ_4_vs(struct brw_compile *p,                        struct brw_reg dest,                        GLboolean relAddr, +                      struct brw_reg addrReg,                        GLuint location,                        GLuint bind_table_index)  { -   const GLuint msg_reg_nr = 1; +   GLuint msg_reg_nr = 1;     /*     printf("vs const read msg, location %u, msg_reg_nr %d\n", @@ -1034,7 +1037,12 @@ void brw_dp_READ_4_vs(struct brw_compile *p,        b = brw_message_reg(msg_reg_nr);        b = retype(b, BRW_REGISTER_TYPE_UD);        /*b = get_element_ud(b, 2);*/ -      brw_MOV(p, b, brw_imm_ud(location)); +      if (relAddr) { +         brw_ADD(p, b, addrReg, brw_imm_ud(location)); +      } +      else { +         brw_MOV(p, b, brw_imm_ud(location)); +      }        brw_pop_insn_state(p);     } @@ -1053,13 +1061,56 @@ void brw_dp_READ_4_vs(struct brw_compile *p,        brw_set_dp_read_message(insn,  			      bind_table_index, -			      0,  /* msg_control (0 means 1 Oword) */ +			      0,  /* msg_control (0 means 1 Oword, lower half) */  			      BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */  			      0, /* source cache = data cache */  			      1, /* msg_length */  			      1, /* response_length (1 Oword) */  			      0); /* eot */     } + +   if (relAddr) { +      /* second read to get second constant */ +      msg_reg_nr++; +      { +         /* Setup MRF[1] with location/offset into const buffer */ +         struct brw_reg b; + +         brw_push_insn_state(p); +         brw_set_compression_control(p, BRW_COMPRESSION_NONE); +         brw_set_mask_control(p, BRW_MASK_DISABLE); +         brw_set_predicate_control(p, BRW_PREDICATE_NONE); + +         b = brw_message_reg(msg_reg_nr); +         b = retype(b, BRW_REGISTER_TYPE_UD); +         addrReg = suboffset(addrReg, 1); /* upper half of addrReg */ +         brw_ADD(p, b, addrReg, brw_imm_ud(location)); + +         brw_pop_insn_state(p); +      } + +      { +         struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + +         insn->header.predicate_control = BRW_PREDICATE_NONE; +         insn->header.compression_control = BRW_COMPRESSION_NONE;  +         insn->header.destreg__conditonalmod = msg_reg_nr; +         insn->header.mask_control = BRW_MASK_DISABLE; +         /*insn->header.access_mode = BRW_ALIGN_16;*/ + +         brw_set_dest(insn, dest); +         brw_set_src0(insn, brw_null_reg()); + +         brw_set_dp_read_message(insn, +                                 bind_table_index, +                                 1,  /* msg_control (1 means 1 Oword, upper half) */ +                                 BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ +                                 0, /* source cache = data cache */ +                                 1, /* msg_length */ +                                 1, /* response_length (1 Oword) */ +                                 0); /* eot */ +      } +   }  } diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index 5d332d010c..a713262269 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -84,6 +84,19 @@ get_965_surfacetype(unsigned int surfacetype)      }  } +static const char * +get_965_surface_format(unsigned int surface_format) +{ +    switch (surface_format) { +    case 0x000: return "r32g32b32a32_float"; +    case 0x0c1: return "b8g8r8a8_unorm"; +    case 0x100: return "b5g6r5_unorm"; +    case 0x102: return "b5g5r5a1_unorm"; +    case 0x104: return "b4g4r4a4_unorm"; +    default: return "unknown"; +    } +} +  static void dump_wm_surface_state(struct brw_context *brw)  {     int i; @@ -95,7 +108,7 @@ static void dump_wm_surface_state(struct brw_context *brw)        char name[20];        if (surf_bo == NULL) { -	 fprintf(stderr, "WM SS%d: NULL\n", i); +	 fprintf(stderr, "  WM SS%d: NULL\n", i);  	 continue;        }        dri_bo_map(surf_bo, GL_FALSE); @@ -103,8 +116,9 @@ static void dump_wm_surface_state(struct brw_context *brw)        surf = (struct brw_surface_state *)(surf_bo->virtual);        sprintf(name, "WM SS%d", i); -      state_out(name, surf, surfoff, 0, "%s\n", -		get_965_surfacetype(surf->ss0.surface_type)); +      state_out(name, surf, surfoff, 0, "%s %s\n", +		get_965_surfacetype(surf->ss0.surface_type), +		get_965_surface_format(surf->ss0.surface_format));        state_out(name, surf, surfoff, 1, "offset\n");        state_out(name, surf, surfoff, 2, "%dx%d size, %d mips\n",  		surf->ss2.width + 1, surf->ss2.height + 1, surf->ss2.mip_count); diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 42f6a99142..af0f501621 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -170,6 +170,14 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )        reg++;     } +   if (c->use_const_buffer) { +      for (i = 0; i < 3; i++) { +         c->current_const[i].index = -1; +         c->current_const[i].reg = brw_vec8_grf(reg, 0); +         reg++; +      } +   } +     for (i = 0; i < 128; i++) {        if (c->output_regs[i].used_in_src) {           c->output_regs[i].reg = brw_vec8_grf(reg, 0); @@ -194,13 +202,6 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )     c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;     c->prog_data.total_grf = reg; -   if (c->use_const_buffer) { -       for (i = 0; i < 3; i++) { -          c->current_const[i].index = -1; -          c->current_const[i].reg = get_tmp(c); -       } -   } -     if (INTEL_DEBUG & DEBUG_VS) {        _mesa_printf("%s NumAddrRegs %d\n", __FUNCTION__, c->vp->program.Base.NumAddressRegs);        _mesa_printf("%s NumTemps %d\n", __FUNCTION__, c->vp->program.Base.NumTemporaries); @@ -655,6 +656,8 @@ static void emit_lit_noalias( struct brw_vs_compile *c,     }     brw_ENDIF(p, if_insn); + +   release_tmp(c, tmp);  }  static void emit_lrp_noalias(struct brw_vs_compile *c, @@ -704,7 +707,9 @@ get_constant(struct brw_vs_compile *c,     struct brw_compile *p = &c->func;     struct brw_reg const_reg; -   if (c->current_const[argIndex].index != src->Index) { +   assert(argIndex < 3); + +   if (c->current_const[argIndex].index != src->Index || src->RelAddr) {        c->current_const[argIndex].index = src->Index; @@ -717,15 +722,18 @@ get_constant(struct brw_vs_compile *c,        brw_dp_READ_4_vs(p,                         c->current_const[argIndex].reg, /* writeback dest */                         src->RelAddr,                   /* relative indexing? */ +                       c->regs[PROGRAM_ADDRESS][0],    /* address register */                         16 * src->Index,                /* byte offset */                         SURF_INDEX_VERT_CONST_BUFFER    /* binding table index */                         );     } -   /* replicate lower four floats into upper four floats (to get XYZWXYZW) */     const_reg = c->current_const[argIndex].reg; -   const_reg = stride(const_reg, 0, 4, 0); -   const_reg.subnr = 0; +   if (!src->RelAddr) { +      /* replicate lower four floats into upper half (to get XYZWXYZW) */ +      const_reg = stride(const_reg, 0, 4, 0); +      const_reg.subnr = 0; +   }     return const_reg;  } @@ -767,6 +775,42 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,  /** + * Indirect addressing:  get reg[[arg] + offset]. + */ +static struct brw_reg deref( struct brw_vs_compile *c, +			     struct brw_reg arg, +			     GLint offset) +{ +   struct brw_compile *p = &c->func; +   struct brw_reg tmp = vec4(get_tmp(c)); +   struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0]; +   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_UW); +   GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * 16; +   struct brw_reg indirect = brw_vec4_indirect(0,0); + +   { +      brw_push_insn_state(p); +      brw_set_access_mode(p, BRW_ALIGN_1); + +      /* This is pretty clunky - load the address register twice and +       * fetch each 4-dword value in turn.  There must be a way to do +       * this in a single pass, but I couldn't get it to work. +       */ +      brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset)); +      brw_MOV(p, tmp, indirect); + +      brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset)); +      brw_MOV(p, suboffset(tmp, 4), indirect); + +      brw_pop_insn_state(p); +   } +    +   /* NOTE: tmp not released */ +   return vec8(tmp); +} + + +/**   * Get brw reg corresponding to the instruction's [argIndex] src reg.   * TODO: relative addressing!   */ @@ -777,19 +821,29 @@ get_src_reg( struct brw_vs_compile *c,  {     const GLuint file = inst->SrcReg[argIndex].File;     const GLint index = inst->SrcReg[argIndex].Index; +   const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;     switch (file) {     case PROGRAM_TEMPORARY:     case PROGRAM_INPUT:     case PROGRAM_OUTPUT: -      assert(c->regs[file][index].nr != 0); -      return c->regs[file][index]; +      if (relAddr) { +         return deref(c, c->regs[file][0], index); +      } +      else { +         assert(c->regs[file][index].nr != 0); +         return c->regs[file][index]; +      } +     case PROGRAM_STATE_VAR:     case PROGRAM_CONSTANT:     case PROGRAM_UNIFORM:        if (c->use_const_buffer) {           return get_constant(c, inst, argIndex);        } +      else if (relAddr) { +         return deref(c, c->regs[PROGRAM_STATE_VAR][0], index); +      }        else {           assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);           return c->regs[PROGRAM_STATE_VAR][index]; @@ -812,41 +866,6 @@ get_src_reg( struct brw_vs_compile *c,  } -/** - * Indirect addressing:  get reg[[arg] + offset]. - */ -static struct brw_reg deref( struct brw_vs_compile *c, -			     struct brw_reg arg, -			     GLint offset) -{ -   struct brw_compile *p = &c->func; -   struct brw_reg tmp = vec4(get_tmp(c)); -   struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0]; -   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_UW); -   GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * 16; -   struct brw_reg indirect = brw_vec4_indirect(0,0); - -   { -      brw_push_insn_state(p); -      brw_set_access_mode(p, BRW_ALIGN_1); - -      /* This is pretty clunky - load the address register twice and -       * fetch each 4-dword value in turn.  There must be a way to do -       * this in a single pass, but I couldn't get it to work. -       */ -      brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset)); -      brw_MOV(p, tmp, indirect); - -      brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset)); -      brw_MOV(p, suboffset(tmp, 4), indirect); - -      brw_pop_insn_state(p); -   } -    -   return vec8(tmp); -} - -  static void emit_arl( struct brw_vs_compile *c,  		      struct brw_reg dst,  		      struct brw_reg arg0 ) @@ -858,8 +877,8 @@ static void emit_arl( struct brw_vs_compile *c,     if (need_tmp)         tmp = get_tmp(c); -   brw_RNDD(p, tmp, arg0); -   brw_MUL(p, dst, tmp, brw_imm_d(16)); +   brw_RNDD(p, tmp, arg0);               /* tmp = round(arg0) */ +   brw_MUL(p, dst, tmp, brw_imm_d(16));  /* dst = tmp * 16 */     if (need_tmp)        release_tmp(c, tmp); @@ -882,13 +901,7 @@ static struct brw_reg get_arg( struct brw_vs_compile *c,     if (src->File == PROGRAM_UNDEFINED)        return brw_null_reg(); -   if (src->RelAddr) { -      /* XXX fix */ -      reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index); -   } -   else { -      reg = get_src_reg(c, inst, argIndex); -   } +   reg = get_src_reg(c, inst, argIndex);     /* Convert 3-bit swizzle to 2-bit.        */ @@ -919,6 +932,10 @@ static struct brw_reg get_dst( struct brw_vs_compile *c,        assert(c->regs[dst.File][dst.Index].nr != 0);        reg = c->regs[dst.File][dst.Index];        break; +   case PROGRAM_ADDRESS: +      assert(dst.Index == 0); +      reg = c->regs[dst.File][dst.Index]; +      break;     case PROGRAM_UNDEFINED:        /* we may hit this for OPCODE_END, OPCODE_KIL, etc */        reg = brw_null_reg(); @@ -979,10 +996,7 @@ static void emit_swz( struct brw_vs_compile *c,     if (src_mask) {        struct brw_reg arg0; -      if (src.RelAddr)  -	 arg0 = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index); -      else -	 arg0 = get_src_reg(c, inst, argIndex); +      arg0 = get_src_reg(c, inst, argIndex);        arg0 = brw_swizzle(arg0,   			 src_swz[0], src_swz[1],  @@ -1178,6 +1192,11 @@ void brw_vs_emit(struct brw_vs_compile *c )        struct brw_reg args[3], dst;        GLuint i; +#if 0 +      printf("%d: ", insn); +      _mesa_print_instruction(inst); +#endif +        /* Get argument regs.  SWZ is special and does this itself.         */        if (inst->Opcode != OPCODE_SWZ) diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 385efd2dd3..2d13088ddb 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -346,10 +346,10 @@ get_src_reg_const(struct brw_wm_compile *c,        const_reg = brw_abs(const_reg);  #if 0 -   printf("  form const[%d] for arg %d, comp %d, reg %d\n", +   printf("  form const[%d].%d for arg %d, reg %d\n",            c->current_const[srcRegIndex].index, -          srcRegIndex,            component, +          srcRegIndex,            const_reg.nr);  #endif @@ -407,7 +407,7 @@ static struct brw_reg get_src_reg_imm(struct brw_wm_compile *c,         if (src->Abs)            value = FABSF(value);  #if 0 -       printf("  form imm reg %f\n", value); +       printf("  form immed value %f for chan %d\n", value, channel);  #endif         return brw_imm_f(value);      } @@ -527,7 +527,9 @@ static void emit_mov( struct brw_wm_compile *c,  	if (mask & (1<<i)) {  	    struct brw_reg src, dst;  	    dst = get_dst_reg(c, inst, i); -	    src = get_src_reg_imm(c, inst, 0, i); +            /* XXX some moves from immediate value don't work reliably!!! */ +            /*src = get_src_reg_imm(c, inst, 0, i);*/ +            src = get_src_reg(c, inst, 0, i);  	    brw_MOV(p, dst, src);  	}      } 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 ce5dbb334b..0dc377be65 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -38,7 +38,7 @@  #include "intel_mipmap_tree.h"  #include "intel_batchbuffer.h"  #include "intel_tex.h" - +#include "intel_fbo.h"  #include "brw_context.h"  #include "brw_state.h" @@ -505,15 +505,18 @@ brw_update_vs_constant_surface( GLcontext *ctx,   * usable for further buffers when doing ARB_draw_buffer support.   */  static void -brw_update_region_surface(struct brw_context *brw, struct intel_region *region, -			  unsigned int unit, GLboolean cached) +brw_update_renderbuffer_surface(struct brw_context *brw, +				struct gl_renderbuffer *rb, +				unsigned int unit, GLboolean cached)  {     GLcontext *ctx = &brw->intel.ctx;     dri_bo *region_bo = NULL; +   struct intel_renderbuffer *irb = intel_renderbuffer(rb); +   struct intel_region *region = irb ? irb->region : NULL;     struct {        unsigned int surface_type;        unsigned int surface_format; -      unsigned int width, height, cpp; +      unsigned int width, height, pitch, cpp;        GLubyte color_mask[4];        GLboolean color_blend;        uint32_t tiling; @@ -525,13 +528,27 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,        region_bo = region->buffer;        key.surface_type = BRW_SURFACE_2D; -      if (region->cpp == 4) +      switch (irb->texformat->MesaFormat) { +      case MESA_FORMAT_ARGB8888:  	 key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; -      else +	 break; +      case MESA_FORMAT_RGB565:  	 key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; +	 break; +      case MESA_FORMAT_ARGB1555: +	 key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM; +	 break; +      case MESA_FORMAT_ARGB4444: +	 key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM; +	 break; +      default: +	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n", +		       irb->texformat->MesaFormat); +      }        key.tiling = region->tiling; -      key.width = region->pitch; /* XXX: not really! */ -      key.height = region->height; +      key.width = rb->Width; +      key.height = rb->Height; +      key.pitch = region->pitch;        key.cpp = region->cpp;     } else {        key.surface_type = BRW_SURFACE_NULL; @@ -567,7 +584,7 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,        surf.ss2.width = key.width - 1;        surf.ss2.height = key.height - 1;        brw_set_surface_tiling(&surf, key.tiling); -      surf.ss3.pitch = (key.width * key.cpp) - 1; +      surf.ss3.pitch = (key.pitch * key.cpp) - 1;        /* _NEW_COLOR */        surf.ss0.color_blend = key.color_blend; @@ -655,14 +672,17 @@ static void prepare_wm_surfaces(struct brw_context *brw )     GLuint i;     int old_nr_surfaces; +   /* _NEW_BUFFERS */     /* Update surfaces for drawing buffers */ -   if (brw->state.nr_color_regions > 1) { -      for (i = 0; i < brw->state.nr_color_regions; i++) { -         brw_update_region_surface(brw, brw->state.color_regions[i], i, -				   GL_FALSE); +   if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) { +      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { +         brw_update_renderbuffer_surface(brw, +					 ctx->DrawBuffer->_ColorDrawBuffers[i], +					 i, +					 GL_FALSE);        }     } else { -      brw_update_region_surface(brw, brw->state.color_regions[0], 0, GL_TRUE); +      brw_update_renderbuffer_surface(brw, NULL, 0, GL_TRUE);     }     old_nr_surfaces = brw->wm.nr_surfaces; diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 4ae9b118a3..4919828131 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -32,6 +32,8 @@  #include "main/mtypes.h"  #include "main/context.h"  #include "main/enums.h" +#include "main/texformat.h" +#include "main/colormac.h"  #include "intel_blit.h"  #include "intel_buffers.h" @@ -484,10 +486,9 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)              const GLbitfield bufBit = 1 << buf;              if ((clearMask & bufBit) && !(bufBit & skipBuffers)) {                 /* OK, clear this renderbuffer */ -               struct intel_region *irb_region = -		  intel_get_rb_region(fb, buf); +	       struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf);                 dri_bo *write_buffer = -                  intel_region_buffer(intel, irb_region, +                  intel_region_buffer(intel, irb->region,                                        all ? INTEL_WRITE_FULL :                                        INTEL_WRITE_PART); @@ -495,15 +496,13 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)                 GLint pitch, cpp;                 GLuint BR13, CMD; -               ASSERT(irb_region); - -               pitch = irb_region->pitch; -               cpp = irb_region->cpp; +               pitch = irb->region->pitch; +               cpp = irb->region->cpp;                 DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",                     __FUNCTION__, -                   irb_region->buffer, (pitch * cpp), -                   irb_region->draw_offset, +                   irb->region->buffer, (pitch * cpp), +                   irb->region->draw_offset,                     b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1);  	       BR13 = 0xf0 << 16; @@ -529,7 +528,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)                 }  #ifndef I915 -	       if (irb_region->tiling != I915_TILING_NONE) { +	       if (irb->region->tiling != I915_TILING_NONE) {  		  CMD |= XY_DST_TILED;  		  pitch /= 4;  	       } @@ -540,9 +539,36 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)                    clearVal = clear_depth;                 }                 else { -                  clearVal = (cpp == 4) -                     ? intel->ClearColor8888 : intel->ClearColor565; -               } +		  uint8_t clear[4]; +		  GLclampf *color = ctx->Color.ClearColor; + +		  CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); +		  CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); +		  CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); +		  CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + +		  switch (irb->texformat->MesaFormat) { +		  case MESA_FORMAT_ARGB8888: +		     clearVal = intel->ClearColor8888; +		     break; +		  case MESA_FORMAT_RGB565: +		     clearVal = intel->ClearColor565; +		     break; +		  case MESA_FORMAT_ARGB4444: +		     clearVal = PACK_COLOR_4444(clear[3], clear[0], +						clear[1], clear[2]); +		     break; +		  case MESA_FORMAT_ARGB1555: +		     clearVal = PACK_COLOR_1555(clear[3], clear[0], +						clear[1], clear[2]); +		     break; +		  default: +		     _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", +				   irb->texformat->MesaFormat); +		     clearVal = 0; +		  } +	       } +                 /*                    _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n",                    buf, irb->Base.Name); @@ -558,7 +584,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)                 OUT_BATCH((b.y2 << 16) | b.x2);                 OUT_RELOC(write_buffer,  			 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, -                         irb_region->draw_offset); +                         irb->region->draw_offset);                 OUT_BATCH(clearVal);                 ADVANCE_BATCH();                 clearMask &= ~bufBit;    /* turn off bit, for faster loop exit */ diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index bd3810549a..d798225ddd 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -48,6 +48,8 @@  #define DV_PF_555  (1<<8)  #define DV_PF_565  (2<<8)  #define DV_PF_8888 (3<<8) +#define DV_PF_4444 (8<<8) +#define DV_PF_1555 (9<<8)  struct intel_region;  struct intel_context; @@ -337,6 +339,7 @@ extern char *__progname;  #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))  #define ALIGN(value, alignment)  ((value + alignment - 1) & ~(alignment - 1)) +#define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0)  #define INTEL_FIREVERTICES(intel)		\  do {						\ diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c index f04638206d..a9dfe281cb 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.c +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -800,6 +800,7 @@ static int  decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830)  {      unsigned int len, i, c, opcode, word, map, sampler, instr; +    char *format;      struct {  	uint32_t opcode; @@ -1001,6 +1002,35 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	    (*failures)++;  	}  	return len; +    case 0x85: +	len = (data[0] & 0x0000000f) + 2; + +	if (len != 2) +	    fprintf(out, "Bad count in 3DSTATE_DEST_BUFFER_VARIABLES\n"); +	if (count < 2) +	    BUFFER_FAIL(count, len, "3DSTATE_DEST_BUFFER_VARIABLES"); + +	instr_out(data, hw_offset, 0, +		  "3DSTATE_DEST_BUFFER_VARIABLES\n"); + +	switch ((data[1] >> 8) & 0xf) { +	case 0x0: format = "g8"; break; +	case 0x1: format = "x1r5g5b5"; break; +	case 0x2: format = "r5g6b5"; break; +	case 0x3: format = "a8r8g8b8"; break; +	case 0x4: format = "ycrcb_swapy"; break; +	case 0x5: format = "ycrcb_normal"; break; +	case 0x6: format = "ycrcb_swapuv"; break; +	case 0x7: format = "ycrcb_swapuvy"; break; +	case 0x8: format = "a4r4g4b4"; break; +	case 0x9: format = "a1r5g5b5"; break; +	case 0xa: format = "a2r10g10b10"; break; +	default: format = "BAD"; break; +	} +	instr_out(data, hw_offset, 1, "%s format, early Z %sabled\n", +		  format, +		  (data[1] & (1 << 31)) ? "en" : "dis"); +	return len;      }      for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index a401f730ba..52647ddf8b 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -119,6 +119,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->RedBits = 5;        rb->GreenBits = 6;        rb->BlueBits = 5; +      irb->texformat = &_mesa_texformat_rgb565;        cpp = 2;        break;     case GL_RGB: @@ -132,6 +133,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->GreenBits = 8;        rb->BlueBits = 8;        rb->AlphaBits = 0; +      irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */        cpp = 4;        break;     case GL_RGBA: @@ -148,6 +150,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->GreenBits = 8;        rb->BlueBits = 8;        rb->AlphaBits = 8; +      irb->texformat = &_mesa_texformat_argb8888;        cpp = 4;        break;     case GL_STENCIL_INDEX: @@ -160,12 +163,14 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->DataType = GL_UNSIGNED_INT_24_8_EXT;        rb->StencilBits = 8;        cpp = 4; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     case GL_DEPTH_COMPONENT16:        rb->_ActualFormat = GL_DEPTH_COMPONENT16;        rb->DataType = GL_UNSIGNED_SHORT;        rb->DepthBits = 16;        cpp = 2; +      irb->texformat = &_mesa_texformat_z16;        break;     case GL_DEPTH_COMPONENT:     case GL_DEPTH_COMPONENT24: @@ -174,6 +179,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->DataType = GL_UNSIGNED_INT_24_8_EXT;        rb->DepthBits = 24;        cpp = 4; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     case GL_DEPTH_STENCIL_EXT:     case GL_DEPTH24_STENCIL8_EXT: @@ -182,6 +188,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,        rb->DepthBits = 24;        rb->StencilBits = 8;        cpp = 4; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     default:        _mesa_problem(ctx, @@ -322,6 +329,7 @@ intel_create_renderbuffer(GLenum intFormat)        irb->Base.GreenBits = 6;        irb->Base.BlueBits = 5;        irb->Base.DataType = GL_UNSIGNED_BYTE; +      irb->texformat = &_mesa_texformat_rgb565;        break;     case GL_RGB8:        irb->Base._ActualFormat = GL_RGB8; @@ -331,6 +339,7 @@ intel_create_renderbuffer(GLenum intFormat)        irb->Base.BlueBits = 8;        irb->Base.AlphaBits = 0;        irb->Base.DataType = GL_UNSIGNED_BYTE; +      irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */        break;     case GL_RGBA8:        irb->Base._ActualFormat = GL_RGBA8; @@ -340,24 +349,28 @@ intel_create_renderbuffer(GLenum intFormat)        irb->Base.BlueBits = 8;        irb->Base.AlphaBits = 8;        irb->Base.DataType = GL_UNSIGNED_BYTE; +      irb->texformat = &_mesa_texformat_argb8888;        break;     case GL_STENCIL_INDEX8_EXT:        irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT;        irb->Base._BaseFormat = GL_STENCIL_INDEX;        irb->Base.StencilBits = 8;        irb->Base.DataType = GL_UNSIGNED_BYTE; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     case GL_DEPTH_COMPONENT16:        irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;        irb->Base._BaseFormat = GL_DEPTH_COMPONENT;        irb->Base.DepthBits = 16;        irb->Base.DataType = GL_UNSIGNED_SHORT; +      irb->texformat = &_mesa_texformat_z16;        break;     case GL_DEPTH_COMPONENT24:        irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;        irb->Base._BaseFormat = GL_DEPTH_COMPONENT;        irb->Base.DepthBits = 24;        irb->Base.DataType = GL_UNSIGNED_INT; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     case GL_DEPTH24_STENCIL8_EXT:        irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; @@ -365,6 +378,7 @@ intel_create_renderbuffer(GLenum intFormat)        irb->Base.DepthBits = 24;        irb->Base.StencilBits = 8;        irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; +      irb->texformat = &_mesa_texformat_s8_z24;        break;     default:        _mesa_problem(NULL, @@ -449,6 +463,8 @@ static GLboolean  intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,   		     struct gl_texture_image *texImage)  { +   irb->texformat = texImage->TexFormat; +     if (texImage->TexFormat == &_mesa_texformat_argb8888) {        irb->Base._ActualFormat = GL_RGBA8;        irb->Base._BaseFormat = GL_RGBA; @@ -458,9 +474,21 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,     else if (texImage->TexFormat == &_mesa_texformat_rgb565) {        irb->Base._ActualFormat = GL_RGB5;        irb->Base._BaseFormat = GL_RGB; -      irb->Base.DataType = GL_UNSIGNED_SHORT; +      irb->Base.DataType = GL_UNSIGNED_BYTE;        DBG("Render to RGB5 texture OK\n");     } +   else if (texImage->TexFormat == &_mesa_texformat_argb1555) { +      irb->Base._ActualFormat = GL_RGB5_A1; +      irb->Base._BaseFormat = GL_RGBA; +      irb->Base.DataType = GL_UNSIGNED_BYTE; +      DBG("Render to ARGB1555 texture OK\n"); +   } +   else if (texImage->TexFormat == &_mesa_texformat_argb4444) { +      irb->Base._ActualFormat = GL_RGBA4; +      irb->Base._BaseFormat = GL_RGBA; +      irb->Base.DataType = GL_UNSIGNED_BYTE; +      DBG("Render to ARGB4444 texture OK\n"); +   }     else if (texImage->TexFormat == &_mesa_texformat_z16) {        irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;        irb->Base._BaseFormat = GL_DEPTH_COMPONENT; @@ -631,11 +659,11 @@ intel_finish_render_texture(GLcontext * ctx,  static void  intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)  { -   struct intel_context *intel = intel_context(ctx);     const struct intel_renderbuffer *depthRb =        intel_get_renderbuffer(fb, BUFFER_DEPTH);     const struct intel_renderbuffer *stencilRb =        intel_get_renderbuffer(fb, BUFFER_STENCIL); +   int i;     if (stencilRb && stencilRb != depthRb) {        /* we only support combined depth/stencil buffers, not separate @@ -644,32 +672,21 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)        fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;     } -   /* check that texture color buffers are a format we can render into */ -   { -      const struct gl_texture_format *supportedFormat; -      GLuint i; - -      /* The texture format we can render into seems to depend on the -       * screen depth.  There currently seems to be a problem when -       * rendering into a rgb565 texture when the screen is abgr8888. -       */ +   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { +      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; +      struct intel_renderbuffer *irb = intel_renderbuffer(rb); -      if (intel->ctx.Visual.rgbBits >= 24) -         supportedFormat = &_mesa_texformat_argb8888; -      else  -         supportedFormat = &_mesa_texformat_rgb565; +      if (rb == NULL) +	 continue; -      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { -         const struct gl_texture_object *texObj = -            fb->Attachment[BUFFER_COLOR0 + i].Texture; -         if (texObj) { -            const struct gl_texture_image *texImg = -               texObj->Image[0][texObj->BaseLevel]; -            if (texImg && texImg->TexFormat != supportedFormat) { -               fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; -               break; -            } -         } +      switch (irb->texformat->MesaFormat) { +      case MESA_FORMAT_ARGB8888: +      case MESA_FORMAT_RGB565: +      case MESA_FORMAT_ARGB1555: +      case MESA_FORMAT_ARGB4444: +	 break; +      default: +	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;        }     }  } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index 7226ee026f..f0665af482 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -61,6 +61,8 @@ struct intel_renderbuffer     struct gl_renderbuffer Base;     struct intel_region *region; +   const struct gl_texture_format *texformat; +     GLuint vbl_pending;   /**< vblank sequence number of pending flip */     uint8_t *span_cache; diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index c3a873f1ab..34b78ebc1a 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -29,6 +29,7 @@  #include "main/macros.h"  #include "main/mtypes.h"  #include "main/colormac.h" +#include "main/texformat.h"  #include "intel_buffers.h"  #include "intel_fbo.h" @@ -313,6 +314,22 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,  #define INTEL_TAG(x) x##_RGB565  #include "intel_spantmp.h" +/* a4r4g4b4 color span and pixel functions */ +#define INTEL_PIXEL_FMT GL_BGRA +#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV +#define INTEL_READ_VALUE(offset) pread_16(irb, offset) +#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v) +#define INTEL_TAG(x) x##_ARGB4444 +#include "intel_spantmp.h" + +/* a1r5g5b5 color span and pixel functions */ +#define INTEL_PIXEL_FMT GL_BGRA +#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV +#define INTEL_READ_VALUE(offset) pread_16(irb, offset) +#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v) +#define INTEL_TAG(x) x##_ARGB1555 +#include "intel_spantmp.h" +  /* a8r8g8b8 color span and pixel functions */  #define INTEL_PIXEL_FMT GL_BGRA  #define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV @@ -561,8 +578,8 @@ intel_set_span_functions(struct intel_context *intel,     else        tiling = I915_TILING_NONE; -   if (rb->_ActualFormat == GL_RGB5) { -      /* 565 RGB */ +   switch (irb->texformat->MesaFormat) { +   case MESA_FORMAT_RGB565:        switch (tiling) {        case I915_TILING_NONE:        default: @@ -575,38 +592,67 @@ intel_set_span_functions(struct intel_context *intel,  	 intel_YTile_InitPointers_RGB565(rb);  	 break;        } -   } -   else if (rb->_ActualFormat == GL_RGB8) { -      /* 8888 RGBx */ +      break; +   case MESA_FORMAT_ARGB4444:        switch (tiling) {        case I915_TILING_NONE:        default: -	 intelInitPointers_xRGB8888(rb); +	 intelInitPointers_ARGB4444(rb);  	 break;        case I915_TILING_X: -	 intel_XTile_InitPointers_xRGB8888(rb); +	 intel_XTile_InitPointers_ARGB4444(rb);  	 break;        case I915_TILING_Y: -	 intel_YTile_InitPointers_xRGB8888(rb); +	 intel_YTile_InitPointers_ARGB4444(rb);  	 break;        } -   } -   else if (rb->_ActualFormat == GL_RGBA8) { -      /* 8888 RGBA */ +      break; +   case MESA_FORMAT_ARGB1555:        switch (tiling) {        case I915_TILING_NONE:        default: -	 intelInitPointers_ARGB8888(rb); +	 intelInitPointers_ARGB1555(rb);  	 break;        case I915_TILING_X: -	 intel_XTile_InitPointers_ARGB8888(rb); +	 intel_XTile_InitPointers_ARGB1555(rb);  	 break;        case I915_TILING_Y: -	 intel_YTile_InitPointers_ARGB8888(rb); +	 intel_YTile_InitPointers_ARGB1555(rb);  	 break;        } -   } -   else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { +      break; +   case MESA_FORMAT_ARGB8888: +      if (rb->AlphaBits == 0) { /* XXX: Need xRGB8888 Mesa format */ +	 /* 8888 RGBx */ +	 switch (tiling) { +	 case I915_TILING_NONE: +	 default: +	    intelInitPointers_xRGB8888(rb); +	    break; +	 case I915_TILING_X: +	    intel_XTile_InitPointers_xRGB8888(rb); +	    break; +	 case I915_TILING_Y: +	    intel_YTile_InitPointers_xRGB8888(rb); +	    break; +	 } +      } else { +	 /* 8888 RGBA */ +	 switch (tiling) { +	 case I915_TILING_NONE: +	 default: +	    intelInitPointers_ARGB8888(rb); +	    break; +	 case I915_TILING_X: +	    intel_XTile_InitPointers_ARGB8888(rb); +	    break; +	 case I915_TILING_Y: +	    intel_YTile_InitPointers_ARGB8888(rb); +	    break; +	 } +      } +      break; +   case MESA_FORMAT_Z16:        switch (tiling) {        case I915_TILING_NONE:        default: @@ -619,51 +665,57 @@ intel_set_span_functions(struct intel_context *intel,  	 intel_YTile_InitDepthPointers_z16(rb);  	 break;        } -   } -   else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) { -      switch (tiling) { -      case I915_TILING_NONE: -      default: -	 intelInitDepthPointers_z24(rb); -	 break; -      case I915_TILING_X: -	 intel_XTile_InitDepthPointers_z24(rb); -	 break; -      case I915_TILING_Y: -	 intel_YTile_InitDepthPointers_z24(rb); -	 break; -      } -   } -   else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { -      switch (tiling) { -      case I915_TILING_NONE: -      default: -	 intelInitDepthPointers_z24_s8(rb); -	 break; -      case I915_TILING_X: -	 intel_XTile_InitDepthPointers_z24_s8(rb); -	 break; -      case I915_TILING_Y: -	 intel_YTile_InitDepthPointers_z24_s8(rb); -	 break; -      } -   } -   else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { -      switch (tiling) { -      case I915_TILING_NONE: -      default: -	 intelInitStencilPointers_z24_s8(rb); -	 break; -      case I915_TILING_X: -	 intel_XTile_InitStencilPointers_z24_s8(rb); -	 break; -      case I915_TILING_Y: -	 intel_YTile_InitStencilPointers_z24_s8(rb); -	 break; +      break; +   case MESA_FORMAT_S8_Z24: +      /* There are a few different ways SW asks us to access the S8Z24 data: +       * Z24 depth-only depth reads +       * S8Z24 depth reads +       * S8Z24 stencil reads. +       */ +      if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) { +	 switch (tiling) { +	 case I915_TILING_NONE: +	 default: +	    intelInitDepthPointers_z24(rb); +	    break; +	 case I915_TILING_X: +	    intel_XTile_InitDepthPointers_z24(rb); +	    break; +	 case I915_TILING_Y: +	    intel_YTile_InitDepthPointers_z24(rb); +	    break; +	 } +      } else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { +	 switch (tiling) { +	 case I915_TILING_NONE: +	 default: +	    intelInitDepthPointers_z24_s8(rb); +	    break; +	 case I915_TILING_X: +	    intel_XTile_InitDepthPointers_z24_s8(rb); +	    break; +	 case I915_TILING_Y: +	    intel_YTile_InitDepthPointers_z24_s8(rb); +	    break; +	 } +      } else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { +	 switch (tiling) { +	 case I915_TILING_NONE: +	 default: +	    intelInitStencilPointers_z24_s8(rb); +	    break; +	 case I915_TILING_X: +	    intel_XTile_InitStencilPointers_z24_s8(rb); +	    break; +	 case I915_TILING_Y: +	    intel_YTile_InitStencilPointers_z24_s8(rb); +	    break; +	 }        } -   } -   else { +      break; +   default:        _mesa_problem(NULL, -                    "Unexpected _ActualFormat in intelSetSpanFunctions"); +                    "Unexpected MesaFormat in intelSetSpanFunctions"); +      break;     }  } diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 71561cf85c..1f192dafbe 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -315,8 +315,8 @@ intelTexImage(GLcontext * ctx,     GLint postConvWidth = width;     GLint postConvHeight = height;     GLint texelBytes, sizeInBytes; -   GLuint dstRowStride, srcRowStride = texImage->RowStride; - +   GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; +   GLboolean needs_map;     DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,         _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); @@ -482,8 +482,15 @@ intelTexImage(GLcontext * ctx,     LOCK_HARDWARE(intel); +   /* Two cases where we need a mapping of the miptree: when the user supplied +    * data is mapped as well (non-PBO, memcpy upload) or when we're going to do +    * (software) mipmap generation. +    */ +   needs_map = (pixels != NULL) || (level == texObj->BaseLevel && +				  texObj->GenerateMipmap); +     if (intelImage->mt) { -      if (pixels) +      if (needs_map)           texImage->Data = intel_miptree_image_map(intel,                                                    intelImage->mt,                                                    intelImage->face, @@ -509,8 +516,9 @@ intelTexImage(GLcontext * ctx,     }     DBG("Upload image %dx%dx%d row_len %d " -       "pitch %d\n", -       width, height, depth, width * texelBytes, dstRowStride); +       "pitch %d pixels %d compressed %d\n", +       width, height, depth, width * texelBytes, dstRowStride, +       pixels ? 1 : 0, compressed);     /* Copy data.  Would like to know when it's ok for us to eg. use      * the blitter to copy.  Or, use the hardware to do the format @@ -523,7 +531,7 @@ intelTexImage(GLcontext * ctx,  	       _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,  			       0, 0,  			       intelImage->mt->level[level].width, -			       intelImage->mt->level[level].height/4, +			       (intelImage->mt->level[level].height+3)/4,  			       pixels,  			       srcRowStride,  			       0, 0); @@ -549,7 +557,7 @@ intelTexImage(GLcontext * ctx,     _mesa_unmap_teximage_pbo(ctx, unpack);     if (intelImage->mt) { -      if (pixels) +      if (needs_map)           intel_miptree_image_unmap(intel, intelImage->mt);        texImage->Data = NULL;     } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index d5d0a552db..e43fa96dd3 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1265,7 +1265,7 @@ _mesa_PopAttrib(void)                 /* restore clip planes */                 for (i = 0; i < MAX_CLIP_PLANES; i++) { -                  const GLuint mask = 1 << 1; +                  const GLuint mask = 1 << i;                    const GLfloat *eyePlane = xform->EyeUserPlane[i];                    COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);                    if (xform->ClipPlanesEnabled & mask) { diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index cc37d63636..4f9088dd22 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -470,7 +470,8 @@ _mesa_update_state_locked( GLcontext *ctx )     /* Determine which state flags effect vertex/fragment program state */     if (ctx->FragmentProgram._MaintainTexEnvProgram) { -      prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); +      prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR | +		     _NEW_ARRAY);     }     if (ctx->VertexProgram._MaintainTnlProgram) {        prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index d17e18da6b..a1c0f18f36 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -205,7 +205,7 @@ texstore_rgb_dxt1(TEXSTORE_PARAMS)                                dst, dstRowStride);     }     else { -      _mesa_warning(ctx, "external dxt library not available"); +      _mesa_warning(ctx, "external dxt library not available: texstore_rgb_dxt1");     }     if (tempImage) @@ -267,7 +267,7 @@ texstore_rgba_dxt1(TEXSTORE_PARAMS)                                dst, dstRowStride);     }     else { -      _mesa_warning(ctx, "external dxt library not available"); +      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt1");     }     if (tempImage) @@ -328,7 +328,7 @@ texstore_rgba_dxt3(TEXSTORE_PARAMS)                                dst, dstRowStride);     }     else { -      _mesa_warning(ctx, "external dxt library not available"); +      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt3");     }     if (tempImage) @@ -389,7 +389,7 @@ texstore_rgba_dxt5(TEXSTORE_PARAMS)                                dst, dstRowStride);     }     else { -      _mesa_warning(ctx, "external dxt library not available"); +      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt5");     }     if (tempImage) @@ -410,7 +410,7 @@ fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage,                           (GLubyte *)(texImage)->Data, i, j, texel);     }     else -      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); +      _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgb_dxt1");  } @@ -438,7 +438,7 @@ fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage,                            (GLubyte *)(texImage)->Data, i, j, texel);     }     else -      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); +      _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt1\n");  } @@ -467,7 +467,7 @@ fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage,                            i, j, texel);     }     else -      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); +      _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt3\n");  } @@ -495,7 +495,7 @@ fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage,                            i, j, texel);     }     else -      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); +      _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt5\n");  } diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 3f9a825a15..1510a1e236 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -40,6 +40,7 @@  #include "st_draw.h"  #include "st_public.h"  #include "st_format.h" +#include "st_texture.h"  #include "pipe/p_context.h"  #include "pipe/p_defines.h"  #include "pipe/p_inlines.h" @@ -118,6 +119,9 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)     const GLint height = ctx->DrawBuffer->_Ymax - ypos;     GLubyte *map; +   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, +				PIPE_TRANSFER_WRITE); +     acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,                                       PIPE_TRANSFER_WRITE, xpos, ypos,                                       width, height); @@ -163,6 +167,9 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,     struct pipe_transfer *acc_pt;     GLubyte *map; +   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, +				PIPE_TRANSFER_READ_WRITE); +     acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,                                       PIPE_TRANSFER_READ_WRITE, xpos, ypos,                                       width, height); @@ -192,20 +199,27 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,  static void -accum_accum(struct pipe_context *pipe, GLfloat value, +accum_accum(struct st_context *st, GLfloat value,              GLint xpos, GLint ypos, GLint width, GLint height,              struct st_renderbuffer *acc_strb,              struct st_renderbuffer *color_strb)  { +   struct pipe_context *pipe = st->pipe;     struct pipe_screen *screen = pipe->screen;     struct pipe_transfer *acc_trans, *color_trans;     GLfloat *colorBuf, *accBuf;     GLint i; +   st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,                                          PIPE_TRANSFER_READ, xpos, ypos,                                          width, height); +   st_teximage_flush_before_map(st, color_strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,                                            PIPE_TRANSFER_READ, xpos, ypos,                                            width, height); @@ -235,20 +249,27 @@ accum_accum(struct pipe_context *pipe, GLfloat value,  static void -accum_load(struct pipe_context *pipe, GLfloat value, +accum_load(struct st_context *st, GLfloat value,             GLint xpos, GLint ypos, GLint width, GLint height,             struct st_renderbuffer *acc_strb,             struct st_renderbuffer *color_strb)  { +   struct pipe_context *pipe = st->pipe;     struct pipe_screen *screen = pipe->screen;     struct pipe_transfer *acc_trans, *color_trans;     GLfloat *buf;     GLint i; +   st_teximage_flush_before_map(st, acc_strb->texture, 0, 0, +				PIPE_TRANSFER_WRITE); +     acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,                                          PIPE_TRANSFER_WRITE, xpos, ypos,                                          width, height); +   st_teximage_flush_before_map(st, color_strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,                                          PIPE_TRANSFER_READ, xpos, ypos,                                          width, height); @@ -284,10 +305,16 @@ accum_return(GLcontext *ctx, GLfloat value,     abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); +   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,                                          PIPE_TRANSFER_READ, xpos, ypos,                                          width, height); +   st_teximage_flush_before_map(ctx->st, color_strb->texture, 0, 0, +				PIPE_TRANSFER_READ_WRITE); +     color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,                                            PIPE_TRANSFER_READ_WRITE, xpos, ypos,                                            width, height); @@ -325,7 +352,6 @@ static void  st_Accum(GLcontext *ctx, GLenum op, GLfloat value)  {     struct st_context *st = ctx->st; -   struct pipe_context *pipe = st->pipe;     struct st_renderbuffer *acc_strb       = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);     struct st_renderbuffer *color_strb @@ -352,11 +378,11 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)        break;     case GL_ACCUM:        if (value != 0.0F) { -         accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); +         accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb);        }        break;     case GL_LOAD: -      accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); +      accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb);        break;     case GL_RETURN:        accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb); diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 3651e4ae7d..fdb800fbd0 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -32,6 +32,7 @@  #include "st_context.h"  #include "st_cb_bufferobjects.h" +#include "st_public.h"  #include "pipe/p_context.h"  #include "pipe/p_defines.h" @@ -103,6 +104,9 @@ st_bufferobj_subdata(GLcontext *ctx,     if (offset >= st_obj->size || size > (st_obj->size - offset))        return; +   if (pipe->is_buffer_referenced(pipe, st_obj->buffer)) +      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); +     pipe_buffer_write(pipe->screen, st_obj->buffer, offset, size, data);  } @@ -123,6 +127,10 @@ st_bufferobj_get_subdata(GLcontext *ctx,     if (offset >= st_obj->size || size > (st_obj->size - offset))        return; +   if (pipe->is_buffer_referenced(pipe, st_obj->buffer) & +       PIPE_REFERENCED_FOR_WRITE) +      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); +     pipe_buffer_read(pipe->screen, st_obj->buffer, offset, size, data);  } @@ -171,7 +179,7 @@ st_bufferobj_data(GLcontext *ctx,     st_obj->size = size;     if (data) -      st_bufferobj_subdata(ctx, target, 0, size, data, obj); +      pipe_buffer_write(pipe->screen, st_obj->buffer, 0, size, data);  } @@ -185,6 +193,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,     struct pipe_context *pipe = st_context(ctx)->pipe;     struct st_buffer_object *st_obj = st_buffer_object(obj);     GLuint flags; +   unsigned referenced;     switch (access) {     case GL_WRITE_ONLY: @@ -200,6 +209,11 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,        break;           } +   referenced = pipe->is_buffer_referenced(pipe, st_obj->buffer); +   if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || +		      (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) +      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL); +     obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags);     if(obj->Pointer) {        obj->Offset = 0; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 0a4430501f..c67b026413 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -631,8 +631,6 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,     GLint skipPixels;     ubyte *stmap; -   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); -     strb = st_renderbuffer(ctx->DrawBuffer->                            Attachment[BUFFER_STENCIL].Renderbuffer); @@ -640,6 +638,9 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,        y = ctx->DrawBuffer->Height - y - height;     } +   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, +				PIPE_TRANSFER_WRITE); +     pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,                                   PIPE_TRANSFER_WRITE, x, y,                                   width, height); @@ -825,6 +826,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,                            GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,                            &ctx->DefaultPacking, buffer); +   st_teximage_flush_before_map(ctx->st, rbDraw->texture, 0, 0, +				PIPE_TRANSFER_WRITE); +     ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0,                                       PIPE_TRANSFER_WRITE, dstx, dsty,                                       width, height); diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 9ce5f3fe84..519ad6660f 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -42,13 +42,14 @@  #include "pipe/p_defines.h"  #include "pipe/p_inlines.h"  #include "util/u_tile.h" +  #include "st_context.h"  #include "st_cb_bitmap.h"  #include "st_cb_readpixels.h"  #include "st_cb_fbo.h"  #include "st_format.h"  #include "st_public.h" - +#include "st_texture.h"  /**   * Special case for reading stencil buffer. @@ -73,6 +74,10 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,     }     /* Create a read transfer from the renderbuffer's texture */ + +   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     pt = screen->get_tex_transfer(screen, strb->texture,  0, 0, 0,                                   PIPE_TRANSFER_READ, x, y, width, height); @@ -240,6 +245,9 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,           y = strb->texture->height[0] - y - height;        } +      st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, +				   PIPE_TRANSFER_READ); +        trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,                                         PIPE_TRANSFER_READ, x, y, width, height);        if (!trans) { diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 1f14b3705d..98dc6ec74d 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -26,6 +26,7 @@   **************************************************************************/  #include "main/mfeatures.h" +#include "main/bufferobj.h"  #if FEATURE_convolve  #include "main/convolve.h"  #endif @@ -55,6 +56,7 @@  #include "pipe/p_inlines.h"  #include "util/u_tile.h"  #include "util/u_blit.h" +#include "util/u_surface.h"  #define DBG if (0) printf @@ -110,6 +112,25 @@ compressed_num_bytes(GLuint mesaFormat)  } +static GLboolean +is_compressed_mesa_format(const struct gl_texture_format *format) +{ +   switch (format->MesaFormat) { +   case MESA_FORMAT_RGB_DXT1: +   case MESA_FORMAT_RGBA_DXT1: +   case MESA_FORMAT_RGBA_DXT3: +   case MESA_FORMAT_RGBA_DXT5: +   case MESA_FORMAT_SRGB_DXT1: +   case MESA_FORMAT_SRGBA_DXT1: +   case MESA_FORMAT_SRGBA_DXT3: +   case MESA_FORMAT_SRGBA_DXT5: +      return GL_TRUE; +   default: +      return GL_FALSE; +   } +} + +  /** called via ctx->Driver.NewTextureImage() */  static struct gl_texture_image *  st_NewTextureImage(GLcontext * ctx) @@ -379,6 +400,110 @@ strip_texture_border(GLint border,  /** + * Try to do texture compression via rendering.  If the Gallium driver + * can render into a compressed surface this will allow us to do texture + * compression. + * \return GL_TRUE for success, GL_FALSE for failure + */ +static GLboolean +compress_with_blit(GLcontext * ctx, +                   GLenum target, GLint level, +                   GLint xoffset, GLint yoffset, GLint zoffset, +                   GLint width, GLint height, GLint depth, +                   GLenum format, GLenum type, const void *pixels, +                   const struct gl_pixelstore_attrib *unpack, +                   struct gl_texture_image *texImage) +{ +   const GLuint dstImageOffsets[1] = {0}; +   struct st_texture_image *stImage = st_texture_image(texImage); +   struct pipe_screen *screen = ctx->st->pipe->screen; +   const GLuint face = _mesa_tex_target_to_face(target); +   const struct gl_texture_format *mesa_format; +   struct pipe_texture templ; +   struct pipe_texture *src_tex; +   struct pipe_surface *dst_surface; +   struct pipe_transfer *tex_xfer; +   void *map; + + +   if (!stImage->pt) { +      /* XXX: Can this happen? Should we assert? */ +      return GL_FALSE; +   } + +   /* get destination surface (in the compressed texture) */ +   dst_surface = screen->get_tex_surface(screen, stImage->pt, +                                         stImage->face, stImage->level, 0, +                                         PIPE_BUFFER_USAGE_GPU_WRITE); +   if (!dst_surface) { +      /* can't render into this format (or other problem) */ +      return GL_FALSE; +   } + +   /* Choose format for the temporary RGBA texture image. +    */ +   mesa_format = st_ChooseTextureFormat(ctx, GL_RGBA, format, type); +   assert(mesa_format); +   if (!mesa_format) +      return GL_FALSE; + +   /* Create the temporary source texture +    */ +   memset(&templ, 0, sizeof(templ)); +   templ.target = PIPE_TEXTURE_2D; +   templ.format = st_mesa_format_to_pipe_format(mesa_format->MesaFormat); +   pf_get_block(templ.format, &templ.block); +   templ.width[0] = width; +   templ.height[0] = height; +   templ.depth[0] = 1; +   templ.last_level = 0; +   templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; +   src_tex = screen->texture_create(screen, &templ); + +   if (!src_tex) +      return GL_FALSE; + +   /* Put user's tex data into the temporary texture +    */ +   tex_xfer = screen->get_tex_transfer(screen, src_tex, +                                       face, level, 0, +                                       PIPE_TRANSFER_WRITE, +                                       0, 0, width, height); /* x, y, w, h */ +   map = screen->transfer_map(screen, tex_xfer); + +   mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format, +                           map,              /* dest ptr */ +                           0, 0, 0,          /* dest x/y/z offset */ +                           tex_xfer->stride, /* dest row stride (bytes) */ +                           dstImageOffsets,  /* image offsets (for 3D only) */ +                           width, height, 1, /* size */ +                           format, type,     /* source format/type */ +                           pixels,           /* source data */ +                           unpack);          /* source data packing */ + +   screen->transfer_unmap(screen, tex_xfer); +   screen->tex_transfer_destroy(tex_xfer); + +   /* copy / compress image */ +   util_blit_pixels_tex(ctx->st->blit, +                        src_tex,          /* pipe_texture (src) */ +                        0, 0,             /* src x0, y0 */ +                        width, height,    /* src x1, y1 */ +                        dst_surface,      /* pipe_surface (dst) */ +                        xoffset, yoffset, /* dst x0, y0 */ +                        xoffset + width,  /* dst x1 */ +                        yoffset + height, /* dst y1 */ +                        0.0,              /* z */ +                        PIPE_TEX_MIPFILTER_NEAREST); + +   pipe_surface_reference(&dst_surface, NULL); +   pipe_texture_reference(&src_tex, NULL); + +   return GL_TRUE; +} + + +/**   * Do glTexImage1/2/3D().   */  static void @@ -392,8 +517,9 @@ st_TexImage(GLcontext * ctx,              const struct gl_pixelstore_attrib *unpack,              struct gl_texture_object *texObj,              struct gl_texture_image *texImage, -            GLsizei imageSize, GLboolean compressed) +            GLsizei imageSize, GLboolean compressed_src)  { +   struct pipe_screen *screen = ctx->st->pipe->screen;     struct st_texture_object *stObj = st_texture_object(texObj);     struct st_texture_image *stImage = st_texture_image(texImage);     GLint postConvWidth, postConvHeight; @@ -522,7 +648,7 @@ st_TexImage(GLcontext * ctx,      * the expectation that the texture will be set up but nothing      * more will be done.  This is where those calls return:      */ -   if (compressed) { +   if (compressed_src) {        pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,  						      unpack,  						      "glCompressedTexImage"); @@ -535,6 +661,21 @@ st_TexImage(GLcontext * ctx,     if (!pixels)        return; +   /* See if we can do texture compression with a blit/render. +    */ +   if (!compressed_src && +       !ctx->Mesa_DXTn && +       is_compressed_mesa_format(texImage->TexFormat) && +       screen->is_format_supported(screen, +                                   stImage->pt->format, +                                   stImage->pt->target, +                                   PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { +      if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth, +                             format, type, pixels, unpack, texImage)) { +         return; +      } +   } +     if (stImage->pt) {        texImage->Data = st_texture_image_map(ctx->st, stImage, 0,                                              PIPE_TRANSFER_WRITE, 0, 0, @@ -570,7 +711,7 @@ st_TexImage(GLcontext * ctx,      * the blitter to copy.  Or, use the hardware to do the format      * conversion and copy:      */ -   if (compressed) { +   if (compressed_src) {        memcpy(texImage->Data, pixels, imageSize);     }     else { @@ -607,7 +748,7 @@ st_TexImage(GLcontext * ctx,     _mesa_unmap_teximage_pbo(ctx, unpack); -   if (stImage->pt) { +   if (stImage->pt && texImage->Data) {        st_texture_image_unmap(ctx->st, stImage);        texImage->Data = NULL;     } @@ -678,6 +819,90 @@ st_CompressedTexImage2D(GLcontext *ctx, GLenum target, GLint level,  } + +/** + * glGetTexImage() helper: decompress a compressed texture by rendering + * a textured quad.  Store the results in the user's buffer. + */ +static void +decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, +                     GLenum format, GLenum type, GLvoid *pixels, +                     struct gl_texture_object *texObj, +                     struct gl_texture_image *texImage) +{ +   struct pipe_screen *screen = ctx->st->pipe->screen; +   struct st_texture_image *stImage = st_texture_image(texImage); +   const GLuint width = texImage->Width; +   const GLuint height = texImage->Height; +   struct pipe_surface *dst_surface; +   struct pipe_texture *dst_texture; +   struct pipe_transfer *tex_xfer; + +   /* create temp / dest surface */ +   if (!util_create_rgba_surface(screen, width, height, +                                 &dst_texture, &dst_surface)) { +      _mesa_problem(ctx, "util_create_rgba_surface() failed " +                    "in decompress_with_blit()"); +      return; +   } + +   /* blit/render/decompress */ +   util_blit_pixels_tex(ctx->st->blit, +                        stImage->pt,      /* pipe_texture (src) */ +                        0, 0,             /* src x0, y0 */ +                        width, height,    /* src x1, y1 */ +                        dst_surface,      /* pipe_surface (dst) */ +                        0, 0,             /* dst x0, y0 */ +                        width, height,    /* dst x1, y1 */ +                        0.0,              /* z */ +                        PIPE_TEX_MIPFILTER_NEAREST); + +   /* map the dst_surface so we can read from it */ +   tex_xfer = screen->get_tex_transfer(screen, dst_texture, 0, 0, 0, +                                       PIPE_TRANSFER_READ, +                                       0, 0, width, height); + +   pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels); + +   /* copy/pack data into user buffer */ +   if (st_equal_formats(stImage->pt->format, format, type)) { +      /* memcpy */ +      const uint bytesPerRow = width * pf_get_size(stImage->pt->format); +      ubyte *map = screen->transfer_map(screen, tex_xfer); +      GLuint row; +      for (row = 0; row < height; row++) { +         GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, +                                              height, format, type, row, 0); +         memcpy(dest, map, bytesPerRow); +         map += tex_xfer->stride; +      } +      screen->transfer_unmap(screen, tex_xfer); +   } +   else { +      /* format translation via floats */ +      GLuint row; +      for (row = 0; row < height; row++) { +         const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ +         GLfloat rgba[4 * MAX_WIDTH]; +         GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, +                                              height, format, type, row, 0); + +         /* get float[4] rgba row from surface */ +         pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba); + +         _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, +                                    type, dest, &ctx->Pack, transferOps); +      } +   } + +   _mesa_unmap_readpix_pbo(ctx, &ctx->Pack); + +   /* destroy the temp / dest surface */ +   util_destroy_rgba_surface(dst_texture, dst_surface); +} + + +  /**   * Need to map texture image into memory before copying image data,   * then unmap it. @@ -686,7 +911,7 @@ static void  st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,                   GLenum format, GLenum type, GLvoid * pixels,                   struct gl_texture_object *texObj, -                 struct gl_texture_image *texImage, GLboolean compressed) +                 struct gl_texture_image *texImage, GLboolean compressed_dst)  {     struct st_texture_image *stImage = st_texture_image(texImage);     const GLuint dstImageStride = @@ -695,11 +920,27 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,     GLuint depth, i;     GLubyte *dest; +   if (stImage->pt && +       pf_is_compressed(stImage->pt->format) && +       !compressed_dst) { +      /* Need to decompress the texture. +       * We'll do this by rendering a textured quad. +       * Note that we only expect RGBA formats (no Z/depth formats). +       */ +      decompress_with_blit(ctx, target, level, format, type, pixels, +                           texObj, texImage); +      return; +   } +     /* Map */     if (stImage->pt) {        /* Image is stored in hardware format in a buffer managed by the         * kernel.  Need to explicitly map and unmap it.         */ + +      st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, +				   PIPE_TRANSFER_READ); +        texImage->Data = st_texture_image_map(ctx->st, stImage, 0,                                              PIPE_TRANSFER_READ, 0, 0,                                              stImage->base.Width, @@ -724,7 +965,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,     dest = (GLubyte *) pixels;     for (i = 0; i < depth; i++) { -      if (compressed) { +      if (compressed_dst) {  	 _mesa_get_compressed_teximage(ctx, target, level, dest,  				       texObj, texImage);        } @@ -787,6 +1028,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,                 struct gl_texture_object *texObj,                 struct gl_texture_image *texImage)  { +   struct pipe_screen *screen = ctx->st->pipe->screen;     struct st_texture_image *stImage = st_texture_image(texImage);     GLuint dstRowStride;     const GLuint srcImageStride = @@ -804,10 +1046,28 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,     if (!pixels)        return; +   /* See if we can do texture compression with a blit/render. +    */ +   if (!ctx->Mesa_DXTn && +       is_compressed_mesa_format(texImage->TexFormat) && +       screen->is_format_supported(screen, +                                   stImage->pt->format, +                                   stImage->pt->target, +                                   PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { +      if (compress_with_blit(ctx, target, level, +                             xoffset, yoffset, zoffset, +                             width, height, depth, +                             format, type, pixels, packing, texImage)) { +         return; +      } +   } +     /* Map buffer if necessary.  Need to lock to prevent other contexts      * from uploading the buffer under us.      */     if (stImage->pt) { +      st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level, +				   PIPE_TRANSFER_WRITE);        texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,                                               PIPE_TRANSFER_WRITE,                                              xoffset, yoffset, @@ -932,6 +1192,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,        srcY = strb->Base.Height - srcY - height;     } +   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0, +				PIPE_TRANSFER_READ); +     src_trans = screen->get_tex_transfer( screen,                                           strb->texture,                                           0, 0, 0, @@ -939,6 +1202,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,                                           srcX, srcY,                                           width, height); +   st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0, +				PIPE_TRANSFER_WRITE); +     texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE,                                    destX, destY, width, height); @@ -1318,6 +1584,11 @@ copy_image_data_to_texture(struct st_context *st,        /* More straightforward upload.           */ + +      st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel, +				   PIPE_TRANSFER_WRITE); + +        st_texture_image_data(st->pipe,                              stObj->pt,                              stImage->face, diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 9e2d60c926..d507e3e58d 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -716,3 +716,23 @@ st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,     return translate_gallium_format_to_mesa_format(pFormat);  } + + +/** + * Test if a gallium format is equivalent to a GL format/type. + */ +GLboolean +st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type) +{ +   switch (pFormat) { +   case PIPE_FORMAT_R8G8B8A8_UNORM: +      return format == GL_RGBA && type == GL_UNSIGNED_BYTE; +   case PIPE_FORMAT_B8G8R8A8_UNORM: +      return format == GL_BGRA && type == GL_UNSIGNED_BYTE; +   case PIPE_FORMAT_R5G6B5_UNORM: +      return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5; +   /* XXX more combos... */ +   default: +      return GL_FALSE; +   } +} diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 3f5ac3201b..7bbbe2d570 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -76,4 +76,8 @@ st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat,                         GLenum format, GLenum type); +extern GLboolean +st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type); + +  #endif /* ST_CB_TEXIMAGE_H */ diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 9cc2176d5e..6e9aa5245e 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -123,10 +123,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,        const ubyte *srcData;        ubyte *dstData; +      st_teximage_flush_before_map(ctx->st, pt, face, srcLevel, +				   PIPE_TRANSFER_READ); +        srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,                                            PIPE_TRANSFER_READ, 0, 0,                                            pt->width[srcLevel],                                            pt->height[srcLevel]); + +      st_teximage_flush_before_map(ctx->st, pt, face, dstLevel, +				   PIPE_TRANSFER_WRITE); +        dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,                                            PIPE_TRANSFER_WRITE, 0, 0,                                            pt->width[dstLevel], diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6348e83d8a..2795570cf1 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -484,14 +484,14 @@ st_translate_fragment_program(struct st_context *st,                 /* handled above */                 assert(0);                 break; -            case FRAG_RESULT_COLOR: +            default: +               assert(attr == FRAG_RESULT_COLOR || +                      (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));                 fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;                 fs_output_semantic_index[fs_num_outputs] = numColors;                 outputMapping[attr] = fs_num_outputs;                 numColors++;                 break; -            default: -               assert(0);              }              output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr]; diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 19eb7e2f69..fcbaeb6989 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -188,8 +188,10 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,  		     GLuint zoffset, enum pipe_transfer_usage usage,                       GLuint x, GLuint y, GLuint w, GLuint h)  { -   struct pipe_screen *screen = st->pipe->screen; +   struct pipe_context *pipe = st->pipe; +   struct pipe_screen *screen = pipe->screen;     struct pipe_texture *pt = stImage->pt; +     DBG("%s \n", __FUNCTION__);     stImage->transfer = screen->get_tex_transfer(screen, pt, stImage->face, @@ -265,6 +267,7 @@ st_texture_image_data(struct pipe_context *pipe,     struct pipe_transfer *dst_transfer;     DBG("%s\n", __FUNCTION__); +     for (i = 0; i < depth; i++) {        dst_transfer = screen->get_tex_transfer(screen, dst, face, level, i,                                                PIPE_TRANSFER_WRITE, 0, 0, @@ -481,3 +484,20 @@ st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,     return 1;  } + +void +st_teximage_flush_before_map(struct st_context *st, +			     struct pipe_texture *pt, +			     unsigned int face, +			     unsigned int level, +			     enum pipe_transfer_usage usage) +{ +   struct pipe_context *pipe = st->pipe; +   unsigned referenced = +      pipe->is_texture_referenced(pipe, pt, face, level); + +   if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || +		      usage == PIPE_TRANSFER_WRITE || +		      usage == PIPE_TRANSFER_READ_WRITE)) +      st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); +} diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 60c000115e..a392e3d57c 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -170,5 +170,10 @@ st_texture_image_copy(struct pipe_context *pipe,                        struct pipe_texture *src,                        GLuint face); - +extern void +st_teximage_flush_before_map(struct st_context *st, +			     struct pipe_texture *pt, +			     unsigned int face, +			     unsigned int level, +			     enum pipe_transfer_usage usage);  #endif diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 9558f83883..86bbd24f7b 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -64,6 +64,13 @@ struct vbo_save_vertex_list {     GLubyte attrsz[VBO_ATTRIB_MAX];     GLuint vertex_size; +   /* Copy of the final vertex from node->vertex_store->bufferobj. +    * Keep this in regular (non-VBO) memory to avoid repeated +    * map/unmap of the VBO when updating GL current data. +    */ +   GLfloat *current_data; +   GLuint current_size; +     GLuint buffer_offset;     GLuint count;     GLuint wrap_count;		/* number of copied vertices at start */ diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 52b6f1884e..868226075a 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -289,6 +289,31 @@ static void _save_compile_vertex_list( GLcontext *ctx )     node->vertex_store->refcount++;     node->prim_store->refcount++; + +   node->current_size = node->vertex_size - node->attrsz[0]; +   node->current_data = NULL; + +   if (node->current_size) { +      /* If the malloc fails, we just pull the data out of the VBO +       * later instead. +       */ +      node->current_data = MALLOC( node->current_size * sizeof(GLfloat) ); +      if (node->current_data) { +         const char *buffer = (const char *)save->vertex_store->buffer; +         unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat); +         unsigned vertex_offset = 0; + +         if (node->count) +            vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat); + +         memcpy( node->current_data, +                 buffer + node->buffer_offset + vertex_offset + attr_offset, +                 node->current_size * sizeof(GLfloat) ); +      } +   } + + +     assert(node->attrsz[VBO_ATTRIB_POS] != 0 ||  	  node->count == 0); diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index f59e1036d0..5110648c28 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -46,20 +46,31 @@ static void _playback_copy_to_current( GLcontext *ctx,  				       const struct vbo_save_vertex_list *node )  {     struct vbo_context *vbo = vbo_context(ctx); -   GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex; +   GLfloat vertex[VBO_ATTRIB_MAX * 4]; +   GLfloat *data;     GLuint i, offset; -   if (node->count) -      offset = (node->buffer_offset +  -		(node->count-1) * node->vertex_size * sizeof(GLfloat)); -   else -      offset = node->buffer_offset; +   if (node->current_size == 0) +      return; -   ctx->Driver.GetBufferSubData( ctx, 0, offset,  -				 node->vertex_size * sizeof(GLfloat),  -				 data, node->vertex_store->bufferobj ); +   if (node->current_data) { +      data = node->current_data; +   } +   else { +      data = vertex; + +      if (node->count) +         offset = (node->buffer_offset +  +                   (node->count-1) * node->vertex_size * sizeof(GLfloat)); +      else +         offset = node->buffer_offset; -   data += node->attrsz[0]; /* skip vertex position */ +      ctx->Driver.GetBufferSubData( ctx, 0, offset,  +                                    node->vertex_size * sizeof(GLfloat),  +                                    data, node->vertex_store->bufferobj ); + +      data += node->attrsz[0]; /* skip vertex position */ +   }     for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {        if (node->attrsz[i]) { | 
