Add surface storage allocation function to winsys interface.

This commit is contained in:
José Fonseca 2007-12-11 01:14:38 +00:00
parent 609538f57c
commit 12363674e5
6 changed files with 107 additions and 65 deletions

View file

@ -178,32 +178,11 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys,
}
static unsigned
intel_i915_surface_pitch(struct pipe_winsys *winsys,
unsigned cpp, unsigned width, unsigned flags)
{
/* Choose a pitch to match hardware requirements - requires 64 byte
* alignment of render targets.
*
* XXX: is this ok for textures??
* clearly want to be able to render to textures under some
* circumstances, but maybe not always a requirement.
*/
/* XXX is the pitch different for textures vs. drawables? */
if (1/*flags & PIPE_SURFACE_FLAG_TEXTURE*/) /* or PIPE_SURFACE_FLAG_RENDER? */
return ((cpp * width + 63) & ~63) / cpp;
else
return ((cpp * width + 63) & ~63) / cpp;
}
static struct pipe_surface *
intel_i915_surface_alloc(struct pipe_winsys *winsys, enum pipe_format format)
intel_i915_surface_alloc(struct pipe_winsys *winsys)
{
struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
if (surf) {
surf->format = format;
surf->refcount = 1;
surf->winsys = winsys;
}
@ -211,6 +190,53 @@ intel_i915_surface_alloc(struct pipe_winsys *winsys, enum pipe_format format)
}
/**
* Round n up to next multiple.
*/
static INLINE unsigned
round_up(unsigned n, unsigned multiple)
{
return (n + multiple - 1) & ~(multiple - 1);
}
/**
* Copied from xm_winsys.c
*/
static int
intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
unsigned flags)
{
const unsigned alignment = 64;
int ret;
surf->width = width;
surf->height = height;
surf->format = format;
surf->cpp = pf_get_size(format);
surf->pitch = round_up(width, alignment / surf->cpp);
assert(!surf->buffer);
surf->buffer = winsys->buffer_create(winsys, alignment, 0, 0);
if(!surf->buffer)
return -1;
ret = winsys->buffer_data(winsys,
surf->buffer,
surf->pitch * surf->cpp * height,
NULL,
0);
if(ret) {
winsys->buffer_reference(winsys, &surf->buffer, NULL);
return ret;
}
return 0;
}
static void
intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
{
@ -265,8 +291,8 @@ intel_create_pipe_winsys( int fd )
iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
iws->winsys.printf = intel_printf;
iws->winsys.get_name = intel_get_name;
iws->winsys.surface_pitch = intel_i915_surface_pitch;
iws->winsys.surface_alloc = intel_i915_surface_alloc;
iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;
iws->winsys.surface_release = intel_i915_surface_release;
if (fd)

View file

@ -238,11 +238,12 @@ i915_get_tex_surface(struct pipe_context *pipe,
assert(zslice == 0);
}
ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
ps = pipe->winsys->surface_alloc(pipe->winsys);
if (ps) {
assert(ps->format);
assert(ps->refcount);
pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];

View file

@ -76,16 +76,16 @@ struct pipe_winsys
const char *, ... );
/**
* flags is bitmask of PIPE_SURFACE_FLAG_RENDER, PIPE_SURFACE_FLAG_TEXTURE
*/
unsigned (*surface_pitch)(struct pipe_winsys *ws, unsigned cpp,
unsigned with, unsigned flags);
/** allocate a new surface (no context dependency) */
struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws,
enum pipe_format format);
struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws);
/** allocate storage for a pipe_surface */
int (*surface_alloc_storage)(struct pipe_winsys *ws,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
unsigned flags);
void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s);

View file

@ -576,11 +576,11 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
assert(zslice == 0);
}
ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
ps = pipe->winsys->surface_alloc(pipe->winsys);
if (ps) {
assert(ps->format);
assert(ps->refcount);
pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];

View file

@ -388,11 +388,38 @@ round_up(unsigned n, unsigned multiple)
return (n + multiple - 1) & ~(multiple - 1);
}
static unsigned
xm_surface_pitch(struct pipe_winsys *winsys, unsigned cpp, unsigned width,
unsigned flags)
static int
xm_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
unsigned width, unsigned height,
enum pipe_format format,
unsigned flags)
{
return round_up(width, 64 / cpp);
const unsigned alignment = 64;
int ret;
surf->width = width;
surf->height = height;
surf->format = format;
surf->cpp = pf_get_size(format);
surf->pitch = round_up(width, alignment / surf->cpp);
assert(!surf->buffer);
surf->buffer = winsys->buffer_create(winsys, alignment, 0, 0);
if(!surf->buffer)
return -1;
ret = winsys->buffer_data(winsys,
surf->buffer,
surf->pitch * surf->cpp * height,
NULL,
0);
if(ret) {
winsys->buffer_reference(winsys, &surf->buffer, NULL);
return ret;
}
return 0;
}
@ -401,14 +428,12 @@ xm_surface_pitch(struct pipe_winsys *winsys, unsigned cpp, unsigned width,
* renderbuffers, etc.
*/
static struct pipe_surface *
xm_surface_alloc(struct pipe_winsys *ws, enum pipe_format pipeFormat)
xm_surface_alloc(struct pipe_winsys *ws)
{
struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
assert(ws);
assert(pipeFormat);
xms->surface.format = pipeFormat;
xms->surface.refcount = 1;
xms->surface.winsys = ws;
@ -463,8 +488,8 @@ xmesa_get_pipe_winsys(void)
ws->buffer_subdata = xm_buffer_subdata;
ws->buffer_get_subdata = xm_buffer_get_subdata;
ws->surface_pitch = xm_surface_pitch;
ws->surface_alloc = xm_surface_alloc;
ws->surface_alloc_storage = xm_surface_alloc_storage;
ws->surface_release = xm_surface_release;
ws->flush_frontbuffer = xm_flush_frontbuffer;

View file

@ -90,29 +90,15 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
uint type = strb->screenSurface ? PIPE_SCREEN_SURFACE : PIPE_SURFACE;
const enum pipe_format pipeFormat
= st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE, type);
GLuint cpp;
GLbitfield flags = 0x0; /* XXX needed? */
cpp = init_renderbuffer_bits(strb, pipeFormat);
assert(cpp);
if (strb->surface && strb->surface->format != pipeFormat) {
/* need to change surface types, free this surface */
pipe_surface_reference(&strb->surface, NULL);
assert(strb->surface == NULL);
}
if (!strb->surface) {
strb->surface = pipe->winsys->surface_alloc(pipe->winsys, pipeFormat);
strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
assert(strb->surface);
if (!strb->surface)
return GL_FALSE;
strb->surface->cpp = cpp;
}
strb->surface->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp,
width, flags);
/* loop here since mapping is refcounted */
while (strb->surface->map)
pipe_surface_unmap(strb->surface);
@ -120,20 +106,24 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
pipe->winsys->buffer_reference(pipe->winsys, &strb->surface->buffer,
NULL);
/* XXX don't hard-code magic 32 here */
strb->surface->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0);
pipe->winsys->surface_alloc_storage(pipe->winsys,
strb->surface,
width,
height,
pipeFormat,
flags);
if (!strb->surface->buffer)
return GL_FALSE; /* out of memory, try s/w buffer? */
pipe->winsys->buffer_data(pipe->winsys, strb->surface->buffer,
strb->surface->pitch * cpp * height, NULL,
PIPE_BUFFER_USAGE_PIXEL);
ASSERT(strb->surface->buffer);
ASSERT(strb->surface->format);
ASSERT(strb->surface->cpp);
ASSERT(strb->surface->width == width);
ASSERT(strb->surface->height == height);
ASSERT(strb->surface->pitch);
strb->Base.Width = strb->surface->width = width;
strb->Base.Height = strb->surface->height = height;
strb->Base.Width = width;
strb->Base.Height = height;
return GL_TRUE;
}