예제 #1
0
static struct pipe_texture *
create_texture(struct pipe_context *pipe, enum pipe_format format,
               VGint width, VGint height)
{
   struct pipe_texture templ;

   memset(&templ, 0, sizeof(templ));

   if (format != PIPE_FORMAT_NONE) {
      templ.format = format;
   }
   else {
      templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
   }

   templ.target = PIPE_TEXTURE_2D;
   pf_get_block(templ.format, &templ.block);
   templ.width[0] = width;
   templ.height[0] = height;
   templ.depth[0] = 1;
   templ.last_level = 0;

   if (pf_get_component_bits(format, PIPE_FORMAT_COMP_S)) {
      templ.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
   } else {
      templ.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
                         PIPE_TEXTURE_USAGE_RENDER_TARGET |
                         PIPE_TEXTURE_USAGE_SAMPLER);
   }

   return pipe->screen->texture_create(pipe->screen, &templ);
}
예제 #2
0
/**
 * Bind a pipe surface to a texture object.  After the call,
 * the texture object is marked dirty and will be (re-)validated.
 *
 * If this is the first surface bound, the texture object is said to
 * switch from normal to surface based.  It will be cleared first in
 * this case.
 *
 * \param ps      pipe surface to be unbound
 * \param target  texture target
 * \param level   image level
 * \param format  internal format of the texture
 */
int
st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
                        enum pipe_format format)
{
   GET_CURRENT_CONTEXT(ctx);
   const GLuint unit = ctx->Texture.CurrentUnit;
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *texObj;
   struct gl_texture_image *texImage;
   struct st_texture_object *stObj;
   struct st_texture_image *stImage;
   GLenum internalFormat;

   switch (target) {
   case ST_TEXTURE_2D:
      target = GL_TEXTURE_2D;
      break;
   case ST_TEXTURE_RECT:
      target = GL_TEXTURE_RECTANGLE_ARB;
      break;
   default:
      return 0;
   }

   /* map pipe format to base format for now */
   if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0)
      internalFormat = GL_RGBA;
   else
      internalFormat = GL_RGB;

   texObj = _mesa_select_tex_object(ctx, texUnit, target);
   _mesa_lock_texture(ctx, texObj);

   stObj = st_texture_object(texObj);
   /* switch to surface based */
   if (!stObj->surface_based) {
      _mesa_clear_texture_object(ctx, texObj);
      stObj->surface_based = GL_TRUE;
   }

   texImage = _mesa_get_tex_image(ctx, texObj, target, level);
   stImage = st_texture_image(texImage);

   _mesa_init_teximage_fields(ctx, target, texImage,
                              ps->width, ps->height, 1, 0, internalFormat);
   texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
                                                GL_RGBA, GL_UNSIGNED_BYTE);
   _mesa_set_fetch_functions(texImage, 2);
   pipe_texture_reference(&stImage->pt, ps->texture);

   _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
   _mesa_unlock_texture(ctx, texObj);
   
   return 1;
}
예제 #3
0
static int pf_is_depth_stencil( enum pipe_format format ) {
    return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
            pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
}
예제 #4
0
static void
copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                    GLsizei width, GLsizei height,
                    GLint dstx, GLint dsty)
{
   struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
   struct pipe_screen *screen = ctx->st->pipe->screen;
   enum pipe_transfer_usage usage;
   struct pipe_transfer *ptDraw;
   ubyte *drawMap;
   ubyte *buffer;
   int i;

   buffer = _mesa_malloc(width * height * sizeof(ubyte));
   if (!buffer) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
      return;
   }

   /* this will do stencil pixel transfer ops */
   st_read_stencil_pixels(ctx, srcx, srcy, width, height,
                          GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                          &ctx->DefaultPacking, buffer);

   if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
      usage = PIPE_TRANSFER_READ_WRITE;
   else
      usage = PIPE_TRANSFER_WRITE;
   
   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
      dsty = rbDraw->Base.Height - dsty - height;
   }

   ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx),
					   rbDraw->texture, 0, 0, 0,
					   usage, dstx, dsty,
					   width, height);

   assert(ptDraw->block.width == 1);
   assert(ptDraw->block.height == 1);
   
   /* map the stencil buffer */
   drawMap = screen->transfer_map(screen, ptDraw);

   /* draw */
   /* XXX PixelZoom not handled yet */
   for (i = 0; i < height; i++) {
      ubyte *dst;
      const ubyte *src;
      int y;

      y = i;

      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
         y = height - y - 1;
      }

      dst = drawMap + y * ptDraw->stride;
      src = buffer + i * width;

      switch (ptDraw->format) {
      case PIPE_FORMAT_S8Z24_UNORM:
         {
            uint *dst4 = (uint *) dst;
            int j;
            assert(usage == PIPE_TRANSFER_READ_WRITE);
            for (j = 0; j < width; j++) {
               *dst4 = (*dst4 & 0xffffff) | (src[j] << 24);
               dst4++;
            }
         }
         break;
      case PIPE_FORMAT_Z24S8_UNORM:
         {
            uint *dst4 = (uint *) dst;
            int j;
            assert(usage == PIPE_TRANSFER_READ_WRITE);
            for (j = 0; j < width; j++) {
               *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff);
               dst4++;
            }
         }
         break;
      case PIPE_FORMAT_S8_UNORM:
         assert(usage == PIPE_TRANSFER_WRITE);
         memcpy(dst, src, width);
         break;
      default:
         assert(0);
      }
   }

   _mesa_free(buffer);

   /* unmap the stencil buffer */
   screen->transfer_unmap(screen, ptDraw);
   screen->tex_transfer_destroy(ptDraw);
}
예제 #5
0
static void
draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
                    GLsizei width, GLsizei height, GLenum format, GLenum type,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels)
{
   struct st_context *st = ctx->st;
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct st_renderbuffer *strb;
   enum pipe_transfer_usage usage;
   struct pipe_transfer *pt;
   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
   GLint skipPixels;
   ubyte *stmap;

   strb = st_renderbuffer(ctx->DrawBuffer->
                          Attachment[BUFFER_STENCIL].Renderbuffer);

   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
      y = ctx->DrawBuffer->Height - y - height;
   }

   if(format != GL_DEPTH_STENCIL && 
      pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
      usage = PIPE_TRANSFER_READ_WRITE;
   else
      usage = PIPE_TRANSFER_WRITE;
   
   pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0,
				       usage, x, y,
				       width, height);

   stmap = screen->transfer_map(screen, pt);

   pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
   assert(pixels);

   /* if width > MAX_WIDTH, have to process image in chunks */
   skipPixels = 0;
   while (skipPixels < width) {
      const GLint spanX = skipPixels;
      const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
      GLint row;
      for (row = 0; row < height; row++) {
         GLubyte sValues[MAX_WIDTH];
         GLuint zValues[MAX_WIDTH];
         GLenum destType = GL_UNSIGNED_BYTE;
         const GLvoid *source = _mesa_image_address2d(unpack, pixels,
                                                      width, height,
                                                      format, type,
                                                      row, skipPixels);
         _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
                                   type, source, unpack,
                                   ctx->_ImageTransferState);

         if (format == GL_DEPTH_STENCIL) {
            _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
                                    (1 << 24) - 1, type, source, unpack);
         }

         if (zoom) {
            _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
                          "zoom not complete");
         }

         {
            GLint spanY;

            if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
               spanY = height - row - 1;
            }
            else {
               spanY = row;
            }

            /* now pack the stencil (and Z) values in the dest format */
            switch (pt->format) {
            case PIPE_FORMAT_S8_UNORM:
               {
                  ubyte *dest = stmap + spanY * pt->stride + spanX;
                  assert(usage == PIPE_TRANSFER_WRITE);
                  memcpy(dest, sValues, spanWidth);
               }
               break;
            case PIPE_FORMAT_S8Z24_UNORM:
               if (format == GL_DEPTH_STENCIL) {
                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
                  GLint k;
                  assert(usage == PIPE_TRANSFER_WRITE);
                  for (k = 0; k < spanWidth; k++) {
                     dest[k] = zValues[k] | (sValues[k] << 24);
                  }
               }
               else {
                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
                  GLint k;
                  assert(usage == PIPE_TRANSFER_READ_WRITE);
                  for (k = 0; k < spanWidth; k++) {
                     dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
                  }
               }
               break;
            case PIPE_FORMAT_Z24S8_UNORM:
               if (format == GL_DEPTH_STENCIL) {
                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
                  GLint k;
                  assert(usage == PIPE_TRANSFER_WRITE);
                  for (k = 0; k < spanWidth; k++) {
                     dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
                  }
               }
               else {
                  uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
                  GLint k;
                  assert(usage == PIPE_TRANSFER_READ_WRITE);
                  for (k = 0; k < spanWidth; k++) {
                     dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
                  }
               }
               break;
            default:
               assert(0);
            }
         }
      }
      skipPixels += spanWidth;
   }

   _mesa_unmap_drawpix_pbo(ctx, unpack);

   /* unmap the stencil buffer */
   screen->transfer_unmap(screen, pt);
   screen->tex_transfer_destroy(pt);
}