Some of the code seems to be copy-pasted from dri2_drawable_process_buffers. The MSAA color and depth-stencil texture allocation could be moved to a common function. Marek On Sat, Dec 14, 2013 at 2:25 AM, Keith Packard <keithp@xxxxxxxxxx> wrote: > Provide the hook to pull textures out of __DRIimage structures and use them as > renderbuffers. > > Signed-off-by: Keith Packard <keithp@xxxxxxxxxx> > --- > src/gallium/state_trackers/dri/drm/dri2.c | 238 +++++++++++++++++++++++++++++- > 1 file changed, 230 insertions(+), 8 deletions(-) > > diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c > index 8ff77b3..03b93ae 100644 > --- a/src/gallium/state_trackers/dri/drm/dri2.c > +++ b/src/gallium/state_trackers/dri/drm/dri2.c > @@ -457,6 +457,219 @@ dri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv) > FREE(buffer); > } > > +static void > +dri_image_allocate_textures(struct dri_context *ctx, > + struct dri_drawable *drawable, > + const enum st_attachment_type *statts, > + unsigned statts_count) > +{ > + __DRIdrawable *dPriv = drawable->dPriv; > + __DRIscreen *sPriv = drawable->sPriv; > + struct dri_screen *screen = dri_screen(sPriv); > + unsigned int image_format = __DRI_IMAGE_FORMAT_NONE; > + uint32_t buffer_mask = 0; > + struct __DRIimageList images; > + boolean alloc_depthstencil = FALSE; > + int i, j; > + struct pipe_resource templ; > + > + /* See if we need a depth-stencil buffer. */ > + for (i = 0; i < statts_count; i++) { > + if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) { > + alloc_depthstencil = TRUE; > + break; > + } > + } > + > + /* Delete the resources we won't need. */ > + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { > + /* Don't delete the depth-stencil buffer, we can reuse it. */ > + if (i == ST_ATTACHMENT_DEPTH_STENCIL && alloc_depthstencil) > + continue; > + > + pipe_resource_reference(&drawable->textures[i], NULL); > + } > + > + if (drawable->stvis.samples > 1) { > + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { > + boolean del = TRUE; > + > + /* Don't delete MSAA resources for the attachments which are enabled, > + * we can reuse them. */ > + for (j = 0; j < statts_count; j++) { > + if (i == statts[j]) { > + del = FALSE; > + break; > + } > + } > + > + if (del) { > + pipe_resource_reference(&drawable->msaa_textures[i], NULL); > + } > + } > + } > + > + for (i = 0; i < statts_count; i++) { > + enum pipe_format pf; > + unsigned bind; > + > + dri_drawable_get_format(drawable, statts[i], &pf, &bind); > + if (pf == PIPE_FORMAT_NONE) > + continue; > + > + switch (pf) { > + case PIPE_FORMAT_B5G6R5_UNORM: > + image_format = __DRI_IMAGE_FORMAT_RGB565; > + break; > + case PIPE_FORMAT_B8G8R8X8_UNORM: > + image_format = __DRI_IMAGE_FORMAT_XRGB8888; > + break; > + case PIPE_FORMAT_B8G8R8A8_UNORM: > + image_format = __DRI_IMAGE_FORMAT_ARGB8888; > + break; > + case PIPE_FORMAT_R8G8B8A8_UNORM: > + image_format = __DRI_IMAGE_FORMAT_ABGR8888; > + break; > + default: > + image_format = __DRI_IMAGE_FORMAT_NONE; > + break; > + } > + > + switch (statts[i]) { > + case ST_ATTACHMENT_FRONT_LEFT: > + buffer_mask |= __DRI_IMAGE_BUFFER_FRONT; > + break; > + case ST_ATTACHMENT_BACK_LEFT: > + buffer_mask |= __DRI_IMAGE_BUFFER_BACK; > + break; > + default: > + continue; > + } > + } > + > + (*sPriv->image.loader->getBuffers) (dPriv, > + image_format, > + &dPriv->dri2.stamp, > + dPriv->loaderPrivate, > + buffer_mask, > + &images); > + > + if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) { > + struct pipe_resource *texture = images.front->texture; > + > + dPriv->w = texture->width0; > + dPriv->h = texture->height0; > + > + pipe_resource_reference(&drawable->textures[ST_ATTACHMENT_FRONT_LEFT], texture); > + } > + > + if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) { > + struct pipe_resource *texture = images.back->texture; > + > + dPriv->w = images.back->texture->width0; > + dPriv->h = images.back->texture->height0; > + > + pipe_resource_reference(&drawable->textures[ST_ATTACHMENT_BACK_LEFT], texture); > + } > + > + memset(&templ, 0, sizeof(templ)); > + templ.target = screen->target; > + templ.last_level = 0; > + templ.width0 = dPriv->w; > + templ.height0 = dPriv->h; > + templ.depth0 = 1; > + templ.array_size = 1; > + > + /* Allocate private MSAA colorbuffers. */ > + if (drawable->stvis.samples > 1) { > + for (i = 0; i < statts_count; i++) { > + enum st_attachment_type att = statts[i]; > + > + if (att == ST_ATTACHMENT_DEPTH_STENCIL) > + continue; > + > + if (drawable->textures[att]) { > + templ.format = drawable->textures[att]->format; > + templ.bind = drawable->textures[att]->bind; > + templ.nr_samples = drawable->stvis.samples; > + > + /* Try to reuse the resource. > + * (the other resource parameters should be constant) > + */ > + if (!drawable->msaa_textures[att] || > + drawable->msaa_textures[att]->width0 != templ.width0 || > + drawable->msaa_textures[att]->height0 != templ.height0) { > + /* Allocate a new one. */ > + pipe_resource_reference(&drawable->msaa_textures[att], NULL); > + > + drawable->msaa_textures[att] = > + screen->base.screen->resource_create(screen->base.screen, > + &templ); > + assert(drawable->msaa_textures[att]); > + > + /* If there are any MSAA resources, we should initialize them > + * such that they contain the same data as the single-sample > + * resources we just got from the X server. > + * > + * The reason for this is that the state tracker (and > + * therefore the app) can access the MSAA resources only. > + * The single-sample resources are not exposed > + * to the state tracker. > + * > + */ > + dri_pipe_blit(ctx->st->pipe, > + drawable->msaa_textures[att], > + drawable->textures[att]); > + } > + } > + else { > + pipe_resource_reference(&drawable->msaa_textures[att], NULL); > + } > + } > + } > + > + /* Allocate a private depth-stencil buffer. */ > + if (alloc_depthstencil) { > + enum st_attachment_type att = ST_ATTACHMENT_DEPTH_STENCIL; > + struct pipe_resource **zsbuf; > + enum pipe_format format; > + unsigned bind; > + > + dri_drawable_get_format(drawable, att, &format, &bind); > + > + if (format) { > + templ.format = format; > + templ.bind = bind; > + > + if (drawable->stvis.samples > 1) { > + templ.nr_samples = drawable->stvis.samples; > + zsbuf = &drawable->msaa_textures[att]; > + } > + else { > + templ.nr_samples = 0; > + zsbuf = &drawable->textures[att]; > + } > + > + /* Try to reuse the resource. > + * (the other resource parameters should be constant) > + */ > + if (!*zsbuf || > + (*zsbuf)->width0 != templ.width0 || > + (*zsbuf)->height0 != templ.height0) { > + /* Allocate a new one. */ > + pipe_resource_reference(zsbuf, NULL); > + *zsbuf = screen->base.screen->resource_create(screen->base.screen, > + &templ); > + assert(*zsbuf); > + } > + } > + else { > + pipe_resource_reference(&drawable->msaa_textures[att], NULL); > + pipe_resource_reference(&drawable->textures[att], NULL); > + } > + } > +} > + > /* > * Backend functions for st_framebuffer interface. > */ > @@ -467,13 +680,18 @@ dri2_allocate_textures(struct dri_context *ctx, > const enum st_attachment_type *statts, > unsigned statts_count) > { > - __DRIbuffer *buffers; > - unsigned num_buffers = statts_count; > - > - buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); > - if (buffers) > - dri2_drawable_process_buffers(ctx, drawable, buffers, num_buffers, > - statts, statts_count); > + __DRIscreen *sPriv = drawable->sPriv; > + > + if (sPriv->image.loader) { > + dri_image_allocate_textures(ctx, drawable, statts, statts_count); > + } else { > + __DRIbuffer *buffers; > + unsigned num_buffers = statts_count; > + buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); > + if (buffers) > + dri2_drawable_process_buffers(ctx, drawable, buffers, num_buffers, > + statts, statts_count); > + } > } > > static void > @@ -482,6 +700,7 @@ dri2_flush_frontbuffer(struct dri_context *ctx, > enum st_attachment_type statt) > { > __DRIdrawable *dri_drawable = drawable->dPriv; > + struct __DRIimageLoaderExtensionRec *image = drawable->sPriv->image.loader; > struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader; > struct pipe_context *pipe = ctx->st->pipe; > > @@ -501,7 +720,9 @@ dri2_flush_frontbuffer(struct dri_context *ctx, > > pipe->flush(pipe, NULL, 0); > > - if (loader->flushFrontBuffer) { > + if (image->flushFrontBuffer) { > + image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); > + } else if (loader->flushFrontBuffer) { > loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate); > } > } > @@ -1116,6 +1337,7 @@ const struct __DriverAPIRec driDriverAPI = { > /* This is the table of extensions that the loader will dlsym() for. */ > PUBLIC const __DRIextension *__driDriverExtensions[] = { > &driCoreExtension.base, > + &driImageDriverExtension.base, > &driDRI2Extension.base, > &gallium_config_options.base, > NULL > -- > 1.8.4.4 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel