Пример #1
0
struct pipe_resource *
nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr,
                           unsigned bytes, unsigned bind)
{
   struct nv04_resource *buffer;

   buffer = CALLOC_STRUCT(nv04_resource);
   if (!buffer)
      return NULL;

   pipe_reference_init(&buffer->base.reference, 1);
   buffer->vtbl = &nouveau_buffer_vtbl;
   buffer->base.screen = pscreen;
   buffer->base.format = PIPE_FORMAT_R8_UNORM;
   buffer->base.usage = PIPE_USAGE_IMMUTABLE;
   buffer->base.bind = bind;
   buffer->base.width0 = bytes;
   buffer->base.height0 = 1;
   buffer->base.depth0 = 1;

   buffer->data = ptr;
   buffer->status = NOUVEAU_BUFFER_STATUS_USER_MEMORY;

   util_range_init(&buffer->valid_buffer_range);
   util_range_add(&buffer->valid_buffer_range, 0, bytes);

   return &buffer->base;
}
/**
 * Create a new texture object, using the given template info.
 */
static struct pipe_resource *
fd_resource_create(struct pipe_screen *pscreen,
		const struct pipe_resource *tmpl)
{
	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
	struct pipe_resource *prsc = &rsc->base.b;
	uint32_t size;

	DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
			"nr_samples=%u, usage=%u, bind=%x, flags=%x",
			tmpl->target, util_format_name(tmpl->format),
			tmpl->width0, tmpl->height0, tmpl->depth0,
			tmpl->array_size, tmpl->last_level, tmpl->nr_samples,
			tmpl->usage, tmpl->bind, tmpl->flags);

	if (!rsc)
		return NULL;

	*prsc = *tmpl;

	pipe_reference_init(&prsc->reference, 1);
	list_inithead(&rsc->list);
	prsc->screen = pscreen;

	util_range_init(&rsc->valid_buffer_range);

	rsc->base.vtbl = &fd_resource_vtbl;
	rsc->cpp = util_format_get_blocksize(tmpl->format);

	assert(rsc->cpp);

	if (is_a4xx(fd_screen(pscreen))) {
		switch (tmpl->target) {
		case PIPE_TEXTURE_3D:
			/* TODO 3D_ARRAY? */
			rsc->layer_first = false;
			break;
		default:
			rsc->layer_first = true;
			break;
		}
	}

	size = setup_slices(rsc, slice_alignment(pscreen, tmpl));

	if (rsc->layer_first) {
		rsc->layer_size = align(size, 4096);
		size = rsc->layer_size * prsc->array_size;
	}

	realloc_bo(rsc, size);
	if (!rsc->bo)
		goto fail;

	return prsc;
fail:
	fd_resource_destroy(pscreen, prsc);
	return NULL;
}
static struct r600_resource *
r600_alloc_buffer_struct(struct pipe_screen *screen,
			 const struct pipe_resource *templ)
{
	struct r600_resource *rbuffer;

	rbuffer = MALLOC_STRUCT(r600_resource);

	rbuffer->b.b = *templ;
	pipe_reference_init(&rbuffer->b.b.reference, 1);
	rbuffer->b.b.screen = screen;
	rbuffer->b.vtbl = &r600_buffer_vtbl;
	rbuffer->buf = NULL;
	rbuffer->TC_L2_dirty = false;
	util_range_init(&rbuffer->valid_buffer_range);
	return rbuffer;
}
Пример #4
0
/**
 * Create a texture from a winsys_handle. The handle is often created in
 * another process by first creating a pipe texture and then calling
 * resource_get_handle.
 */
static struct pipe_resource *
fd_resource_from_handle(struct pipe_screen *pscreen,
		const struct pipe_resource *tmpl,
		struct winsys_handle *handle, unsigned usage)
{
	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
	struct fd_resource_slice *slice = &rsc->slices[0];
	struct pipe_resource *prsc = &rsc->base.b;

	DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
			"nr_samples=%u, usage=%u, bind=%x, flags=%x",
			tmpl->target, util_format_name(tmpl->format),
			tmpl->width0, tmpl->height0, tmpl->depth0,
			tmpl->array_size, tmpl->last_level, tmpl->nr_samples,
			tmpl->usage, tmpl->bind, tmpl->flags);

	if (!rsc)
		return NULL;

	*prsc = *tmpl;

	pipe_reference_init(&prsc->reference, 1);
	list_inithead(&rsc->list);
	prsc->screen = pscreen;

	util_range_init(&rsc->valid_buffer_range);

	rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch);
	if (!rsc->bo)
		goto fail;

	rsc->base.vtbl = &fd_resource_vtbl;
	rsc->cpp = util_format_get_blocksize(tmpl->format);
	slice->pitch /= rsc->cpp;
	slice->offset = handle->offset;

	assert(rsc->cpp);

	return prsc;

fail:
	fd_resource_destroy(pscreen, prsc);
	return NULL;
}
Пример #5
0
struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
					 const struct pipe_resource *templ,
					 unsigned alignment)
{
	struct r600_screen *rscreen = (struct r600_screen*)screen;
	struct r600_resource *rbuffer;

	rbuffer = MALLOC_STRUCT(r600_resource);

	rbuffer->b.b = *templ;
	pipe_reference_init(&rbuffer->b.b.reference, 1);
	rbuffer->b.b.screen = screen;
	rbuffer->b.vtbl = &r600_buffer_vtbl;
	util_range_init(&rbuffer->valid_buffer_range);

	if (!r600_init_resource(&rscreen->b, rbuffer, templ->width0, alignment, TRUE, templ->usage)) {
		FREE(rbuffer);
		return NULL;
	}
	return &rbuffer->b.b;
}
Пример #6
0
/**
 * Create a new texture object, using the given template info.
 */
static struct pipe_resource *
fd_resource_create(struct pipe_screen *pscreen,
		const struct pipe_resource *tmpl)
{
	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
	struct pipe_resource *prsc = &rsc->base.b;
	enum pipe_format format = tmpl->format;
	uint32_t size, alignment;

	DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
			"nr_samples=%u, usage=%u, bind=%x, flags=%x",
			tmpl->target, util_format_name(format),
			tmpl->width0, tmpl->height0, tmpl->depth0,
			tmpl->array_size, tmpl->last_level, tmpl->nr_samples,
			tmpl->usage, tmpl->bind, tmpl->flags);

	if (!rsc)
		return NULL;

	*prsc = *tmpl;

	pipe_reference_init(&prsc->reference, 1);
	list_inithead(&rsc->list);
	prsc->screen = pscreen;

	util_range_init(&rsc->valid_buffer_range);

	rsc->base.vtbl = &fd_resource_vtbl;

	if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
		format = PIPE_FORMAT_Z32_FLOAT;
	else if (fd_screen(pscreen)->gpu_id < 400 &&
			 util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
		format = PIPE_FORMAT_R8G8B8A8_UNORM;
	rsc->internal_format = format;
	rsc->cpp = util_format_get_blocksize(format);

	assert(rsc->cpp);

	alignment = slice_alignment(pscreen, tmpl);
	if (is_a4xx(fd_screen(pscreen))) {
		switch (tmpl->target) {
		case PIPE_TEXTURE_3D:
			rsc->layer_first = false;
			break;
		default:
			rsc->layer_first = true;
			alignment = 1;
			break;
		}
	}

	size = setup_slices(rsc, alignment, format);

	if (rsc->layer_first) {
		rsc->layer_size = align(size, 4096);
		size = rsc->layer_size * prsc->array_size;
	}

	realloc_bo(rsc, size);
	if (!rsc->bo)
		goto fail;

	/* There is no native Z32F_S8 sampling or rendering format, so this must
	 * be emulated via two separate textures. The depth texture still keeps
	 * its Z32F_S8 format though, and we also keep a reference to a separate
	 * S8 texture.
	 */
	if (tmpl->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
		struct pipe_resource stencil = *tmpl;
		stencil.format = PIPE_FORMAT_S8_UINT;
		rsc->stencil = fd_resource(fd_resource_create(pscreen, &stencil));
		if (!rsc->stencil)
			goto fail;
	}

	return prsc;
fail:
	fd_resource_destroy(pscreen, prsc);
	return NULL;
}
Пример #7
0
struct pipe_resource *
nouveau_buffer_create(struct pipe_screen *pscreen,
                      const struct pipe_resource *templ)
{
   struct nouveau_screen *screen = nouveau_screen(pscreen);
   struct nv04_resource *buffer;
   boolean ret;

   buffer = CALLOC_STRUCT(nv04_resource);
   if (!buffer)
      return NULL;

   buffer->base = *templ;
   buffer->vtbl = &nouveau_buffer_vtbl;
   pipe_reference_init(&buffer->base.reference, 1);
   buffer->base.screen = pscreen;

   if (buffer->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
                             PIPE_RESOURCE_FLAG_MAP_COHERENT)) {
      buffer->domain = NOUVEAU_BO_GART;
   } else if (buffer->base.bind &
              (screen->vidmem_bindings & screen->sysmem_bindings)) {
      switch (buffer->base.usage) {
      case PIPE_USAGE_DEFAULT:
      case PIPE_USAGE_IMMUTABLE:
         buffer->domain = NOUVEAU_BO_VRAM;
         break;
      case PIPE_USAGE_DYNAMIC:
         /* For most apps, we'd have to do staging transfers to avoid sync
          * with this usage, and GART -> GART copies would be suboptimal.
          */
         buffer->domain = NOUVEAU_BO_VRAM;
         break;
      case PIPE_USAGE_STAGING:
      case PIPE_USAGE_STREAM:
         buffer->domain = NOUVEAU_BO_GART;
         break;
      default:
         assert(0);
         break;
      }
   } else {
      if (buffer->base.bind & screen->vidmem_bindings)
         buffer->domain = NOUVEAU_BO_VRAM;
      else
      if (buffer->base.bind & screen->sysmem_bindings)
         buffer->domain = NOUVEAU_BO_GART;
   }
   ret = nouveau_buffer_allocate(screen, buffer, buffer->domain);

   if (ret == FALSE)
      goto fail;

   if (buffer->domain == NOUVEAU_BO_VRAM && screen->hint_buf_keep_sysmem_copy)
      nouveau_buffer_cache(NULL, buffer);

   NOUVEAU_DRV_STAT(screen, buf_obj_current_count, 1);

   util_range_init(&buffer->valid_buffer_range);

   return &buffer->base;

fail:
   FREE(buffer);
   return NULL;
}