Path: blob/21.2-virgl/src/gallium/drivers/zink/zink_framebuffer.c
4570 views
/*1* Copyright 2018 Collabora Ltd.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*/2223#include "zink_context.h"24#include "zink_framebuffer.h"2526#include "zink_render_pass.h"27#include "zink_screen.h"28#include "zink_surface.h"2930#include "util/u_memory.h"31#include "util/u_string.h"3233void34zink_destroy_framebuffer(struct zink_screen *screen,35struct zink_framebuffer *fb)36{37hash_table_foreach(&fb->objects, he) {38#if defined(_WIN64) || defined(__x86_64__)39vkDestroyFramebuffer(screen->dev, he->data, NULL);40#else41VkFramebuffer *ptr = he->data;42vkDestroyFramebuffer(screen->dev, *ptr, NULL);43#endif44}4546if (fb->null_surface)47pipe_resource_reference(&fb->null_surface->texture, NULL);48zink_surface_reference(screen, (struct zink_surface**)&fb->null_surface, NULL);4950ralloc_free(fb);51}5253void54zink_init_framebuffer(struct zink_screen *screen, struct zink_framebuffer *fb, struct zink_render_pass *rp)55{56VkFramebuffer ret;5758if (fb->rp == rp)59return;6061uint32_t hash = _mesa_hash_pointer(rp);6263struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&fb->objects, hash, rp);64if (he) {65#if defined(_WIN64) || defined(__x86_64__)66ret = (VkFramebuffer)he->data;67#else68VkFramebuffer *ptr = he->data;69ret = *ptr;70#endif71goto out;72}7374VkFramebufferCreateInfo fci = {0};75fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;76fci.renderPass = rp->render_pass;77fci.attachmentCount = fb->state.num_attachments;78fci.pAttachments = fb->state.attachments;79fci.width = fb->state.width;80fci.height = fb->state.height;81fci.layers = fb->state.layers;8283if (vkCreateFramebuffer(screen->dev, &fci, NULL, &ret) != VK_SUCCESS)84return;85#if defined(_WIN64) || defined(__x86_64__)86_mesa_hash_table_insert_pre_hashed(&fb->objects, hash, rp, ret);87#else88VkFramebuffer *ptr = ralloc(fb, VkFramebuffer);89if (!ptr) {90vkDestroyFramebuffer(screen->dev, ret, NULL);91return;92}93*ptr = ret;94_mesa_hash_table_insert_pre_hashed(&fb->objects, hash, rp, ptr);95#endif96out:97fb->rp = rp;98fb->fb = ret;99}100101struct zink_framebuffer *102zink_create_framebuffer(struct zink_context *ctx,103struct zink_framebuffer_state *state,104struct pipe_surface **attachments)105{106struct zink_screen *screen = zink_screen(ctx->base.screen);107struct zink_framebuffer *fb = rzalloc(NULL, struct zink_framebuffer);108if (!fb)109return NULL;110111unsigned num_attachments = 0;112for (int i = 0; i < state->num_attachments; i++) {113struct zink_surface *surf;114if (state->attachments[i]) {115surf = zink_surface(attachments[i]);116/* no ref! */117fb->surfaces[i] = attachments[i];118num_attachments++;119} else {120if (!fb->null_surface)121fb->null_surface = zink_surface_create_null(ctx, PIPE_TEXTURE_2D, state->width, state->height, state->samples);122surf = zink_surface(fb->null_surface);123state->attachments[i] = zink_surface(fb->null_surface)->image_view;124}125util_dynarray_append(&surf->framebuffer_refs, struct zink_framebuffer*, fb);126}127pipe_reference_init(&fb->reference, 1 + num_attachments);128129if (!_mesa_hash_table_init(&fb->objects, fb, _mesa_hash_pointer, _mesa_key_pointer_equal))130goto fail;131memcpy(&fb->state, state, sizeof(struct zink_framebuffer_state));132133return fb;134fail:135zink_destroy_framebuffer(screen, fb);136return NULL;137}138139void140debug_describe_zink_framebuffer(char* buf, const struct zink_framebuffer *ptr)141{142sprintf(buf, "zink_framebuffer");143}144145146