[PATCH] ir_to_mesa: fix copy propagation if a saved MOV's input is written

Christoph Bumiller e0425955 at student.tuwien.ac.at
Wed Jan 26 04:15:49 PST 2011


The following glsl code:
   float a = v.x;
   v.x = v.y;
   v.y = a;
would be wrongly translated into
   MOV TEMP[0].x, TEMP[0].y
   MOV TEMP[0].x, TEMP[0].x
by copy propagation without this.
---
 src/mesa/program/ir_to_mesa.cpp |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 786fdfb..c4e4607 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2727,6 +2727,18 @@ ir_to_mesa_visitor::copy_propagate(void)
 		     acp[4 * inst->dst_reg.index + i] = NULL;
 		  }
 	       }
+               /* If the source of a copy has been modified, we must not
+                * propagate it either.
+                */
+               for (int k = 0; k < this->next_temp * 4; ++k) {
+                  if (!acp[k])
+                     continue;
+                  int src_chan = GET_SWZ(acp[k]->src_reg[0].swizzle, k & 3);
+                  if (acp[k]->src_reg[0].file == PROGRAM_TEMPORARY &&
+                      inst->dst_reg.index == acp[k]->src_reg[0].index &&
+                      inst->dst_reg.writemask & (1 << src_chan))
+                     acp[k] = NULL;
+               }
 	    }
 	 }
 	 break;
-- 
1.7.2.2


--------------000007000508090804070208
Content-Type: text/x-c;
 name="swap.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="swap.c"


#define WIN_W 1024
#define WIN_H 768

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

SDL_Surface *screen;

GLuint prog;

GLuint create_program();

//#define WITH_RESTART
//#define WITH_VBO

int draw()
{
   GLuint vbo;
   float z = -2.0f;

   float vdata[12] =
      {
         -0.5f, 0.0f,
         -0.5f, 0.5f,
          0.0f, 0.0f,
          0.0f, 0.5f,
          0.5f, 0.0f,
          0.5f, 0.5f
      };

   uint8_t idata[7] = { 0, 1, 2, 2, 3, 4, 5 };
   
   glViewport(0, 0, WIN_W, WIN_H);
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glUseProgram(prog);

   glDisable(GL_DEPTH_TEST);

#ifdef WITH_RESTART
   glEnable(GL_PRIMITIVE_RESTART);
#endif
   glPrimitiveRestartIndex(255);

   glEnableVertexAttribArray(0);

#ifdef WITH_VBO
   glGenBuffers(1, &vbo);
   glBindBuffer(GL_ARRAY_BUFFER, vbo);
   glBufferData(GL_ARRAY_BUFFER, sizeof(vdata), vdata, GL_STATIC_DRAW);
   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
#else
   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vdata);
#endif

   glLineWidth(16.0);

   glDrawElementsInstanced(GL_LINE_STRIP, 7, GL_UNSIGNED_BYTE, idata, 3);

   assert(glGetError() == GL_NO_ERROR);

   SDL_GL_SwapBuffers();
}

int main(int argc, char **argv)
{
   const unsigned flags = SDL_HWSURFACE | SDL_OPENGL | SDL_DOUBLEBUF;

   if (SDL_Init(SDL_INIT_VIDEO) < 0) {
      fprintf(stderr, "SDL_INIT_VIDEO failed\n");
      return EXIT_FAILURE;
   }

   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
   SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

   screen = SDL_SetVideoMode(WIN_W, WIN_H, 32, flags);
   if (!screen) {
      fprintf(stderr, "SDL_SetVideoMode failed\n");
      return EXIT_FAILURE;
   }

   atexit(SDL_Quit);

   prog = create_program();

   draw();

   usleep(1000000);

   return 0;
}

GLuint create_program()
{
   GLint ret;
   GLsizei len;
   GLchar log[512];
   GLuint vp, fp;
   GLuint p;

   const char *vertprog = "#extension GL_ARB_draw_instanced : enable\n"
      "attribute vec2 vertex;\n"
      "varying vec4 colour;\n"
      "void main() {\n"
      "   float dy = float(gl_InstanceIDARB) * 0.1;\n"
      "   gl_Position = vec4(vertex.x, vertex.y - dy, -0.5, 1.0);\n"
      "   colour = vec4(1.0, dy * 5.0, 0.0, 1.0);\n"
      "}\n";
   const char *fragprog =
      "varying vec4 colour;\n"
      "void main() {\n"
      "   vec4 col = colour;\n"
      "   while (col.z < 0.6) {\n"
      "      float a = col.x;\n"
      "      col.x = col.y;\n"
      "      col.y = a;\n"
      "      col.z += 0.2;\n"
      "   }\n"
      "   gl_FragColor = col;\n"
      "}\n";

   vp = glCreateShader(GL_VERTEX_SHADER);
   fp = glCreateShader(GL_FRAGMENT_SHADER);

   glShaderSource(vp, 1, &vertprog, NULL);
   glShaderSource(fp, 1, &fragprog, NULL);
   glCompileShader(vp);
   glCompileShader(fp);

   p = glCreateProgram();

   glAttachShader(p, vp);
   glAttachShader(p, fp);

   glBindAttribLocation(p, 0, "vertex");

   glLinkProgram(p);

   glGetShaderiv(vp, GL_COMPILE_STATUS, &ret);
   if (ret != GL_TRUE) {
      glGetShaderInfoLog(vp, 512, &len, log);
      fprintf(stderr, "VP ERROR\n%s\n", log);
      return 0;
   }
   glGetShaderiv(fp, GL_COMPILE_STATUS, &ret);
   if (ret != GL_TRUE) {
      glGetShaderInfoLog(fp, 512, &len, log);
      fprintf(stderr, "FP ERROR\n%s\n", log);
      return 0;
   }

   glGetProgramiv(p, GL_LINK_STATUS, &ret);

   if (ret != GL_TRUE) {
      glGetProgramInfoLog(p, 512, &len, log);
      fprintf(stderr, "GLSL LINKING ERROR\n%s\n", log);
      return 0;
   } else {
      printf("shader compiled successfully\n");
   }

   assert(glGetError() == GL_NO_ERROR);
   return p;
}

--------------000007000508090804070208--


More information about the mesa-dev mailing list