diff options
-rw-r--r-- | src/mesa/state_tracker/st_cb_fbo.c | 168 |
1 files changed, 93 insertions, 75 deletions
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 953295c0e16..01269998453 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -57,25 +57,21 @@ #include "util/u_surface.h" -/** - * gl_renderbuffer::AllocStorage() - * This is called to allocate the original drawing surface, and - * during window resize. - */ static GLboolean -st_renderbuffer_alloc_storage(struct gl_context * ctx, - struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) +st_renderbuffer_alloc_sw_storage(struct gl_context * ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; - struct pipe_screen *screen = st->pipe->screen; + struct pipe_screen *screen = st_context(ctx)->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(rb); enum pipe_format format; - struct pipe_surface surf_tmpl; + size_t size; - if (internalFormat == GL_RGBA16_SNORM && strb->software) { + 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 @@ -84,88 +80,110 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, format = PIPE_FORMAT_R16G16B16A16_SNORM; } else { - format = st_choose_renderbuffer_format(screen, internalFormat, - rb->NumSamples); + 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 + * during window resize. + */ +static GLboolean +st_renderbuffer_alloc_storage(struct gl_context * ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = st->pipe->screen; + struct st_renderbuffer *strb = st_renderbuffer(rb); + enum pipe_format format; + struct pipe_surface surf_tmpl; + struct pipe_resource templ; + /* 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 (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; + return st_renderbuffer_alloc_sw_storage(ctx, rb, internalFormat, + width, height); } - 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; - } + /* Free the old surface and texture + */ + pipe_surface_reference( &strb->surface, NULL ); + pipe_resource_reference( &strb->texture, NULL ); - /* 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); - } + format = st_choose_renderbuffer_format(screen, internalFormat, + rb->NumSamples); - strb->texture = screen->resource_create(screen, &template); + if (format == PIPE_FORMAT_NONE) { + return FALSE; + } - if (!strb->texture) - return FALSE; + strb->Base.Format = st_pipe_format_to_mesa_format(format); - 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); - } + if (width == 0 || height == 0) { + /* if size is zero, nothing to allocate */ + return GL_TRUE; + } - return strb->surface != 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 { + /* 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; } |