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(); |