static struct pipe_surface * dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen, unsigned handle, enum pipe_format format, unsigned width, unsigned height, unsigned pitch) { struct pipe_surface *ps = NULL; struct pipe_texture *pt = NULL; struct pipe_texture tmpl; memset(&tmpl, 0, sizeof(tmpl)); tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY; tmpl.target = PIPE_TEXTURE_2D; tmpl.last_level = 0; tmpl.depth[0] = 1; tmpl.format = format; tmpl.width[0] = width; tmpl.height[0] = height; pf_get_block(tmpl.format, &tmpl.block); pt = api->texture_from_shared_handle(api, pscreen, &tmpl, "front buffer", pitch, handle); if (!pt) return NULL; ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE); /* we don't need the texture from this point on */ pipe_texture_reference(&pt, NULL); return ps; }
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); }
static struct llvmpipe_displaytarget * xm_displaytarget_create(struct llvmpipe_winsys *winsys, enum pipe_format format, unsigned width, unsigned height, unsigned alignment, unsigned *stride) { struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget); unsigned nblocksx, nblocksy, size; xm_dt = CALLOC_STRUCT(xm_displaytarget); if(!xm_dt) goto no_xm_dt; xm_dt->format = format; xm_dt->width = width; xm_dt->height = height; pf_get_block(format, &xm_dt->block); nblocksx = pf_get_nblocksx(&xm_dt->block, width); nblocksy = pf_get_nblocksy(&xm_dt->block, height); xm_dt->stride = align(nblocksx * xm_dt->block.size, alignment); size = xm_dt->stride * nblocksy; #ifdef USE_XSHM if (!debug_get_bool_option("XLIB_NO_SHM", FALSE)) { xm_dt->shminfo.shmid = -1; xm_dt->shminfo.shmaddr = (char *) -1; xm_dt->shm = TRUE; xm_dt->data = alloc_shm(xm_dt, size); if(!xm_dt->data) goto no_data; } #endif if(!xm_dt->data) { xm_dt->data = align_malloc(size, alignment); if(!xm_dt->data) goto no_data; } *stride = xm_dt->stride; return (struct llvmpipe_displaytarget *)xm_dt; no_data: FREE(xm_dt); no_xm_dt: return NULL; }
/** * gl_renderbuffer::AllocStorage() * This is called to allocate the original drawing surface, and * during window resize. */ static GLboolean st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); enum pipe_format format; if (strb->format != PIPE_FORMAT_NONE) format = strb->format; else format = st_choose_renderbuffer_format(pipe->screen, internalFormat); /* init renderbuffer fields */ strb->Base.Width = width; strb->Base.Height = height; init_renderbuffer_bits(strb, format); strb->defined = GL_FALSE; /* undefined contents now */ if(strb->software) { struct pipe_format_block block; size_t size; _mesa_free(strb->data); assert(strb->format != PIPE_FORMAT_NONE); pf_get_block(strb->format, &block); strb->stride = pf_get_stride(&block, width); size = pf_get_2d_size(&block, strb->stride, height); strb->data = _mesa_malloc(size); return strb->data != NULL; } else { struct pipe_texture template; unsigned surface_usage; /* Free the old surface and texture */ pipe_surface_reference( &strb->surface, NULL ); pipe_texture_reference( &strb->texture, NULL ); /* Setup new texture template. */ memset(&template, 0, sizeof(template));
static struct pipe_buffer * xm_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; struct pipe_format_block block; unsigned nblocksx, nblocksy, size; pf_get_block(format, &block); nblocksx = pf_get_nblocksx(&block, width); nblocksy = pf_get_nblocksy(&block, height); *stride = align(nblocksx * block.size, alignment); size = *stride * nblocksy; #ifdef USE_XSHM if (!debug_get_bool_option("XLIB_NO_SHM", FALSE)) { struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); pipe_reference_init(&buffer->base.reference, 1); buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; buffer->userBuffer = FALSE; buffer->shminfo.shmid = -1; buffer->shminfo.shmaddr = (char *) -1; buffer->shm = TRUE; buffer->data = alloc_shm(buffer, size); if (!buffer->data) goto out; return &buffer->base; out: if (buffer) FREE(buffer); } #endif return winsys->buffer_create(winsys, alignment, usage, size); }
static struct pipe_buffer * st_softpipe_surface_buffer_create(struct pipe_winsys *winsys, unsigned width, unsigned height, enum pipe_format format, unsigned usage, unsigned tex_usage, unsigned *stride) { const unsigned alignment = 64; struct pipe_format_block block; unsigned nblocksx, nblocksy; pf_get_block(format, &block); nblocksx = pf_get_nblocksx(&block, width); nblocksy = pf_get_nblocksy(&block, height); *stride = round_up(nblocksx * block.size, alignment); return winsys->buffer_create(winsys, alignment, usage, *stride * nblocksy); }
/** * Allocate a new pipe_texture object * width0, height0, depth0 are the dimensions of the level 0 image * (the highest resolution). last_level indicates how many mipmap levels * to allocate storage for. For non-mipmapped textures, this will be zero. */ struct pipe_texture * st_texture_create(struct st_context *st, enum pipe_texture_target target, enum pipe_format format, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint usage ) { struct pipe_texture pt, *newtex; struct pipe_screen *screen = st->pipe->screen; assert(target <= PIPE_TEXTURE_CUBE); DBG("%s target %s format %s last_level %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), _mesa_lookup_enum_by_nr(format), last_level); assert(format); assert(screen->is_format_supported(screen, format, target, PIPE_TEXTURE_USAGE_SAMPLER, 0)); memset(&pt, 0, sizeof(pt)); pt.target = target; pt.format = format; pt.last_level = last_level; pt.width[0] = width0; pt.height[0] = height0; pt.depth[0] = depth0; pf_get_block(format, &pt.block); pt.tex_usage = usage; newtex = screen->texture_create(screen, &pt); assert(!newtex || pipe_is_referenced(&newtex->reference)); return newtex; }
/** * Create the texture map we'll use for antialiasing the lines. */ static boolean aaline_create_texture(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; uint level; memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = MAX_TEXTURE_LEVEL; texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.depth[0] = 1; pf_get_block(texTemp.format, &texTemp.block); aaline->texture = screen->texture_create(screen, &texTemp); if (!aaline->texture) return FALSE; /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost * texels which are zero. Special case the 1x1 and 2x2 levels. */ for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { struct pipe_surface *surface; const uint size = aaline->texture->width[level]; ubyte *data; uint i, j; assert(aaline->texture->width[level] == aaline->texture->height[level]); /* This texture is new, no need to flush. */ surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0, PIPE_BUFFER_USAGE_CPU_WRITE); data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); if (data == NULL) return FALSE; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { ubyte d; if (size == 1) { d = 255; } else if (size == 2) { d = 200; /* tuneable */ } else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { d = 0; } else { d = 255; } data[i * surface->stride + j] = d; } } /* unmap */ screen->surface_unmap(screen, surface); screen->tex_surface_release(screen, &surface); } return TRUE; }
struct pipe_texture * renderer_clone_texture(struct xorg_renderer *r, struct pipe_texture *src) { enum pipe_format format; struct pipe_context *pipe = r->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture *pt; struct pipe_texture templ; if (pipe->is_texture_referenced(pipe, src, 0, 0) & PIPE_REFERENCED_FOR_WRITE) pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* the coming in texture should already have that invariance */ debug_assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0)); format = src->format; memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.format = format; templ.last_level = 0; templ.width[0] = src->width[0]; templ.height[0] = src->height[0]; templ.depth[0] = 1; pf_get_block(format, &templ.block); templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; pt = screen->texture_create(screen, &templ); debug_assert(!pt || pipe_is_referenced(&pt->reference)); if (!pt) return NULL; { /* copy source framebuffer surface into texture */ struct pipe_surface *ps_read = screen->get_tex_surface( screen, src, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); struct pipe_surface *ps_tex = screen->get_tex_surface( screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE ); if (pipe->surface_copy) { pipe->surface_copy(pipe, ps_tex, /* dest */ 0, 0, /* destx/y */ ps_read, 0, 0, src->width[0], src->height[0]); } else { util_surface_copy(pipe, FALSE, ps_tex, /* dest */ 0, 0, /* destx/y */ ps_read, 0, 0, src->width[0], src->height[0]); } pipe_surface_reference(&ps_read, NULL); pipe_surface_reference(&ps_tex, NULL); } return pt; }