Home | History | Annotate | Download | only in vulkan
      1 /*
      2  * Copyright  2016 Red Hat.
      3  * Copyright  2016 Bas Nieuwenhuizen
      4  *
      5  * based in part on anv driver which is:
      6  * Copyright  2015 Intel Corporation
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the next
     16  * paragraph) shall be included in all copies or substantial portions of the
     17  * Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     25  * IN THE SOFTWARE.
     26  */
     27 #include "radv_private.h"
     28 
     29 #include "vk_util.h"
     30 
     31 VkResult radv_CreateRenderPass(
     32 	VkDevice                                    _device,
     33 	const VkRenderPassCreateInfo*               pCreateInfo,
     34 	const VkAllocationCallbacks*                pAllocator,
     35 	VkRenderPass*                               pRenderPass)
     36 {
     37 	RADV_FROM_HANDLE(radv_device, device, _device);
     38 	struct radv_render_pass *pass;
     39 	size_t size;
     40 	size_t attachments_offset;
     41 	VkRenderPassMultiviewCreateInfoKHX *multiview_info = NULL;
     42 
     43 	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
     44 
     45 	size = sizeof(*pass);
     46 	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
     47 	attachments_offset = size;
     48 	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
     49 
     50 	pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
     51 			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     52 	if (pass == NULL)
     53 		return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
     54 
     55 	memset(pass, 0, size);
     56 	pass->attachment_count = pCreateInfo->attachmentCount;
     57 	pass->subpass_count = pCreateInfo->subpassCount;
     58 	pass->attachments = (void *) pass + attachments_offset;
     59 
     60 	vk_foreach_struct(ext, pCreateInfo->pNext) {
     61 		switch(ext->sType) {
     62 		case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHX:
     63 			multiview_info = ( VkRenderPassMultiviewCreateInfoKHX*)ext;
     64 			break;
     65 		default:
     66 			break;
     67 		}
     68 	}
     69 
     70 	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
     71 		struct radv_render_pass_attachment *att = &pass->attachments[i];
     72 
     73 		att->format = pCreateInfo->pAttachments[i].format;
     74 		att->samples = pCreateInfo->pAttachments[i].samples;
     75 		att->load_op = pCreateInfo->pAttachments[i].loadOp;
     76 		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
     77 		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
     78 		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
     79 		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
     80 		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
     81 	}
     82 	uint32_t subpass_attachment_count = 0;
     83 	VkAttachmentReference *p;
     84 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
     85 		const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
     86 
     87 		subpass_attachment_count +=
     88 			desc->inputAttachmentCount +
     89 			desc->colorAttachmentCount +
     90 			(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
     91 			(desc->pDepthStencilAttachment != NULL);
     92 	}
     93 
     94 	if (subpass_attachment_count) {
     95 		pass->subpass_attachments =
     96 			vk_alloc2(&device->alloc, pAllocator,
     97 				    subpass_attachment_count * sizeof(VkAttachmentReference), 8,
     98 				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     99 		if (pass->subpass_attachments == NULL) {
    100 			vk_free2(&device->alloc, pAllocator, pass);
    101 			return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
    102 		}
    103 	} else
    104 		pass->subpass_attachments = NULL;
    105 
    106 	p = pass->subpass_attachments;
    107 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
    108 		const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
    109 		struct radv_subpass *subpass = &pass->subpasses[i];
    110 
    111 		subpass->input_count = desc->inputAttachmentCount;
    112 		subpass->color_count = desc->colorAttachmentCount;
    113 		if (multiview_info)
    114 			subpass->view_mask = multiview_info->pViewMasks[i];
    115 
    116 		if (desc->inputAttachmentCount > 0) {
    117 			subpass->input_attachments = p;
    118 			p += desc->inputAttachmentCount;
    119 
    120 			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
    121 				subpass->input_attachments[j]
    122 					= desc->pInputAttachments[j];
    123 				if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
    124 					pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
    125 			}
    126 		}
    127 
    128 		if (desc->colorAttachmentCount > 0) {
    129 			subpass->color_attachments = p;
    130 			p += desc->colorAttachmentCount;
    131 
    132 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
    133 				subpass->color_attachments[j]
    134 					= desc->pColorAttachments[j];
    135 				if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
    136 					pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
    137 			}
    138 		}
    139 
    140 		subpass->has_resolve = false;
    141 		if (desc->pResolveAttachments) {
    142 			subpass->resolve_attachments = p;
    143 			p += desc->colorAttachmentCount;
    144 
    145 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
    146 				uint32_t a = desc->pResolveAttachments[j].attachment;
    147 				subpass->resolve_attachments[j]
    148 					= desc->pResolveAttachments[j];
    149 				if (a != VK_ATTACHMENT_UNUSED) {
    150 					subpass->has_resolve = true;
    151 					pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
    152 				}
    153 			}
    154 		}
    155 
    156 		if (desc->pDepthStencilAttachment) {
    157 			subpass->depth_stencil_attachment =
    158 				*desc->pDepthStencilAttachment;
    159 			if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
    160 				pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
    161 		} else {
    162 			subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
    163 		}
    164 	}
    165 
    166 	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
    167 		uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
    168 		if (dst == VK_SUBPASS_EXTERNAL) {
    169 			pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
    170 			pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
    171 			pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
    172 		} else {
    173 			pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
    174 			pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
    175 			pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
    176 		}
    177 	}
    178 
    179 	*pRenderPass = radv_render_pass_to_handle(pass);
    180 
    181 	return VK_SUCCESS;
    182 }
    183 
    184 void radv_DestroyRenderPass(
    185 	VkDevice                                    _device,
    186 	VkRenderPass                                _pass,
    187 	const VkAllocationCallbacks*                pAllocator)
    188 {
    189 	RADV_FROM_HANDLE(radv_device, device, _device);
    190 	RADV_FROM_HANDLE(radv_render_pass, pass, _pass);
    191 
    192 	if (!_pass)
    193 		return;
    194 	vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
    195 	vk_free2(&device->alloc, pAllocator, pass);
    196 }
    197 
    198 void radv_GetRenderAreaGranularity(
    199     VkDevice                                    device,
    200     VkRenderPass                                renderPass,
    201     VkExtent2D*                                 pGranularity)
    202 {
    203 	pGranularity->width = 1;
    204 	pGranularity->height = 1;
    205 }
    206 
    207