Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_pass.c
4565 views
/*1* Copyright © 2019 Red Hat.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* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* 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 NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "lvp_private.h"2425#include "vk_util.h"2627static void28lvp_render_pass_compile(struct lvp_render_pass *pass)29{30for (uint32_t i = 0; i < pass->subpass_count; i++) {31struct lvp_subpass *subpass = &pass->subpasses[i];3233for (uint32_t j = 0; j < subpass->attachment_count; j++) {34struct lvp_subpass_attachment *subpass_att =35&subpass->attachments[j];36if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)37continue;3839struct lvp_render_pass_attachment *pass_att =40&pass->attachments[subpass_att->attachment];4142pass_att->first_subpass_idx = UINT32_MAX;43}44}4546for (uint32_t i = 0; i < pass->subpass_count; i++) {47struct lvp_subpass *subpass = &pass->subpasses[i];48uint32_t color_sample_count = 1, depth_sample_count = 1;4950/* We don't allow depth_stencil_attachment to be non-NULL and51* be VK_ATTACHMENT_UNUSED. This way something can just check52* for NULL and be guaranteed that they have a valid53* attachment.54*/55if (subpass->depth_stencil_attachment &&56subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)57subpass->depth_stencil_attachment = NULL;5859if (subpass->ds_resolve_attachment &&60subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)61subpass->ds_resolve_attachment = NULL;6263for (uint32_t j = 0; j < subpass->attachment_count; j++) {64struct lvp_subpass_attachment *subpass_att =65&subpass->attachments[j];66if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)67continue;6869struct lvp_render_pass_attachment *pass_att =70&pass->attachments[subpass_att->attachment];7172if (i < pass_att->first_subpass_idx)73pass_att->first_subpass_idx = i;74pass_att->last_subpass_idx = i;75}7677subpass->has_color_att = false;78for (uint32_t j = 0; j < subpass->color_count; j++) {79struct lvp_subpass_attachment *subpass_att =80&subpass->color_attachments[j];81if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)82continue;8384subpass->has_color_att = true;8586struct lvp_render_pass_attachment *pass_att =87&pass->attachments[subpass_att->attachment];8889color_sample_count = pass_att->samples;90}9192if (subpass->depth_stencil_attachment) {93const uint32_t a =94subpass->depth_stencil_attachment->attachment;95struct lvp_render_pass_attachment *pass_att =96&pass->attachments[a];97depth_sample_count = pass_att->samples;98}99100subpass->max_sample_count = MAX2(color_sample_count,101depth_sample_count);102103/* We have to handle resolve attachments specially */104subpass->has_color_resolve = false;105if (subpass->resolve_attachments) {106for (uint32_t j = 0; j < subpass->color_count; j++) {107struct lvp_subpass_attachment *resolve_att =108&subpass->resolve_attachments[j];109110if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)111continue;112113subpass->has_color_resolve = true;114}115}116117for (uint32_t j = 0; j < subpass->input_count; ++j) {118if (subpass->input_attachments[j].attachment == VK_ATTACHMENT_UNUSED)119continue;120121for (uint32_t k = 0; k < subpass->color_count; ++k) {122if (subpass->color_attachments[k].attachment == subpass->input_attachments[j].attachment) {123subpass->input_attachments[j].in_render_loop = true;124subpass->color_attachments[k].in_render_loop = true;125}126}127128if (subpass->depth_stencil_attachment &&129subpass->depth_stencil_attachment->attachment == subpass->input_attachments[j].attachment) {130subpass->input_attachments[j].in_render_loop = true;131subpass->depth_stencil_attachment->in_render_loop = true;132}133}134}135}136137static unsigned138lvp_num_subpass_attachments2(const VkSubpassDescription2 *desc)139{140return desc->inputAttachmentCount +141desc->colorAttachmentCount +142(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +143(desc->pDepthStencilAttachment != NULL);144}145146VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass2(147VkDevice _device,148const VkRenderPassCreateInfo2* pCreateInfo,149const VkAllocationCallbacks* pAllocator,150VkRenderPass* pRenderPass)151{152LVP_FROM_HANDLE(lvp_device, device, _device);153struct lvp_render_pass *pass;154size_t attachments_offset;155size_t size;156157size = sizeof(*pass);158size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);159attachments_offset = size;160size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);161162pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,163VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);164if (pass == NULL)165return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);166167/* Clear the subpasses along with the parent pass. This required because168* each array member of lvp_subpass must be a valid pointer if not NULL.169*/170memset(pass, 0, size);171172vk_object_base_init(&device->vk, &pass->base,173VK_OBJECT_TYPE_RENDER_PASS);174pass->attachment_count = pCreateInfo->attachmentCount;175pass->subpass_count = pCreateInfo->subpassCount;176pass->attachments = (struct lvp_render_pass_attachment *)((char *)pass + attachments_offset);177178for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {179struct lvp_render_pass_attachment *att = &pass->attachments[i];180181att->format = pCreateInfo->pAttachments[i].format;182att->samples = pCreateInfo->pAttachments[i].samples;183att->load_op = pCreateInfo->pAttachments[i].loadOp;184att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;185att->final_layout = pCreateInfo->pAttachments[i].finalLayout;186att->first_subpass_idx = UINT32_MAX;187188bool is_zs = util_format_is_depth_or_stencil(lvp_vk_format_to_pipe_format(att->format));189pass->has_zs_attachment |= is_zs;190pass->has_color_attachment |= !is_zs;191}192uint32_t subpass_attachment_count = 0;193for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {194subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);195}196197if (subpass_attachment_count) {198pass->subpass_attachments =199vk_alloc2(&device->vk.alloc, pAllocator,200subpass_attachment_count * sizeof(struct lvp_subpass_attachment), 8,201VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);202if (pass->subpass_attachments == NULL) {203vk_free2(&device->vk.alloc, pAllocator, pass);204return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);205}206} else207pass->subpass_attachments = NULL;208209struct lvp_subpass_attachment *p = pass->subpass_attachments;210for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {211const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];212struct lvp_subpass *subpass = &pass->subpasses[i];213214subpass->input_count = desc->inputAttachmentCount;215subpass->color_count = desc->colorAttachmentCount;216subpass->attachment_count = lvp_num_subpass_attachments2(desc);217subpass->attachments = p;218subpass->view_mask = desc->viewMask;219220if (desc->inputAttachmentCount > 0) {221subpass->input_attachments = p;222p += desc->inputAttachmentCount;223224for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {225subpass->input_attachments[j] = (struct lvp_subpass_attachment) {226.attachment = desc->pInputAttachments[j].attachment,227.layout = desc->pInputAttachments[j].layout,228};229}230}231232if (desc->colorAttachmentCount > 0) {233subpass->color_attachments = p;234p += desc->colorAttachmentCount;235236for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {237subpass->color_attachments[j] = (struct lvp_subpass_attachment) {238.attachment = desc->pColorAttachments[j].attachment,239.layout = desc->pColorAttachments[j].layout,240};241}242}243244if (desc->pResolveAttachments) {245subpass->resolve_attachments = p;246p += desc->colorAttachmentCount;247248for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {249subpass->resolve_attachments[j] = (struct lvp_subpass_attachment) {250.attachment = desc->pResolveAttachments[j].attachment,251.layout = desc->pResolveAttachments[j].layout,252};253}254}255256if (desc->pDepthStencilAttachment) {257subpass->depth_stencil_attachment = p++;258259*subpass->depth_stencil_attachment = (struct lvp_subpass_attachment) {260.attachment = desc->pDepthStencilAttachment->attachment,261.layout = desc->pDepthStencilAttachment->layout,262};263}264}265266lvp_render_pass_compile(pass);267*pRenderPass = lvp_render_pass_to_handle(pass);268269return VK_SUCCESS;270}271272VKAPI_ATTR void VKAPI_CALL lvp_DestroyRenderPass(273VkDevice _device,274VkRenderPass _pass,275const VkAllocationCallbacks* pAllocator)276{277LVP_FROM_HANDLE(lvp_device, device, _device);278LVP_FROM_HANDLE(lvp_render_pass, pass, _pass);279280if (!_pass)281return;282vk_object_base_finish(&pass->base);283vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments);284vk_free2(&device->vk.alloc, pAllocator, pass);285}286287VKAPI_ATTR void VKAPI_CALL lvp_GetRenderAreaGranularity(288VkDevice device,289VkRenderPass renderPass,290VkExtent2D* pGranularity)291{292*pGranularity = (VkExtent2D) { 1, 1 };293}294295296