aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c45
-rw-r--r--mesalib/src/mesa/drivers/common/meta.h34
-rw-r--r--mesalib/src/mesa/drivers/common/meta_blit.c177
-rw-r--r--mesalib/src/mesa/main/arbprogram.c27
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_blit.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_readpixels.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp161
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();