[Mesa-dev] [PATCH 15/18] gallium: Add __DRIimageDriverExtension support to gallium
Marek Olšák
maraeo at gmail.com
Sat Dec 14 03:27:25 PST 2013
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 at keithp.com> wrote:
> Provide the hook to pull textures out of __DRIimage structures and use them as
> renderbuffers.
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
> 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the mesa-dev
mailing list