{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
- (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
+ (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
- 0u, // deUint32 descriptorSetCount;
- DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
+ 1, // deUint32 descriptorSetCount;
+ &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
0u, // deUint32 pushConstantRangeCount;
DE_NULL // const VkPushConstantRange* pPushConstantRanges;
};
}
}
- de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
+ void ShaderExecutor::setupUniformData (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ Allocator& memAlloc,
+ deUint32 bindingLocation,
+ VkDescriptorType descriptorType,
+ deUint32 size,
+ const void* dataPtr)
+ {
+ DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
+
+ VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+
+ const VkBufferCreateInfo uniformBufferParams =
+ {
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ size, // VkDeviceSize size;
+ usage, // VkBufferUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyIndexCount;
+ &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
+ };
+
+ Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
- sampler.get(), // VkSampler sampler;
- imageView.get(), // VkImageView imageView;
- VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
++ de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
+
+ deMemcpy(alloc->getHostPtr(), dataPtr, size);
+ flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
+
+ de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
+ uniformInfo->type = descriptorType;
+ uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
+ uniformInfo->location = bindingLocation;
+ uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
+ uniformInfo->alloc = AllocationSp(alloc.release());
+
+ m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
+ m_descriptorPoolBuilder.addType(descriptorType);
+
+ m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
+ }
+
+ void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ Allocator& memAlloc,
+ deUint32 bindingLocation,
+ deUint32 numSamplers,
+ const tcu::Sampler& refSampler,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ VkImageType imageType,
+ VkImageViewType imageViewType,
+ const void* data)
+ {
+ DE_ASSERT(numSamplers > 0);
+
+ std::vector<VkSampler> vkSamplers;
+ de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform());
+
+ samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ samplers->location = bindingLocation;
+
+ for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
+ {
+ const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
+ const void* samplerData = ((deUint8*)data) + offset;
+ de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
+
+ vkSamplers.push_back(uniform->sampler.get()->get());
+
+ samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
+ }
+
+ m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, &vkSamplers[0]);
+ m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
+
+ m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
+ }
+
+ void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc)
+ {
+ if (!m_uniformSetup)
+ return;
+
+ for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
+ {
+ const UniformDataBase* uniformData = it->get()->get();
+ uniformData->setup(*this, vkDevice, vk, queueFamilyIndex, memAlloc);
+ }
+ }
+
+ void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
+ {
+ for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
+ {
+ const UniformInfo* uniformInfo = it->get()->get();
+
+ if (uniformInfo->isSamplerArray())
+ {
+ const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo);
+ std::vector<VkDescriptorImageInfo> descriptors;
+
+ for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
+ {
+ descriptors.push_back(ait->get()->get()->descriptor);
+ }
+
+ descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
+ }
+ else if (uniformInfo->isBufferUniform())
+ {
+ const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
+ descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
+ }
+ else if (uniformInfo->isSamplerUniform())
+ {
+ const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo);
+ descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
+ }
+ }
+ }
+
+ Move<VkImage> ShaderExecutor::createCombinedImage (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ const tcu::IVec3& texSize,
+ const VkFormat format,
+ const VkImageType imageType,
+ const VkImageViewType imageViewType,
+ const VkImageUsageFlags usage,
+ const VkImageTiling tiling)
+ {
+ const bool isCube = imageViewType == vk::VK_IMAGE_VIEW_TYPE_CUBE;
+ const VkImageCreateFlags flags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
+ const deUint32 arraySize = isCube ? 6u : 1u;
+
+ const VkImageCreateInfo imageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pnext;
+ flags, // VkImageCreateFlags flags;
+ imageType, // VkImageType imageType;
+ format, // VkFormat format;
+ { texSize.x(), texSize.y(), texSize.z() }, // VkExtend3D extent;
+ 1u, // deUint32 mipLevels;
+ arraySize, // deUint32 arraySize;
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
+ tiling, // VkImageTiling tiling;
+ usage, // VkImageUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deuint32 queueFamilyCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
+ };
+
+ Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
+ return vkTexture;
+ }
+
+ de::MovePtr<Allocation> ShaderExecutor::uploadImage (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ Allocator& memAlloc,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ const void* data,
+ const VkImage& vkTexture,
+ const VkImageAspectFlags aspectMask)
+ {
+ de::MovePtr<Allocation> allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
+
+ const VkImageSubresource subres =
+ {
+ aspectMask, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 mipLevel;
+ 0u // deUint32 arraySlice
+ };
+
+ VkSubresourceLayout layout;
+ vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
+
+ tcu::ConstPixelBufferAccess access (texFormat, texSize, data);
+ tcu::PixelBufferAccess destAccess (texFormat, texSize, allocation->getHostPtr());
+
+ tcu::copy(destAccess, access);
+
+ flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
+
+ return allocation;
+ }
+
+ de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ Allocator& memAlloc,
+ deUint32 bindingLocation,
+ const tcu::Sampler& refSampler,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ VkImageType imageType,
+ VkImageViewType imageViewType,
+ const void* data)
+ {
+ const VkFormat format = mapTextureFormat(texFormat);
+ const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
+ const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
+ const VkImageUsageFlags imageUsage = isShadowSampler ? (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) : VK_IMAGE_USAGE_SAMPLED_BIT;
+ const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
+ const deUint32 arraySize = isCube ? 6u : 1u;
+ Move<VkImage> vkTexture;
+ de::MovePtr<Allocation> allocation;
+
+ vkTexture = createCombinedImage(vkDevice, vk, queueFamilyIndex, texSize, format, imageType, imageViewType, imageUsage, VK_IMAGE_TILING_OPTIMAL);
+ allocation = uploadImage(vkDevice, vk, memAlloc, texFormat, texSize, data, *vkTexture, aspectMask);
+
+ // Create sampler
+ const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
+ const VkSamplerCreateInfo samplerParams =
+ {
+ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ VkSamplerCreateFlags(0u), // VkSamplerCreateFlags flags;
+ mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter;
+ mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter;
+ mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode;
+ mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU;
+ mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV;
+ mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW;
+ refSampler.lodThreshold, // float mipLodBias;
+ 1, // float maxAnisotropy;
+ compareEnabled, // VkBool32 compareEnable;
+ mapCompareMode(refSampler.compare), // VkCompareOp compareOp;
+ 0.0f, // float minLod;
+ 0.0f, // float maxLod;
+ VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor;
+ VK_FALSE, // VkBool32 unnormalizerdCoordinates;
+ };
+
+ Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
+
+ const VkImageViewCreateInfo viewParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ NULL, // const voide* pNexŧ;
+ 0u, // VkImageViewCreateFlags flags;
+ *vkTexture, // VkImage image;
+ imageViewType, // VkImageViewType viewType;
+ format, // VkFormat format;
+ {
+ VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
+ VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
+ VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
+ VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
+ }, // VkComponentMapping components;
+ {
+ aspectMask, // VkImageAspectFlags aspectMask;
+ 0, // deUint32 baseMipLevel;
+ 1, // deUint32 mipLevels;
+ 0, // deUint32 baseArraySlice;
+ arraySize // deUint32 arraySize;
+ } // VkImageSubresourceRange subresourceRange;
+ };
+
+ Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
+
+ const VkDescriptorImageInfo descriptor =
+ {
++ sampler.get(), // VkSampler sampler;
++ imageView.get(), // VkImageView imageView;
++ VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
+ };
+
+ de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
+ uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ uniform->descriptor = descriptor;
+ uniform->location = bindingLocation;
+ uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
+ uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
+ uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
+ uniform->alloc = AllocationSp(allocation.release());
+
+ return uniform;
+ }
+
+ SamplerUniformData::SamplerUniformData (deUint32 bindingLocation,
+ deUint32 numSamplers,
+ const tcu::Sampler& refSampler,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ VkImageType imageType,
+ VkImageViewType imageViewType,
+ const void* data)
+ : UniformDataBase (bindingLocation)
+ , m_numSamplers (numSamplers)
+ , m_refSampler (refSampler)
+ , m_texFormat (texFormat)
+ , m_texSize (texSize)
+ , m_imageType (imageType)
+ , m_imageViewType (imageViewType)
+ , m_data (data)
+ {
+ }
+
+ SamplerUniformData::~SamplerUniformData (void)
+ {
+ }
+
+ void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
+ {
+ executor.setupSamplerData(vkDevice, vk, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);
+ }
+
} // shaderexecutor
} // vkt
//! Execute
virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) = 0;
- virtual void setShaderSources (vk::SourceCollections& programCollection) const = 0;
- virtual void setShaderSources (SourceCollections& programCollection) const = 0;
++ virtual void setShaderSources (SourceCollections& programCollection) const = 0;
+
+ void setUniforms (const UniformSetup* uniformSetup)
+ {
+ m_uniformSetup = de::MovePtr<const UniformSetup>(uniformSetup);
+ };
+
+ void setupUniformData (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ Allocator& memAlloc,
+ deUint32 bindingLocation,
+ VkDescriptorType descriptorType,
+ deUint32 size,
+ const void* dataPtr);
+
+ void setupSamplerData (const VkDevice& vkDevice,
+ const DeviceInterface& vk,
+ const deUint32 queueFamilyIndex,
+ Allocator& memAlloc,
+ deUint32 bindingLocation,
+ deUint32 numSamplers,
+ const tcu::Sampler& refSampler,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ VkImageType imageType,
+ VkImageViewType imageViewType,
+ const void* data);
protected:
ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
ShaderExecutor* createExecutor(glu::ShaderType shaderType, const ShaderSpec& shaderSpec);
- T m_data;
+ class UniformDataBase
+ {
+ public:
+ UniformDataBase (deUint32 bindingLocation)
+ : m_bindingLocation (bindingLocation)
+ {
+ }
+ virtual ~UniformDataBase (void) {}
+ virtual void setup (ShaderExecutor&, const VkDevice&, const DeviceInterface&, const deUint32, Allocator&) const = 0;
+
+ protected:
+ const deUint32 m_bindingLocation;
+ };
+
+ template<typename T>
+ class UniformData : public UniformDataBase
+ {
+ public:
+ UniformData (deUint32 bindingLocation, VkDescriptorType descriptorType, const T data);
+ virtual ~UniformData (void);
+ virtual void setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const;
+
+ private:
+ VkDescriptorType m_descriptorType;
++ T m_data;
+ };
+
+ template<typename T>
+ UniformData<T>::UniformData (deUint32 bindingLocation, VkDescriptorType descriptorType, const T data)
+ : UniformDataBase (bindingLocation)
+ , m_descriptorType (descriptorType)
+ , m_data (data)
+ {
+ }
+
+ template<typename T>
+ UniformData<T>::~UniformData (void)
+ {
+ }
+
+ template<typename T>
+ void UniformData<T>::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
+ {
+ executor.setupUniformData(vkDevice, vk, queueFamilyIndex, memAlloc, m_bindingLocation, m_descriptorType, sizeof(T), &m_data);
+ }
+
+ class SamplerUniformData : public UniformDataBase
+ {
+ public:
+ SamplerUniformData (deUint32 bindingLocation,
+ deUint32 numSamplers,
+ const tcu::Sampler& refSampler,
+ const tcu::TextureFormat& texFormat,
+ const tcu::IVec3& texSize,
+ VkImageType imageType,
+ VkImageViewType imageViewType,
+ const void* data);
+ virtual ~SamplerUniformData (void);
+ virtual void setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const;
+
+ private:
+ deUint32 m_numSamplers;
+ const tcu::Sampler m_refSampler;
+ const tcu::TextureFormat m_texFormat;
+ const tcu::IVec3 m_texSize;
+ VkImageType m_imageType;
+ VkImageViewType m_imageViewType;
+ const void* m_data;
+ };
+
} // shaderexecutor
} // vkt