diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index e5a502f2f0d..5ab2b90b741 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -706,19 +706,21 @@ static struct zink_framebuffer * create_framebuffer(struct zink_context *ctx) { struct zink_screen *screen = zink_screen(ctx->base.screen); + struct pipe_surface *attachments[PIPE_MAX_COLOR_BUFS + 1] = {}; struct zink_framebuffer_state state = {}; state.rp = get_render_pass(ctx); for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { struct pipe_surface *psurf = ctx->fb_state.cbufs[i]; - state.attachments[i] = zink_surface(psurf); - state.has_null_attachments |= !state.attachments[i]; + state.attachments[i] = psurf ? zink_surface(psurf)->image_view : VK_NULL_HANDLE; + attachments[i] = psurf; } state.num_attachments = ctx->fb_state.nr_cbufs; if (ctx->fb_state.zsbuf) { struct pipe_surface *psurf = ctx->fb_state.zsbuf; - state.attachments[state.num_attachments++] = zink_surface(psurf); + state.attachments[state.num_attachments] = psurf ? zink_surface(psurf)->image_view : VK_NULL_HANDLE;; + attachments[state.num_attachments++] = psurf; } state.width = MAX2(ctx->fb_state.width, 1); @@ -726,7 +728,7 @@ create_framebuffer(struct zink_context *ctx) state.layers = MAX2(util_framebuffer_get_num_layers(&ctx->fb_state), 1); state.samples = ctx->fb_state.samples; - return zink_create_framebuffer(ctx, screen, &state); + return zink_create_framebuffer(ctx, screen, &state, attachments); } static void diff --git a/src/gallium/drivers/zink/zink_framebuffer.c b/src/gallium/drivers/zink/zink_framebuffer.c index a19db805c76..102e7f82805 100644 --- a/src/gallium/drivers/zink/zink_framebuffer.c +++ b/src/gallium/drivers/zink/zink_framebuffer.c @@ -76,7 +76,8 @@ zink_destroy_framebuffer(struct zink_screen *screen, struct zink_framebuffer * zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen, - struct zink_framebuffer_state *fb) + struct zink_framebuffer_state *fb, + struct pipe_surface **attachments) { struct zink_framebuffer *fbuf = CALLOC_STRUCT(zink_framebuffer); if (!fbuf) @@ -84,16 +85,14 @@ zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen, pipe_reference_init(&fbuf->reference, 1); - if (fb->has_null_attachments) - fbuf->null_surface = framebuffer_null_surface_init(ctx, fb); - - VkImageView attachments[ARRAY_SIZE(fb->attachments)] = {}; for (int i = 0; i < fb->num_attachments; i++) { - struct zink_surface *surf = fb->attachments[i]; - if (!surf) - surf = zink_surface(fbuf->null_surface); - pipe_surface_reference(fbuf->surfaces + i, &surf->base); - attachments[i] = surf->image_view; + if (fb->attachments[i]) + pipe_surface_reference(&fbuf->surfaces[i], attachments[i]); + else { + if (!fbuf->null_surface) + fbuf->null_surface = framebuffer_null_surface_init(ctx, fb); + fb->attachments[i] = zink_surface(fbuf->null_surface)->image_view; + } } zink_render_pass_reference(screen, &fbuf->rp, fb->rp); @@ -102,7 +101,7 @@ zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen, fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fci.renderPass = fbuf->rp->render_pass; fci.attachmentCount = fb->num_attachments; - fci.pAttachments = attachments; + fci.pAttachments = fb->attachments; fci.width = fb->width; fci.height = fb->height; fci.layers = fb->layers; @@ -111,6 +110,7 @@ zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen, zink_destroy_framebuffer(screen, fbuf); return NULL; } + memcpy(&fbuf->state, fb, sizeof(struct zink_framebuffer_state)); return fbuf; } diff --git a/src/gallium/drivers/zink/zink_framebuffer.h b/src/gallium/drivers/zink/zink_framebuffer.h index ca3fd4fb231..55b721ea21d 100644 --- a/src/gallium/drivers/zink/zink_framebuffer.h +++ b/src/gallium/drivers/zink/zink_framebuffer.h @@ -39,8 +39,7 @@ struct zink_framebuffer_state { uint16_t height, layers; uint8_t samples; uint8_t num_attachments; - struct zink_surface *attachments[PIPE_MAX_COLOR_BUFS + 1]; - bool has_null_attachments; + VkImageView attachments[PIPE_MAX_COLOR_BUFS + 1]; }; struct zink_framebuffer { @@ -50,11 +49,13 @@ struct zink_framebuffer { struct pipe_surface *surfaces[PIPE_MAX_COLOR_BUFS + 1]; struct zink_render_pass *rp; struct pipe_surface *null_surface; /* for use with unbound attachments */ + struct zink_framebuffer_state state; }; struct zink_framebuffer * zink_create_framebuffer(struct zink_context *ctx, struct zink_screen *screen, - struct zink_framebuffer_state *fb); + struct zink_framebuffer_state *fb, + struct pipe_surface **attachments); void zink_destroy_framebuffer(struct zink_screen *screen,