Exemplo n.º 1
0
/**
 * Fallback for pipe->clear_stencil() function.
 * sw fallback doesn't look terribly useful here.
 * Plus can't use these transfer fallbacks when clearing
 * multisampled surfaces for instance.
 * Clears all bound layers.
 */
void
util_clear_depth_stencil(struct pipe_context *pipe,
                         struct pipe_surface *dst,
                         unsigned clear_flags,
                         double depth,
                         unsigned stencil,
                         unsigned dstx, unsigned dsty,
                         unsigned width, unsigned height)
{
   enum pipe_format format = dst->format;
   struct pipe_transfer *dst_trans;
   ubyte *dst_map;
   boolean need_rmw = FALSE;
   unsigned max_layer, layer;

   if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) &&
       ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
       util_format_is_depth_and_stencil(format))
      need_rmw = TRUE;

   assert(dst->texture);
   if (!dst->texture)
      return;

   max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer;
   dst_map = pipe_transfer_map_3d(pipe,
                                  dst->texture,
                                  dst->u.tex.level,
                                  (need_rmw ? PIPE_TRANSFER_READ_WRITE :
                                              PIPE_TRANSFER_WRITE),
                                  dstx, dsty, dst->u.tex.first_layer,
                                  width, height, max_layer + 1, &dst_trans);
   assert(dst_map);

   if (dst_map) {
      unsigned dst_stride = dst_trans->stride;
      uint64_t zstencil = util_pack64_z_stencil(format, depth, stencil);
      ubyte *dst_layer = dst_map;
      unsigned i, j;
      assert(dst_trans->stride > 0);

      for (layer = 0; layer <= max_layer; layer++) {
         dst_map = dst_layer;

         switch (util_format_get_blocksize(format)) {
         case 1:
            assert(format == PIPE_FORMAT_S8_UINT);
            if(dst_stride == width)
               memset(dst_map, (uint8_t) zstencil, height * width);
            else {
               for (i = 0; i < height; i++) {
                  memset(dst_map, (uint8_t) zstencil, width);
                  dst_map += dst_stride;
               }
            }
            break;
         case 2:
            assert(format == PIPE_FORMAT_Z16_UNORM);
            for (i = 0; i < height; i++) {
               uint16_t *row = (uint16_t *)dst_map;
               for (j = 0; j < width; j++)
                  *row++ = (uint16_t) zstencil;
               dst_map += dst_stride;
               }
            break;
         case 4:
            if (!need_rmw) {
               for (i = 0; i < height; i++) {
                  uint32_t *row = (uint32_t *)dst_map;
                  for (j = 0; j < width; j++)
                     *row++ = (uint32_t) zstencil;
                  dst_map += dst_stride;
               }
            }
            else {
               uint32_t dst_mask;
               if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT)
                  dst_mask = 0x00ffffff;
               else {
                  assert(format == PIPE_FORMAT_S8_UINT_Z24_UNORM);
                  dst_mask = 0xffffff00;
               }
               if (clear_flags & PIPE_CLEAR_DEPTH)
                  dst_mask = ~dst_mask;
               for (i = 0; i < height; i++) {
                  uint32_t *row = (uint32_t *)dst_map;
                  for (j = 0; j < width; j++) {
                     uint32_t tmp = *row & dst_mask;
                     *row++ = tmp | ((uint32_t) zstencil & ~dst_mask);
                  }
                  dst_map += dst_stride;
               }
            }
            break;
         case 8:
            if (!need_rmw) {
               for (i = 0; i < height; i++) {
                  uint64_t *row = (uint64_t *)dst_map;
                  for (j = 0; j < width; j++)
                     *row++ = zstencil;
                  dst_map += dst_stride;
               }
            }
            else {
               uint64_t src_mask;

               if (clear_flags & PIPE_CLEAR_DEPTH)
                  src_mask = 0x00000000ffffffffull;
               else
                  src_mask = 0x000000ff00000000ull;

               for (i = 0; i < height; i++) {
                  uint64_t *row = (uint64_t *)dst_map;
                  for (j = 0; j < width; j++) {
                     uint64_t tmp = *row & ~src_mask;
                     *row++ = tmp | (zstencil & src_mask);
                  }
                  dst_map += dst_stride;
               }
            }
            break;
         default:
            assert(0);
            break;
         }
         dst_layer += dst_trans->layer_stride;
      }

      pipe->transfer_unmap(pipe, dst_trans);
   }
}
Exemplo n.º 2
0
static void
begin_binning( struct lp_setup_context *setup )
{
   struct lp_scene *scene = setup->scene;
   boolean need_zsload = FALSE;
   boolean ok;
   unsigned i, j;

   assert(scene);
   assert(scene->fence == NULL);

   /* Always create a fence:
    */
   scene->fence = lp_fence_create(MAX2(1, setup->num_threads));

   /* Initialize the bin flags and x/y coords:
    */
   for (i = 0; i < scene->tiles_x; i++) {
      for (j = 0; j < scene->tiles_y; j++) {
         scene->tile[i][j].x = i;
         scene->tile[i][j].y = j;
      }
   }

   ok = try_update_scene_state(setup);
   assert(ok);

   if (setup->fb.zsbuf &&
       ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
        util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
      need_zsload = TRUE;

   LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
          (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
          need_zsload ? "clear": "load");

   if (setup->fb.nr_cbufs) {
      if (setup->clear.flags & PIPE_CLEAR_COLOR) {
         ok = lp_scene_bin_everywhere( scene, 
                                       LP_RAST_OP_CLEAR_COLOR, 
                                       setup->clear.color );
         assert(ok);
      }
   }

   if (setup->fb.zsbuf) {
      if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
         if (!need_zsload)
            scene->has_depthstencil_clear = TRUE;
         ok = lp_scene_bin_everywhere( scene,
                                       LP_RAST_OP_CLEAR_ZSTENCIL,
                                       lp_rast_arg_clearzs(
                                          setup->clear.zsvalue,
                                          setup->clear.zsmask));
         assert(ok);
      }
   }

   if (setup->active_query) {
      ok = lp_scene_bin_everywhere( scene,
                                    LP_RAST_OP_BEGIN_QUERY,
                                    lp_rast_arg_query(setup->active_query) );
      assert(ok);
   }
      

   setup->clear.flags = 0;
   setup->clear.zsmask = 0;
   setup->clear.zsvalue = 0;

   LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__);
}
Exemplo n.º 3
0
/**
 * Do a CopyTexSubImage operation using a read transfer from the source,
 * a write transfer to the destination and get_tile()/put_tile() to access
 * the pixels/texels.
 *
 * Note: srcY=0=TOP of renderbuffer
 */
static void
fallback_copy_texsubimage(struct gl_context *ctx,
                          struct st_renderbuffer *strb,
                          struct st_texture_image *stImage,
                          GLenum baseFormat,
                          GLint destX, GLint destY, GLint destZ,
                          GLint srcX, GLint srcY,
                          GLsizei width, GLsizei height)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct pipe_transfer *src_trans;
   GLvoid *texDest;
   enum pipe_transfer_usage transfer_usage;
   void *map;

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

   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
      srcY = strb->Base.Height - srcY - height;
   }

   map = pipe_transfer_map(pipe,
                           strb->texture,
                           strb->rtt_level,
                           strb->rtt_face + strb->rtt_slice,
                           PIPE_TRANSFER_READ,
                           srcX, srcY,
                           width, height, &src_trans);

   if ((baseFormat == GL_DEPTH_COMPONENT ||
        baseFormat == GL_DEPTH_STENCIL) &&
       util_format_is_depth_and_stencil(stImage->pt->format))
      transfer_usage = PIPE_TRANSFER_READ_WRITE;
   else
      transfer_usage = PIPE_TRANSFER_WRITE;

   /* XXX this used to ignore destZ param */
   texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
                                  destX, destY, width, height);

   if (baseFormat == GL_DEPTH_COMPONENT ||
       baseFormat == GL_DEPTH_STENCIL) {
      const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
                                     ctx->Pixel.DepthBias != 0.0F);
      GLint row, yStep;
      uint *data;

      /* determine bottom-to-top vs. top-to-bottom order for src buffer */
      if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
         srcY = height - 1;
         yStep = -1;
      }
      else {
         srcY = 0;
         yStep = 1;
      }

      data = malloc(width * sizeof(uint));

      if (data) {
         /* To avoid a large temp memory allocation, do copy row by row */
         for (row = 0; row < height; row++, srcY += yStep) {
            pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data);
            if (scaleOrBias) {
               _mesa_scale_and_bias_depth_uint(ctx, width, data);
            }
            pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
                            data);
         }
      }
      else {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
      }

      free(data);
   }
   else {
      /* RGBA format */
      GLfloat *tempSrc =
         malloc(width * height * 4 * sizeof(GLfloat));

      if (tempSrc && texDest) {
         const GLint dims = 2;
         const GLint dstRowStride = stImage->transfer->stride;
         struct gl_texture_image *texImage = &stImage->base;
         struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;

         if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
            unpack.Invert = GL_TRUE;
         }

         /* get float/RGBA image from framebuffer */
         /* XXX this usually involves a lot of int/float conversion.
          * try to avoid that someday.
          */
         pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height,
                                   util_format_linear(strb->texture->format),
                                   tempSrc);

         /* Store into texture memory.
          * Note that this does some special things such as pixel transfer
          * ops and format conversion.  In particular, if the dest tex format
          * is actually RGBA but the user created the texture as GL_RGB we
          * need to fill-in/override the alpha channel with 1.0.
          */
         _mesa_texstore(ctx, dims,
                        texImage->_BaseFormat, 
                        texImage->TexFormat, 
                        dstRowStride,
                        (GLubyte **) &texDest,
                        width, height, 1,
                        GL_RGBA, GL_FLOAT, tempSrc, /* src */
                        &unpack);
      }
      else {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
      }

      free(tempSrc);
   }

   st_texture_image_unmap(st, stImage);
   pipe->transfer_unmap(pipe, src_trans);
}
Exemplo n.º 4
0
static boolean
begin_binning( struct lp_setup_context *setup )
{
   struct lp_scene *scene = setup->scene;
   boolean need_zsload = FALSE;
   boolean ok;

   assert(scene);
   assert(scene->fence == NULL);

   /* Always create a fence:
    */
   scene->fence = lp_fence_create(MAX2(1, setup->num_threads));
   if (!scene->fence)
      return FALSE;

   ok = try_update_scene_state(setup);
   if (!ok)
      return FALSE;

   if (setup->fb.zsbuf &&
       ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
        util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
      need_zsload = TRUE;

   LP_DBG(DEBUG_SETUP, "%s color clear bufs: %x depth: %s\n", __FUNCTION__,
          setup->clear.flags >> 2,
          need_zsload ? "clear": "load");

   if (setup->clear.flags & PIPE_CLEAR_COLOR) {
      unsigned cbuf;
      for (cbuf = 0; cbuf < setup->fb.nr_cbufs; cbuf++) {
         assert(PIPE_CLEAR_COLOR0 == 1 << 2);
         if (setup->clear.flags & (1 << (2 + cbuf))) {
            union lp_rast_cmd_arg clearrb_arg;
            struct lp_rast_clear_rb *cc_scene =
               (struct lp_rast_clear_rb *)
                  lp_scene_alloc(scene, sizeof(struct lp_rast_clear_rb));

            if (!cc_scene) {
               return FALSE;
            }

            cc_scene->cbuf = cbuf;
            cc_scene->color_val = setup->clear.color_val[cbuf];
            clearrb_arg.clear_rb = cc_scene;

            if (!lp_scene_bin_everywhere(scene,
                                         LP_RAST_OP_CLEAR_COLOR,
                                         clearrb_arg))
               return FALSE;
         }
      }
   }

   if (setup->fb.zsbuf) {
      if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
         ok = lp_scene_bin_everywhere( scene,
                                       LP_RAST_OP_CLEAR_ZSTENCIL,
                                       lp_rast_arg_clearzs(
                                          setup->clear.zsvalue,
                                          setup->clear.zsmask));
         if (!ok)
            return FALSE;
      }
   }

   setup->clear.flags = 0;
   setup->clear.zsmask = 0;
   setup->clear.zsvalue = 0;

   scene->had_queries = !!setup->active_binned_queries;

   LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__);
   return TRUE;
}
Exemplo n.º 5
0
static int r600_init_surface(struct radeon_surface *surface,
			     const struct pipe_resource *ptex,
			     unsigned array_mode)
{
	surface->npix_x = ptex->width0;
	surface->npix_y = ptex->height0;
	surface->npix_z = ptex->depth0;
	surface->blk_w = util_format_get_blockwidth(ptex->format);
	surface->blk_h = util_format_get_blockheight(ptex->format);
	surface->blk_d = 1;
	surface->array_size = 1;
	surface->last_level = ptex->last_level;
	surface->bpe = util_format_get_blocksize(ptex->format);
	/* align byte per element on dword */
	if (surface->bpe == 3) {
		surface->bpe = 4;
	}
	surface->nsamples = 1;
	surface->flags = 0;
	switch (array_mode) {
	case V_009910_ARRAY_1D_TILED_THIN1:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
		break;
	case V_009910_ARRAY_2D_TILED_THIN1:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
		break;
	case V_009910_ARRAY_LINEAR_ALIGNED:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
		break;
	case V_009910_ARRAY_LINEAR_GENERAL:
	default:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
		break;
	}
	switch (ptex->target) {
	case PIPE_TEXTURE_1D:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
		break;
	case PIPE_TEXTURE_RECT:
	case PIPE_TEXTURE_2D:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
		break;
	case PIPE_TEXTURE_3D:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
		break;
	case PIPE_TEXTURE_1D_ARRAY:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
		surface->array_size = ptex->array_size;
		break;
	case PIPE_TEXTURE_2D_ARRAY:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
		surface->array_size = ptex->array_size;
		break;
	case PIPE_TEXTURE_CUBE:
		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
		break;
	case PIPE_BUFFER:
	default:
		return -EINVAL;
	}
	if (ptex->bind & PIPE_BIND_SCANOUT) {
		surface->flags |= RADEON_SURF_SCANOUT;
	}
	if (util_format_is_depth_and_stencil(ptex->format)) {
		surface->flags |= RADEON_SURF_ZBUFFER;
		surface->flags |= RADEON_SURF_SBUFFER;
	}

	return 0;
}
Exemplo n.º 6
0
static void
st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
              GLsizei width, GLsizei height,
              GLint dstx, GLint dsty, GLenum type)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct st_renderbuffer *rbRead;
   void *driver_vp, *driver_fp;
   struct pipe_resource *pt;
   struct pipe_sampler_view *sv[2];
   int num_sampler_view = 1;
   GLfloat *color;
   enum pipe_format srcFormat, texFormat;
   GLboolean invertTex = GL_FALSE;
   GLint readX, readY, readW, readH;
   GLuint sample_count;
   struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
   struct st_fp_variant *fpv;

   st_validate_state(st);

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

   if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
      return;

   /*
    * The subsequent code implements glCopyPixels by copying the source
    * pixels into a temporary texture that's then applied to a textured quad.
    * When we draw the textured quad, all the usual per-fragment operations
    * are handled.
    */


   /*
    * Get vertex/fragment shaders
    */
   if (type == GL_COLOR) {
      rbRead = st_get_color_read_renderbuffer(ctx);
      color = NULL;

      fpv = get_color_fp_variant(st);
      driver_fp = fpv->driver_shader;

      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);

      if (st->pixel_xfer.pixelmap_enabled) {
	  sv[1] = st->pixel_xfer.pixelmap_sampler_view;
	  num_sampler_view++;
      }
   }
   else {
      assert(type == GL_DEPTH);
      rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
      color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];

      fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE);
      driver_fp = fpv->driver_shader;

      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
   }

   /* update fragment program constants */
   st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);


   if (rbRead->Base.Wrapped)
      rbRead = st_renderbuffer(rbRead->Base.Wrapped);

   sample_count = rbRead->texture->nr_samples;
   /* I believe this would be legal, presumably would need to do a resolve
      for color, and for depth/stencil spec says to just use one of the
      depth/stencil samples per pixel? Need some transfer clarifications. */
   assert(sample_count < 2);

   srcFormat = rbRead->texture->format;

   if (screen->is_format_supported(screen, srcFormat, st->internal_target,
                                   sample_count,
                                   PIPE_BIND_SAMPLER_VIEW)) {
      texFormat = srcFormat;
   }
   else {
      /* srcFormat can't be used as a texture format */
      if (type == GL_DEPTH) {
         texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
                                      GL_NONE, GL_NONE, st->internal_target,
				      sample_count, PIPE_BIND_DEPTH_STENCIL);
         assert(texFormat != PIPE_FORMAT_NONE);
      }
      else {
         /* default color format */
         texFormat = st_choose_format(screen, GL_RGBA,
                                      GL_NONE, GL_NONE, st->internal_target,
                                      sample_count, PIPE_BIND_SAMPLER_VIEW);
         assert(texFormat != PIPE_FORMAT_NONE);
      }
   }

   /* Invert src region if needed */
   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
      srcy = ctx->ReadBuffer->Height - srcy - height;
      invertTex = !invertTex;
   }

   /* Clip the read region against the src buffer bounds.
    * We'll still allocate a temporary buffer/texture for the original
    * src region size but we'll only read the region which is on-screen.
    * This may mean that we draw garbage pixels into the dest region, but
    * that's expected.
    */
   readX = srcx;
   readY = srcy;
   readW = width;
   readH = height;
   _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack);
   readW = MAX2(0, readW);
   readH = MAX2(0, readH);

   /* alloc temporary texture */
   pt = alloc_texture(st, width, height, texFormat);
   if (!pt)
      return;

   sv[0] = st_create_texture_sampler_view(st->pipe, pt);
   if (!sv[0]) {
      pipe_resource_reference(&pt, NULL);
      return;
   }

   /* Make temporary texture which is a copy of the src region.
    */
   if (srcFormat == texFormat) {
      struct pipe_box src_box;
      u_box_2d(readX, readY, readW, readH, &src_box);
      /* copy source framebuffer surface into mipmap/texture */
      pipe->resource_copy_region(pipe,
                                 pt,                                /* dest tex */
                                 0,                                 /* dest lvl */
                                 pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
                                 rbRead->texture,                   /* src tex */
                                 rbRead->rtt_level,                 /* src lvl */
                                 &src_box);

   }
   else {
      /* CPU-based fallback/conversion */
      struct pipe_transfer *ptRead =
         pipe_get_transfer(st->pipe, rbRead->texture,
                           rbRead->rtt_level,
                           rbRead->rtt_face + rbRead->rtt_slice,
                           PIPE_TRANSFER_READ,
                           readX, readY, readW, readH);
      struct pipe_transfer *ptTex;
      enum pipe_transfer_usage transfer_usage;

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

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

      ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
                                0, 0, width, height);

      /* copy image from ptRead surface to ptTex surface */
      if (type == GL_COLOR) {
         /* alternate path using get/put_tile() */
         GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
         enum pipe_format readFormat, drawFormat;
         readFormat = util_format_linear(rbRead->texture->format);
         drawFormat = util_format_linear(pt->format);
         pipe_get_tile_rgba_format(pipe, ptRead, 0, 0, readW, readH,
                                   readFormat, buf);
         pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
                                   readW, readH, drawFormat, buf);
         free(buf);
      }
      else {
         /* GL_DEPTH */
         GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
         pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf);
         pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
                         readW, readH, buf);
         free(buf);
      }

      pipe->transfer_destroy(pipe, ptRead);
      pipe->transfer_destroy(pipe, ptTex);
   }

   /* OK, the texture 'pt' contains the src image/pixels.  Now draw a
    * textured quad with that texture.
    */
   draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                      width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
                      sv,
                      num_sampler_view,
                      driver_vp, 
                      driver_fp,
                      color, invertTex, GL_FALSE, GL_FALSE);

   pipe_resource_reference(&pt, NULL);
   pipe_sampler_view_reference(&sv[0], NULL);
}
Exemplo n.º 7
0
static void cik_sdma_copy_tile(struct si_context *ctx,
			       struct pipe_resource *dst,
			       unsigned dst_level,
			       struct pipe_resource *src,
			       unsigned src_level,
			       unsigned y,
			       unsigned copy_height,
			       unsigned y_align,
			       unsigned pitch,
			       unsigned bpe)
{
	struct radeon_winsys_cs *cs = ctx->b.dma.cs;
	struct si_screen *sscreen = ctx->screen;
	struct r600_texture *rsrc = (struct r600_texture*)src;
	struct r600_texture *rdst = (struct r600_texture*)dst;
	struct r600_texture *rlinear, *rtiled;
	unsigned linear_lvl, tiled_lvl;
	unsigned array_mode, lbpe, pitch_tile_max, slice_tile_max, size;
	unsigned ncopy, height, cheight, detile, i, src_mode, dst_mode;
	unsigned sub_op, bank_h, bank_w, mt_aspect, nbanks, tile_split, mt;
	uint64_t base, addr;
	unsigned pipe_config, tile_mode_index;

	dst_mode = rdst->surface.level[dst_level].mode;
	src_mode = rsrc->surface.level[src_level].mode;
	assert(dst_mode != src_mode);
	assert(src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED || dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED);

	sub_op = CIK_SDMA_COPY_SUB_OPCODE_TILED;
	lbpe = util_logbase2(bpe);
	pitch_tile_max = ((pitch / bpe) / 8) - 1;

	detile = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
	rlinear = detile ? rdst : rsrc;
	rtiled = detile ? rsrc : rdst;
	linear_lvl = detile ? dst_level : src_level;
	tiled_lvl = detile ? src_level : dst_level;

	assert(!util_format_is_depth_and_stencil(rtiled->resource.b.b.format));

	array_mode = si_array_mode(rtiled->surface.level[tiled_lvl].mode);
	slice_tile_max = (rtiled->surface.level[tiled_lvl].nblk_x *
			  rtiled->surface.level[tiled_lvl].nblk_y) / (8*8) - 1;
	height = rlinear->surface.level[linear_lvl].nblk_y;
	base = rtiled->surface.level[tiled_lvl].offset;
	addr = rlinear->surface.level[linear_lvl].offset;
	bank_h = cik_bank_wh(rtiled->surface.bankh);
	bank_w = cik_bank_wh(rtiled->surface.bankw);
	mt_aspect = cik_macro_tile_aspect(rtiled->surface.mtilea);
	tile_split = cik_tile_split(rtiled->surface.tile_split);
	tile_mode_index = si_tile_mode_index(rtiled, tiled_lvl, false);
	nbanks = si_num_banks(sscreen, rtiled);
	base += rtiled->resource.gpu_address;
	addr += rlinear->resource.gpu_address;

	pipe_config = cik_db_pipe_config(sscreen, tile_mode_index);
	mt = cik_micro_tile_mode(sscreen, tile_mode_index);

	size = (copy_height * pitch) / 4;
	cheight = copy_height;
	if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
		cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
		cheight &= ~(y_align - 1);
	}
	ncopy = (copy_height + cheight - 1) / cheight;
	r600_need_dma_space(&ctx->b, ncopy * 12);

	radeon_add_to_buffer_list(&ctx->b, &ctx->b.dma, &rsrc->resource,
			      RADEON_USAGE_READ, RADEON_PRIO_SDMA_TEXTURE);
	radeon_add_to_buffer_list(&ctx->b, &ctx->b.dma, &rdst->resource,
			      RADEON_USAGE_WRITE, RADEON_PRIO_SDMA_TEXTURE);

	copy_height = size * 4 / pitch;
	for (i = 0; i < ncopy; i++) {
		cheight = copy_height;
		if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
			cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
			cheight &= ~(y_align - 1);
		}
		size = (cheight * pitch) / 4;

		cs->buf[cs->cdw++] = CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
						     sub_op, detile << 15);
		cs->buf[cs->cdw++] = base;
		cs->buf[cs->cdw++] = base >> 32;
		cs->buf[cs->cdw++] = ((height - 1) << 16) | pitch_tile_max;
		cs->buf[cs->cdw++] = slice_tile_max;
		cs->buf[cs->cdw++] = (pipe_config << 26) | (mt_aspect << 24) |
			(nbanks << 21) | (bank_h << 18) | (bank_w << 15) |
			(tile_split << 11) | (mt << 8) | (array_mode << 3) |
			lbpe;
		cs->buf[cs->cdw++] = y << 16; /* | x */
		cs->buf[cs->cdw++] = 0; /* z */
		cs->buf[cs->cdw++] = addr & 0xfffffffc;
		cs->buf[cs->cdw++] = addr >> 32;
		cs->buf[cs->cdw++] = (pitch / bpe) - 1;
		cs->buf[cs->cdw++] = size;

		copy_height -= cheight;
		y += cheight;
	}
}
Exemplo n.º 8
0
static void
vc4_clear(struct pipe_context *pctx, unsigned buffers,
          const union pipe_color_union *color, double depth, unsigned stencil)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        struct vc4_job *job = vc4_get_job_for_fbo(vc4);

        /* We can't flag new buffers for clearing once we've queued draws.  We
         * could avoid this by using the 3d engine to clear.
         */
        if (job->draw_calls_queued) {
                perf_debug("Flushing rendering to process new clear.\n");
                vc4_job_submit(vc4, job);
                job = vc4_get_job_for_fbo(vc4);
        }

        if (buffers & PIPE_CLEAR_COLOR0) {
                struct vc4_resource *rsc =
                        vc4_resource(vc4->framebuffer.cbufs[0]->texture);
                uint32_t clear_color;

                if (vc4_rt_format_is_565(vc4->framebuffer.cbufs[0]->format)) {
                        /* In 565 mode, the hardware will be packing our color
                         * for us.
                         */
                        clear_color = pack_rgba(PIPE_FORMAT_R8G8B8A8_UNORM,
                                                color->f);
                } else {
                        /* Otherwise, we need to do this packing because we
                         * support multiple swizzlings of RGBA8888.
                         */
                        clear_color =
                                pack_rgba(vc4->framebuffer.cbufs[0]->format,
                                          color->f);
                }
                job->clear_color[0] = job->clear_color[1] = clear_color;
                rsc->initialized_buffers |= (buffers & PIPE_CLEAR_COLOR0);
        }

        if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
                struct vc4_resource *rsc =
                        vc4_resource(vc4->framebuffer.zsbuf->texture);
                unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;

                /* Clearing ZS will clear both Z and stencil, so if we're
                 * trying to clear just one then we need to draw a quad to do
                 * it instead.
                 */
                if ((zsclear == PIPE_CLEAR_DEPTH ||
                     zsclear == PIPE_CLEAR_STENCIL) &&
                    (rsc->initialized_buffers & ~(zsclear | job->cleared)) &&
                    util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
                        perf_debug("Partial clear of Z+stencil buffer, "
                                   "drawing a quad instead of fast clearing\n");
                        vc4_blitter_save(vc4);
                        util_blitter_clear(vc4->blitter,
                                           vc4->framebuffer.width,
                                           vc4->framebuffer.height,
                                           1,
                                           zsclear,
                                           NULL, depth, stencil);
                        buffers &= ~zsclear;
                        if (!buffers)
                                return;
                }

                /* Though the depth buffer is stored with Z in the high 24,
                 * for this field we just need to store it in the low 24.
                 */
                if (buffers & PIPE_CLEAR_DEPTH) {
                        job->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM,
                                                       depth);
                }
                if (buffers & PIPE_CLEAR_STENCIL)
                        job->clear_stencil = stencil;

                rsc->initialized_buffers |= zsclear;
        }

        job->draw_min_x = 0;
        job->draw_min_y = 0;
        job->draw_max_x = vc4->framebuffer.width;
        job->draw_max_y = vc4->framebuffer.height;
        job->cleared |= buffers;
        job->resolve |= buffers;

        vc4_start_draw(vc4);
}
Exemplo n.º 9
0
static void
si_flush_depth_texture(struct si_context *sctx,
		       struct r600_texture *tex,
		       unsigned required_planes,
		       unsigned first_level, unsigned last_level,
		       unsigned first_layer, unsigned last_layer)
{
	unsigned inplace_planes = 0;
	unsigned copy_planes = 0;
	unsigned level_mask = u_bit_consecutive(first_level, last_level - first_level + 1);
	unsigned levels_z = 0;
	unsigned levels_s = 0;

	if (required_planes & PIPE_MASK_Z) {
		levels_z = level_mask & tex->dirty_level_mask;

		if (levels_z) {
			if (r600_can_sample_zs(tex, false))
				inplace_planes |= PIPE_MASK_Z;
			else
				copy_planes |= PIPE_MASK_Z;
		}
	}
	if (required_planes & PIPE_MASK_S) {
		levels_s = level_mask & tex->stencil_dirty_level_mask;

		if (levels_s) {
			if (r600_can_sample_zs(tex, true))
				inplace_planes |= PIPE_MASK_S;
			else
				copy_planes |= PIPE_MASK_S;
		}
	}

	/* We may have to allocate the flushed texture here when called from
	 * si_decompress_subresource.
	 */
	if (copy_planes &&
	    (tex->flushed_depth_texture ||
	     r600_init_flushed_depth_texture(&sctx->b.b, &tex->resource.b.b, NULL))) {
		struct r600_texture *dst = tex->flushed_depth_texture;
		unsigned fully_copied_levels;
		unsigned levels = 0;

		assert(tex->flushed_depth_texture);

		if (util_format_is_depth_and_stencil(dst->resource.b.b.format))
			copy_planes = PIPE_MASK_Z | PIPE_MASK_S;

		if (copy_planes & PIPE_MASK_Z) {
			levels |= levels_z;
			levels_z = 0;
		}
		if (copy_planes & PIPE_MASK_S) {
			levels |= levels_s;
			levels_s = 0;
		}

		fully_copied_levels = si_blit_dbcb_copy(
			sctx, tex, dst, copy_planes, levels,
			first_layer, last_layer,
			0, u_max_sample(&tex->resource.b.b));

		if (copy_planes & PIPE_MASK_Z)
			tex->dirty_level_mask &= ~fully_copied_levels;
		if (copy_planes & PIPE_MASK_S)
			tex->stencil_dirty_level_mask &= ~fully_copied_levels;
	}

	if (inplace_planes) {
		si_blit_decompress_zs_in_place(
			sctx, tex,
			levels_z, levels_s,
			first_layer, last_layer);
	}
}