Merge branch 'master' into libktx

# Conflicts:
#	examples/texturemipmapgen/texturemipmapgen.cpp
This commit is contained in:
Sascha Willems 2019-12-07 16:04:45 +01:00
commit 3537d2cca2
12 changed files with 122 additions and 106 deletions

View file

@ -567,5 +567,36 @@ namespace vks
return (std::find(supportedExtensions.begin(), supportedExtensions.end(), extension) != supportedExtensions.end());
}
/**
* Select the best-fit depth format for this device from a list of possible depth (and stencil) formats
*
* @param checkSamplingSupport Check if the format can be sampled from (e.g. for shader reads)
*
* @return The depth format that best fits for the current device
*
* @throw Throws an exception if no depth format fits the requirements
*/
VkFormat getSupportedDepthFormat(bool checkSamplingSupport)
{
// All depth formats may be optional, so we need to find a suitable depth format to use
std::vector<VkFormat> depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM };
for (auto& format : depthFormats)
{
VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties);
// Format must support depth stencil attachment for optimal tiling
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
if (checkSamplingSupport) {
if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
continue;
}
}
return format;
}
}
throw std::runtime_error("Could not find a matching depth format");
}
};
}

View file

@ -351,10 +351,10 @@ namespace vks
VkBufferCopy copyRegion{};
copyRegion.size = vertices.size;
copyRegion.size = vBufferSize;
vkCmdCopyBuffer(copyCmd, vertexStaging.buffer, vertices.buffer, 1, &copyRegion);
copyRegion.size = indices.size;
copyRegion.size = iBufferSize;
vkCmdCopyBuffer(copyCmd, indexStaging.buffer, indices.buffer, 1, &copyRegion);
device->flushCommandBuffer(copyCmd, copyQueue);

View file

@ -1,7 +1,6 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
layout (binding = 2) uniform sampler2D samplerColorMap;
layout (location = 0) in vec2 inUV;
layout (location = 1) in vec4 inPos;
@ -21,8 +20,7 @@ void main()
// For demonstration purposes only
const float blurSize = 1.0 / 512.0;
vec4 color = texture(samplerColorMap, inUV);
outFragColor = color * 0.25;
outFragColor = vec4(vec3(0.0), 1.);
if (gl_FrontFacing)
{
@ -35,6 +33,6 @@ void main()
reflection += texture(samplerColor, vec2(projCoord.s + x * blurSize, projCoord.t + y * blurSize)) / 49.0;
}
}
outFragColor += reflection * 1.5 * (color.r);
outFragColor += reflection;
};
}

View file

@ -412,9 +412,9 @@ public:
Pool
*/
std::vector<VkDescriptorPoolSize> poolSizes = {
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 4),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 4),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, attachments.size() + 1),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, attachments.size() + 1),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, attachments.size() * 2 + 1),
};
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(static_cast<uint32_t>(poolSizes.size()), poolSizes.data(), 4);
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));

View file

@ -183,6 +183,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -220,6 +221,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -244,7 +246,7 @@ public:
*/
void createScene()
{
// Setup vertices for a single uv-mapped quad made from two triangles
// Setup vertices for a single triangle
struct Vertex {
float pos[3];
};
@ -336,7 +338,7 @@ public:
// Acceleration structure build requires some scratch space to store temporary information
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
VkMemoryRequirements2 memReqBottomLevelAS;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;

View file

@ -196,6 +196,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -233,6 +234,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -325,7 +327,7 @@ public:
// Acceleration structure build requires some scratch space to store temporary information
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
VkMemoryRequirements2 memReqBottomLevelAS;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;

View file

@ -197,6 +197,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -234,6 +235,7 @@ public:
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.accelerationStructure = topLevelAS.accelerationStructure;
VkMemoryRequirements2 memoryRequirements2{};
@ -334,7 +336,7 @@ public:
// Acceleration structure build requires some scratch space to store temporary information
VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{};
memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
VkMemoryRequirements2 memReqBottomLevelAS;
memoryRequirementsInfo.accelerationStructure = bottomLevelAS.accelerationStructure;

View file

@ -19,7 +19,6 @@
#include <vulkan/vulkan.h>
#include "vulkanexamplebase.h"
#include "VulkanTexture.hpp"
#include "VulkanModel.hpp"
#include "VulkanBuffer.hpp"
@ -34,10 +33,6 @@ class VulkanExample : public VulkanExampleBase
public:
bool debugDisplay = false;
struct {
vks::Texture2D colorMap;
} textures;
// Vertex layout for the models
vks::VertexLayout vertexLayout = vks::VertexLayout({
vks::VERTEX_COMPONENT_POSITION,
@ -124,9 +119,6 @@ public:
// Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class
// Textures
textures.colorMap.destroy();
// Frame buffer
// Color attachment
@ -453,20 +445,6 @@ public:
{
models.plane.loadFromFile(getAssetPath() + "models/plane.obj", vertexLayout, 0.5f, vulkanDevice, queue);
models.example.loadFromFile(getAssetPath() + "models/chinesedragon.dae", vertexLayout, 0.3f, vulkanDevice, queue);
// Textures
if (vulkanDevice->features.textureCompressionBC) {
textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_bc3_unorm.ktx", VK_FORMAT_BC3_UNORM_BLOCK, vulkanDevice, queue);
}
else if (vulkanDevice->features.textureCompressionASTC_LDR) {
textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_astc_8x8_unorm.ktx", VK_FORMAT_ASTC_8x8_UNORM_BLOCK, vulkanDevice, queue);
}
else if (vulkanDevice->features.textureCompressionETC2) {
textures.colorMap.loadFromFile(getAssetPath() + "textures/darkmetal_etc2_unorm.ktx", VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, vulkanDevice, queue);
}
else {
vks::tools::exitFatal("Device does not support any compressed texture format!", VK_ERROR_FEATURE_NOT_PRESENT);
}
}
void generateQuad()
@ -591,12 +569,6 @@ public:
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,
&offscreenPass.descriptor),
// Binding 2 : Fragment shader texture sampler
vks::initializers::writeDescriptorSet(
descriptorSets.mirror,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2,
&textures.colorMap.descriptor)
};
vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL);
@ -625,7 +597,6 @@ public:
allocInfo.pSetLayouts = &descriptorSetLayouts.shaded;
// Model
// No texture
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.model));
std::vector<VkWriteDescriptorSet> modelWriteDescriptorSets =

View file

@ -262,8 +262,7 @@ public:
*/
void prepareDepthPass()
{
VkFormat depthFormat;
vks::tools::getSupportedDepthFormat(physicalDevice, &depthFormat);
VkFormat depthFormat = vulkanDevice->getSupportedDepthFormat(true);
/*
Depth map renderpass

View file

@ -68,15 +68,16 @@ subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 1;
vkTools::setImageLayout(
vks::tools::insertImageMemoryBarrier(
copyCmd,
texture.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
subresourceRange,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
VK_PIPELINE_STAGE_TRANSFER_BIT,
subresourceRange);
```
### Generating the mip-chain
@ -119,16 +120,17 @@ Before we can blit to this mip level, we need to transition it's image layout to
mipSubRange.levelCount = 1;
mipSubRange.layerCount = 1;
// Transiton current mip level to transfer dest
vkTools::setImageLayout(
// Prepare current mip level as image blit destination
vks::tools::insertImageMemoryBarrier(
blitCmd,
texture.image,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
mipSubRange,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
VK_PIPELINE_STAGE_TRANSFER_BIT,
mipSubRange);
```
Note that we set the ```baseMipLevel``` member of the subresource range so the image memory barrier will only affect the one mip level we want to copy to.
@ -150,15 +152,17 @@ Now that the mip level we want to copy from and the one we'll copy to have are i
After the blit is done we can use this mip level as a base for the next level, so we transition the layout from ```TRANSFER_DST_OPTIMAL``` to ```TRANSFER_SRC_OPTIMAL``` so we can use this level as transfer source for the next level:
```cpp
vkTools::setImageLayout(
blitCmd,
// Prepare current mip level as image blit source for next level
vks::tools::insertImageMemoryBarrier(
copyCmd,
texture.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
mipSubRange,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
VK_PIPELINE_STAGE_TRANSFER_BIT,
mipSubRange);
}
```
@ -167,15 +171,16 @@ Once the loop is done we need to transition all mip levels of the image to their
```cpp
subresourceRange.levelCount = texture.mipLevels;
vkTools::setImageLayout(
blitCmd,
vks::tools::insertImageMemoryBarrier(
copyCmd,
texture.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;,
subresourceRange,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
subresourceRange);
```
Submitting that command buffer will result in an image with a complete mip-chain and all mip levels being transitioned to the proper image layout for shader reads.

View file

@ -34,7 +34,6 @@ class VulkanExample : public VulkanExampleBase
public:
struct Texture {
VkImage image;
VkImageLayout imageLayout;
VkDeviceMemory deviceMemory;
VkImageView view;
uint32_t width, height;
@ -109,7 +108,14 @@ public:
models.tunnel.destroy();
}
void loadTexture(std::string filename, VkFormat format, bool forceLinearTiling)
virtual void getEnabledFeatures()
{
if (deviceFeatures.samplerAnisotropy) {
enabledFeatures.samplerAnisotropy = VK_TRUE;
}
}
void loadTexture(std::string fileName, VkFormat format, bool forceLinearTiling)
{
ktxResult result;
ktxTexture* ktxTexture;
@ -137,6 +143,9 @@ public:
#endif
assert(result == KTX_SUCCESS);
VkFormatProperties formatProperties;
VkFormatProperties formatProperties;
texture.width = ktxTexture->baseWidth;
@ -208,11 +217,15 @@ public:
subresourceRange.layerCount = 1;
// Optimal image will be used as destination for the copy, so we must transfer from our initial undefined image layout to the transfer destination layout
vks::tools::setImageLayout(
vks::tools::insertImageMemoryBarrier(
copyCmd,
texture.image,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
subresourceRange);
// Copy the first mip of the chain, remaining mips will be generated
@ -228,12 +241,15 @@ public:
vkCmdCopyBufferToImage(copyCmd, stagingBuffer, texture.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);
// Transition first mip level to transfer source for read during blit
texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
vks::tools::setImageLayout(
vks::tools::insertImageMemoryBarrier(
copyCmd,
texture.image,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
subresourceRange);
VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true);
@ -276,15 +292,17 @@ public:
mipSubRange.levelCount = 1;
mipSubRange.layerCount = 1;
// Transiton current mip level to transfer dest
vks::tools::setImageLayout(
// Prepare current mip level as image blit destination
vks::tools::insertImageMemoryBarrier(
blitCmd,
texture.image,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
mipSubRange,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
VK_PIPELINE_STAGE_TRANSFER_BIT,
mipSubRange);
// Blit from previous level
vkCmdBlitImage(
@ -297,24 +315,30 @@ public:
&imageBlit,
VK_FILTER_LINEAR);
// Transiton current mip level to transfer source for read in next iteration
vks::tools::setImageLayout(
// Prepare current mip level as image blit source for next level
vks::tools::insertImageMemoryBarrier(
blitCmd,
texture.image,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
mipSubRange,
VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT);
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
mipSubRange);
}
// After the loop, all mip layers are in TRANSFER_SRC layout, so transition all to SHADER_READ
subresourceRange.levelCount = texture.mipLevels;
vks::tools::setImageLayout(
vks::tools::insertImageMemoryBarrier(
blitCmd,
texture.image,
VK_ACCESS_TRANSFER_READ_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
texture.imageLayout,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
subresourceRange);
VulkanExampleBase::flushCommandBuffer(blitCmd, queue, true);
@ -543,34 +567,17 @@ public:
void setupDescriptorSet()
{
VkDescriptorSetAllocateInfo allocInfo =
vks::initializers::descriptorSetAllocateInfo(
descriptorPool,
&descriptorSetLayout,
1);
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout,1);
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
VkDescriptorImageInfo textureDescriptor = vks::initializers::descriptorImageInfo(VK_NULL_HANDLE, texture.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
// Binding 0: Vertex shader uniform buffer
writeDescriptorSets.push_back(vks::initializers::writeDescriptorSet(
descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,
&uniformBufferVS.descriptor));
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBufferVS.descriptor),
// Binding 1: Sampled image
VkDescriptorImageInfo textureDescriptor =
vks::initializers::descriptorImageInfo(
VK_NULL_HANDLE,
texture.view,
texture.imageLayout);
writeDescriptorSets.push_back(vks::initializers::writeDescriptorSet(
descriptorSet,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
1,
&textureDescriptor));
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, &textureDescriptor)
};
// Binding 2: Sampler array
std::vector<VkDescriptorImageInfo> samplerDescriptors;
@ -587,7 +594,6 @@ public:
samplerDescriptorWrite.dstBinding = 2;
samplerDescriptorWrite.dstArrayElement = 0;
writeDescriptorSets.push_back(samplerDescriptorWrite);
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
}