From 236595c940f9726c2a75ce556e982695cdec7be4 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Wed, 2 Sep 2020 19:14:11 +0200 Subject: [PATCH] Proper shading rate image size based on device properties Fill with different shading rate invocation patters --- .../variablerateshading.cpp | 45 ++++++++++++++++--- .../variablerateshading/variablerateshading.h | 5 ++- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/examples/variablerateshading/variablerateshading.cpp b/examples/variablerateshading/variablerateshading.cpp index f17ff520..758a5409 100644 --- a/examples/variablerateshading/variablerateshading.cpp +++ b/examples/variablerateshading/variablerateshading.cpp @@ -122,19 +122,27 @@ void VulkanExample::setupDescriptors() // [POI] void VulkanExample::prepareShadingRateImage() { + // Shading rate image size depends on shading rate texel size + // For each texel in the target image, there is a corresponding shading texel size width x height block in the shading rate image + const VkExtent3D imageExtent = { width / physicalDeviceShadingRateImagePropertiesNV.shadingRateTexelSize.width, height / physicalDeviceShadingRateImagePropertiesNV.shadingRateTexelSize.height, 1 }; + VkImageCreateInfo imageCI{}; imageCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCI.imageType = VK_IMAGE_TYPE_2D; imageCI.format = VK_FORMAT_R8_UINT; - imageCI.extent = { 512, 512, 1 }; + imageCI.extent = imageExtent; imageCI.mipLevels = 1; imageCI.arrayLayers = 1; imageCI.samples = VK_SAMPLE_COUNT_1_BIT; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.usage = VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV | VK_IMAGE_USAGE_TRANSFER_DST_BIT; VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &shadingRateImage.image)); VkMemoryRequirements memReqs{}; vkGetImageMemoryRequirements(device, shadingRateImage.image, &memReqs); + + VkDeviceSize bufferSize = imageExtent.width * imageExtent.height * sizeof(uint8_t); VkMemoryAllocateInfo memAllloc{}; memAllloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -156,11 +164,29 @@ void VulkanExample::prepareShadingRateImage() VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &shadingRateImage.view)); // Populate with shading rate pattern - const size_t bufferSize = 512 * 512 * sizeof(uint8_t); - uint8_t val = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV; - uint8_t* shadingRatePatternData = new uint8_t[512 * 512]; + uint8_t val = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV; + uint8_t* shadingRatePatternData = new uint8_t[bufferSize]; memset(shadingRatePatternData, val, bufferSize); + uint8_t* ptrData = shadingRatePatternData; + for (uint32_t y = 0; y < imageExtent.height; y++) { + for (uint32_t x = 0; x < imageExtent.width; x++) { + const float deltaX = imageExtent.width / 2 - (float)x; + const float deltaY = imageExtent.height / 2 - (float)y; + const float dist = std::sqrt(deltaX * deltaX + deltaY * deltaY); + if (dist <= 16.0f) { + *ptrData = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV; + } else { + if (dist <= 32.0f) { + *ptrData = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV; + } else { + *ptrData = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV; + } + } + ptrData++; + } + } + VkBuffer stagingBuffer; VkDeviceMemory stagingMemory; @@ -206,8 +232,8 @@ void VulkanExample::prepareShadingRateImage() VkBufferImageCopy bufferCopyRegion{}; bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = 512; - bufferCopyRegion.imageExtent.height = 512; + bufferCopyRegion.imageExtent.width = imageExtent.width; + bufferCopyRegion.imageExtent.height = imageExtent.height; bufferCopyRegion.imageExtent.depth = 1; vkCmdCopyBufferToImage(copyCmd, stagingBuffer, shadingRateImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); { @@ -309,6 +335,13 @@ void VulkanExample::prepare() vkCmdBindShadingRateImageNV = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdBindShadingRateImageNV")); + // [POI] + physicalDeviceShadingRateImagePropertiesNV.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV; + VkPhysicalDeviceProperties2 deviceProperties2{}; + deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + deviceProperties2.pNext = &physicalDeviceShadingRateImagePropertiesNV; + vkGetPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); + prepareShadingRateImage(); prepareUniformBuffers(); setupDescriptors(); diff --git a/examples/variablerateshading/variablerateshading.h b/examples/variablerateshading/variablerateshading.h index 8d7aede2..0eda31a7 100644 --- a/examples/variablerateshading/variablerateshading.h +++ b/examples/variablerateshading/variablerateshading.h @@ -28,7 +28,7 @@ public: glm::mat4 projection; glm::mat4 view; glm::mat4 model = glm::mat4(1.0f); - glm::vec4 lightPos = glm::vec4(0.0f, -2.5f, 0.0f, 1.0f); + glm::vec4 lightPos = glm::vec4(0.0f, -5.0f, 0.0f, 1.0f); glm::vec4 viewPos; } values; } shaderData; @@ -38,7 +38,8 @@ public: VkDescriptorSet descriptorSet; VkDescriptorSetLayout descriptorSetLayout; - VkPhysicalDeviceShadingRateImageFeaturesNV enabledPhysicalDeviceShadingRateImageFeaturesNV; + VkPhysicalDeviceShadingRateImagePropertiesNV physicalDeviceShadingRateImagePropertiesNV{}; + VkPhysicalDeviceShadingRateImageFeaturesNV enabledPhysicalDeviceShadingRateImageFeaturesNV{}; PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV; VulkanExample();