{
struct pipe_context *pipe = ctx->st->pipe;
struct st_renderbuffer *strb = st_renderbuffer(rb);
- enum pipe_format pipeFormat;
- unsigned flags = (PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ);
- int ret;
+ struct pipe_texture template, *texture;
+
+ /* Free the old surface (and texture if we hold the last
+ * reference):
+ */
pipe_surface_reference( &strb->surface, NULL );
- if (!strb->surface) {
- /* first time surface creation */
- strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
- assert(strb->surface);
- assert(strb->surface->refcount);
- assert(strb->surface->winsys);
- if (!strb->surface)
- return GL_FALSE;
- }
-#if 0
- else if (strb->surface->buffer) {
- /* release/discard the old surface buffer */
- pipe_reference_buffer(pipe, &strb->surface->buffer, NULL);
- }
-#else
- else {
- assert(0);
- }
-#endif
- /* Determine surface format here */
+ memset(&template, 0, sizeof(template));
+
if (strb->format != PIPE_FORMAT_NONE) {
- assert(strb->format != 0);
- /* we'll hit this for front/back color bufs */
- pipeFormat = strb->format;
+ template.format = strb->format;
}
else {
- pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
+ template.format = st_choose_renderbuffer_format(pipe, internalFormat);
}
- init_renderbuffer_bits(strb, pipeFormat);
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width,
- height,
- pipeFormat,
- flags);
- if (ret || !strb->surface->buffer) {
- if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
- /* Accum buffer. Try a different surface format. Since accum
- * buffers are s/w only for now, the surface pixel format doesn't
- * really matter, only that the buffer is large enough.
- */
- int sz, mult;
- enum pipe_format accum_format;
-
- /* allocate a buffer of (typically) double height to get 64bpp */
- accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
- sz = pf_get_size(accum_format);
- mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width, height * mult,
- accum_format, flags);
- if (ret)
- return GL_FALSE; /* we've _really_ failed */
-
- }
- else {
- return GL_FALSE; /* out of memory, try s/w buffer? */
- }
+ strb->Base.Width = width;
+ strb->Base.Height = height;
+ init_renderbuffer_bits(strb, template.format);
+
+ template.compressed = 0;
+ template.cpp = pf_get_size(template.format);
+ template.width[0] = width;
+ template.height[0] = height;
+ template.depth[0] = 1;
+ template.last_level = 0;
+ template.usage = (PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ texture = pipe->screen->texture_create( pipe->screen,
+ &template );
+
+ /* Special path for accum buffers.
+ *
+ * Try a different surface format. Since accum buffers are s/w
+ * only for now, the surface pixel format doesn't really matter,
+ * only that the buffer is large enough.
+ */
+ if (!texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
+ {
+ /* Actually, just setting this usage value should be sufficient
+ * to tell the driver to go ahead and allocate the buffer, even
+ * if HW doesn't support the format.
+ */
+ template.usage = (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ texture = pipe->screen->texture_create( pipe->screen,
+ &template );
}
- 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);
+ if (!texture)
+ return FALSE;
- strb->Base.Width = width;
- strb->Base.Height = height;
+ strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+ texture,
+ 0, 0, 0,
+ template.usage );
+
+ pipe_texture_reference( &texture, NULL );
- return GL_TRUE;
+ 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);
+
+
+ return strb->surface != NULL;
}
{
struct st_renderbuffer *strb = st_renderbuffer(rb);
ASSERT(strb);
- if (strb->surface) {
- struct pipe_winsys *ws = strb->surface->winsys;
- ws->surface_release(ws, &strb->surface);
- }
+ pipe_surface_reference(&strb->surface, NULL);
free(strb);
}