Commit 9f8337e6 by Alexis Hetu Committed by Alexis Hétu

Support for VK_KHR_create_renderpass2

This cl adds support for the VK_KHR_create_renderpass2. It doesn't add any new functionality and ignores any new performance hints that are part of this extension, but it properly supports the new API entries that are part of this extension. Bug: b/148884281 Tests: dEQP-VK.* Change-Id: I15d9d00658e65380f4e93e59299a8c5e5212f95e Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40988 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent b7e6d8e3
......@@ -320,6 +320,15 @@ static const std::vector<std::pair<const char *, std::unordered_map<std::string,
{
MAKE_VULKAN_DEVICE_ENTRY(vkGetDescriptorSetLayoutSupportKHR),
} },
// VK_KHR_create_renderpass2
{
VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME,
{
MAKE_VULKAN_DEVICE_ENTRY(vkCreateRenderPass2KHR),
MAKE_VULKAN_DEVICE_ENTRY(vkCmdBeginRenderPass2KHR),
MAKE_VULKAN_DEVICE_ENTRY(vkCmdNextSubpass2KHR),
MAKE_VULKAN_DEVICE_ENTRY(vkCmdEndRenderPass2KHR),
} },
// VK_EXT_line_rasterization
{
VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME,
......
......@@ -16,6 +16,112 @@
#include "VkStringify.hpp"
#include <cstring>
namespace {
template<class T>
size_t ComputeRequiredAllocationSizeT(const T *pCreateInfo)
{
size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription) + pCreateInfo->attachmentCount * sizeof(int) // first use
+ pCreateInfo->attachmentCount * sizeof(uint32_t); // union of subpass view masks, per attachment
size_t subpassesSize = 0;
for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
{
const auto &subpass = pCreateInfo->pSubpasses[i];
uint32_t nbAttachments = subpass.inputAttachmentCount + subpass.colorAttachmentCount;
if(subpass.pResolveAttachments)
{
nbAttachments += subpass.colorAttachmentCount;
}
if(subpass.pDepthStencilAttachment)
{
nbAttachments += 1;
}
subpassesSize += sizeof(VkSubpassDescription) +
sizeof(VkAttachmentReference) * nbAttachments +
sizeof(uint32_t) * subpass.preserveAttachmentCount +
sizeof(uint32_t); // view mask
}
size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
return attachmentSize + subpassesSize + dependenciesSize;
}
template<class T>
void CopySubpasses(VkSubpassDescription *dst, const T *src, uint32_t count)
{
for(uint32_t i = 0; i < count; ++i)
{
dst[i].flags = src[i].flags;
dst[i].pipelineBindPoint = src[i].pipelineBindPoint;
dst[i].inputAttachmentCount = src[i].inputAttachmentCount;
dst[i].pInputAttachments = nullptr;
dst[i].colorAttachmentCount = src[i].colorAttachmentCount;
dst[i].pColorAttachments = nullptr;
dst[i].pResolveAttachments = nullptr;
dst[i].pDepthStencilAttachment = nullptr;
dst[i].preserveAttachmentCount = src[i].preserveAttachmentCount;
dst[i].pPreserveAttachments = nullptr;
}
}
template<class T>
void CopyAttachmentDescriptions(VkAttachmentDescription *dst, const T *src, uint32_t count)
{
for(uint32_t i = 0; i < count; ++i)
{
dst[i].flags = src[i].flags;
dst[i].format = src[i].format;
dst[i].samples = src[i].samples;
dst[i].loadOp = src[i].loadOp;
dst[i].storeOp = src[i].storeOp;
dst[i].stencilLoadOp = src[i].stencilLoadOp;
dst[i].stencilStoreOp = src[i].stencilStoreOp;
dst[i].initialLayout = src[i].initialLayout;
dst[i].finalLayout = src[i].finalLayout;
}
}
template<class T>
void CopyAttachmentReferences(VkAttachmentReference *dst, const T *src, uint32_t count)
{
for(uint32_t i = 0; i < count; ++i)
{
dst[i].attachment = src[i].attachment;
dst[i].layout = src[i].layout;
}
}
template<class T>
void CopySubpassDependencies(VkSubpassDependency *dst, const T *src, uint32_t count)
{
for(uint32_t i = 0; i < count; ++i)
{
dst[i].srcSubpass = src[i].srcSubpass;
dst[i].dstSubpass = src[i].dstSubpass;
dst[i].srcStageMask = src[i].srcStageMask;
dst[i].dstStageMask = src[i].dstStageMask;
dst[i].srcAccessMask = src[i].srcAccessMask;
dst[i].dstAccessMask = src[i].dstAccessMask;
dst[i].dependencyFlags = src[i].dependencyFlags;
}
}
bool GetViewMasks(const VkRenderPassCreateInfo *pCreateInfo, uint32_t *masks)
{
return false;
}
bool GetViewMasks(const VkRenderPassCreateInfo2KHR *pCreateInfo, uint32_t *masks)
{
for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
{
masks[i] = pCreateInfo->pSubpasses[i].viewMask;
}
return true;
}
} // namespace
namespace vk {
RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
......@@ -23,6 +129,25 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
, subpassCount(pCreateInfo->subpassCount)
, dependencyCount(pCreateInfo->dependencyCount)
{
init(pCreateInfo, mem);
}
RenderPass::RenderPass(const VkRenderPassCreateInfo2KHR *pCreateInfo, void *mem)
: attachmentCount(pCreateInfo->attachmentCount)
, subpassCount(pCreateInfo->subpassCount)
, dependencyCount(pCreateInfo->dependencyCount)
{
init(pCreateInfo, mem);
// Note: the init function above ignores:
// - pCorrelatedViewMasks: This provides a potential performance optimization
// - VkAttachmentReference2::aspectMask : This specifies which aspects may be used
// - VkSubpassDependency2::viewOffset : This is the same as VkRenderPassMultiviewCreateInfo::pViewOffsets, which is currently ignored
// - Any pNext pointer in VkRenderPassCreateInfo2KHR's internal structures
}
template<class T>
void RenderPass::init(const T *pCreateInfo, void *mem)
{
char *hostMemory = reinterpret_cast<char *>(mem);
// subpassCount must be greater than 0
......@@ -30,16 +155,16 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
size_t subpassesSize = pCreateInfo->subpassCount * sizeof(VkSubpassDescription);
subpasses = reinterpret_cast<VkSubpassDescription *>(hostMemory);
memcpy(subpasses, pCreateInfo->pSubpasses, subpassesSize);
CopySubpasses(subpasses, pCreateInfo->pSubpasses, pCreateInfo->subpassCount);
hostMemory += subpassesSize;
uint32_t *masks = reinterpret_cast<uint32_t *>(hostMemory);
hostMemory += pCreateInfo->subpassCount * sizeof(uint32_t);
hostMemory += subpassCount * sizeof(uint32_t);
if(pCreateInfo->attachmentCount > 0)
if(attachmentCount > 0)
{
size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription);
attachments = reinterpret_cast<VkAttachmentDescription *>(hostMemory);
memcpy(attachments, pCreateInfo->pAttachments, attachmentSize);
CopyAttachmentDescriptions(attachments, pCreateInfo->pAttachments, pCreateInfo->attachmentCount);
hostMemory += attachmentSize;
size_t firstUseSize = pCreateInfo->attachmentCount * sizeof(int);
......@@ -70,7 +195,9 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
masks[i] = multiviewCreateInfo->pViewMasks[i];
// This is now a multiview renderpass, so make the masks available
if(masks[i])
{
viewMasks = masks;
}
}
break;
......@@ -83,22 +210,28 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
extensionCreateInfo = extensionCreateInfo->pNext;
}
if(!viewMasks && (GetViewMasks(pCreateInfo, masks)))
{
for(auto i = 0u; i < pCreateInfo->subpassCount; i++)
{
if(masks[i])
{
viewMasks = masks;
}
}
}
// Deep copy subpasses
for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
{
const auto &subpass = pCreateInfo->pSubpasses[i];
subpasses[i].pInputAttachments = nullptr;
subpasses[i].pColorAttachments = nullptr;
subpasses[i].pResolveAttachments = nullptr;
subpasses[i].pDepthStencilAttachment = nullptr;
subpasses[i].pPreserveAttachments = nullptr;
if(subpass.inputAttachmentCount > 0)
{
size_t inputAttachmentsSize = subpass.inputAttachmentCount * sizeof(VkAttachmentReference);
subpasses[i].pInputAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
memcpy(const_cast<VkAttachmentReference *>(subpasses[i].pInputAttachments),
pCreateInfo->pSubpasses[i].pInputAttachments, inputAttachmentsSize);
CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pInputAttachments),
pCreateInfo->pSubpasses[i].pInputAttachments, subpass.inputAttachmentCount);
hostMemory += inputAttachmentsSize;
for(auto j = 0u; j < subpasses[i].inputAttachmentCount; j++)
......@@ -112,15 +245,15 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
{
size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference);
subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
memcpy(const_cast<VkAttachmentReference *>(subpasses[i].pColorAttachments),
subpass.pColorAttachments, colorAttachmentsSize);
CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pColorAttachments),
subpass.pColorAttachments, subpass.colorAttachmentCount);
hostMemory += colorAttachmentsSize;
if(subpass.pResolveAttachments)
{
subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
memcpy(const_cast<VkAttachmentReference *>(subpasses[i].pResolveAttachments),
subpass.pResolveAttachments, colorAttachmentsSize);
CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pResolveAttachments),
subpass.pResolveAttachments, subpass.colorAttachmentCount);
hostMemory += colorAttachmentsSize;
}
......@@ -137,8 +270,8 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
if(subpass.pDepthStencilAttachment)
{
subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference *>(hostMemory);
memcpy(const_cast<VkAttachmentReference *>(subpasses[i].pDepthStencilAttachment),
subpass.pDepthStencilAttachment, sizeof(VkAttachmentReference));
CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pDepthStencilAttachment),
subpass.pDepthStencilAttachment, 1);
hostMemory += sizeof(VkAttachmentReference);
if(subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
......@@ -149,8 +282,10 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
{
size_t preserveAttachmentSize = subpass.preserveAttachmentCount * sizeof(uint32_t);
subpasses[i].pPreserveAttachments = reinterpret_cast<uint32_t *>(hostMemory);
memcpy(const_cast<uint32_t *>(subpasses[i].pPreserveAttachments),
pCreateInfo->pSubpasses[i].pPreserveAttachments, preserveAttachmentSize);
for(uint32_t j = 0u; j < subpass.preserveAttachmentCount; j++)
{
const_cast<uint32_t *>(subpasses[i].pPreserveAttachments)[j] = pCreateInfo->pSubpasses[i].pPreserveAttachments[j];
}
hostMemory += preserveAttachmentSize;
for(auto j = 0u; j < subpasses[i].preserveAttachmentCount; j++)
......@@ -163,9 +298,8 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
if(pCreateInfo->dependencyCount > 0)
{
size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
dependencies = reinterpret_cast<VkSubpassDependency *>(hostMemory);
memcpy(dependencies, pCreateInfo->pDependencies, dependenciesSize);
CopySubpassDependencies(dependencies, pCreateInfo->pDependencies, pCreateInfo->dependencyCount);
}
}
......@@ -176,29 +310,12 @@ void RenderPass::destroy(const VkAllocationCallbacks *pAllocator)
size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo *pCreateInfo)
{
size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription) + pCreateInfo->attachmentCount * sizeof(int) // first use
+ pCreateInfo->attachmentCount * sizeof(uint32_t); // union of subpass view masks, per attachment
size_t subpassesSize = 0;
for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
{
const auto &subpass = pCreateInfo->pSubpasses[i];
uint32_t nbAttachments = subpass.inputAttachmentCount + subpass.colorAttachmentCount;
if(subpass.pResolveAttachments)
{
nbAttachments += subpass.colorAttachmentCount;
}
if(subpass.pDepthStencilAttachment)
{
nbAttachments += 1;
}
subpassesSize += sizeof(VkSubpassDescription) +
sizeof(VkAttachmentReference) * nbAttachments +
sizeof(uint32_t) * subpass.preserveAttachmentCount +
sizeof(uint32_t); // view mask
}
size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
return ComputeRequiredAllocationSizeT(pCreateInfo);
}
return attachmentSize + subpassesSize + dependenciesSize;
size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo2KHR *pCreateInfo)
{
return ComputeRequiredAllocationSizeT(pCreateInfo);
}
void RenderPass::getRenderAreaGranularity(VkExtent2D *pGranularity) const
......
......@@ -25,9 +25,11 @@ class RenderPass : public Object<RenderPass, VkRenderPass>
{
public:
RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem);
RenderPass(const VkRenderPassCreateInfo2KHR *pCreateInfo, void *mem);
void destroy(const VkAllocationCallbacks *pAllocator);
static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo *pCreateInfo);
static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo2KHR *pCreateInfo);
void getRenderAreaGranularity(VkExtent2D *pGranularity) const;
......@@ -93,6 +95,8 @@ private:
uint32_t *attachmentViewMasks = nullptr;
void MarkFirstUse(int attachment, int subpass);
template<class T>
void init(const T *pCreateInfo, void *mem);
};
static inline RenderPass *Cast(VkRenderPass object)
......
......@@ -165,6 +165,92 @@ void initializeLibrary()
(void)doOnce;
}
template<class T>
void ValidateRenderPassPNextChain(VkDevice device, const T *pCreateInfo)
{
const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
while(extensionCreateInfo)
{
switch(extensionCreateInfo->sType)
{
case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
{
const VkRenderPassInputAttachmentAspectCreateInfo *inputAttachmentAspectCreateInfo = reinterpret_cast<const VkRenderPassInputAttachmentAspectCreateInfo *>(extensionCreateInfo);
for(uint32_t i = 0; i < inputAttachmentAspectCreateInfo->aspectReferenceCount; i++)
{
const auto &aspectReference = inputAttachmentAspectCreateInfo->pAspectReferences[i];
ASSERT(aspectReference.subpass < pCreateInfo->subpassCount);
const auto &subpassDescription = pCreateInfo->pSubpasses[aspectReference.subpass];
ASSERT(aspectReference.inputAttachmentIndex < subpassDescription.inputAttachmentCount);
const auto &attachmentReference = subpassDescription.pInputAttachments[aspectReference.inputAttachmentIndex];
if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
{
// If the pNext chain includes an instance of VkRenderPassInputAttachmentAspectCreateInfo, for any
// element of the pInputAttachments member of any element of pSubpasses where the attachment member
// is not VK_ATTACHMENT_UNUSED, the aspectMask member of the corresponding element of
// VkRenderPassInputAttachmentAspectCreateInfo::pAspectReferences must only include aspects that are
// present in images of the format specified by the element of pAttachments at attachment
vk::Format format(pCreateInfo->pAttachments[attachmentReference.attachment].format);
bool isDepth = format.isDepth();
bool isStencil = format.isStencil();
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) || (!isDepth && !isStencil));
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) || isDepth);
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) || isStencil);
}
}
}
break;
case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
{
const VkRenderPassMultiviewCreateInfo *multiviewCreateInfo = reinterpret_cast<const VkRenderPassMultiviewCreateInfo *>(extensionCreateInfo);
ASSERT((multiviewCreateInfo->subpassCount == 0) || (multiviewCreateInfo->subpassCount == pCreateInfo->subpassCount));
ASSERT((multiviewCreateInfo->dependencyCount == 0) || (multiviewCreateInfo->dependencyCount == pCreateInfo->dependencyCount));
bool zeroMask = (multiviewCreateInfo->pViewMasks[0] == 0);
for(uint32_t i = 1; i < multiviewCreateInfo->subpassCount; i++)
{
ASSERT((multiviewCreateInfo->pViewMasks[i] == 0) == zeroMask);
}
if(zeroMask)
{
ASSERT(multiviewCreateInfo->correlationMaskCount == 0);
}
for(uint32_t i = 0; i < multiviewCreateInfo->dependencyCount; i++)
{
const auto &dependency = pCreateInfo->pDependencies[i];
if(multiviewCreateInfo->pViewOffsets[i] != 0)
{
ASSERT(dependency.srcSubpass != dependency.dstSubpass);
ASSERT(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT);
}
if(zeroMask)
{
ASSERT(!(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT));
}
}
// If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo,
// each element of its pViewMask member must not include a bit at a position
// greater than the value of VkPhysicalDeviceLimits::maxFramebufferLayers
// pViewMask is a 32 bit value. If maxFramebufferLayers > 32, it's impossible
// for pViewMask to contain a bit at an illegal position
// Note: Verify pViewMask values instead if we hit this assert
ASSERT(vk::Cast(device)->getPhysicalDevice()->getProperties().limits.maxFramebufferLayers >= 32);
}
break;
default:
WARN("pCreateInfo->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
break;
}
extensionCreateInfo = extensionCreateInfo->pNext;
}
}
} // namespace
extern "C" {
......@@ -212,6 +298,7 @@ static const VkExtensionProperties deviceExtensionProperties[] = {
// Vulkan 1.1 promoted extensions
{ VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION },
{ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_SPEC_VERSION },
{ VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION },
{ VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION },
{ VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION },
{ VK_KHR_DEVICE_GROUP_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_SPEC_VERSION },
......@@ -1884,88 +1971,24 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRende
UNSUPPORTED("pCreateInfo->flags %d", int(pCreateInfo->flags));
}
const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
while(extensionCreateInfo)
{
switch(extensionCreateInfo->sType)
{
case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
{
const VkRenderPassInputAttachmentAspectCreateInfo *inputAttachmentAspectCreateInfo = reinterpret_cast<const VkRenderPassInputAttachmentAspectCreateInfo *>(extensionCreateInfo);
for(uint32_t i = 0; i < inputAttachmentAspectCreateInfo->aspectReferenceCount; i++)
{
const VkInputAttachmentAspectReference &aspectReference = inputAttachmentAspectCreateInfo->pAspectReferences[i];
ASSERT(aspectReference.subpass < pCreateInfo->subpassCount);
const VkSubpassDescription &subpassDescription = pCreateInfo->pSubpasses[aspectReference.subpass];
ASSERT(aspectReference.inputAttachmentIndex < subpassDescription.inputAttachmentCount);
const VkAttachmentReference &attachmentReference = subpassDescription.pInputAttachments[aspectReference.inputAttachmentIndex];
if(attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
{
// If the pNext chain includes an instance of VkRenderPassInputAttachmentAspectCreateInfo, for any
// element of the pInputAttachments member of any element of pSubpasses where the attachment member
// is not VK_ATTACHMENT_UNUSED, the aspectMask member of the corresponding element of
// VkRenderPassInputAttachmentAspectCreateInfo::pAspectReferences must only include aspects that are
// present in images of the format specified by the element of pAttachments at attachment
vk::Format format(pCreateInfo->pAttachments[attachmentReference.attachment].format);
bool isDepth = format.isDepth();
bool isStencil = format.isStencil();
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) || (!isDepth && !isStencil));
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) || isDepth);
ASSERT(!(aspectReference.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) || isStencil);
}
}
}
break;
case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
{
const VkRenderPassMultiviewCreateInfo *multiviewCreateInfo = reinterpret_cast<const VkRenderPassMultiviewCreateInfo *>(extensionCreateInfo);
ASSERT((multiviewCreateInfo->subpassCount == 0) || (multiviewCreateInfo->subpassCount == pCreateInfo->subpassCount));
ASSERT((multiviewCreateInfo->dependencyCount == 0) || (multiviewCreateInfo->dependencyCount == pCreateInfo->dependencyCount));
bool zeroMask = (multiviewCreateInfo->pViewMasks[0] == 0);
for(uint32_t i = 1; i < multiviewCreateInfo->subpassCount; i++)
{
ASSERT((multiviewCreateInfo->pViewMasks[i] == 0) == zeroMask);
}
if(zeroMask)
{
ASSERT(multiviewCreateInfo->correlationMaskCount == 0);
}
ValidateRenderPassPNextChain(device, pCreateInfo);
for(uint32_t i = 0; i < multiviewCreateInfo->dependencyCount; i++)
{
const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i];
if(multiviewCreateInfo->pViewOffsets[i] != 0)
{
ASSERT(dependency.srcSubpass != dependency.dstSubpass);
ASSERT(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT);
}
if(zeroMask)
{
ASSERT(!(dependency.dependencyFlags & VK_DEPENDENCY_VIEW_LOCAL_BIT));
}
}
return vk::RenderPass::Create(pAllocator, pCreateInfo, pRenderPass);
}
// If the pNext chain includes an instance of VkRenderPassMultiviewCreateInfo,
// each element of its pViewMask member must not include a bit at a position
// greater than the value of VkPhysicalDeviceLimits::maxFramebufferLayers
// pViewMask is a 32 bit value. If maxFramebufferLayers > 32, it's impossible
// for pViewMask to contain a bit at an illegal position
// Note: Verify pViewMask values instead if we hit this assert
ASSERT(vk::Cast(device)->getPhysicalDevice()->getProperties().limits.maxFramebufferLayers >= 32);
}
break;
default:
WARN("pCreateInfo->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
break;
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass)
{
TRACE("(VkDevice device = %p, const VkRenderPassCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkRenderPass* pRenderPass = %p)",
device, pCreateInfo, pAllocator, pRenderPass);
extensionCreateInfo = extensionCreateInfo->pNext;
if(pCreateInfo->flags != 0)
{
// Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
UNSUPPORTED("pCreateInfo->flags %d", int(pCreateInfo->flags));
}
ValidateRenderPassPNextChain(device, pCreateInfo);
return vk::RenderPass::Create(pAllocator, pCreateInfo, pRenderPass);
}
......@@ -2415,6 +2438,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, c
vk::Cast(commandBuffer)->beginRenderPass(vk::Cast(pRenderPassBegin->renderPass), vk::Cast(pRenderPassBegin->framebuffer), pRenderPassBegin->renderArea, pRenderPassBegin->clearValueCount, pRenderPassBegin->pClearValues, contents);
}
VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
{
TRACE("(VkCommandBuffer commandBuffer = %p, const VkRenderPassBeginInfo* pRenderPassBegin = %p, const VkSubpassBeginInfoKHR* pSubpassBeginInfo = %p)",
commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
vk::Cast(commandBuffer)->beginRenderPass(vk::Cast(pRenderPassBegin->renderPass), vk::Cast(pRenderPassBegin->framebuffer), pRenderPassBegin->renderArea, pRenderPassBegin->clearValueCount, pRenderPassBegin->pClearValues, pSubpassBeginInfo->contents);
}
VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
{
TRACE("(VkCommandBuffer commandBuffer = %p, VkSubpassContents contents = %d)",
......@@ -2423,6 +2454,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSub
vk::Cast(commandBuffer)->nextSubpass(contents);
}
VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR *pSubpassBeginInfo, const VkSubpassEndInfoKHR *pSubpassEndInfo)
{
TRACE("(VkCommandBuffer commandBuffer = %p, const VkSubpassBeginInfoKHR* pSubpassBeginInfo = %p, const VkSubpassEndInfoKHR* pSubpassEndInfo = %p)",
commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
vk::Cast(commandBuffer)->nextSubpass(pSubpassBeginInfo->contents);
}
VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
{
TRACE("(VkCommandBuffer commandBuffer = %p)", commandBuffer);
......@@ -2430,6 +2469,13 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
vk::Cast(commandBuffer)->endRenderPass();
}
VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR *pSubpassEndInfo)
{
TRACE("(VkCommandBuffer commandBuffer = %p, const VkSubpassEndInfoKHR* pSubpassEndInfo = %p)", commandBuffer, pSubpassEndInfo);
vk::Cast(commandBuffer)->endRenderPass();
}
VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
{
TRACE("(VkCommandBuffer commandBuffer = %p, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = %p)",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment