diff options
Diffstat (limited to 'mesalib/src/mesa')
| -rw-r--r-- | mesalib/src/mesa/drivers/common/meta.c | 45 | ||||
| -rw-r--r-- | mesalib/src/mesa/drivers/common/meta.h | 34 | ||||
| -rw-r--r-- | mesalib/src/mesa/drivers/common/meta_blit.c | 177 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/arbprogram.c | 27 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_blit.c | 1 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_readpixels.c | 1 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 2 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 161 | 
8 files changed, 283 insertions, 165 deletions
| diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index b4c30564f..3ef3f7971 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -204,6 +204,31 @@ _mesa_meta_link_program_with_debug(struct gl_context *ctx, GLuint program)     return 0;  } +void +_mesa_meta_compile_and_link_program(struct gl_context *ctx, +                                    const char *vs_source, +                                    const char *fs_source, +                                    const char *name, +                                    GLuint *program) +{ +   GLuint vs = _mesa_meta_compile_shader_with_debug(ctx, GL_VERTEX_SHADER, +                                                    vs_source); +   GLuint fs = _mesa_meta_compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, +                                                    fs_source); + +   *program = _mesa_CreateProgram(); +   _mesa_AttachShader(*program, fs); +   _mesa_DeleteShader(fs); +   _mesa_AttachShader(*program, vs); +   _mesa_DeleteShader(vs); +   _mesa_BindAttribLocation(*program, 0, "position"); +   _mesa_BindAttribLocation(*program, 1, "texcoords"); +   _mesa_meta_link_program_with_debug(ctx, *program); +   _mesa_ObjectLabel(GL_PROGRAM, *program, -1, name); + +   _mesa_UseProgram(*program); +} +  /**   * Generate a generic shader to blit from a texture to a framebuffer   * @@ -219,10 +244,8 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,  {     const char *vs_source;     char *fs_source; -   GLuint vs, fs;     void *const mem_ctx = ralloc_context(NULL);     struct blit_shader *shader = choose_blit_shader(target, table); -   char *name;     assert(shader != NULL); @@ -282,22 +305,12 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,                                    shader->texcoords);     } -   vs = _mesa_meta_compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); -   fs = _mesa_meta_compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); -   shader->shader_prog = _mesa_CreateProgram(); -   _mesa_AttachShader(shader->shader_prog, fs); -   _mesa_DeleteShader(fs); -   _mesa_AttachShader(shader->shader_prog, vs); -   _mesa_DeleteShader(vs); -   _mesa_BindAttribLocation(shader->shader_prog, 0, "position"); -   _mesa_BindAttribLocation(shader->shader_prog, 1, "texcoords"); -   _mesa_meta_link_program_with_debug(ctx, shader->shader_prog); -   name = ralloc_asprintf(mem_ctx, "%s blit", shader->type); -   _mesa_ObjectLabel(GL_PROGRAM, shader->shader_prog, -1, name); +   _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, +                                       ralloc_asprintf(mem_ctx, "%s blit", +                                                       shader->type), +                                       &shader->shader_prog);     ralloc_free(mem_ctx); - -   _mesa_UseProgram(shader->shader_prog);  }  /** diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h index 32b71fae7..2186a39f8 100644 --- a/mesalib/src/mesa/drivers/common/meta.h +++ b/mesalib/src/mesa/drivers/common/meta.h @@ -267,6 +267,13 @@ struct blit_state     bool no_ctsi_fallback;  }; +struct fb_tex_blit_state +{ +   GLint baseLevelSave, maxLevelSave; +   GLuint sampler, samplerSave; +   GLuint tempTex; +}; +  /**   * State for glClear() @@ -396,6 +403,26 @@ extern GLboolean  _mesa_meta_in_progress(struct gl_context *ctx);  extern void +_mesa_meta_fb_tex_blit_begin(const struct gl_context *ctx, +                             struct fb_tex_blit_state *blit); + +extern void +_mesa_meta_fb_tex_blit_end(const struct gl_context *ctx, GLenum target, +                           struct fb_tex_blit_state *blit); + +extern GLboolean +_mesa_meta_bind_rb_as_tex_image(struct gl_context *ctx, +                                struct gl_renderbuffer *rb, +                                GLuint *tex, +                                struct gl_texture_object **texObj, +                                GLenum *target); + +GLuint +_mesa_meta_setup_sampler(struct gl_context *ctx, +                         const struct gl_texture_object *texObj, +                         GLenum target, GLenum filter, GLuint srcLevel); + +extern void  _mesa_meta_BlitFramebuffer(struct gl_context *ctx,                             GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,                             GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, @@ -455,6 +482,13 @@ _mesa_meta_compile_shader_with_debug(struct gl_context *ctx, GLenum target,  GLuint  _mesa_meta_link_program_with_debug(struct gl_context *ctx, GLuint program); +void +_mesa_meta_compile_and_link_program(struct gl_context *ctx, +                                    const char *vs_source, +                                    const char *fs_source, +                                    const char *name, +                                    GLuint *program); +  GLboolean  _mesa_meta_alloc_texture(struct temp_texture *tex,                           GLsizei width, GLsizei height, GLenum intFormat); diff --git a/mesalib/src/mesa/drivers/common/meta_blit.c b/mesalib/src/mesa/drivers/common/meta_blit.c index c3dc14614..e5a0a9ad0 100644 --- a/mesalib/src/mesa/drivers/common/meta_blit.c +++ b/mesalib/src/mesa/drivers/common/meta_blit.c @@ -62,7 +62,6 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,  {     const char *vs_source;     char *fs_source; -   GLuint vs, fs;     void *mem_ctx;     enum blit_msaa_shader shader_index;     bool dst_is_msaa = false; @@ -314,21 +313,10 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,                                    sample_resolve);     } -   vs = _mesa_meta_compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); -   fs = _mesa_meta_compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); - -   blit->msaa_shaders[shader_index] = _mesa_CreateProgram(); -   _mesa_AttachShader(blit->msaa_shaders[shader_index], fs); -   _mesa_DeleteShader(fs); -   _mesa_AttachShader(blit->msaa_shaders[shader_index], vs); -   _mesa_DeleteShader(vs); -   _mesa_BindAttribLocation(blit->msaa_shaders[shader_index], 0, "position"); -   _mesa_BindAttribLocation(blit->msaa_shaders[shader_index], 1, "texcoords"); -   _mesa_meta_link_program_with_debug(ctx, blit->msaa_shaders[shader_index]); -   _mesa_ObjectLabel(GL_PROGRAM, blit->msaa_shaders[shader_index], -1, name); -   ralloc_free(mem_ctx); +   _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, name, +                                       &blit->msaa_shaders[shader_index]); -   _mesa_UseProgram(blit->msaa_shaders[shader_index]); +   ralloc_free(mem_ctx);  }  static void @@ -368,19 +356,14 @@ blitframebuffer_texture(struct gl_context *ctx,     const struct gl_renderbuffer_attachment *readAtt =        &readFb->Attachment[att_index];     struct blit_state *blit = &ctx->Meta->Blit; +   struct fb_tex_blit_state fb_tex_blit;     const GLint dstX = MIN2(dstX0, dstX1);     const GLint dstY = MIN2(dstY0, dstY1);     const GLint dstW = abs(dstX1 - dstX0);     const GLint dstH = abs(dstY1 - dstY0);     struct gl_texture_object *texObj;     GLuint srcLevel; -   GLint baseLevelSave; -   GLint maxLevelSave;     GLenum target; -   GLuint sampler, samplerSave = -      ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? -      ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; -   GLuint tempTex = 0;     struct gl_renderbuffer *rb = readAtt->Renderbuffer;     struct temp_texture *meta_temp_texture; @@ -392,6 +375,8 @@ blitframebuffer_texture(struct gl_context *ctx,        filter = GL_LINEAR;     } +   _mesa_meta_fb_tex_blit_begin(ctx, &fb_tex_blit); +     if (readAtt->Texture &&         (readAtt->Texture->Target == GL_TEXTURE_2D ||          readAtt->Texture->Target == GL_TEXTURE_RECTANGLE || @@ -404,38 +389,16 @@ blitframebuffer_texture(struct gl_context *ctx,        texObj = readAtt->Texture;        target = texObj->Target;     } else if (!readAtt->Texture && ctx->Driver.BindRenderbufferTexImage) { -      /* Otherwise, we need the driver to be able to bind a renderbuffer as -       * a texture image. -       */ -      struct gl_texture_image *texImage; - -      if (rb->NumSamples > 1) -         target = GL_TEXTURE_2D_MULTISAMPLE; -      else -         target = GL_TEXTURE_2D; - -      _mesa_GenTextures(1, &tempTex); -      _mesa_BindTexture(target, tempTex); -      srcLevel = 0; -      texObj = _mesa_lookup_texture(ctx, tempTex); -      texImage = _mesa_get_tex_image(ctx, texObj, target, srcLevel); - -      if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) { -         _mesa_DeleteTextures(1, &tempTex); +      if (!_mesa_meta_bind_rb_as_tex_image(ctx, rb, &fb_tex_blit.tempTex, +                                           &texObj, &target))           return false; -      } else { -         if (ctx->Driver.FinishRenderTexture && -             !rb->NeedsFinishRenderTexture) { -            rb->NeedsFinishRenderTexture = true; -            ctx->Driver.FinishRenderTexture(ctx, rb); -         } -         if (_mesa_is_winsys_fbo(readFb)) { -            GLint temp = srcY0; -            srcY0 = rb->Height - srcY1; -            srcY1 = rb->Height - temp; -            flipY = -flipY; -         } +      srcLevel = 0; +      if (_mesa_is_winsys_fbo(readFb)) { +         GLint temp = srcY0; +         srcY0 = rb->Height - srcY1; +         srcY1 = rb->Height - temp; +         flipY = -flipY;        }     } else {        GLenum tex_base_format; @@ -476,8 +439,8 @@ blitframebuffer_texture(struct gl_context *ctx,        srcY1 = srcH;     } -   baseLevelSave = texObj->BaseLevel; -   maxLevelSave = texObj->MaxLevel; +   fb_tex_blit.baseLevelSave = texObj->BaseLevel; +   fb_tex_blit.maxLevelSave = texObj->MaxLevel;     if (glsl_version) {        setup_glsl_blit_framebuffer(ctx, blit, rb, target); @@ -488,25 +451,14 @@ blitframebuffer_texture(struct gl_context *ctx,                                         2);     } -   _mesa_GenSamplers(1, &sampler); -   _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); -     /*       printf("Blit from texture!\n");       printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);       printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);     */ -   /* Prepare src texture state */ -   _mesa_BindTexture(target, texObj->Name); -   _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter); -   _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter); -   if (target != GL_TEXTURE_RECTANGLE_ARB) { -      _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); -      _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); -   } -   _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -   _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +   fb_tex_blit.sampler = _mesa_meta_setup_sampler(ctx, texObj, target, filter, +                                                  srcLevel);     /* Always do our blits with no net sRGB decode or encode.      * @@ -527,11 +479,12 @@ blitframebuffer_texture(struct gl_context *ctx,     if (ctx->Extensions.EXT_texture_sRGB_decode) {        if (_mesa_get_format_color_encoding(rb->Format) == GL_SRGB &&            ctx->DrawBuffer->Visual.sRGBCapable) { -         _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, -                                 GL_DECODE_EXT); +         _mesa_SamplerParameteri(fb_tex_blit.sampler, +                                 GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);           _mesa_set_framebuffer_srgb(ctx, GL_TRUE);        } else { -         _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, +         _mesa_SamplerParameteri(fb_tex_blit.sampler, +                                 GL_TEXTURE_SRGB_DECODE_EXT,                                   GL_SKIP_DECODE_EXT);           /* set_framebuffer_srgb was set by _mesa_meta_begin(). */        } @@ -598,23 +551,95 @@ blitframebuffer_texture(struct gl_context *ctx,     _mesa_DepthFunc(GL_ALWAYS);     _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); +   _mesa_meta_fb_tex_blit_end(ctx, target, &fb_tex_blit); + +   return true; +} +void +_mesa_meta_fb_tex_blit_begin(const struct gl_context *ctx, +                             struct fb_tex_blit_state *blit) +{ +   blit->samplerSave = +      ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? +      ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; +   blit->tempTex = 0; +} + +void +_mesa_meta_fb_tex_blit_end(const struct gl_context *ctx, GLenum target, +                           struct fb_tex_blit_state *blit) +{     /* Restore texture object state, the texture binding will      * be restored by _mesa_meta_end().      */     if (target != GL_TEXTURE_RECTANGLE_ARB) { -      _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); -      _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); +      _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, blit->baseLevelSave); +      _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, blit->maxLevelSave);     } -   _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); -   _mesa_DeleteSamplers(1, &sampler); -   if (tempTex) -      _mesa_DeleteTextures(1, &tempTex); +   _mesa_BindSampler(ctx->Texture.CurrentUnit, blit->samplerSave); +   _mesa_DeleteSamplers(1, &blit->sampler); +   if (blit->tempTex) +      _mesa_DeleteTextures(1, &blit->tempTex); +} + +GLboolean +_mesa_meta_bind_rb_as_tex_image(struct gl_context *ctx, +                                struct gl_renderbuffer *rb, +                                GLuint *tex, +                                struct gl_texture_object **texObj, +                                GLenum *target) +{ +   struct gl_texture_image *texImage; + +   if (rb->NumSamples > 1) +      *target = GL_TEXTURE_2D_MULTISAMPLE; +   else +      *target = GL_TEXTURE_2D; + +   _mesa_GenTextures(1, tex); +   _mesa_BindTexture(*target, *tex); +   *texObj = _mesa_lookup_texture(ctx, *tex); +   texImage = _mesa_get_tex_image(ctx, *texObj, *target, 0); + +   if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) { +      _mesa_DeleteTextures(1, tex); +      return false; +   } + +   if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) { +      rb->NeedsFinishRenderTexture = true; +      ctx->Driver.FinishRenderTexture(ctx, rb); +   }     return true;  } +GLuint +_mesa_meta_setup_sampler(struct gl_context *ctx, +                         const struct gl_texture_object *texObj, +                         GLenum target, GLenum filter, GLuint srcLevel) +{ +   GLuint sampler; + +   _mesa_GenSamplers(1, &sampler); +   _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); + +   /* Prepare src texture state */ +   _mesa_BindTexture(target, texObj->Name); +   _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter); +   _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter); +   if (target != GL_TEXTURE_RECTANGLE_ARB) { +      _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); +      _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); +   } +   _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +   _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +   return sampler; +} +  /**   * Meta implementation of ctx->Driver.BlitFramebuffer() in terms   * of texture mapping and polygon rendering. @@ -707,7 +732,7 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,     _mesa_meta_end(ctx);  fallback: -   if (mask) { +   if (mask && !ctx->Meta->Blit.no_ctsi_fallback) {        _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,                                dstX0, dstY0, dstX1, dstY1, mask, filter);     } diff --git a/mesalib/src/mesa/main/arbprogram.c b/mesalib/src/mesa/main/arbprogram.c index 247b49253..fe8cd6bbc 100644 --- a/mesalib/src/mesa/main/arbprogram.c +++ b/mesalib/src/mesa/main/arbprogram.c @@ -38,6 +38,7 @@  #include "main/arbprogram.h"  #include "program/arbprogparse.h"  #include "program/program.h" +#include "program/prog_print.h"  /** @@ -308,6 +309,7 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,                         const GLvoid *string)  {     struct gl_program *base; +   bool failed;     GET_CURRENT_CONTEXT(ctx);     FLUSH_VERTICES(ctx, _NEW_PROGRAM); @@ -341,13 +343,36 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,        return;     } -   if (ctx->Program.ErrorPos == -1) { +   failed = ctx->Program.ErrorPos != -1; + +   if (!failed) {        /* finally, give the program to the driver for translation/checking */        if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) { +         failed = true;           _mesa_error(ctx, GL_INVALID_OPERATION,                       "glProgramStringARB(rejected by driver");        }     } + +   if (ctx->_Shader->Flags & GLSL_DUMP) { +      const char *shader_type = +         target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex"; + +      fprintf(stderr, "ARB_%s_program source for program %d:\n", +              shader_type, base->Id); +      fprintf(stderr, "%s\n", (const char *) string); + +      if (failed) { +         fprintf(stderr, "ARB_%s_program %d failed to compile.\n", +                 shader_type, base->Id); +      } else { +         fprintf(stderr, "Mesa IR for ARB_%s_program %d:\n", +                 shader_type, base->Id); +         _mesa_print_program(base); +         fprintf(stderr, "\n"); +      } +      fflush(stderr); +   }  } diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c index a5a0d2d8d..9c33f4eb9 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_blit.c +++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c @@ -187,6 +187,7 @@ st_BlitFramebuffer(struct gl_context *ctx,     }     blit.filter = pFilter; +   blit.render_condition_enable = TRUE;     if (mask & GL_COLOR_BUFFER_BIT) {        struct gl_renderbuffer_attachment *srcAtt = diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c index b92147847..3f7bbd973 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c @@ -165,6 +165,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,        goto fallback;     } +   memset(&blit, 0, sizeof(blit));     blit.src.resource = src;     blit.src.level = strb->surface->u.tex.level;     blit.src.format = src_format; diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index 97bba8b7d..aa6b05f0b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -765,6 +765,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,     _mesa_unmap_teximage_pbo(ctx, unpack);     /* Blit. */ +   memset(&blit, 0, sizeof(blit));     blit.src.resource = src;     blit.src.level = 0;     blit.src.format = src_format; @@ -998,6 +999,7 @@ st_GetTexImage(struct gl_context * ctx,        height = 1;     } +   memset(&blit, 0, sizeof(blit));     blit.src.resource = src;     blit.src.level = texImage->Level;     blit.src.format = src_format; diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index bdee1f4eb..739e1089e 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -325,6 +325,7 @@ public:     struct gl_context *ctx;     struct gl_program *prog;     struct gl_shader_program *shader_program; +   struct gl_shader *shader;     struct gl_shader_compiler_options *options;     int next_temp; @@ -459,8 +460,7 @@ public:     int get_last_temp_write(int index);     void copy_propagate(void); -   void eliminate_dead_code(void); -   int eliminate_dead_code_advanced(void); +   int eliminate_dead_code(void);     void merge_registers(void);     void renumber_registers(void); @@ -1671,30 +1671,82 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)     case ir_unop_any: {        assert(ir->operands[0]->type->is_vector()); -      /* After the dot-product, the value will be an integer on the -       * range [0,4].  Zero stays zero, and positive values become 1.0. -       */ -      glsl_to_tgsi_instruction *const dp = -         emit_dp(ir, result_dst, op[0], op[0], -                 ir->operands[0]->type->vector_elements); -      if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && -          result_dst.type == GLSL_TYPE_FLOAT) { -	      /* The clamping to [0,1] can be done for free in the fragment -	       * shader with a saturate. -	       */ -	      dp->saturate = true; -      } else if (result_dst.type == GLSL_TYPE_FLOAT) { -	      /* Negating the result of the dot-product gives values on the range -	       * [-4, 0].  Zero stays zero, and negative values become 1.0.  This -	       * is achieved using SLT. -	       */ -	      st_src_reg slt_src = result_src; -	      slt_src.negate = ~slt_src.negate; -	      emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); -      } -      else { -         /* Use SNE 0 if integers are being used as boolean values. */ -         emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); +      if (native_integers) { +         int dst_swizzle = 0, op0_swizzle, i; +         st_src_reg accum = op[0]; + +         op0_swizzle = op[0].swizzle; +         accum.swizzle = MAKE_SWIZZLE4(GET_SWZ(op0_swizzle, 0), +                                       GET_SWZ(op0_swizzle, 0), +                                       GET_SWZ(op0_swizzle, 0), +                                       GET_SWZ(op0_swizzle, 0)); +         for (i = 0; i < 4; i++) { +            if (result_dst.writemask & (1 << i)) { +               dst_swizzle = MAKE_SWIZZLE4(i, i, i, i); +               break; +            } +         } +         assert(i != 4); +         assert(ir->operands[0]->type->is_boolean()); + +         /* OR all the components together, since they should be either 0 or ~0 +          */ +         switch (ir->operands[0]->type->vector_elements) { +         case 4: +            op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(op0_swizzle, 3), +                                          GET_SWZ(op0_swizzle, 3), +                                          GET_SWZ(op0_swizzle, 3), +                                          GET_SWZ(op0_swizzle, 3)); +            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]); +            accum = st_src_reg(result_dst); +            accum.swizzle = dst_swizzle; +            /* fallthrough */ +         case 3: +            op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(op0_swizzle, 2), +                                          GET_SWZ(op0_swizzle, 2), +                                          GET_SWZ(op0_swizzle, 2), +                                          GET_SWZ(op0_swizzle, 2)); +            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]); +            accum = st_src_reg(result_dst); +            accum.swizzle = dst_swizzle; +            /* fallthrough */ +         case 2: +            op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(op0_swizzle, 1), +                                          GET_SWZ(op0_swizzle, 1), +                                          GET_SWZ(op0_swizzle, 1), +                                          GET_SWZ(op0_swizzle, 1)); +            emit(ir, TGSI_OPCODE_OR, result_dst, accum, op[0]); +            break; +         default: +            assert(!"Unexpected vector size"); +            break; +         } +      } else { +         /* After the dot-product, the value will be an integer on the +          * range [0,4].  Zero stays zero, and positive values become 1.0. +          */ +         glsl_to_tgsi_instruction *const dp = +            emit_dp(ir, result_dst, op[0], op[0], +                    ir->operands[0]->type->vector_elements); +         if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && +             result_dst.type == GLSL_TYPE_FLOAT) { +            /* The clamping to [0,1] can be done for free in the fragment +             * shader with a saturate. +             */ +            dp->saturate = true; +         } else if (result_dst.type == GLSL_TYPE_FLOAT) { +            /* Negating the result of the dot-product gives values on the range +             * [-4, 0].  Zero stays zero, and negative values become 1.0.  This +             * is achieved using SLT. +             */ +            st_src_reg slt_src = result_src; +            slt_src.negate = ~slt_src.negate; +            emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); +         } +         else { +            /* Use SNE 0 if integers are being used as boolean values. */ +            emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); +         }        }        break;     } @@ -3103,6 +3155,7 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()     ctx = NULL;     prog = NULL;     shader_program = NULL; +   shader = NULL;     options = NULL;  } @@ -3672,7 +3725,8 @@ glsl_to_tgsi_visitor::copy_propagate(void)  }  /* - * Tracks available PROGRAM_TEMPORARY registers for dead code elimination. + * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead + * code elimination.   *   * The glsl_to_tgsi_visitor lazily produces code assuming that this pass   * will occur.  As an example, a TXP production after copy propagation but  @@ -3685,48 +3739,9 @@ glsl_to_tgsi_visitor::copy_propagate(void)   * and after this pass:   *   * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; - *  - * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB) - * FIXME: doesn't eliminate all dead code inside of loops; it steps around them - */ -void -glsl_to_tgsi_visitor::eliminate_dead_code(void) -{ -   int i; -    -   for (i=0; i < this->next_temp; i++) { -      int last_read = get_last_temp_read(i); -      int j = 0; -       -      foreach_list_safe(node, &this->instructions) { -         glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - -         if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && -             j > last_read) -         { -            inst->remove(); -            delete inst; -         } -          -         j++; -      } -   } -} - -/* - * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead - * code elimination.  This is less primitive than eliminate_dead_code(), as it - * is per-channel and can detect consecutive writes without a read between them - * as dead code.  However, there is some dead code that can be eliminated by  - * eliminate_dead_code() but not this function - for example, this function  - * cannot eliminate an instruction writing to a register that is never read and - * is the only instruction writing to that register. - * - * The glsl_to_tgsi_visitor lazily produces code assuming that this pass - * will occur.   */  int -glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) +glsl_to_tgsi_visitor::eliminate_dead_code(void)  {     glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx,                                                       glsl_to_tgsi_instruction *, @@ -3974,6 +3989,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,     v->ctx = original->ctx;     v->prog = prog;     v->shader_program = NULL; +   v->shader = NULL;     v->glsl_version = original->glsl_version;     v->native_integers = original->native_integers;     v->options = original->options; @@ -4104,6 +4120,7 @@ get_bitmap_visitor(struct st_fragment_program *fp,     v->ctx = original->ctx;     v->prog = prog;     v->shader_program = NULL; +   v->shader = NULL;     v->glsl_version = original->glsl_version;     v->native_integers = original->native_integers;     v->options = original->options; @@ -5083,11 +5100,11 @@ st_translate_program(        }     } -   if (program->shader_program) { -      unsigned num_ubos = program->shader_program->NumUniformBlocks; +   if (program->shader) { +      unsigned num_ubos = program->shader->NumUniformBlocks;        for (i = 0; i < num_ubos; i++) { -         ureg_DECL_constant2D(t->ureg, 0, program->shader_program->UniformBlocks[i].UniformBufferSize / 4, i + 1); +         ureg_DECL_constant2D(t->ureg, 0, program->shader->UniformBlocks[i].UniformBufferSize / 4, i + 1);        }     } @@ -5208,6 +5225,7 @@ get_mesa_program(struct gl_context *ctx,     v->ctx = ctx;     v->prog = prog;     v->shader_program = shader_program; +   v->shader = shader;     v->options = options;     v->glsl_version = ctx->Const.GLSLVersion;     v->native_integers = ctx->Const.NativeIntegers; @@ -5270,9 +5288,8 @@ get_mesa_program(struct gl_context *ctx,     /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */     v->simplify_cmp();     v->copy_propagate(); -   while (v->eliminate_dead_code_advanced()); +   while (v->eliminate_dead_code()); -   v->eliminate_dead_code();     v->merge_registers();     v->renumber_registers(); | 
