mesa: Add an index parameter to _mesa_set_viewport
[mesa.git] / src / mesa / drivers / common / meta.c
index 69b06ed8e53ddd7b59491a8c84eaccdf536a9f00..9a8f7a5a2d53c956a3cac45a8340b16e6194de1f 100644 (file)
@@ -170,7 +170,7 @@ struct save_state
    struct gl_buffer_object *ArrayBufferObj;
 
    /** MESA_META_VIEWPORT */
-   GLint ViewportX, ViewportY, ViewportW, ViewportH;
+   GLfloat ViewportX, ViewportY, ViewportW, ViewportH;
    GLclampd DepthNear, DepthFar;
 
    /** MESA_META_CLAMP_FRAGMENT_COLOR */
@@ -241,9 +241,11 @@ struct clear_state
    GLuint VBO;
    GLuint ShaderProg;
    GLint ColorLocation;
+   GLint LayerLocation;
 
    GLuint IntegerShaderProg;
    GLint IntegerColorLocation;
+   GLint IntegerLayerLocation;
 };
 
 
@@ -735,21 +737,21 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 
    if (state & MESA_META_VIEWPORT) {
       /* save viewport state */
-      save->ViewportX = ctx->Viewport.X;
-      save->ViewportY = ctx->Viewport.Y;
-      save->ViewportW = ctx->Viewport.Width;
-      save->ViewportH = ctx->Viewport.Height;
+      save->ViewportX = ctx->ViewportArray[0].X;
+      save->ViewportY = ctx->ViewportArray[0].Y;
+      save->ViewportW = ctx->ViewportArray[0].Width;
+      save->ViewportH = ctx->ViewportArray[0].Height;
       /* set viewport to match window size */
-      if (ctx->Viewport.X != 0 ||
-          ctx->Viewport.Y != 0 ||
-          ctx->Viewport.Width != ctx->DrawBuffer->Width ||
-          ctx->Viewport.Height != ctx->DrawBuffer->Height) {
-         _mesa_set_viewport(ctx, 0, 0,
+      if (ctx->ViewportArray[0].X != 0 ||
+          ctx->ViewportArray[0].Y != 0 ||
+          ctx->ViewportArray[0].Width != (float) ctx->DrawBuffer->Width ||
+          ctx->ViewportArray[0].Height != (float) ctx->DrawBuffer->Height) {
+         _mesa_set_viewport(ctx, 0, 0, 0,
                             ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
       }
       /* save depth range state */
-      save->DepthNear = ctx->Viewport.Near;
-      save->DepthFar = ctx->Viewport.Far;
+      save->DepthNear = ctx->ViewportArray[0].Near;
+      save->DepthFar = ctx->ViewportArray[0].Far;
       /* set depth range to default */
       _mesa_DepthRange(0.0, 1.0);
    }
@@ -931,9 +933,9 @@ _mesa_meta_end(struct gl_context *ctx)
    }
 
    if (state & MESA_META_SCISSOR) {
-      _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
-      _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
-                    save->Scissor.Width, save->Scissor.Height);
+      _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.EnableFlags);
+      _mesa_Scissor(save->Scissor.ScissorArray[0].X, save->Scissor.ScissorArray[0].Y,
+                    save->Scissor.ScissorArray[0].Width, save->Scissor.ScissorArray[0].Height);
    }
 
    if (state & MESA_META_SHADER) {
@@ -1087,11 +1089,11 @@ _mesa_meta_end(struct gl_context *ctx)
    }
 
    if (state & MESA_META_VIEWPORT) {
-      if (save->ViewportX != ctx->Viewport.X ||
-          save->ViewportY != ctx->Viewport.Y ||
-          save->ViewportW != ctx->Viewport.Width ||
-          save->ViewportH != ctx->Viewport.Height) {
-         _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
+      if (save->ViewportX != ctx->ViewportArray[0].X ||
+          save->ViewportY != ctx->ViewportArray[0].Y ||
+          save->ViewportW != ctx->ViewportArray[0].Width ||
+          save->ViewportH != ctx->ViewportArray[0].Height) {
+         _mesa_set_viewport(ctx, 0, save->ViewportX, save->ViewportY,
                             save->ViewportW, save->ViewportH);
       }
       _mesa_DepthRange(save->DepthNear, save->DepthFar);
@@ -1515,6 +1517,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
                                    sizeof(struct vertex), OFFSET(x));
       _mesa_VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
                                    sizeof(struct vertex), OFFSET(s));
+
+      _mesa_EnableVertexAttribArray(0);
+      _mesa_EnableVertexAttribArray(1);
    }
 
    /* Generate a relevant fragment shader program for the texture target */
@@ -1537,6 +1542,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
          "}\n";
 
       fs_source = ralloc_asprintf(mem_ctx,
+                                  "#ifdef GL_ES\n"
+                                  "precision highp float;\n"
+                                  "#endif\n"
                                   "uniform %s texSampler;\n"
                                   "varying vec2 texCoords;\n"
                                   "void main()\n"
@@ -1561,6 +1569,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
                                   _mesa_is_desktop_gl(ctx) ? "130" : "300 es");
       fs_source = ralloc_asprintf(mem_ctx,
                                   "#version %s\n"
+                                  "#ifdef GL_ES\n"
+                                  "precision highp float;\n"
+                                  "#endif\n"
                                   "uniform %s texSampler;\n"
                                   "in vec2 texCoords;\n"
                                   "out vec4 out_color;\n"
@@ -1585,8 +1596,6 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
    _mesa_DeleteObjectARB(vs);
    _mesa_BindAttribLocation(ShaderProg, 0, "position");
    _mesa_BindAttribLocation(ShaderProg, 1, "texcoords");
-   _mesa_EnableVertexAttribArray(0);
-   _mesa_EnableVertexAttribArray(1);
    link_program_with_debug(ctx, ShaderProg);
    ralloc_free(mem_ctx);
    if (texture_2d)
@@ -1723,10 +1732,10 @@ blitframebuffer_texture(struct gl_context *ctx,
             }
             else {
                assert(target == GL_TEXTURE_RECTANGLE_ARB);
-               s0 = srcX0;
-               s1 = srcX1;
-               t0 = srcY0;
-               t1 = srcY1;
+               s0 = (float) srcX0;
+               s1 = (float) srcX1;
+               t0 = (float) srcY0;
+               t1 = (float) srcY1;
             }
 
             /* setup vertex positions */
@@ -1752,7 +1761,7 @@ blitframebuffer_texture(struct gl_context *ctx,
          }
 
          /* setup viewport */
-         _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+         _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
          _mesa_DepthMask(GL_FALSE);
          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -1884,25 +1893,30 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
       const GLenum rb_base_format =
          _mesa_base_tex_format(ctx, colorReadRb->InternalFormat);
 
-      newTex = alloc_texture(tex, srcW, srcH, rb_base_format);
-      setup_copypix_texture(ctx, tex, newTex, srcX, srcY, srcW, srcH,
+      /* Using  the exact source rectangle to create the texture does incorrect
+       * linear filtering along the edges. So, allocate the texture extended along
+       * edges by one pixel in x, y directions.
+       */
+      newTex = alloc_texture(tex, srcW + 2, srcH + 2, rb_base_format);
+      setup_copypix_texture(ctx, tex, newTex,
+                            srcX - 1, srcY - 1, srcW + 2, srcH + 2,
                             rb_base_format, filter);
       /* texcoords (after texture allocation!) */
       {
-         verts[0].s = 0.0F;
-         verts[0].t = 0.0F;
-         verts[1].s = tex->Sright;
-         verts[1].t = 0.0F;
-         verts[2].s = tex->Sright;
-         verts[2].t = tex->Ttop;
-         verts[3].s = 0.0F;
-         verts[3].t = tex->Ttop;
+         verts[0].s = 1.0F;
+         verts[0].t = 1.0F;
+         verts[1].s = tex->Sright - 1.0F;
+         verts[1].t = 1.0F;
+         verts[2].s = tex->Sright - 1.0F;
+         verts[2].t = tex->Ttop - 1.0F;
+         verts[3].s = 1.0F;
+         verts[3].t = tex->Ttop - 1.0F;
 
          /* upload new vertex data */
          _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
       }
 
-      _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+      _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
       _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
       _mesa_DepthMask(GL_FALSE);
@@ -1951,7 +1965,7 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
          _mesa_DepthFunc(GL_ALWAYS);
          _mesa_DepthMask(GL_TRUE);
 
-         _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH);
+         _mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
          _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
          mask &= ~GL_DEPTH_BUFFER_BIT;
@@ -2133,13 +2147,29 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
       "{\n"
       "   gl_Position = position;\n"
       "}\n";
+   const char *gs_source =
+      "#version 150\n"
+      "layout(triangles) in;\n"
+      "layout(triangle_strip, max_vertices = 4) out;\n"
+      "uniform int layer;\n"
+      "void main()\n"
+      "{\n"
+      "  for (int i = 0; i < 3; i++) {\n"
+      "    gl_Layer = layer;\n"
+      "    gl_Position = gl_in[i].gl_Position;\n"
+      "    EmitVertex();\n"
+      "  }\n"
+      "}\n";
    const char *fs_source =
+      "#ifdef GL_ES\n"
+      "precision highp float;\n"
+      "#endif\n"
       "uniform vec4 color;\n"
       "void main()\n"
       "{\n"
       "   gl_FragColor = color;\n"
       "}\n";
-   GLuint vs, fs;
+   GLuint vs, gs = 0, fs;
    bool has_integer_textures;
 
    if (clear->ArrayObj != 0)
@@ -2161,6 +2191,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
    _mesa_ShaderSource(vs, 1, &vs_source, NULL);
    _mesa_CompileShader(vs);
 
+   if (_mesa_has_geometry_shaders(ctx)) {
+      gs = _mesa_CreateShaderObjectARB(GL_GEOMETRY_SHADER);
+      _mesa_ShaderSource(gs, 1, &gs_source, NULL);
+      _mesa_CompileShader(gs);
+   }
+
    fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER);
    _mesa_ShaderSource(fs, 1, &fs_source, NULL);
    _mesa_CompileShader(fs);
@@ -2168,6 +2204,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
    clear->ShaderProg = _mesa_CreateProgramObjectARB();
    _mesa_AttachShader(clear->ShaderProg, fs);
    _mesa_DeleteObjectARB(fs);
+   if (gs != 0)
+      _mesa_AttachShader(clear->ShaderProg, gs);
    _mesa_AttachShader(clear->ShaderProg, vs);
    _mesa_DeleteObjectARB(vs);
    _mesa_BindAttribLocation(clear->ShaderProg, 0, "position");
@@ -2175,6 +2213,10 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
 
    clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
                                                      "color");
+   if (gs != 0) {
+      clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg,
+                                                     "layer");
+   }
 
    has_integer_textures = _mesa_is_gles3(ctx) ||
       (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
@@ -2193,6 +2235,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
       const char *fs_int_source =
          ralloc_asprintf(shader_source_mem_ctx,
                          "#version %s\n"
+                         "#ifdef GL_ES\n"
+                         "precision highp float;\n"
+                         "#endif\n"
                          "uniform ivec4 color;\n"
                          "out ivec4 out_color;\n"
                          "\n"
@@ -2209,6 +2254,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
       clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
       _mesa_AttachShader(clear->IntegerShaderProg, fs);
       _mesa_DeleteObjectARB(fs);
+      if (gs != 0)
+         _mesa_AttachShader(clear->IntegerShaderProg, gs);
       _mesa_AttachShader(clear->IntegerShaderProg, vs);
       _mesa_DeleteObjectARB(vs);
       _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position");
@@ -2222,7 +2269,13 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
 
       clear->IntegerColorLocation =
         _mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
+      if (gs != 0) {
+         clear->IntegerLayerLocation =
+            _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
+      }
    }
+   if (gs != 0)
+      _mesa_DeleteObjectARB(gs);
 }
 
 static void
@@ -2353,8 +2406,19 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers)
    _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
                       GL_DYNAMIC_DRAW_ARB);
 
-   /* draw quad */
-   _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+   /* draw quad(s) */
+   if (fb->MaxNumLayers > 0) {
+      unsigned layer;
+      for (layer = 0; layer < fb->MaxNumLayers; layer++) {
+         if (fb->_IntegerColor)
+            _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
+         else
+            _mesa_Uniform1i(clear->LayerLocation, layer);
+         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+      }
+   } else {
+      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+   }
 
    _mesa_meta_end(ctx);
 }
@@ -2808,7 +2872,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
             _mesa_StencilMask(mask);
 
             _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
-                                             255.0 / mask, 0.5, 0.0, 0.0);
+                                             255.0f / mask, 0.5f, 0.0f, 0.0f);
 
             _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
          }
@@ -3167,7 +3231,7 @@ setup_texture_coords(GLenum faceTarget,
          r = (slice + 0.5f) / depth;
       }
       else if (faceTarget == GL_TEXTURE_2D_ARRAY)
-         r = slice;
+         r = (float) slice;
       else
          r = 0.0F;
       coords0[0] = 0.0F; /* s */
@@ -3187,28 +3251,28 @@ setup_texture_coords(GLenum faceTarget,
       coords0[0] = 0.0F; /* s */
       coords0[1] = 0.0F; /* t */
       coords0[2] = 0.0F; /* r */
-      coords1[0] = width;
+      coords1[0] = (float) width;
       coords1[1] = 0.0F;
       coords1[2] = 0.0F;
-      coords2[0] = width;
-      coords2[1] = height;
+      coords2[0] = (float) width;
+      coords2[1] = (float) height;
       coords2[2] = 0.0F;
       coords3[0] = 0.0F;
-      coords3[1] = height;
+      coords3[1] = (float) height;
       coords3[2] = 0.0F;
       break;
    case GL_TEXTURE_1D_ARRAY:
       coords0[0] = 0.0F; /* s */
-      coords0[1] = slice; /* t */
+      coords0[1] = (float) slice; /* t */
       coords0[2] = 0.0F; /* r */
       coords1[0] = 1.0f;
-      coords1[1] = slice;
+      coords1[1] = (float) slice;
       coords1[2] = 0.0F;
       coords2[0] = 1.0F;
-      coords2[1] = slice;
+      coords2[1] = (float) slice;
       coords2[2] = 0.0F;
       coords3[0] = 0.0F;
-      coords3[1] = slice;
+      coords3[1] = (float) slice;
       coords3[2] = 0.0F;
       break;
 
@@ -3421,6 +3485,9 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
 
       fs_source = ralloc_asprintf(mem_ctx,
                                   "#extension GL_EXT_texture_array : enable\n"
+                                  "#ifdef GL_ES\n"
+                                  "precision highp float;\n"
+                                  "#endif\n"
                                   "uniform %s texSampler;\n"
                                   "varying vec3 texCoords;\n"
                                   "void main()\n"
@@ -3444,6 +3511,9 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
                                   _mesa_is_desktop_gl(ctx) ? "130" : "300 es");
       fs_source = ralloc_asprintf(mem_ctx,
                                   "#version %s\n"
+                                  "#ifdef GL_ES\n"
+                                  "precision highp float;\n"
+                                  "#endif\n"
                                   "uniform %s texSampler;\n"
                                   "in vec3 texCoords;\n"
                                   "out vec4 out_color;\n"
@@ -3712,7 +3782,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
       assert(dstHeight == ctx->DrawBuffer->Height);
 
       /* setup viewport */
-      _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
+      _mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight);
 
       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
@@ -3999,6 +4069,11 @@ decompress_texture_image(struct gl_context *ctx,
    verts[3].x = 0.0F;
    verts[3].y = height;
 
+   _mesa_MatrixMode(GL_PROJECTION);
+   _mesa_LoadIdentity();
+   _mesa_Ortho(0.0, width, 0.0, height, -1.0, 1.0);
+   _mesa_set_viewport(ctx, 0, 0, 0, width, height);
+
    /* upload new vertex data */
    _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);