Merge changes Ide16cac3,Id5d767fc
* changes:
Update Marl to 246091e81
Squashed 'third_party/marl/' changes from 14e4d862a..246091e81
diff --git a/BUILD.gn b/BUILD.gn
index eba6788..7d2a6f5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -109,26 +109,28 @@
]
} else if (target_cpu == "mipsel" && current_cpu == target_cpu) {
cflags += [
- "-march=mipsel",
+ "-EL",
"-fPIC",
"-mhard-float",
"-mfp32",
+ "-mxgot",
]
if (mips_arch_variant == "r1") {
cflags += [
- "-mcpu=mips32",
+ "-march=mips32",
]
} else {
cflags += [
- "-mcpu=mips32r2",
+ "-march=mips32r2",
]
}
} else if (target_cpu == "mips64el" && current_cpu == target_cpu) {
cflags += [
- "-march=mips64el",
- "-mcpu=mips64r2",
+ "-EL",
+ "-arch=mips64r2",
"-mabi=64",
"-fPIC",
+ "-mxgot",
]
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e6b867..02f903c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -475,15 +475,19 @@
set_cpp_flag("-mtune=generic")
endif()
if(ARCH STREQUAL "mipsel")
+ set_cpp_flag("-EL")
set_cpp_flag("-march=mips32r2")
set_cpp_flag("-fPIC")
set_cpp_flag("-mhard-float")
set_cpp_flag("-mfp32")
+ set_cpp_flag("-mxgot")
endif()
if(ARCH STREQUAL "mips64el")
+ set_cpp_flag("-EL")
set_cpp_flag("-march=mips64r2")
set_cpp_flag("-mabi=64")
set_cpp_flag("-fPIC")
+ set_cpp_flag("-mxgot")
endif()
if(SWIFTSHADER_LESS_DEBUG_INFO)
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 4246880..0fe5b09 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -423,18 +423,20 @@
case spv::OpExtInstImport:
{
- auto const extensionsByName = std::initializer_list<std::pair<const char *, Extension::Name>>{
+ static constexpr std::pair<const char *, Extension::Name> extensionsByName[] = {
{ "GLSL.std.450", Extension::GLSLstd450 },
{ "OpenCL.DebugInfo.100", Extension::OpenCLDebugInfo100 },
};
+ static constexpr auto extensionCount = sizeof(extensionsByName) / sizeof(extensionsByName[0]);
+
auto id = Extension::ID(insn.word(1));
auto name = insn.string(2);
auto ext = Extension{ Extension::Unknown };
- for(auto it : extensionsByName)
+ for(size_t i = 0; i < extensionCount; i++)
{
- if(0 == strcmp(name, it.first))
+ if(0 == strcmp(name, extensionsByName[i].first))
{
- ext = Extension{ it.second };
+ ext = Extension{ extensionsByName[i].second };
break;
}
}
diff --git a/src/Reactor/Debug.cpp b/src/Reactor/Debug.cpp
index 5b10036..2df3e28 100644
--- a/src/Reactor/Debug.cpp
+++ b/src/Reactor/Debug.cpp
@@ -39,7 +39,7 @@
#endif
#ifndef REACTOR_LOGGING_LEVEL
-# define REACTOR_LOGGING_LEVEL INFO
+# define REACTOR_LOGGING_LEVEL Info
#endif
namespace {
@@ -98,11 +98,11 @@
enum class Level
{
- DEBUG,
- INFO,
- WARN,
- ERROR,
- FATAL,
+ Debug,
+ Info,
+ Warn,
+ Error,
+ Fatal,
};
#ifdef __ANDROID__
@@ -110,19 +110,19 @@
{
switch(level)
{
- case Level::DEBUG:
+ case Level::Debug:
__android_log_write(ANDROID_LOG_DEBUG, "SwiftShader", msg);
break;
- case Level::INFO:
+ case Level::Info:
__android_log_write(ANDROID_LOG_INFO, "SwiftShader", msg);
break;
- case Level::WARN:
+ case Level::Warn:
__android_log_write(ANDROID_LOG_WARN, "SwiftShader", msg);
break;
- case Level::ERROR:
+ case Level::Error:
__android_log_write(ANDROID_LOG_ERROR, "SwiftShader", msg);
break;
- case Level::FATAL:
+ case Level::Fatal:
__android_log_write(ANDROID_LOG_FATAL, "SwiftShader", msg);
break;
}
@@ -132,13 +132,13 @@
{
switch(level)
{
- case Level::DEBUG:
- case Level::INFO:
+ case Level::Debug:
+ case Level::Info:
fprintf(stdout, "%s", msg);
break;
- case Level::WARN:
- case Level::ERROR:
- case Level::FATAL:
+ case Level::Warn:
+ case Level::Error:
+ case Level::Fatal:
fprintf(stderr, "%s", msg);
break;
}
@@ -187,7 +187,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::DEBUG, format, vararg);
+ logv(Level::Debug, format, vararg);
va_end(vararg);
}
@@ -195,7 +195,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::WARN, format, vararg);
+ logv(Level::Warn, format, vararg);
va_end(vararg);
}
@@ -204,7 +204,7 @@
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
::abort();
@@ -218,7 +218,7 @@
// Abort after tracing and printing to stderr
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
::abort();
@@ -227,7 +227,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
}
}
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 4624064..7efeb5b 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -45,6 +45,7 @@
# include <Windows.h>
#endif
+#include <array>
#include <iostream>
#include <limits>
#include <mutex>
@@ -159,7 +160,7 @@
ret = function->makeVariable(retTy);
}
- std::initializer_list<Ice::Variable *> iceArgs = { std::forward<RArgs>(args)... };
+ std::array<Ice::Variable *, sizeof...(args)> iceArgs {{ std::forward<RArgs>(args)... }};
auto call = Ice::InstCall::create(function, iceArgs.size(), ret, getConstantPointer(function->getContext(), reinterpret_cast<void const *>(fptr)), false);
for(auto arg : iceArgs)
diff --git a/src/System/Debug.cpp b/src/System/Debug.cpp
index f386156..8be91a1 100644
--- a/src/System/Debug.cpp
+++ b/src/System/Debug.cpp
@@ -39,7 +39,7 @@
#endif
#ifndef SWIFTSHADER_LOGGING_LEVEL
-# define SWIFTSHADER_LOGGING_LEVEL INFO
+# define SWIFTSHADER_LOGGING_LEVEL Info
#endif
namespace {
@@ -98,11 +98,11 @@
enum class Level
{
- DEBUG,
- INFO,
- WARN,
- ERROR,
- FATAL,
+ Debug,
+ Info,
+ Warn,
+ Error,
+ Fatal,
};
#ifdef __ANDROID__
@@ -110,19 +110,19 @@
{
switch(level)
{
- case Level::DEBUG:
+ case Level::Debug:
__android_log_write(ANDROID_LOG_DEBUG, "SwiftShader", msg);
break;
- case Level::INFO:
+ case Level::Info:
__android_log_write(ANDROID_LOG_INFO, "SwiftShader", msg);
break;
- case Level::WARN:
+ case Level::Warn:
__android_log_write(ANDROID_LOG_WARN, "SwiftShader", msg);
break;
- case Level::ERROR:
+ case Level::Error:
__android_log_write(ANDROID_LOG_ERROR, "SwiftShader", msg);
break;
- case Level::FATAL:
+ case Level::Fatal:
__android_log_write(ANDROID_LOG_FATAL, "SwiftShader", msg);
break;
}
@@ -132,13 +132,13 @@
{
switch(level)
{
- case Level::DEBUG:
- case Level::INFO:
+ case Level::Debug:
+ case Level::Info:
fprintf(stdout, "%s", msg);
break;
- case Level::WARN:
- case Level::ERROR:
- case Level::FATAL:
+ case Level::Warn:
+ case Level::Error:
+ case Level::Fatal:
fprintf(stderr, "%s", msg);
break;
}
@@ -187,7 +187,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::DEBUG, format, vararg);
+ logv(Level::Debug, format, vararg);
va_end(vararg);
}
@@ -195,7 +195,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::WARN, format, vararg);
+ logv(Level::Warn, format, vararg);
va_end(vararg);
}
@@ -204,7 +204,7 @@
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
::abort();
@@ -218,7 +218,7 @@
// Abort after tracing and printing to stderr
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
::abort();
@@ -227,7 +227,7 @@
{
va_list vararg;
va_start(vararg, format);
- logv(Level::FATAL, format, vararg);
+ logv(Level::Fatal, format, vararg);
va_end(vararg);
}
}
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 796596b..f293ca5 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -320,6 +320,15 @@
{
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,
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index f3e62f5..70047a9 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -158,6 +158,11 @@
features->shaderDrawParameters = VK_FALSE;
}
+void PhysicalDevice::getFeatures(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR* features) const
+{
+ features->separateDepthStencilLayouts = VK_TRUE;
+}
+
void PhysicalDevice::getFeatures(VkPhysicalDeviceLineRasterizationFeaturesEXT *features) const
{
features->rectangularLines = VK_TRUE;
diff --git a/src/Vulkan/VkPhysicalDevice.hpp b/src/Vulkan/VkPhysicalDevice.hpp
index 8e94466..2542e35 100644
--- a/src/Vulkan/VkPhysicalDevice.hpp
+++ b/src/Vulkan/VkPhysicalDevice.hpp
@@ -43,6 +43,7 @@
void getFeatures(VkPhysicalDeviceProtectedMemoryFeatures *features) const;
void getFeatures(VkPhysicalDeviceShaderDrawParameterFeatures *features) const;
void getFeatures(VkPhysicalDeviceLineRasterizationFeaturesEXT *features) const;
+ void getFeatures(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR* features) const;
void getFeatures(VkPhysicalDeviceProvokingVertexFeaturesEXT *features) const;
bool hasFeatures(const VkPhysicalDeviceFeatures &requestedFeatures) const;
diff --git a/src/Vulkan/VkRenderPass.cpp b/src/Vulkan/VkRenderPass.cpp
index 914c1d7..0830709 100644
--- a/src/Vulkan/VkRenderPass.cpp
+++ b/src/Vulkan/VkRenderPass.cpp
@@ -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 @@
, 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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
{
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 @@
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 @@
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
diff --git a/src/Vulkan/VkRenderPass.hpp b/src/Vulkan/VkRenderPass.hpp
index 2c2fe85..3f02f6b 100644
--- a/src/Vulkan/VkRenderPass.hpp
+++ b/src/Vulkan/VkRenderPass.hpp
@@ -25,9 +25,11 @@
{
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 @@
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)
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 1d93641..61eb97c 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -165,6 +165,92 @@
(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 @@
// 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 },
@@ -225,6 +312,7 @@
{ VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION },
{ VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME, VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION },
{ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION },
+ { VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME, VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION },
// Only 1.1 core version of this is supported. The extension has additional requirements
//{ VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION },
{ VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION },
@@ -626,6 +714,14 @@
}
}
break;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR:
+ {
+ const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR* shaderDrawParametersFeatures = reinterpret_cast<const VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR*>(extensionCreateInfo);
+
+ // Separate depth and stencil layouts is already supported
+ (void)(shaderDrawParametersFeatures->separateDepthStencilLayouts);
+ }
+ break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
{
const VkPhysicalDeviceLineRasterizationFeaturesEXT *lineRasterizationFeatures = reinterpret_cast<const VkPhysicalDeviceLineRasterizationFeaturesEXT *>(extensionCreateInfo);
@@ -1884,88 +1980,24 @@
UNSUPPORTED("pCreateInfo->flags %d", int(pCreateInfo->flags));
}
- const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
+ ValidateRenderPassPNextChain(device, pCreateInfo);
- while(extensionCreateInfo)
+ return vk::RenderPass::Create(pAllocator, pCreateInfo, pRenderPass);
+}
+
+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);
+
+ if(pCreateInfo->flags != 0)
{
- 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);
- }
-
- 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));
- }
- }
-
- // 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;
+ // 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 +2447,14 @@
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 +2463,14 @@
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 +2478,13 @@
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)",
@@ -2700,6 +2755,12 @@
vk::Cast(physicalDevice)->getFeatures(features);
}
break;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR:
+ {
+ auto features = reinterpret_cast<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR*>(extensionFeatures);
+ vk::Cast(physicalDevice)->getFeatures(features);
+ }
+ break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
{
auto features = reinterpret_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT *>(extensionFeatures);