Esempio n. 1
0
void
debug_dump_transfer_bmp(const char *filename,
                        struct pipe_transfer *transfer)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
   float *rgba;

   if (!transfer)
      goto error1;

   rgba = MALLOC(transfer->width*transfer->height*4*sizeof(float));
   if(!rgba)
      goto error1;

   pipe_get_tile_rgba(transfer, 0, 0,
                      transfer->width, transfer->height,
                      rgba);

   debug_dump_float_rgba_bmp(filename,
                             transfer->width, transfer->height,
                             rgba, transfer->width);

   FREE(rgba);
error1:
   ;
#endif
}
Esempio n. 2
0
void
debug_dump_transfer_bmp(struct pipe_context *pipe,
                        const char *filename,
                        struct pipe_transfer *transfer, void *ptr)
{
   float *rgba;

   if (!transfer)
      goto error1;

   rgba = MALLOC(transfer->box.width *
		 transfer->box.height *
		 transfer->box.depth *
		 4*sizeof(float));
   if(!rgba)
      goto error1;

   pipe_get_tile_rgba(transfer, ptr, 0, 0,
                      transfer->box.width, transfer->box.height,
                      rgba);

   debug_dump_float_rgba_bmp(filename,
                             transfer->box.width, transfer->box.height,
                             rgba, transfer->box.width);

   FREE(rgba);
error1:
   ;
}
Esempio n. 3
0
/**
 * Probe and test if the rectangle contains the expected color.
 *
 * If "num_expected_colors" > 1, at least one expected color must match
 * the probed color. "expected" should be an array of 4*num_expected_colors
 * floats.
 */
static bool
util_probe_rect_rgba_multi(struct pipe_context *ctx, struct pipe_resource *tex,
                           unsigned offx, unsigned offy, unsigned w,
                           unsigned h,
                           const float *expected,
                           unsigned num_expected_colors)
{
   struct pipe_transfer *transfer;
   void *map;
   float *pixels = malloc(w * h * 4 * sizeof(float));
   int x,y,e,c;
   bool pass = true;

   map = pipe_transfer_map(ctx, tex, 0, 0, PIPE_TRANSFER_READ,
                           offx, offy, w, h, &transfer);
   pipe_get_tile_rgba(transfer, map, 0, 0, w, h, pixels);
   pipe_transfer_unmap(ctx, transfer);

   for (e = 0; e < num_expected_colors; e++) {
      for (y = 0; y < h; y++) {
         for (x = 0; x < w; x++) {
            float *probe = &pixels[(y*w + x)*4];

            for (c = 0; c < 4; c++) {
               if (fabs(probe[c] - expected[e*4+c]) >= TOLERANCE) {
                  if (e < num_expected_colors-1)
                     goto next_color; /* test the next expected color */

                  printf("Probe color at (%i,%i),  ", offx+x, offy+y);
                  printf("Expected: %.3f, %.3f, %.3f, %.3f,  ",
                         expected[e*4], expected[e*4+1],
                         expected[e*4+2], expected[e*4+3]);
                  printf("Got: %.3f, %.3f, %.3f, %.3f\n",
                         probe[0], probe[1], probe[2], probe[2]);
                  pass = false;
                  goto done;
               }
            }
         }
      }
      break; /* this color was successful */

   next_color:;
   }
done:

   free(pixels);
   return pass;
}
Esempio n. 4
0
static void
accum_load(struct st_context *st, GLfloat value,
           GLint xpos, GLint ypos, GLint width, GLint height,
           struct st_renderbuffer *acc_strb,
           struct st_renderbuffer *color_strb)
{
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct pipe_transfer *color_trans;
   size_t stride = acc_strb->stride;
   GLubyte *data = acc_strb->data;
   GLfloat *buf;


   if (ST_DEBUG & DEBUG_FALLBACK)
      debug_printf("%s: fallback processing\n", __FUNCTION__);

   color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
						0, 0, 0,
						PIPE_TRANSFER_READ, xpos, ypos,
						width, height);

   buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));

   pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);

   switch (acc_strb->format) {
   case PIPE_FORMAT_R16G16B16A16_SNORM:
      {
         const GLfloat *color = buf;
         int i, j;
         for (i = 0; i < height; i++) {
            GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
            for (j = 0; j < width * 4; j++) {
               float val = *color++ * value;
               *acc++ = FLOAT_TO_SHORT(val);
            }
         }
      }
      break;
   default:
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
   }

   _mesa_free(buf);
   screen->tex_transfer_destroy(color_trans);
}
Esempio n. 5
0
void image_get_sub_data(struct vg_image * image,
                        void * data,
                        VGint dataStride,
                        VGImageFormat dataFormat,
                        VGint sx, VGint sy,
                        VGint width, VGint height)
{
   struct vg_context *ctx = vg_current_context();
   struct pipe_context *pipe = ctx->pipe;
   struct pipe_screen *screen = pipe->screen;
   VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
   VGfloat *df = (VGfloat*)temp;
   VGint y = 0, yStep = 1;
   VGint i;
   VGubyte *dst = (VGubyte *)data;

   {
      struct pipe_transfer *transfer =
         screen->get_tex_transfer(screen,
                                  image->texture,  0, 0, 0,
                                  PIPE_TRANSFER_READ,
                                  0, 0,
                                  image->x + image->width,
                                  image->y + image->height);
      /* Do a row at a time to flip image data vertically */
      for (i = 0; i < height; i++) {
#if 0
         debug_printf("%d-%d  == %d\n", sy, height, y);
#endif
         pipe_get_tile_rgba(transfer, sx+image->x, y, width, 1, df);
         y += yStep;
         _vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst);
         dst += dataStride;
      }

      screen->tex_transfer_destroy(transfer);
   }
}
Esempio n. 6
0
void vgReadPixels(void * data, VGint dataStride,
                  VGImageFormat dataFormat,
                  VGint sx, VGint sy,
                  VGint width, VGint height)
{
   struct vg_context *ctx = vg_current_context();
   struct pipe_context *pipe = ctx->pipe;
   struct pipe_screen *screen = pipe->screen;

   struct st_framebuffer *stfb = ctx->draw_buffer;
   struct st_renderbuffer *strb = stfb->strb;
   struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;

   VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
   VGfloat *df = (VGfloat*)temp;
   VGint y = (fb->height - sy) - 1, yStep = -1;
   VGint i;
   VGubyte *dst = (VGubyte *)data;
   VGint xoffset = 0, yoffset = 0;

   if (!supported_image_format(dataFormat)) {
      vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
      return;
   }
   if (!data || !is_aligned(data)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   if (width <= 0 || height <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   /* make sure rendering has completed */
   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
   if (sx < 0) {
      xoffset = -sx;
      xoffset *= _vega_size_for_format(dataFormat);
      width += sx;
      sx = 0;
   }
   if (sy < 0) {
      yoffset = -sy;
      height += sy;
      sy = 0;
      y = (fb->height - sy) - 1;
      yoffset *= dataStride;
   }

   {
      struct pipe_transfer *transfer;

      transfer = screen->get_tex_transfer(screen, strb->texture,  0, 0, 0,
                                          PIPE_TRANSFER_READ,
                                          0, 0, width, height);

      /* Do a row at a time to flip image data vertically */
      for (i = 0; i < height; i++) {
#if 0
         debug_printf("%d-%d  == %d\n", sy, height, y);
#endif
         pipe_get_tile_rgba(transfer, sx, y, width, 1, df);
         y += yStep;
         _vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
                                    dst + yoffset + xoffset);
         dst += dataStride;
      }

      screen->tex_transfer_destroy(transfer);
   }
}
Esempio n. 7
0
static void
accum_return(GLcontext *ctx, GLfloat value,
             GLint xpos, GLint ypos, GLint width, GLint height,
             struct st_renderbuffer *acc_strb,
             struct st_renderbuffer *color_strb)
{
   struct pipe_context *pipe = ctx->st->pipe;
   struct pipe_screen *screen = pipe->screen;
   const GLubyte *colormask = ctx->Color.ColorMask;
   enum pipe_transfer_usage usage;
   struct pipe_transfer *color_trans;
   size_t stride = acc_strb->stride;
   const GLubyte *data = acc_strb->data;
   GLfloat *buf;

   if (ST_DEBUG & DEBUG_FALLBACK)
      debug_printf("%s: fallback processing\n", __FUNCTION__);

   buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));

   if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
      usage = PIPE_TRANSFER_READ_WRITE;
   else
      usage = PIPE_TRANSFER_WRITE;
   
   color_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
						color_strb->texture, 0, 0, 0,
						usage,
						xpos, ypos,
						width, height);

   if (usage & PIPE_TRANSFER_READ)
      pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);

   switch (acc_strb->format) {
   case PIPE_FORMAT_R16G16B16A16_SNORM:
      {
         GLfloat *color = buf;
         int i, j, ch;
         for (i = 0; i < height; i++) {
            const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
            for (j = 0; j < width; j++) {
               for (ch = 0; ch < 4; ch++) {
                  if (colormask[ch]) {
                     GLfloat val = SHORT_TO_FLOAT(*acc * value);
                     *color = CLAMP(val, 0.0f, 1.0f);
                  }
                  else {
                     /* No change */
                  }
                  ++acc;
                  ++color;
               }
            }
         }
      }
      break;
   default:
      _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
   }

   pipe_put_tile_rgba(color_trans, 0, 0, width, height, buf);

   _mesa_free(buf);
   screen->tex_transfer_destroy(color_trans);
}
/**
 * Get a tile from the cache.
 * \param x, y  position of tile, in pixels
 */
struct softpipe_cached_tile *
sp_find_cached_tile(struct softpipe_tile_cache *tc, 
                    union tile_address addr )
{
   struct pipe_transfer *pt = tc->transfer;
   
   /* cache pos/entry: */
   const int pos = CACHE_POS(addr.bits.x,
                             addr.bits.y);
   struct softpipe_cached_tile *tile = tc->entries + pos;

   if (addr.value != tile->addr.value) {

      assert(pt->resource);
      if (tile->addr.bits.invalid == 0) {
         /* put dirty tile back in framebuffer */
         if (tc->depth_stencil) {
            pipe_put_tile_raw(tc->pipe, pt,
                              tile->addr.bits.x * TILE_SIZE,
                              tile->addr.bits.y * TILE_SIZE,
                              TILE_SIZE, TILE_SIZE,
                              tile->data.depth32, 0/*STRIDE*/);
         }
         else {
            pipe_put_tile_rgba(tc->pipe, pt,
                               tile->addr.bits.x * TILE_SIZE,
                               tile->addr.bits.y * TILE_SIZE,
                               TILE_SIZE, TILE_SIZE,
                               (float *) tile->data.color);
         }
      }

      tile->addr = addr;

      if (is_clear_flag_set(tc->clear_flags, addr)) {
         /* don't get tile from framebuffer, just clear it */
         if (tc->depth_stencil) {
            clear_tile(tile, pt->resource->format, tc->clear_val);
         }
         else {
            clear_tile_rgba(tile, pt->resource->format, tc->clear_color);
         }
         clear_clear_flag(tc->clear_flags, addr);
      }
      else {
         /* get new tile data from transfer */
         if (tc->depth_stencil) {
            pipe_get_tile_raw(tc->pipe, pt,
                              tile->addr.bits.x * TILE_SIZE, 
                              tile->addr.bits.y * TILE_SIZE, 
                              TILE_SIZE, TILE_SIZE,
                              tile->data.depth32, 0/*STRIDE*/);
         }
         else {
            pipe_get_tile_rgba(tc->pipe, pt,
                               tile->addr.bits.x * TILE_SIZE, 
                               tile->addr.bits.y * TILE_SIZE,
                               TILE_SIZE, TILE_SIZE,
                               (float *) tile->data.color);
         }
      }
   }

   tc->last_tile = tile;
   return tile;
}
Esempio n. 9
0
void vegaReadPixels(void * data, VGint dataStride,
                    VGImageFormat dataFormat,
                    VGint sx, VGint sy,
                    VGint width, VGint height)
{
   struct vg_context *ctx = vg_current_context();
   struct pipe_context *pipe = ctx->pipe;

   struct st_framebuffer *stfb = ctx->draw_buffer;
   struct st_renderbuffer *strb = stfb->strb;

   VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
   VGfloat *df = (VGfloat*)temp;
   VGint i;
   VGubyte *dst = (VGubyte *)data;
   VGint xoffset = 0, yoffset = 0;

   if (!supported_image_format(dataFormat)) {
      vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
      return;
   }
   if (!data || !is_aligned(data)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   if (width <= 0 || height <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (sx < 0) {
      xoffset = -sx;
      xoffset *= _vega_size_for_format(dataFormat);
      width += sx;
      sx = 0;
   }
   if (sy < 0) {
      yoffset = -sy;
      yoffset *= dataStride;
      height += sy;
      sy = 0;
   }

   if (sx + width > stfb->width || sy + height > stfb->height) {
      width = stfb->width - sx;
      height = stfb->height - sy;
      /* nothing to read */
      if (width <= 0 || height <= 0)
         return;
   }

   {
      VGint y = (stfb->height - sy) - 1, yStep = -1;
      struct pipe_transfer *transfer;
      void *map;

      map = pipe_transfer_map(pipe, strb->texture,  0, 0,
                              PIPE_TRANSFER_READ,
                              0, 0, sx + width, stfb->height - sy,
                              &transfer);

      /* Do a row at a time to flip image data vertically */
      for (i = 0; i < height; i++) {
#if 0
         debug_printf("%d-%d  == %d\n", sy, height, y);
#endif
         pipe_get_tile_rgba(transfer, map, sx, y, width, 1, df);
         y += yStep;
         _vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
                                    dst + yoffset + xoffset);
         dst += dataStride;
      }

      pipe->transfer_unmap(pipe, transfer);
   }
}
Esempio n. 10
0
void 
debug_dump_surface_bmp(const char *filename,
                       struct pipe_surface *surface)
{
   struct util_stream *stream;
   unsigned surface_usage;
   struct bmp_file_header bmfh;
   struct bmp_info_header bmih;
   float *rgba;
   unsigned x, y;

   if (!surface)
      goto error1;

   rgba = MALLOC(surface->width*4*sizeof(float));
   if(!rgba)
      goto error1;
   
   bmfh.bfType = 0x4d42;
   bmfh.bfSize = 14 + 40 + surface->height*surface->width*4;
   bmfh.bfReserved1 = 0;
   bmfh.bfReserved2 = 0;
   bmfh.bfOffBits = 14 + 40;
   
   bmih.biSize = 40;
   bmih.biWidth = surface->width;
   bmih.biHeight = surface->height;
   bmih.biPlanes = 1;
   bmih.biBitCount = 32;
   bmih.biCompression = 0;
   bmih.biSizeImage = surface->height*surface->width*4;
   bmih.biXPelsPerMeter = 0;
   bmih.biYPelsPerMeter = 0;
   bmih.biClrUsed = 0;
   bmih.biClrImportant = 0;
   
   stream = util_stream_create(filename, bmfh.bfSize);
   if(!stream)
      goto error2;
   
   util_stream_write(stream, &bmfh, 14);
   util_stream_write(stream, &bmih, 40);
   
   /* XXX: force mappable surface */
   surface_usage = surface->usage;
   surface->usage |= PIPE_BUFFER_USAGE_CPU_READ;

   y = surface->height;
   while(y--) {
      pipe_get_tile_rgba(surface,
                         0, y, surface->width, 1,
                         rgba);
      for(x = 0; x < surface->width; ++x)
      {
         struct bmp_rgb_quad pixel;
         pixel.rgbRed   = float_to_ubyte(rgba[x*4 + 0]);
         pixel.rgbGreen = float_to_ubyte(rgba[x*4 + 1]);
         pixel.rgbBlue  = float_to_ubyte(rgba[x*4 + 2]);
         pixel.rgbAlpha = float_to_ubyte(rgba[x*4 + 3]);
         util_stream_write(stream, &pixel, 4);
      }  
   }
   
   surface->usage = surface_usage;

   util_stream_close(stream);
error2:
   FREE(rgba);
error1:
   ;
}
Esempio n. 11
0
static void
st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
              GLsizei width, GLsizei height,
              GLint dstx, GLint dsty, GLenum type)
{
   struct st_context *st = ctx->st;
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct st_renderbuffer *rbRead;
   struct st_vertex_program *stvp;
   struct st_fragment_program *stfp;
   struct pipe_texture *pt;
   GLfloat *color;
   enum pipe_format srcFormat, texFormat;

   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);

   st_validate_state(st);

   if (srcx < 0) {
      width -= -srcx;
      dstx += -srcx;
      srcx = 0;
   }

   if (srcy < 0) {
      height -= -srcy;
      dsty += -srcy;
      srcy = 0;
   }

   if (dstx < 0) {
      width -= -dstx;
      srcx += -dstx;
      dstx = 0;
   }

   if (dsty < 0) {
      height -= -dsty;
      srcy += -dsty;
      dsty = 0;
   }

   if (width < 0 || height < 0)
      return;


   if (type == GL_STENCIL) {
      /* can't use texturing to do stencil */
      copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
      return;
   }

   if (type == GL_COLOR) {
      rbRead = st_get_color_read_renderbuffer(ctx);
      color = NULL;
      stfp = combined_drawpix_fragment_program(ctx);
      stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
   }
   else {
      assert(type == GL_DEPTH);
      rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
      color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
      stfp = make_fragment_shader_z(ctx->st);
      stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
   }

   srcFormat = rbRead->texture->format;

   if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, 
                                   PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
      texFormat = srcFormat;
   }
   else {
      /* srcFormat can't be used as a texture format */
      if (type == GL_DEPTH) {
         texFormat = st_choose_format(pipe, GL_DEPTH_COMPONENT, PIPE_TEXTURE_2D, 
                                      PIPE_TEXTURE_USAGE_DEPTH_STENCIL);
         assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
      }
      else {
         /* default color format */
         texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D, 
                                      PIPE_TEXTURE_USAGE_SAMPLER);
         assert(texFormat != PIPE_FORMAT_NONE);
      }
   }

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

      if (srcy < 0) {
         height -= -srcy;
         srcy = 0;
      }
      
      if (height < 0)
         return;
   }

   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
                          width, height, 1,
                          PIPE_TEXTURE_USAGE_SAMPLER);
   if (!pt)
      return;


   if (srcFormat == texFormat) {
      /* copy source framebuffer surface into mipmap/texture */
      struct pipe_surface *psRead = screen->get_tex_surface(screen,
                                       rbRead->texture, 0, 0, 0,
                                       PIPE_BUFFER_USAGE_GPU_READ);
      struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, 
                                      PIPE_BUFFER_USAGE_GPU_WRITE );
      pipe->surface_copy(pipe,
			 psTex, /* dest */
			 0, 0, /* destx/y */
			 psRead,
			 srcx, srcy, width, height);
      pipe_surface_reference(&psRead, NULL); 
      pipe_surface_reference(&psTex, NULL);
   }
   else {
      /* CPU-based fallback/conversion */
      struct pipe_transfer *ptRead =
         st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0,
					PIPE_TRANSFER_READ, srcx, srcy, width,
					height);
      struct pipe_transfer *ptTex;
      enum pipe_transfer_usage transfer_usage;

      if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
         transfer_usage = PIPE_TRANSFER_READ_WRITE;
      else
         transfer_usage = PIPE_TRANSFER_WRITE;

      ptTex = st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, transfer_usage,
                                             0, 0, width, height);

      if (type == GL_COLOR) {
         /* alternate path using get/put_tile() */
         GLfloat *buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));

         pipe_get_tile_rgba(ptRead, 0, 0, width, height, buf);
         pipe_put_tile_rgba(ptTex, 0, 0, width, height, buf);

         _mesa_free(buf);
      }
      else {
         /* GL_DEPTH */
         GLuint *buf = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
         pipe_get_tile_z(ptRead, 0, 0, width, height, buf);
         pipe_put_tile_z(ptTex, 0, 0, width, height, buf);
         _mesa_free(buf);
      }

      screen->tex_transfer_destroy(ptRead);
      screen->tex_transfer_destroy(ptTex);
   }

   /* draw textured quad */
   draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                      width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                      pt, stvp, stfp, color, GL_TRUE);

   pipe_texture_reference(&pt, NULL);
}