Opaque sparse memory bindings for mip tails
This commit is contained in:
parent
8f2ea86e11
commit
385b760770
3 changed files with 59 additions and 24 deletions
|
|
@ -18,7 +18,7 @@ layout (location = 0) out vec4 outFragColor;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Get residency code for current texel
|
// Get residency code for current texel
|
||||||
int residencyCode = sparseTextureARB(samplerColor, inUV, outFragColor);
|
int residencyCode = sparseTextureARB(samplerColor, inUV, outFragColor, inLodBias);
|
||||||
// Check if texel is resident
|
// Check if texel is resident
|
||||||
bool texelResident = sparseTexelsResidentARB(residencyCode);
|
bool texelResident = sparseTexelsResidentARB(residencyCode);
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -210,8 +210,7 @@ public:
|
||||||
{
|
{
|
||||||
texture.width = width;
|
texture.width = width;
|
||||||
texture.height = height;
|
texture.height = height;
|
||||||
//texture.mipLevels = floor(log2(std::max(width, height))) + 1; //todo
|
texture.mipLevels = floor(log2(std::max(width, height))) + 1; //todo
|
||||||
texture.mipLevels = 1;
|
|
||||||
texture.layerCount = layerCount;
|
texture.layerCount = layerCount;
|
||||||
texture.format = format;
|
texture.format = format;
|
||||||
|
|
||||||
|
|
@ -330,9 +329,14 @@ public:
|
||||||
uint32_t sparseBindsCount = static_cast<uint32_t>(sparseImageMemoryReqs.size / sparseImageMemoryReqs.alignment);
|
uint32_t sparseBindsCount = static_cast<uint32_t>(sparseImageMemoryReqs.size / sparseImageMemoryReqs.alignment);
|
||||||
std::vector<VkSparseMemoryBind> sparseMemoryBinds(sparseBindsCount);
|
std::vector<VkSparseMemoryBind> sparseMemoryBinds(sparseBindsCount);
|
||||||
|
|
||||||
|
// Check if the format has a single mip tail for all layers or one mip tail for each layer
|
||||||
|
// The mip tail contains all mip levels > sparseMemoryReq.imageMipTailFirstLod
|
||||||
|
bool singleMipTail = sparseMemoryReq.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT;
|
||||||
|
|
||||||
// Sparse bindings for each mip level of all layers outside of the mip tail
|
// Sparse bindings for each mip level of all layers outside of the mip tail
|
||||||
for (uint32_t layer = 0; layer < texture.layerCount; layer++)
|
for (uint32_t layer = 0; layer < texture.layerCount; layer++)
|
||||||
{
|
{
|
||||||
|
// sparseMemoryReq.imageMipTailFirstLod is the first mip level that's stored inside the mip tail
|
||||||
for (uint32_t mipLevel = 0; mipLevel < sparseMemoryReq.imageMipTailFirstLod; mipLevel++)
|
for (uint32_t mipLevel = 0; mipLevel < sparseMemoryReq.imageMipTailFirstLod; mipLevel++)
|
||||||
{
|
{
|
||||||
VkExtent3D extent;
|
VkExtent3D extent;
|
||||||
|
|
@ -396,14 +400,47 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sparse binding for the mip tail (if present) containing the remaining mip levels
|
// Check if format has one mip tail per layer
|
||||||
// The mip tail contains all mip levels > sparseMemoryReq.imageMipTailFirstLod
|
if ((!singleMipTail) && (sparseMemoryReq.imageMipTailFirstLod < texture.mipLevels))
|
||||||
if ((sparseMemoryReq.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && (sparseMemoryReq.imageMipTailFirstLod < texture.mipLevels))
|
|
||||||
{
|
{
|
||||||
//todo
|
// Allocate memory for the mip tail
|
||||||
}
|
VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo();
|
||||||
|
allocInfo.allocationSize = sparseMemoryReq.imageMipTailSize;
|
||||||
|
allocInfo.memoryTypeIndex = memoryTypeIndex;
|
||||||
|
|
||||||
|
VkDeviceMemory deviceMemory;
|
||||||
|
VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &deviceMemory));
|
||||||
|
|
||||||
|
// (Opaque) sparse memory binding
|
||||||
|
VkSparseMemoryBind sparseMemoryBind{};
|
||||||
|
sparseMemoryBind.resourceOffset = sparseMemoryReq.imageMipTailOffset + layer * sparseMemoryReq.imageMipTailStride;
|
||||||
|
sparseMemoryBind.size = sparseMemoryReq.imageMipTailSize;
|
||||||
|
sparseMemoryBind.memory = deviceMemory;
|
||||||
|
|
||||||
|
texture.opaqueMemoryBinds.push_back(sparseMemoryBind);
|
||||||
|
}
|
||||||
} // end layers and mips
|
} // end layers and mips
|
||||||
|
|
||||||
|
// Check if format has one mip tail for all layers
|
||||||
|
if ((sparseMemoryReq.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && (sparseMemoryReq.imageMipTailFirstLod < texture.mipLevels))
|
||||||
|
{
|
||||||
|
// Allocate memory for the mip tail
|
||||||
|
VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo();
|
||||||
|
allocInfo.allocationSize = sparseMemoryReq.imageMipTailSize;
|
||||||
|
allocInfo.memoryTypeIndex = memoryTypeIndex;
|
||||||
|
|
||||||
|
VkDeviceMemory deviceMemory;
|
||||||
|
VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &deviceMemory));
|
||||||
|
|
||||||
|
// (Opaque) sparse memory binding
|
||||||
|
VkSparseMemoryBind sparseMemoryBind{};
|
||||||
|
sparseMemoryBind.resourceOffset = sparseMemoryReq.imageMipTailOffset;
|
||||||
|
sparseMemoryBind.size = sparseMemoryReq.imageMipTailSize;
|
||||||
|
sparseMemoryBind.memory = deviceMemory;
|
||||||
|
|
||||||
|
texture.opaqueMemoryBinds.push_back(sparseMemoryBind);
|
||||||
|
}
|
||||||
|
|
||||||
// Create signal semaphore for sparse binding
|
// Create signal semaphore for sparse binding
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vkTools::initializers::semaphoreCreateInfo();
|
VkSemaphoreCreateInfo semaphoreCreateInfo = vkTools::initializers::semaphoreCreateInfo();
|
||||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &bindSparseSemaphore));
|
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &bindSparseSemaphore));
|
||||||
|
|
@ -442,21 +479,15 @@ public:
|
||||||
sampler.magFilter = VK_FILTER_LINEAR;
|
sampler.magFilter = VK_FILTER_LINEAR;
|
||||||
sampler.minFilter = VK_FILTER_LINEAR;
|
sampler.minFilter = VK_FILTER_LINEAR;
|
||||||
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
sampler.mipLodBias = 0.0f;
|
sampler.mipLodBias = 0.0f;
|
||||||
sampler.compareOp = VK_COMPARE_OP_NEVER;
|
sampler.compareOp = VK_COMPARE_OP_NEVER;
|
||||||
sampler.minLod = 0.0f;
|
sampler.minLod = 0.0f;
|
||||||
sampler.maxLod = (float)texture.mipLevels;
|
sampler.maxLod = static_cast<float>(texture.mipLevels);
|
||||||
sampler.maxAnisotropy = 1.0;
|
sampler.anisotropyEnable = vulkanDevice->features.samplerAnisotropy;
|
||||||
sampler.anisotropyEnable = VK_FALSE;
|
sampler.maxAnisotropy = vulkanDevice->features.samplerAnisotropy ? vulkanDevice->properties.limits.maxSamplerAnisotropy : 1.0f;
|
||||||
if (vulkanDevice->features.samplerAnisotropy)
|
|
||||||
{
|
|
||||||
// Use max. level of anisotropy for this example
|
|
||||||
sampler.maxAnisotropy = vulkanDevice->properties.limits.maxSamplerAnisotropy;
|
|
||||||
sampler.anisotropyEnable = VK_TRUE;
|
|
||||||
}
|
|
||||||
sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||||
VK_CHECK_RESULT(vkCreateSampler(device, &sampler, nullptr, &texture.sampler));
|
VK_CHECK_RESULT(vkCreateSampler(device, &sampler, nullptr, &texture.sampler));
|
||||||
|
|
||||||
|
|
@ -486,11 +517,15 @@ public:
|
||||||
vkDestroyImageView(device, texture.view, nullptr);
|
vkDestroyImageView(device, texture.view, nullptr);
|
||||||
vkDestroyImage(device, texture.image, nullptr);
|
vkDestroyImage(device, texture.image, nullptr);
|
||||||
vkDestroySampler(device, texture.sampler, nullptr);
|
vkDestroySampler(device, texture.sampler, nullptr);
|
||||||
//vkFreeMemory(device, texture.deviceMemory, nullptr);
|
// Release sparse image memory
|
||||||
// Sparse memory
|
for (auto residencyBind : texture.residencyMemoryBinds)
|
||||||
for (auto residency : texture.residencyMemoryBinds)
|
|
||||||
{
|
{
|
||||||
vkFreeMemory(device, residency.memory, nullptr);
|
vkFreeMemory(device, residencyBind.memory, nullptr);
|
||||||
|
}
|
||||||
|
// Release sparse opqaue memory (mip tail)
|
||||||
|
for (auto opaqueBind : texture.opaqueMemoryBinds)
|
||||||
|
{
|
||||||
|
vkFreeMemory(device, opaqueBind.memory, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue