meta: use _mesa_prepare_mipmap_levels()
[mesa.git] / src / mesa / drivers / common / meta_tex_subimage.c
index b0ac6771cb25bb8f808c38b8daa38a48b0d2e0da..62c3fce4249c259ef37baae98abedb4069b3681a 100644 (file)
@@ -30,6 +30,7 @@
 #include "buffers.h"
 #include "clear.h"
 #include "fbobject.h"
+#include "framebuffer.h"
 #include "glformats.h"
 #include "glheader.h"
 #include "image.h"
@@ -69,7 +70,7 @@ create_texture_for_pbo(struct gl_context *ctx,
                        int dims, int width, int height, int depth,
                        GLenum format, GLenum type, const void *pixels,
                        const struct gl_pixelstore_attrib *packing,
-                       GLuint *tmp_pbo, GLuint *tmp_tex)
+                       struct gl_buffer_object **tmp_pbo, GLuint *tmp_tex)
 {
    uint32_t pbo_format;
    GLenum internal_format;
@@ -101,7 +102,7 @@ create_texture_for_pbo(struct gl_context *ctx,
    row_stride = _mesa_image_row_stride(packing, width, format, type);
 
    if (_mesa_is_bufferobj(packing->BufferObj)) {
-      *tmp_pbo = 0;
+      *tmp_pbo = NULL;
       buffer_obj = packing->BufferObj;
       first_pixel += (intptr_t)pixels;
    } else {
@@ -109,23 +110,27 @@ create_texture_for_pbo(struct gl_context *ctx,
 
       assert(create_pbo);
 
-      _mesa_CreateBuffers(1, tmp_pbo);
+      *tmp_pbo = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
+      if (*tmp_pbo == NULL)
+         return NULL;
 
       /* In case of GL_PIXEL_PACK_BUFFER, pass null pointer for the pixel
-       * data to avoid unnecessary data copying in _mesa_NamedBufferData().
+       * data to avoid unnecessary data copying in _mesa_buffer_data.
        */
       if (is_pixel_pack)
-         _mesa_NamedBufferData(*tmp_pbo,
-                               last_pixel - first_pixel,
-                               NULL,
-                               GL_STREAM_READ);
+         _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
+                           last_pixel - first_pixel,
+                           NULL,
+                           GL_STREAM_READ,
+                           __func__);
       else
-         _mesa_NamedBufferData(*tmp_pbo,
-                               last_pixel - first_pixel,
-                               (char *)pixels + first_pixel,
-                               GL_STREAM_DRAW);
+         _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
+                           last_pixel - first_pixel,
+                           (char *)pixels + first_pixel,
+                           GL_STREAM_DRAW,
+                           __func__);
 
-      buffer_obj = _mesa_lookup_bufferobj(ctx, *tmp_pbo);
+      buffer_obj = *tmp_pbo;
       first_pixel = 0;
    }
 
@@ -157,7 +162,7 @@ create_texture_for_pbo(struct gl_context *ctx,
                                                      row_stride,
                                                      read_only)) {
       _mesa_DeleteTextures(1, tmp_tex);
-      _mesa_DeleteBuffers(1, tmp_pbo);
+      _mesa_reference_buffer_object(ctx, tmp_pbo, NULL);
       return NULL;
    }
 
@@ -170,10 +175,13 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
                            int xoffset, int yoffset, int zoffset,
                            int width, int height, int depth,
                            GLenum format, GLenum type, const void *pixels,
-                           bool allocate_storage, bool create_pbo,
+                           bool create_pbo,
                            const struct gl_pixelstore_attrib *packing)
 {
-   GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+   struct gl_buffer_object *pbo = NULL;
+   GLuint pbo_tex = 0;
+   struct gl_framebuffer *readFb = NULL;
+   struct gl_framebuffer *drawFb = NULL;
    int image_height;
    struct gl_texture_image *pbo_tex_image;
    GLenum status;
@@ -206,23 +214,28 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
     */
    image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
 
+   _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER |
+                           MESA_META_PIXEL_STORE));
+
    pbo_tex_image = create_texture_for_pbo(ctx, create_pbo,
                                           GL_PIXEL_UNPACK_BUFFER,
                                           dims, width, height, depth,
                                           format, type, pixels, packing,
                                           &pbo, &pbo_tex);
-   if (!pbo_tex_image)
+   if (!pbo_tex_image) {
+      _mesa_meta_end(ctx);
       return false;
+   }
 
-   if (allocate_storage)
-      ctx->Driver.AllocTextureImageBuffer(ctx, tex_image);
+   readFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF);
+   if (readFb == NULL)
+      goto fail;
 
-   _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER |
-                           MESA_META_PIXEL_STORE));
+   drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF);
+   if (drawFb == NULL)
+      goto fail;
 
-   _mesa_GenFramebuffers(2, fbos);
-   _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
-   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
+   _mesa_bind_framebuffers(ctx, drawFb, tex_image ? readFb : ctx->ReadBuffer);
 
    if (tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
       assert(depth == 1);
@@ -234,20 +247,25 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
       yoffset = 0;
    }
 
-   _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                             pbo_tex_image, 0);
+   _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer,
+                                        GL_COLOR_ATTACHMENT0,
+                                        pbo_tex_image, 0);
    /* If this passes on the first layer it should pass on the others */
-   status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+   status = _mesa_check_framebuffer_status(ctx, ctx->ReadBuffer);
    if (status != GL_FRAMEBUFFER_COMPLETE)
       goto fail;
 
-   _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                             tex_image, zoffset);
+   _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer,
+                                        GL_COLOR_ATTACHMENT0,
+                                        tex_image, zoffset);
    /* If this passes on the first layer it should pass on the others */
-   status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+   status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer);
    if (status != GL_FRAMEBUFFER_COMPLETE)
       goto fail;
 
+   /* Explicitly disable sRGB encoding */
+   ctx->DrawBuffer->Visual.sRGBCapable = false;
+
    _mesa_update_state(ctx);
 
    if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
@@ -258,8 +276,9 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
       goto fail;
 
    for (z = 1; z < depth; z++) {
-      _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                tex_image, zoffset + z);
+      _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer,
+                                           GL_COLOR_ATTACHMENT0,
+                                           tex_image, zoffset + z);
 
       _mesa_update_state(ctx);
 
@@ -274,9 +293,10 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
    success = true;
 
 fail:
-   _mesa_DeleteFramebuffers(2, fbos);
+   _mesa_reference_framebuffer(&readFb, NULL);
+   _mesa_reference_framebuffer(&drawFb, NULL);
    _mesa_DeleteTextures(1, &pbo_tex);
-   _mesa_DeleteBuffers(1, &pbo);
+   _mesa_reference_buffer_object(ctx, &pbo, NULL);
 
    _mesa_meta_end(ctx);
 
@@ -291,7 +311,10 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
                               GLenum format, GLenum type, const void *pixels,
                               const struct gl_pixelstore_attrib *packing)
 {
-   GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+   struct gl_buffer_object *pbo = NULL;
+   GLuint pbo_tex = 0;
+   struct gl_framebuffer *readFb;
+   struct gl_framebuffer *drawFb;
    int image_height;
    struct gl_texture_image *pbo_tex_image;
    struct gl_renderbuffer *rb = NULL;
@@ -340,21 +363,30 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
     */
    image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
 
+   _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER |
+                           MESA_META_PIXEL_STORE));
+
    pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER,
                                           dims, width, height, depth,
                                           format, type, pixels, packing,
                                           &pbo, &pbo_tex);
-   if (!pbo_tex_image)
-      return false;
 
-   _mesa_meta_begin(ctx, ~(MESA_META_PIXEL_TRANSFER |
-                           MESA_META_PIXEL_STORE));
+   if (!pbo_tex_image) {
+      _mesa_meta_end(ctx);
+      return false;
+   }
 
    /* GL_CLAMP_FRAGMENT_COLOR doesn't affect ReadPixels and GettexImage */
    if (ctx->Extensions.ARB_color_buffer_float)
       _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
 
-   _mesa_GenFramebuffers(2, fbos);
+   readFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF);
+   if (readFb == NULL)
+      goto fail;
+
+   drawFb = ctx->Driver.NewFramebuffer(ctx, 0xDEADBEEF);
+   if (drawFb == NULL)
+      goto fail;
 
    if (tex_image && tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
       assert(depth == 1);
@@ -370,26 +402,30 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
     * we're doing a ReadPixels and we should just use whatever framebuffer
     * the client has bound.
     */
+   _mesa_bind_framebuffers(ctx, drawFb, tex_image ? readFb : ctx->ReadBuffer);
    if (tex_image) {
-      _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
-      _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                tex_image, zoffset);
+      _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer,
+                                           GL_COLOR_ATTACHMENT0,
+                                           tex_image, zoffset);
       /* If this passes on the first layer it should pass on the others */
-      status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+      status = _mesa_check_framebuffer_status(ctx, ctx->ReadBuffer);
       if (status != GL_FRAMEBUFFER_COMPLETE)
          goto fail;
    } else {
       assert(depth == 1);
    }
 
-   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
-   _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                             pbo_tex_image, 0);
+   _mesa_meta_framebuffer_texture_image(ctx, ctx->DrawBuffer,
+                                        GL_COLOR_ATTACHMENT0,
+                                        pbo_tex_image, 0);
    /* If this passes on the first layer it should pass on the others */
-   status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+   status = _mesa_check_framebuffer_status(ctx, ctx->DrawBuffer);
    if (status != GL_FRAMEBUFFER_COMPLETE)
       goto fail;
 
+   /* Explicitly disable sRGB encoding */
+   ctx->DrawBuffer->Visual.sRGBCapable = false;
+
    _mesa_update_state(ctx);
 
    if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
@@ -421,8 +457,9 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
    }
 
    for (z = 1; z < depth; z++) {
-      _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                tex_image, zoffset + z);
+      _mesa_meta_framebuffer_texture_image(ctx, ctx->ReadBuffer,
+                                           GL_COLOR_ATTACHMENT0,
+                                           tex_image, zoffset + z);
 
       _mesa_update_state(ctx);
 
@@ -446,9 +483,10 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
    success = true;
 
 fail:
-   _mesa_DeleteFramebuffers(2, fbos);
+   _mesa_reference_framebuffer(&drawFb, NULL);
+   _mesa_reference_framebuffer(&readFb, NULL);
    _mesa_DeleteTextures(1, &pbo_tex);
-   _mesa_DeleteBuffers(1, &pbo);
+   _mesa_reference_buffer_object(ctx, &pbo, NULL);
 
    _mesa_meta_end(ctx);