st/mesa: separate sw renderbuffer allocation from hw one

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák 2012-06-15 17:58:35 +02:00
parent a82227ce4a
commit e4b2e6b527
1 changed files with 97 additions and 79 deletions

View File

@ -57,6 +57,44 @@
#include "util/u_surface.h"
static GLboolean
st_renderbuffer_alloc_sw_storage(struct gl_context * ctx,
struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width, GLuint height)
{
struct pipe_screen *screen = st_context(ctx)->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(rb);
enum pipe_format format;
size_t size;
free(strb->data);
strb->data = NULL;
if (internalFormat == GL_RGBA16_SNORM) {
/* Special case for software accum buffers. Otherwise, if the
* call to st_choose_renderbuffer_format() fails (because the
* driver doesn't support signed 16-bit/channel colors) we'd
* just return without allocating the software accum buffer.
*/
format = PIPE_FORMAT_R16G16B16A16_SNORM;
}
else {
format = st_choose_renderbuffer_format(screen, internalFormat, 0);
}
if (format == PIPE_FORMAT_NONE) {
return FALSE;
}
strb->Base.Format = st_pipe_format_to_mesa_format(format);
size = _mesa_format_image_size(strb->Base.Format, width, height, 1);
strb->data = malloc(size);
return strb->data != NULL;
}
/**
* gl_renderbuffer::AllocStorage()
* This is called to allocate the original drawing surface, and
@ -74,98 +112,78 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx,
struct st_renderbuffer *strb = st_renderbuffer(rb);
enum pipe_format format;
struct pipe_surface surf_tmpl;
struct pipe_resource templ;
if (internalFormat == GL_RGBA16_SNORM && strb->software) {
/* Special case for software accum buffers. Otherwise, if the
* call to st_choose_renderbuffer_format() fails (because the
* driver doesn't support signed 16-bit/channel colors) we'd
* just return without allocating the software accum buffer.
*/
format = PIPE_FORMAT_R16G16B16A16_SNORM;
}
else {
format = st_choose_renderbuffer_format(screen, internalFormat,
rb->NumSamples);
/* init renderbuffer fields */
strb->Base.Width = width;
strb->Base.Height = height;
strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
strb->defined = GL_FALSE; /* undefined contents now */
if (strb->software) {
return st_renderbuffer_alloc_sw_storage(ctx, rb, internalFormat,
width, height);
}
/* Free the old surface and texture
*/
pipe_surface_reference( &strb->surface, NULL );
pipe_resource_reference( &strb->texture, NULL );
format = st_choose_renderbuffer_format(screen, internalFormat,
rb->NumSamples);
if (format == PIPE_FORMAT_NONE) {
return FALSE;
}
/* init renderbuffer fields */
strb->Base.Width = width;
strb->Base.Height = height;
strb->Base.Format = st_pipe_format_to_mesa_format(format);
strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
strb->defined = GL_FALSE; /* undefined contents now */
if (width == 0 || height == 0) {
/* if size is zero, nothing to allocate */
return GL_TRUE;
}
if (strb->software) {
size_t size;
free(strb->data);
size = _mesa_format_image_size(strb->Base.Format, width, height, 1);
strb->data = malloc(size);
return strb->data != NULL;
/* Setup new texture template.
*/
memset(&templ, 0, sizeof(templ));
templ.target = st->internal_target;
templ.format = format;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
templ.nr_samples = rb->NumSamples;
if (util_format_is_depth_or_stencil(format)) {
templ.bind = PIPE_BIND_DEPTH_STENCIL;
}
else if (strb->Base.Name != 0) {
/* this is a user-created renderbuffer */
templ.bind = PIPE_BIND_RENDER_TARGET;
}
else {
struct pipe_resource template;
/* Free the old surface and texture
*/
pipe_surface_reference( &strb->surface, NULL );
pipe_resource_reference( &strb->texture, NULL );
if (width == 0 || height == 0) {
/* if size is zero, nothing to allocate */
return GL_TRUE;
}
/* Setup new texture template.
*/
memset(&template, 0, sizeof(template));
template.target = st->internal_target;
template.format = format;
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
template.array_size = 1;
template.last_level = 0;
template.nr_samples = rb->NumSamples;
if (util_format_is_depth_or_stencil(format)) {
template.bind = PIPE_BIND_DEPTH_STENCIL;
}
else if (strb->Base.Name != 0) {
/* this is a user-created renderbuffer */
template.bind = PIPE_BIND_RENDER_TARGET;
}
else {
/* this is a window-system buffer */
template.bind = (PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_RENDER_TARGET);
}
strb->texture = screen->resource_create(screen, &template);
if (!strb->texture)
return FALSE;
u_surface_default_template(&surf_tmpl, strb->texture, template.bind);
strb->surface = pipe->create_surface(pipe,
strb->texture,
&surf_tmpl);
if (strb->surface) {
assert(strb->surface->texture);
assert(strb->surface->format);
assert(strb->surface->width == width);
assert(strb->surface->height == height);
}
return strb->surface != NULL;
/* this is a window-system buffer */
templ.bind = (PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_RENDER_TARGET);
}
strb->texture = screen->resource_create(screen, &templ);
if (!strb->texture)
return FALSE;
u_surface_default_template(&surf_tmpl, strb->texture, templ.bind);
strb->surface = pipe->create_surface(pipe,
strb->texture,
&surf_tmpl);
if (strb->surface) {
assert(strb->surface->texture);
assert(strb->surface->format);
assert(strb->surface->width == width);
assert(strb->surface->height == height);
}
return strb->surface != NULL;
}