blob: 4fce063bc340ee37e2aaca3d24d77f0622319a56 [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2019 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Vulkan Decriptor Indexing Tests
*//*--------------------------------------------------------------------*/
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
#include <sstream>
#include <utility>
#include <vector>
#include "vktDescriptorSetsIndexingTests.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkDefs.hpp"
#include "vkObjUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuResource.hpp"
#include "tcuImageCompare.hpp"
#include "tcuCommandLine.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuVectorUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deStringUtil.hpp"
namespace vkt
{
namespace DescriptorIndexing
{
namespace
{
using namespace vk;
using tcu::UVec2;
using tcu::Vec4;
using tcu::TestStatus;
using tcu::PixelBufferAccess;
using tcu::Texture2D;
#define RESOLUTION_width 64
#define RESOLUTION_height 64
static const VkExtent3D RESOLUTION = { RESOLUTION_width, RESOLUTION_height, 1 };
#define MAX_DESCRIPTORS 4200
#define FUZZY_COMPARE DE_FALSE
#define CMP_THRESHOLD 0.02f
#define BINDING_Undefined 0
#define BINDING_UniformBuffer 1
#define BINDING_StorageBuffer 2
#define BINDING_UniformTexelBuffer 3
#define BINDING_StorageTexelBuffer 4
#define BINDING_Sampler 5
#define BINDING_SampledImage 6
#define BINDING_CombinedImageSampler 7
#define BINDING_UniformBufferDynamic 8
#define BINDING_StorageBufferDynamic 9
#define BINDING_InputAttachment 10
#define BINDING_StorageImage 11
#define BINDING_DescriptorEnumerator 12
static const VkExtent3D smallImageExtent = { 4, 4, 1 };
static const VkExtent3D bigImageExtent = { 32, 32, 1 };
static const VkDescriptorType VK_DESCRIPTOR_TYPE_UNDEFINED = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
template<deUint32 BindingNumber>
struct Binding
{
static const deUint32 binding = BindingNumber;
};
struct BindingUniformBuffer : Binding<BINDING_UniformBuffer>
{
typedef struct
{
tcu::Vec4 c;
} Data;
};
struct BindingStorageBuffer : Binding<BINDING_StorageBuffer>
{
typedef struct
{
tcu::Vec4 cnew;
tcu::Vec4 cold;
} Data;
};
struct TestCaseParams
{
VkDescriptorType descriptorType; // used only to distinguish test class instance
VkShaderStageFlags stageFlags; // used only to build a proper program
VkExtent3D frameResolution; // target frame buffer resolution
bool updateAfterBind; // whether a test will use update after bind feature
bool calculateInLoop; // perform calculation in a loop
bool usesMipMaps; // this makes a sense and affects in image test cases only
bool minNonUniform; // whether a test will use the minimum nonUniform decorations
deBool fuzzyComparison; // if true then a test will use fuzzy comparison, otherwise float threshold
float thresholdValue; // a threshold that will be used for both, float and fuzzy comparisons
};
struct TestParams
{
VkShaderStageFlags stageFlags;
VkDescriptorType descriptorType;
deUint32 descriptorBinding;
VkDescriptorType additionalDescriptorType;
deUint32 additionalDescriptorBinding;
bool copyBuffersToImages;
bool allowVertexStoring;
VkExtent3D frameResolution;
bool updateAfterBind;
bool calculateInLoop;
bool usesMipMaps;
bool minNonUniform;
deBool fuzzyComparison;
float thresholdValue;
TestParams (VkShaderStageFlags stageFlags_,
VkDescriptorType descriptorType_,
deUint32 descriptorBinding_,
VkDescriptorType additionalDescriptorType_,
deUint32 additionalDescriptorBinding_,
bool copyBuffersToImages_,
bool allowVertexStoring_,
const TestCaseParams& caseParams)
: stageFlags (stageFlags_)
, descriptorType (descriptorType_)
, descriptorBinding (descriptorBinding_)
, additionalDescriptorType (additionalDescriptorType_)
, additionalDescriptorBinding (additionalDescriptorBinding_)
, copyBuffersToImages (copyBuffersToImages_)
, allowVertexStoring (allowVertexStoring_)
, frameResolution (caseParams.frameResolution)
, updateAfterBind (caseParams.updateAfterBind)
, calculateInLoop (caseParams.calculateInLoop)
, usesMipMaps (caseParams.usesMipMaps)
, minNonUniform (caseParams.minNonUniform)
, fuzzyComparison (caseParams.fuzzyComparison ? true : false)
, thresholdValue (caseParams.thresholdValue)
{
}
};
struct DescriptorEnumerator
{
ut::BufferHandleAllocSp buffer;
ut::BufferViewSp bufferView;
VkDeviceSize bufferSize;
Move<VkDescriptorSetLayout> descriptorSetLayout;
Move<VkDescriptorPool> descriptorPool;
Move<VkDescriptorSet> descriptorSet;
void init(const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount);
void update(const vkt::Context& context);
};
struct IterateCommonVariables
{
// An amount of descriptors of a given type available on the platform
deUint32 availableDescriptorCount;
// An amount of valid descriptors that have connected a buffers to them
deUint32 validDescriptorCount;
// As the name suggests, sometimes it is used as invocationCount
deUint32 vertexCount;
VkRect2D renderArea;
VkDeviceSize dataAlignment;
deUint32 lowerBound;
deUint32 upperBound;
DescriptorEnumerator descriptorEnumerator;
ut::BufferHandleAllocSp vertexAttributesBuffer;
ut::BufferHandleAllocSp descriptorsBuffer;
std::vector<VkDescriptorBufferInfo> descriptorsBufferInfos;
std::vector<ut::BufferViewSp> descriptorsBufferViews;
std::vector<ut::ImageViewSp> descriptorImageViews;
std::vector<ut::SamplerSp> descriptorSamplers;
std::vector<ut::ImageHandleAllocSp> descriptorsImages;
ut::FrameBufferSp frameBuffer;
Move<VkDescriptorSetLayout> descriptorSetLayout;
Move<VkDescriptorPool> descriptorPool;
Move<VkDescriptorSet> descriptorSet;
Move<VkPipelineLayout> pipelineLayout;
Move<VkRenderPass> renderPass;
Move<VkPipeline> pipeline;
Move<VkCommandBuffer> commandBuffer;
};
class CommonDescriptorInstance : public TestInstance
{
public:
CommonDescriptorInstance (Context& context,
const TestParams& testParams);
deUint32 computeAvailableDescriptorCount (VkDescriptorType descriptorType,
bool reserveUniformTexelBuffer) const;
Move<VkDescriptorSetLayout> createDescriptorSetLayout (bool reserveUniformTexelBuffer,
deUint32& descriptorCount) const;
Move<VkDescriptorPool> createDescriptorPool (deUint32 descriptorCount) const;
Move<VkDescriptorSet> createDescriptorSet (VkDescriptorPool dsPool,
VkDescriptorSetLayout dsLayout) const;
struct attributes
{
typedef tcu::Vec4 vec4;
typedef tcu::Vec2 vec2;
typedef tcu::IVec4 ivec4;
vec4 position;
vec2 normalpos;
ivec4 index;
attributes& operator()(const vec4& pos)
{
position = pos;
normalpos.x() = (pos.x() + 1.0f) / 2.0f;
normalpos.y() = (pos.y() + 1.0f) / 2.0f;
return *this;
}
};
void createVertexAttributeBuffer (ut::BufferHandleAllocSp& buffer,
deUint32 availableDescriptorCount) const;
static std::string substBinding (deUint32 binding,
const char* str,
deUint32 count = 0,
const char* name = DE_NULL);
static const char* getVertexShaderProlog (void);
static const char* getFragmentShaderProlog (void);
static const char* getShaderEpilog (void);
static bool performWritesInVertex (VkDescriptorType descriptorType);
static bool performWritesInVertex (VkDescriptorType descriptorType,
const Context& context);
static std::string getShaderAsm (VkShaderStageFlagBits shaderType,
const TestCaseParams& testCaseParams,
bool allowVertexStoring);
static std::string getShaderSource (VkShaderStageFlagBits shaderType,
const TestCaseParams& testCaseParams,
bool allowVertexStoring);
static std::string getColorAccess (VkDescriptorType descriptorType,
const char* indexVariableName,
bool usesMipMaps);
static std::string getFragmentReturnSource (const std::string& colorAccess);
static std::string getFragmentLoopSource (const std::string& colorAccess1,
const std::string& colorAccess2);
virtual Move<VkRenderPass> createRenderPass (const IterateCommonVariables& variables);
struct push_constant
{
deInt32 lowerBound;
deInt32 upperBound;
};
VkPushConstantRange makePushConstantRange (void) const;
Move<VkPipelineLayout> createPipelineLayout (const std::vector<VkDescriptorSetLayout>& descriptorSetLayouts) const;
// Creates graphics or compute pipeline and appropriate shaders' modules according the testCaseParams.stageFlags
// In the case of compute pipeline renderPass parameter is ignored.
// Viewport will be created with a width and a height taken from testCaseParam.fragResolution.
Move<VkPipeline> createPipeline (VkPipelineLayout pipelineLayout,
VkRenderPass renderPass);
virtual void createFramebuffer (ut::FrameBufferSp& frameBuffer,
VkRenderPass renderPass,
const IterateCommonVariables& variables);
// Creates one big stagging buffer cutted out on chunks that can accomodate an element of elementSize size
VkDeviceSize createBuffers (std::vector<VkDescriptorBufferInfo>& bufferInfos,
ut::BufferHandleAllocSp& buffer,
deUint32 elementCount,
deUint32 elementSize,
VkDeviceSize alignment,
VkBufferUsageFlags bufferUsage);
// Creates and binds an imagesCount of images with given parameters.
// Additionally creates stagging buffer for their data and PixelBufferAccess for particular images.
VkDeviceSize createImages (std::vector<ut::ImageHandleAllocSp>& images,
std::vector<VkDescriptorBufferInfo>& bufferInfos,
ut::BufferHandleAllocSp& buffer,
VkBufferUsageFlags bufferUsage,
const VkExtent3D& imageExtent,
VkFormat imageFormat,
VkImageLayout imageLayout,
deUint32 imageCount,
bool withMipMaps = false);
void createBuffersViews (std::vector<ut::BufferViewSp>& views,
const std::vector<VkDescriptorBufferInfo>& bufferInfos,
VkFormat format);
void createImagesViews (std::vector<ut::ImageViewSp>& views,
const std::vector<ut::ImageHandleAllocSp>& images,
VkFormat format);
virtual void copyBuffersToImages (IterateCommonVariables& variables);
virtual void copyImagesToBuffers (IterateCommonVariables& variables);
PixelBufferAccess getPixelAccess (deUint32 imageIndex,
const VkExtent3D& imageExtent,
VkFormat imageFormat,
const std::vector<VkDescriptorBufferInfo>& bufferInfos,
const ut::BufferHandleAllocSp& buffer,
deUint32 mipLevel = 0u) const;
virtual void createAndPopulateDescriptors (IterateCommonVariables& variables) = 0;
virtual void updateDescriptors (IterateCommonVariables& variables);
virtual void iterateCollectResults (ut::UpdatablePixelBufferAccessPtr& result,
const IterateCommonVariables& variables,
bool fromTest);
void iterateCommandSetup (IterateCommonVariables& variables);
void iterateCommandBegin (IterateCommonVariables& variables,
bool firstPass = true);
void iterateCommandEnd (IterateCommonVariables& variables,
ut::UpdatablePixelBufferAccessPtr& programResult,
ut::UpdatablePixelBufferAccessPtr& referenceResult,
bool collectBeforeSubmit = true);
bool iterateVerifyResults (IterateCommonVariables& variables,
ut::UpdatablePixelBufferAccessPtr programResult,
ut::UpdatablePixelBufferAccessPtr referenceResult);
Move<VkCommandBuffer> createCmdBuffer (void);
void commandBindPipeline (VkCommandBuffer commandBuffer,
VkPipeline pipeline);
void commandBindVertexAttributes (VkCommandBuffer commandBuffer,
const ut::BufferHandleAllocSp& vertexAttributesBuffer);
void commandBindDescriptorSets (VkCommandBuffer commandBuffer,
VkPipelineLayout pipelineLayout,
VkDescriptorSet descriptorSet,
deUint32 descriptorSetIndex);
void commandReadFrameBuffer (ut::BufferHandleAllocSp& content,
VkCommandBuffer commandBuffer,
const ut::FrameBufferSp& frameBuffer);
ut::UpdatablePixelBufferAccessPtr
commandReadFrameBuffer (VkCommandBuffer commandBuffer,
const ut::FrameBufferSp& frameBuffer);
Move<VkFence> commandSubmit (VkCommandBuffer commandBuffer);
virtual bool verifyVertexWriteResults (IterateCommonVariables& variables);
protected:
virtual tcu::TestStatus iterate (void);
protected:
const VkDevice m_vkd;
const DeviceInterface& m_vki;
Allocator& m_allocator;
const VkQueue m_queue;
const deUint32 m_queueFamilyIndex;
const Move<VkCommandPool> m_commandPool;
const VkFormat m_colorFormat;
const TestParams m_testParams;
static const tcu::Vec4 m_clearColor;
const std::vector<float> m_colorScheme;
const deUint32 m_schemeSize;
private:
Move<VkPipeline> createGraphicsPipeline (VkPipelineLayout pipelineLayout,
VkRenderPass renderPass);
Move<VkPipeline> createComputePipeline (VkPipelineLayout pipelineLayout);
int constructShaderModules (void);
static std::vector<float> createColorScheme();
Move<VkShaderModule> m_vertexModule;
Move<VkShaderModule> m_fragmentModule;
Move<VkShaderModule> m_computeModule;
};
const tcu::Vec4 CommonDescriptorInstance::m_clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
void DescriptorEnumerator::init (const vkt::Context& context, deUint32 vertexCount, deUint32 availableDescriptorCount)
{
const VkDevice device = context.getDevice();
const DeviceInterface& deviceInterface = context.getDeviceInterface();
const VkFormat imageFormat = VK_FORMAT_R32G32B32A32_SINT;
typedef ut::mapVkFormat2Type<imageFormat>::type pixelType;
const VkDeviceSize dataSize = vertexCount * sizeof(pixelType);
const std::vector<deUint32> primes = ut::generatePrimes(availableDescriptorCount);
const deUint32 primeCount = static_cast<deUint32>(primes.size());
std::vector<pixelType> data(vertexCount);
// e.g. 2,3,5,7,11,13,2,3,5,7,...
for (deUint32 idx = 0; idx < vertexCount; ++idx)
{
data[idx].x() = static_cast<pixelType::Element>(primes[idx % primeCount]);
data[idx].y() = static_cast<pixelType::Element>(idx);
}
bufferSize = ut::createBufferAndBind(buffer, context, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, dataSize);
deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(dataSize));
const VkBufferViewCreateInfo bufferViewCreateInfo =
{
VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // sType
DE_NULL, // pNext
0u, // flags
*(buffer.get()->buffer), // buffer
imageFormat, // format
0u, // offset
bufferSize, // range
};
bufferView = ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(deviceInterface, device, &bufferViewCreateInfo)));
const VkDescriptorSetLayoutBinding binding =
{
BINDING_DescriptorEnumerator, // binding
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // descriptorType
1u, // descriptorCount
VK_SHADER_STAGE_ALL, // stageFlags
DE_NULL, // pImmutableSamplers
};
const VkDescriptorSetLayoutCreateInfo layoutCreateInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
DE_NULL, // pNext
0u, // flags
1u, // bindingCount
&binding, // pBindings
};
descriptorSetLayout = vk::createDescriptorSetLayout(deviceInterface, device, &layoutCreateInfo);
descriptorPool = DescriptorPoolBuilder().addType(binding.descriptorType)
.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
const VkDescriptorSetAllocateInfo dsAllocInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
DE_NULL, // pNext
*descriptorPool, // descriptorPool
1u, // descriptorSetCount
&(*descriptorSetLayout) // pSetLayouts
};
descriptorSet = vk::allocateDescriptorSet(deviceInterface, device, &dsAllocInfo);
}
void DescriptorEnumerator::update (const vkt::Context& context)
{
const VkDescriptorBufferInfo bufferInfo =
{
*(buffer.get()->buffer), // buffer
0u, // offset
bufferSize, // range
};
const VkWriteDescriptorSet writeInfo =
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
DE_NULL, // pNext
*descriptorSet, // dstSet
BINDING_DescriptorEnumerator, // dstBinding
0u, // dstArrayElement
1u, // descriptorCount
VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // descriptorType
DE_NULL, // pImageInfo
&bufferInfo, // pBufferInfo
&(**bufferView), // pTexelBufferView
};
context.getDeviceInterface().updateDescriptorSets(context.getDevice(), 1u, &writeInfo, 0u, DE_NULL);
}
CommonDescriptorInstance::CommonDescriptorInstance (Context& context,
const TestParams& testParams)
: TestInstance (context)
, m_vkd (context.getDevice())
, m_vki (context.getDeviceInterface())
, m_allocator (context.getDefaultAllocator())
, m_queue (context.getUniversalQueue())
, m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
, m_commandPool (vk::createCommandPool(m_vki, m_vkd, (VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT), m_queueFamilyIndex))
, m_colorFormat (VK_FORMAT_R32G32B32A32_SFLOAT)
, m_testParams (testParams)
, m_colorScheme (createColorScheme())
, m_schemeSize (static_cast<deUint32>(m_colorScheme.size()))
{
}
deUint32 CommonDescriptorInstance::computeAvailableDescriptorCount (VkDescriptorType descriptorType,
bool reserveUniformTexelBuffer) const
{
DE_UNREF(descriptorType);
const deUint32 vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
const deUint32 availableDescriptorsOnDevice = ut::DeviceProperties(m_context).computeMaxPerStageDescriptorCount(m_testParams.descriptorType, m_testParams.updateAfterBind, reserveUniformTexelBuffer);
return deMinu32(deMinu32(vertexCount, availableDescriptorsOnDevice), MAX_DESCRIPTORS);
}
Move<VkDescriptorSetLayout> CommonDescriptorInstance::createDescriptorSetLayout (bool reserveUniformTexelBuffer,
deUint32& descriptorCount) const
{
descriptorCount = computeAvailableDescriptorCount(m_testParams.descriptorType, reserveUniformTexelBuffer);
bool optional = (m_testParams.additionalDescriptorBinding != BINDING_Undefined) && (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED);
const VkShaderStageFlags bindingStageFlags = (m_testParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ?
VkShaderStageFlags{VK_SHADER_STAGE_FRAGMENT_BIT} : m_testParams.stageFlags;
const VkDescriptorSetLayoutBinding bindings[] =
{
{
m_testParams.descriptorBinding, // binding
m_testParams.descriptorType, // descriptorType
descriptorCount, // descriptorCount
bindingStageFlags, // stageFlags
DE_NULL, // pImmutableSamplers
},
{
m_testParams.additionalDescriptorBinding, // binding
m_testParams.additionalDescriptorType, // descriptorType
1, // descriptorCount
bindingStageFlags, // stageFlags
DE_NULL, // pImmutableSamplers
}
};
const VkDescriptorBindingFlags bindingFlagUpdateAfterBind =
m_testParams.updateAfterBind ? VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT : 0;
const VkDescriptorBindingFlags bindingFlags[] =
{
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind,
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | bindingFlagUpdateAfterBind
};
const VkDescriptorSetLayoutBindingFlagsCreateInfo bindingCreateInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
DE_NULL,
optional ? 2u : 1u, // bindingCount
bindingFlags, // pBindingFlags
};
const VkDescriptorSetLayoutCreateFlags layoutCreateFlags =
m_testParams.updateAfterBind ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT : 0;
const VkDescriptorSetLayoutCreateInfo layoutCreateInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
&bindingCreateInfo, // pNext
layoutCreateFlags, // flags
optional ? 2u : 1u, // bindingCount
bindings, // pBindings
};
return vk::createDescriptorSetLayout(m_vki, m_vkd, &layoutCreateInfo);
}
Move<VkDescriptorPool> CommonDescriptorInstance::createDescriptorPool (deUint32 descriptorCount) const
{
const VkDescriptorPoolCreateFlags pcf = m_testParams.updateAfterBind ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
DescriptorPoolBuilder builder;
builder.addType(m_testParams.descriptorType, descriptorCount);
if (m_testParams.additionalDescriptorType != VK_DESCRIPTOR_TYPE_UNDEFINED && m_testParams.additionalDescriptorBinding != BINDING_Undefined)
{
builder.addType(m_testParams.additionalDescriptorType, 1);
}
return builder.build(m_vki, m_vkd, (VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | pcf), 1u);
}
Move<VkDescriptorSet> CommonDescriptorInstance::createDescriptorSet (VkDescriptorPool dsPool,
VkDescriptorSetLayout dsLayout) const
{
const VkDescriptorSetAllocateInfo dsAllocInfo =
{
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType;
DE_NULL, // pNext;
dsPool, // descriptorPool;
1u, // descriptorSetCount
&dsLayout // pSetLayouts
};
return vk::allocateDescriptorSet(m_vki, m_vkd, &dsAllocInfo);
}
void CommonDescriptorInstance::createVertexAttributeBuffer (ut::BufferHandleAllocSp& buffer,
deUint32 availableDescriptorCount) const
{
float xSize = 0.0f;
float ySize = 0.0f;
const deUint32 invocationCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
const std::vector<Vec4> vertices = ut::createVertices(m_testParams.frameResolution.width, m_testParams.frameResolution.height, xSize, ySize);
const std::vector<deUint32> primes = ut::generatePrimes(availableDescriptorCount);
const deUint32 primeCount = static_cast<deUint32>(primes.size());
std::vector<attributes> data(vertices.size());
std::transform(vertices.begin(), vertices.end(), data.begin(), attributes());
for (deUint32 invIdx = 0; invIdx < invocationCount; ++invIdx)
{
// r: 2,3,5,7,11,13,2,3,5,7,...
data[invIdx].index.x() = primes[invIdx % primeCount];
// b: x index in texel coordinate
data[invIdx].index.z() = invIdx % m_testParams.frameResolution.width;
//a: y index in texel coordinate
data[invIdx].index.w() = invIdx / m_testParams.frameResolution.width;
}
// g: 0,0,2,3,0,5,0,7,0,0,0,11,0,13,...
for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
{
const deUint32 prime = primes[primeIdx];
DE_ASSERT(prime < invocationCount);
data[prime].index.y() = prime;
}
const VkDeviceSize dataSize = data.size() * sizeof(attributes);
VkDeviceSize deviceSize = ut::createBufferAndBind(buffer, m_context, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, dataSize);
deMemcpy(buffer->alloc->getHostPtr(), data.data(), static_cast<size_t>(deviceSize));
vk::flushAlloc(m_vki, m_vkd, *buffer->alloc);
}
std::string CommonDescriptorInstance::substBinding (deUint32 binding,
const char* str,
deUint32 count,
const char* name)
{
std::map<std::string, std::string> vars;
vars["?"] = de::toString(binding);
vars["*"] = (0 == count) ? "" : de::toString(count);
vars["VAR"] = (DE_NULL == name) ? "data" : name;
return tcu::StringTemplate(str).specialize(vars);
}
const char* CommonDescriptorInstance::getVertexShaderProlog (void)
{
return
"layout(location = 0) in vec4 in_position; \n"
"layout(location = 1) in vec2 in_normalpos; \n"
"layout(location = 2) in ivec4 index; \n"
"layout(location = 0) out vec4 position; \n"
"layout(location = 1) out vec2 normalpos; \n"
"layout(location = 2) out int vIndex; \n"
"layout(location = 3) out int rIndex; \n"
"layout(location = 4) out int gIndex; \n"
"layout(location = 5) out int bIndex; \n"
"layout(location = 6) out int aIndex; \n"
"void main() \n"
"{ \n"
" gl_PointSize = 0.2f; \n"
" position = in_position; \n"
" normalpos = in_normalpos; \n"
" gl_Position = position; \n"
" vIndex = gl_VertexIndex; \n"
" rIndex = index.x; \n"
" gIndex = index.y; \n"
" bIndex = index.z; \n"
" aIndex = index.w; \n";
}
const char* CommonDescriptorInstance::getFragmentShaderProlog (void)
{
return
"layout(location = 0) out vec4 FragColor; \n"
"layout(location = 0) in flat vec4 position; \n"
"layout(location = 1) in flat vec2 normalpos; \n"
"layout(location = 2) in flat int vIndex; \n"
"layout(location = 3) in flat int rIndex; \n"
"layout(location = 4) in flat int gIndex; \n"
"layout(location = 5) in flat int bIndex; \n"
"layout(location = 6) in flat int aIndex; \n"
"void main() \n"
"{ \n";
}
const char* CommonDescriptorInstance::getShaderEpilog (void)
{
return "} \n";
}
int CommonDescriptorInstance::constructShaderModules (void)
{
int result = 0;
tcu::TestLog& log = m_context.getTestContext().getLog();
if (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
{
++result;
const std::string name = ut::buildShaderName(VK_SHADER_STAGE_COMPUTE_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, false);
m_computeModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
}
if (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT)
{
++result;
const std::string name = ut::buildShaderName(VK_SHADER_STAGE_FRAGMENT_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
m_fragmentModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
log << tcu::TestLog::Message << "Finally used fragment shader: " << name << '\n' << tcu::TestLog::EndMessage;
}
if (m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT)
{
++result;
const std::string name = ut::buildShaderName(VK_SHADER_STAGE_VERTEX_BIT, m_testParams.descriptorType, m_testParams.updateAfterBind, m_testParams.calculateInLoop, m_testParams.minNonUniform, m_testParams.allowVertexStoring);
m_vertexModule = vk::createShaderModule(m_vki, m_vkd, m_context.getBinaryCollection().get(name), (VkShaderModuleCreateFlags)0);
log << tcu::TestLog::Message << "Finally used vertex shader: " << name << '\n' << tcu::TestLog::EndMessage;
}
DE_ASSERT(result > 0);
return result;
}
Move<VkRenderPass> CommonDescriptorInstance::createRenderPass (const IterateCommonVariables& variables)
{
DE_UNREF(variables);
if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
{
// Use VK_ATTACHMENT_LOAD_OP_LOAD to make the utility function select initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
return vk::makeRenderPass(m_vki, m_vkd, m_colorFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD);
}
return Move<VkRenderPass>();
}
VkPushConstantRange CommonDescriptorInstance::makePushConstantRange (void) const
{
const VkPushConstantRange pcr =
{
m_testParams.stageFlags, // stageFlags
0u, // offset
static_cast<deUint32>(sizeof(push_constant)) // size
};
return pcr;
}
Move<VkPipelineLayout> CommonDescriptorInstance::createPipelineLayout (const std::vector<VkDescriptorSetLayout>& descriptorSetLayouts) const
{
const VkPushConstantRange pcr = makePushConstantRange();
const VkPipelineLayoutCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
DE_NULL, // pNext
(VkPipelineLayoutCreateFlags)0, // flags
static_cast<deUint32>(descriptorSetLayouts.size()), // setLayoutCount
descriptorSetLayouts.data(), // pSetLayouts;
m_testParams.calculateInLoop ? 1u : 0u, // pushConstantRangeCount
m_testParams.calculateInLoop ? &pcr : DE_NULL, // pPushConstantRanges
};
return vk::createPipelineLayout(m_vki, m_vkd, &createInfo);
}
void CommonDescriptorInstance::createFramebuffer (ut::FrameBufferSp& frameBuffer,
VkRenderPass renderPass,
const IterateCommonVariables& variables)
{
DE_UNREF(variables);
ut::createFrameBuffer(frameBuffer, m_context, m_testParams.frameResolution, m_colorFormat, renderPass);
}
Move<VkPipeline> CommonDescriptorInstance::createPipeline (VkPipelineLayout pipelineLayout,
VkRenderPass renderPass)
{ DE_ASSERT(VK_SHADER_STAGE_ALL != m_testParams.stageFlags);
constructShaderModules();
return (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
? createComputePipeline(pipelineLayout)
: createGraphicsPipeline(pipelineLayout, renderPass);
}
Move<VkPipeline> CommonDescriptorInstance::createComputePipeline (VkPipelineLayout pipelineLayout)
{
const VkPipelineShaderStageCreateInfo shaderStaegCreateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
DE_NULL, // pNext
(VkPipelineShaderStageCreateFlags)0, // flags
VK_SHADER_STAGE_COMPUTE_BIT, // stage
*m_computeModule, // module
"main", // pName
(VkSpecializationInfo*)DE_NULL // pSpecializationInfo
};
const VkComputePipelineCreateInfo pipelineCreateInfo =
{
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
DE_NULL, // pNext
0u, // flags
shaderStaegCreateInfo, // stage
pipelineLayout, // layout
(VkPipeline)0, // basePipelineHandle
0u, // basePipelineIndex
};
return vk::createComputePipeline(m_vki, m_vkd, (VkPipelineCache)0u, &pipelineCreateInfo);
}
Move<VkPipeline> CommonDescriptorInstance::createGraphicsPipeline (VkPipelineLayout pipelineLayout,
VkRenderPass renderPass)
{
const VkVertexInputBindingDescription bindingDescriptions[] =
{
{
0u, // binding
sizeof(attributes), // stride
VK_VERTEX_INPUT_RATE_VERTEX, // inputRate
},
};
const VkVertexInputAttributeDescription attributeDescriptions[] =
{
{
0u, // location
0u, // binding
ut::mapType2vkFormat<attributes::vec4>::value, // format
0u // offset
}, // @in_position
{
1u, // location
0u, // binding
ut::mapType2vkFormat<attributes::vec2>::value, // format
static_cast<deUint32>(sizeof(attributes::vec4)) // offset
}, // @normalpos
{
2u, // location
0u, // binding
ut::mapType2vkFormat<attributes::ivec4>::value, // format
static_cast<deUint32>(sizeof(attributes::vec2)
+ sizeof(attributes::vec4)) // offset
}, // @index
};
const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
DE_NULL,
(VkPipelineVertexInputStateCreateFlags)0, // flags
DE_LENGTH_OF_ARRAY(bindingDescriptions), // vertexBindingDescriptionCount
bindingDescriptions, // pVertexBindingDescriptions
DE_LENGTH_OF_ARRAY(attributeDescriptions), // vertexAttributeDescriptionCount
attributeDescriptions // pVertexAttributeDescriptions
};
const VkDynamicState dynamicStates[] =
{
VK_DYNAMIC_STATE_SCISSOR
};
const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType
DE_NULL, // pNext
0u, // flags
DE_LENGTH_OF_ARRAY(dynamicStates), // dynamicStateCount
dynamicStates // pDynamicStates
};
const std::vector<VkViewport> viewports (1, makeViewport(m_testParams.frameResolution.width, m_testParams.frameResolution.height));
const std::vector<VkRect2D> scissors (1, makeRect2D(0u, 0u));
DE_ASSERT(m_vertexModule && m_fragmentModule);
return vk::makeGraphicsPipeline(
m_vki, // vk
m_vkd, // device
pipelineLayout, // pipelineLayout
*m_vertexModule, // vertexShaderModule
DE_NULL, // tessellationControlModule
DE_NULL, // tessellationEvalModule
DE_NULL, // geometryShaderModule
*m_fragmentModule, // fragmentShaderModule
renderPass, // renderPass
viewports, // viewports
scissors, // scissors
VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // topology
0U, // subpass
0U, // patchControlPoints
&vertexInputStateCreateInfo, // vertexInputStateCreateInfo
nullptr, // rasterizationStateCreateInfo
nullptr, // multisampleStateCreateInfo
nullptr, // depthStencilStateCreateInfo
nullptr, // colorBlendStateCreateInfo
&dynamicStateCreateInfo); // dynamicStateCreateInfo
}
VkDeviceSize CommonDescriptorInstance::createBuffers (std::vector<VkDescriptorBufferInfo>& bufferInfos,
ut::BufferHandleAllocSp& buffer,
deUint32 elementCount,
deUint32 elementSize,
VkDeviceSize alignment,
VkBufferUsageFlags bufferUsage)
{
const VkDeviceSize roundedSize = deAlign64(elementSize, alignment);
VkDeviceSize bufferSize = ut::createBufferAndBind(buffer, m_context, bufferUsage, (roundedSize * elementCount));
for (deUint32 elementIdx = 0; elementIdx < elementCount; ++elementIdx)
{
const VkDescriptorBufferInfo bufferInfo =
{
*buffer.get()->buffer, //buffer;
elementIdx * roundedSize, //offset;
elementSize, // range;
};
bufferInfos.push_back(bufferInfo);
}
return bufferSize;
}
VkDeviceSize CommonDescriptorInstance::createImages (std::vector<ut::ImageHandleAllocSp>& images,
std::vector<VkDescriptorBufferInfo>& bufferInfos,
ut::BufferHandleAllocSp& buffer,
VkBufferUsageFlags bufferUsage,
const VkExtent3D& imageExtent,
VkFormat imageFormat,
VkImageLayout imageLayout,
deUint32 imageCount,
bool withMipMaps)
{
const deUint32 imageSize = ut::computeImageSize(imageExtent, imageFormat, withMipMaps);
const VkDeviceSize bufferSize = createBuffers(bufferInfos, buffer, imageCount, imageSize, sizeof(tcu::Vec4), bufferUsage);
for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
{
ut::ImageHandleAllocSp image;
ut::createImageAndBind(image, m_context, imageFormat, imageExtent, imageLayout, withMipMaps);
images.push_back(image);
}
return bufferSize;
}
void CommonDescriptorInstance::createBuffersViews (std::vector<ut::BufferViewSp>& views,
const std::vector<VkDescriptorBufferInfo>& bufferInfos,
VkFormat format)
{
const deUint32 infoCount = static_cast<deUint32>(bufferInfos.size());
for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
{
const VkDescriptorBufferInfo& bufferInfo = bufferInfos[infoIdx];
const VkBufferViewCreateInfo bufferViewInfo =
{
VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // sType
DE_NULL, // pNext
(VkBufferViewCreateFlags)0, // flags
bufferInfo.buffer, // buffer
format, // format
bufferInfo.offset, // offset
bufferInfo.range // range;
};
views.push_back(ut::BufferViewSp(new Move<VkBufferView>(vk::createBufferView(m_vki, m_vkd, &bufferViewInfo))));
}
}
void CommonDescriptorInstance::createImagesViews (std::vector<ut::ImageViewSp>& views,
const std::vector<ut::ImageHandleAllocSp>& images,
VkFormat format)
{
const deUint32 imageCount = static_cast<deUint32>(images.size());
for (deUint32 imageIdx = 0; imageIdx < imageCount; ++imageIdx)
{
const VkImageViewCreateInfo createInfo =
{
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType
DE_NULL, // pNext
(VkImageViewCreateFlags)0, // flags
*images[imageIdx]->image, // image
VK_IMAGE_VIEW_TYPE_2D, // viewType
format, // format
vk::makeComponentMappingRGBA(), // components
{
VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
(deUint32)0, // baseMipLevel
images[imageIdx]->levels, // mipLevels
(deUint32)0, // baseArrayLayer
(deUint32)1u, // arraySize
},
};
views.push_back(ut::ImageViewSp(new Move<VkImageView>(vk::createImageView(m_vki, m_vkd, &createInfo))));
}
}
void CommonDescriptorInstance::copyBuffersToImages (IterateCommonVariables& variables)
{
const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
DE_ASSERT(variables.descriptorsImages.size() == infoCount);
const VkPipelineStageFlagBits dstStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
: VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
{
ut::recordCopyBufferToImage(
*variables.commandBuffer, // commandBuffer
m_vki, // interface
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
dstStageMask, // dstStageMask
variables.descriptorsBufferInfos[infoIdx], // bufferInfo
*(variables.descriptorsImages[infoIdx]->image), // image
variables.descriptorsImages[infoIdx]->extent, // imageExtent
variables.descriptorsImages[infoIdx]->format, // imageFormat
VK_IMAGE_LAYOUT_UNDEFINED, // oldImageLayout
VK_IMAGE_LAYOUT_GENERAL, // newImageLayout
variables.descriptorsImages[infoIdx]->levels); // mipLevelCount
}
}
void CommonDescriptorInstance::copyImagesToBuffers (IterateCommonVariables& variables)
{
const deUint32 infoCount = static_cast<deUint32>(variables.descriptorsBufferInfos.size());
DE_ASSERT(variables.descriptorsImages.size() == infoCount);
const VkPipelineStageFlagBits srcStageMask = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT)
? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
: VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
for (deUint32 infoIdx = 0; infoIdx < infoCount; ++infoIdx)
{
ut::recordCopyImageToBuffer(
*variables.commandBuffer, // commandBuffer
m_vki, // interface
srcStageMask, // srcStageMask
VK_PIPELINE_STAGE_HOST_BIT, // dstStageMask
*(variables.descriptorsImages[infoIdx]->image), // image
variables.descriptorsImages[infoIdx]->extent, // imageExtent
variables.descriptorsImages[infoIdx]->format, // imageFormat
VK_IMAGE_LAYOUT_GENERAL, // oldImageLayout
VK_IMAGE_LAYOUT_GENERAL, // newImageLayout
variables.descriptorsBufferInfos[infoIdx]); // bufferInfo
}
}
PixelBufferAccess CommonDescriptorInstance::getPixelAccess (deUint32 imageIndex,
const VkExtent3D& imageExtent,
VkFormat imageFormat,
const std::vector<VkDescriptorBufferInfo>& bufferInfos,
const ut::BufferHandleAllocSp& buffer,
deUint32 mipLevel) const
{
DE_ASSERT(bufferInfos[imageIndex].buffer == *buffer.get()->buffer);
DE_ASSERT(ut::computeImageSize(imageExtent, imageFormat, true, (mipLevel ? ut::maxDeUint32 : 0)) <= bufferInfos[imageIndex].range);
DE_ASSERT(imageExtent.width >> mipLevel);
DE_ASSERT(imageExtent.height >> mipLevel);
deUint32 mipOffset = 0;
for (deUint32 level = 0; mipLevel && level < mipLevel; ++level)
{
mipOffset += ut::computeImageSize(imageExtent, imageFormat, true, level);
}
unsigned char* hostPtr = static_cast<unsigned char*>(buffer->alloc->getHostPtr());
unsigned char* data = hostPtr + bufferInfos[imageIndex].offset + mipOffset;
return tcu::PixelBufferAccess(vk::mapVkFormat(imageFormat), (imageExtent.width >> mipLevel), (imageExtent.height >> mipLevel), imageExtent.depth, data);
}
void CommonDescriptorInstance::updateDescriptors (IterateCommonVariables& variables)
{
const std::vector<deUint32> primes = ut::generatePrimes(variables.availableDescriptorCount);
const deUint32 primeCount = static_cast<deUint32>(primes.size());
for (deUint32 primeIdx = 0; primeIdx < primeCount; ++primeIdx)
{
const VkDescriptorBufferInfo* pBufferInfo = DE_NULL;
const VkDescriptorImageInfo* pImageInfo = DE_NULL;
const VkBufferView* pTexelBufferView = DE_NULL;
VkDescriptorImageInfo imageInfo =
{
static_cast<VkSampler>(0),
static_cast<VkImageView>(0),
VK_IMAGE_LAYOUT_GENERAL
};
switch (m_testParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
{
pBufferInfo = &variables.descriptorsBufferInfos[primeIdx];
switch (m_testParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
pTexelBufferView = &(**variables.descriptorsBufferViews[primeIdx]);
break;
default:
break;
}
}
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
imageInfo.sampler = **variables.descriptorSamplers[primeIdx];
pImageInfo = &imageInfo;
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
imageInfo.imageView = **variables.descriptorImageViews[primeIdx];
pImageInfo = &imageInfo;
break;
default: break;
}
const VkWriteDescriptorSet writeInfo =
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
DE_NULL, // pNext
*variables.descriptorSet, // descriptorSet
m_testParams.descriptorBinding, // descriptorBinding;
primes[primeIdx], // elementIndex
1u, // descriptorCount
m_testParams.descriptorType, // descriptorType
pImageInfo, // pImageInfo
pBufferInfo, // pBufferInfo
pTexelBufferView // pTexelBufferView
};
m_vki.updateDescriptorSets(m_vkd, 1u, &writeInfo, 0u, DE_NULL);
}
}
void CommonDescriptorInstance::iterateCommandSetup (IterateCommonVariables& variables)
{
variables.dataAlignment = 0;
variables.renderArea.offset.x = 0;
variables.renderArea.offset.y = 0;
variables.renderArea.extent.width = m_testParams.frameResolution.width;
variables.renderArea.extent.height = m_testParams.frameResolution.height;
variables.vertexCount = m_testParams.frameResolution.width * m_testParams.frameResolution.height;
variables.lowerBound = 0;
variables.upperBound = variables.vertexCount;
variables.descriptorSetLayout = createDescriptorSetLayout(m_testParams.calculateInLoop, variables.availableDescriptorCount);
variables.validDescriptorCount = ut::computePrimeCount(variables.availableDescriptorCount);
variables.descriptorPool = createDescriptorPool(variables.availableDescriptorCount);
variables.descriptorSet = createDescriptorSet(*variables.descriptorPool, *variables.descriptorSetLayout);
std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
descriptorSetLayouts.push_back(*variables.descriptorSetLayout);
if (m_testParams.calculateInLoop)
{
variables.descriptorEnumerator.init(m_context, variables.vertexCount, variables.availableDescriptorCount);
descriptorSetLayouts.push_back(*variables.descriptorEnumerator.descriptorSetLayout);
}
variables.pipelineLayout = createPipelineLayout(descriptorSetLayouts);
createAndPopulateDescriptors (variables);
variables.renderPass = createRenderPass(variables);
variables.pipeline = createPipeline(*variables.pipelineLayout, *variables.renderPass);
variables.commandBuffer = createCmdBuffer();
if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
{
createVertexAttributeBuffer (variables.vertexAttributesBuffer, variables.availableDescriptorCount);
createFramebuffer (variables.frameBuffer, *variables.renderPass, variables);
}
if (m_testParams.calculateInLoop)
{
variables.descriptorEnumerator.update(m_context);
}
if (!m_testParams.updateAfterBind)
{
updateDescriptors (variables);
}
}
void CommonDescriptorInstance::iterateCommandBegin (IterateCommonVariables& variables, bool firstPass)
{
vk::beginCommandBuffer (m_vki, *variables.commandBuffer);
// Clear color attachment, and transition it to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
{
if (firstPass)
{
const VkImageMemoryBarrier preImageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
DE_NULL, // const void* pNext
0u, // VkAccessFlags srcAccessMask
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
*variables.frameBuffer->image->image, // VkImage image
{
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0u, // uint32_t baseMipLevel
VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
0u, // uint32_t baseArray
VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
}
};
m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
(VkDependencyFlags)0,
0, (const VkMemoryBarrier*)DE_NULL,
0, (const VkBufferMemoryBarrier*)DE_NULL,
1, &preImageBarrier);
const VkClearColorValue clearColorValue = makeClearValueColor(m_clearColor).color;
m_vki.cmdClearColorImage(*variables.commandBuffer, *variables.frameBuffer->image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &preImageBarrier.subresourceRange);
const VkImageMemoryBarrier postImageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
DE_NULL, // const void* pNext
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
*variables.frameBuffer->image->image, // VkImage image
{
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0u, // uint32_t baseMipLevel
VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
0u, // uint32_t baseArray
VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
}
};
m_vki.cmdPipelineBarrier(*variables.commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
(VkDependencyFlags)0,
0, (const VkMemoryBarrier*)DE_NULL,
0, (const VkBufferMemoryBarrier*)DE_NULL,
1, &postImageBarrier);
}
}
if (m_testParams.calculateInLoop)
{
deRandom rnd;
deRandom_init(&rnd, static_cast<deUint32>(m_testParams.descriptorType));
const deUint32 quarter = variables.vertexCount / 4;
variables.lowerBound = deRandom_getUint32(&rnd) % quarter;
variables.upperBound = (deRandom_getUint32(&rnd) % quarter) + (3 * quarter);
const push_constant pc =
{
static_cast<deInt32>(variables.lowerBound),
static_cast<deInt32>(variables.upperBound)
};
m_vki.cmdPushConstants(*variables.commandBuffer, *variables.pipelineLayout, m_testParams.stageFlags, 0u, static_cast<deUint32>(sizeof(pc)), &pc);
}
if ((m_testParams.stageFlags & VK_SHADER_STAGE_VERTEX_BIT) || (m_testParams.stageFlags & VK_SHADER_STAGE_FRAGMENT_BIT))
{
commandBindVertexAttributes (*variables.commandBuffer, variables.vertexAttributesBuffer);
}
if (m_testParams.calculateInLoop)
{
commandBindDescriptorSets(*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorEnumerator.descriptorSet, 1);
}
if (!ut::isDynamicDescriptor(m_testParams.descriptorType))
{
commandBindDescriptorSets (*variables.commandBuffer, *variables.pipelineLayout, *variables.descriptorSet, 0);
}
commandBindPipeline (*variables.commandBuffer, *variables.pipeline);
}
tcu::TestStatus CommonDescriptorInstance::iterate (void)
{
IterateCommonVariables v;
ut::UpdatablePixelBufferAccessPtr programResult;
ut::UpdatablePixelBufferAccessPtr referenceResult;
bool firstPass = true;
iterateCommandSetup (v);
v.renderArea.extent.width = m_testParams.frameResolution.width/4;
v.renderArea.extent.height = m_testParams.frameResolution.height/4;
for (int x = 0; x < 4; x++)
for (int y= 0; y < 4; y++)
{
iterateCommandBegin (v, firstPass);
if (true == firstPass && true == m_testParams.copyBuffersToImages)
{
copyBuffersToImages (v);
}
firstPass = false;
if (true == m_testParams.updateAfterBind)
{
updateDescriptors (v);
}
v.renderArea.offset.x = x * m_testParams.frameResolution.width/4;
v.renderArea.offset.y = y * m_testParams.frameResolution.height/4;
vk::VkRect2D scissor = makeRect2D(v.renderArea.offset.x, v.renderArea.offset.y, v.renderArea.extent.width, v.renderArea.extent.height);
m_vki.cmdSetScissor(*v.commandBuffer, 0u, 1u, &scissor);
vk::beginRenderPass (m_vki, *v.commandBuffer, *v.renderPass, *v.frameBuffer->buffer, v.renderArea, m_clearColor);
m_vki.cmdDraw (*v.commandBuffer, v.vertexCount, 1u, 0u, 0u);
vk::endRenderPass (m_vki, *v.commandBuffer);
iterateCommandEnd(v, programResult, referenceResult);
programResult->invalidate();
}
return ( iterateVerifyResults(v, programResult, referenceResult) ? tcu::TestStatus::pass : tcu::TestStatus::fail)("");
}
std::vector<float> CommonDescriptorInstance::createColorScheme (void)
{
std::vector<float> cs;
int divider = 2;
for (int i = 0; i < 10; ++i)
{
cs.push_back(1.0f / float(divider));
divider *= 2;
}
return cs;
}
void CommonDescriptorInstance::iterateCommandEnd (IterateCommonVariables& variables,
ut::UpdatablePixelBufferAccessPtr& programResult,
ut::UpdatablePixelBufferAccessPtr& referenceResult,
bool collectBeforeSubmit)
{
if (collectBeforeSubmit)
{
iterateCollectResults(programResult, variables, true);
iterateCollectResults(referenceResult, variables, false);
}
VK_CHECK(m_vki.endCommandBuffer(*variables.commandBuffer));
Move<VkFence> fence = commandSubmit(*variables.commandBuffer);
m_vki.waitForFences(m_vkd, 1, &(*fence), DE_TRUE, ~0ull);
if (false == collectBeforeSubmit)
{
iterateCollectResults(programResult, variables, true);
iterateCollectResults(referenceResult, variables, false);
}
}
bool CommonDescriptorInstance::iterateVerifyResults (IterateCommonVariables& variables,
ut::UpdatablePixelBufferAccessPtr programResult,
ut::UpdatablePixelBufferAccessPtr referenceResult)
{
bool result = false;
if (m_testParams.fuzzyComparison)
{
result = tcu::fuzzyCompare(m_context.getTestContext().getLog(),
"Fuzzy Compare", "Comparison result", *referenceResult.get(), *programResult.get(), 0.02f, tcu::COMPARE_LOG_EVERYTHING);
}
else
{
result = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
"Float Threshold Compare", "Comparison result", *referenceResult.get(), *programResult.get(), tcu::Vec4(0.02f, 0.02f, 0.02f, 0.02f), tcu::COMPARE_LOG_EVERYTHING);
}
if (m_testParams.allowVertexStoring)
{
result = verifyVertexWriteResults(variables);
}
return result;
}
void CommonDescriptorInstance::iterateCollectResults (ut::UpdatablePixelBufferAccessPtr& result,
const IterateCommonVariables& variables,
bool fromTest)
{
if (fromTest)
{
result = commandReadFrameBuffer(*variables.commandBuffer, variables.frameBuffer);
}
else
{
result = ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessAllocation(vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution));
for (deUint32 y = 0, pixelNum = 0; y < m_testParams.frameResolution.height; ++y)
{
for (deUint32 x = 0; x < m_testParams.frameResolution.width; ++x, ++pixelNum)
{
const float component = m_colorScheme[(pixelNum % variables.validDescriptorCount) % m_schemeSize];
result->setPixel(tcu::Vec4(component, component, component, 1.0f), x, y);
}
}
}
}
Move<VkCommandBuffer> CommonDescriptorInstance::createCmdBuffer (void)
{
return vk::allocateCommandBuffer(m_vki, m_vkd, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
}
Move<VkFence> CommonDescriptorInstance::commandSubmit (VkCommandBuffer cmd)
{
Move<VkFence> fence(vk::createFence(m_vki, m_vkd));
const VkSubmitInfo submitInfo =
{
VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
DE_NULL, // pNext
0u, // waitSemaphoreCount
static_cast<VkSemaphore*>(DE_NULL), // pWaitSemaphores
static_cast<const VkPipelineStageFlags*>(DE_NULL), // pWaitDstStageMask
1u, // commandBufferCount
&cmd, // pCommandBuffers
0u, // signalSemaphoreCount
static_cast<VkSemaphore*>(DE_NULL) // pSignalSemaphores
};
VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
return fence;
}
bool CommonDescriptorInstance::verifyVertexWriteResults(IterateCommonVariables& variables)
{
DE_UNREF(variables);
return true;
}
void CommonDescriptorInstance::commandBindPipeline (VkCommandBuffer commandBuffer,
VkPipeline pipeline)
{
const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
m_vki.cmdBindPipeline(commandBuffer, pipelineBindingPoint, pipeline);
}
void CommonDescriptorInstance::commandBindVertexAttributes (VkCommandBuffer commandBuffer,
const ut::BufferHandleAllocSp& vertexAttributesBuffer)
{
const VkDeviceSize offsets[] = { 0u };
const VkBuffer buffers[] = { *vertexAttributesBuffer->buffer };
m_vki.cmdBindVertexBuffers(commandBuffer, 0u, 1u, buffers, offsets);
}
void CommonDescriptorInstance::commandBindDescriptorSets (VkCommandBuffer commandBuffer,
VkPipelineLayout pipelineLayout,
VkDescriptorSet descriptorSet,
deUint32 descriptorSetIndex)
{
const VkPipelineBindPoint pipelineBindingPoint = (m_testParams.stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
m_vki.cmdBindDescriptorSets(commandBuffer, pipelineBindingPoint, pipelineLayout, descriptorSetIndex, 1u, &descriptorSet, 0u, static_cast<deUint32*>(DE_NULL));
}
ut::UpdatablePixelBufferAccessPtr
CommonDescriptorInstance::commandReadFrameBuffer (VkCommandBuffer commandBuffer,
const ut::FrameBufferSp& frameBuffer)
{
ut::BufferHandleAllocSp frameBufferContent;
commandReadFrameBuffer(frameBufferContent, commandBuffer, frameBuffer);
return ut::UpdatablePixelBufferAccessPtr(new ut::PixelBufferAccessBuffer(
m_vkd, m_vki, vk::mapVkFormat(m_colorFormat), m_testParams.frameResolution,
de::SharedPtr< Move<VkBuffer> >(new Move<VkBuffer>(frameBufferContent->buffer)),
de::SharedPtr< de::MovePtr<Allocation> >(new de::MovePtr<Allocation>(frameBufferContent->alloc))));
}
void CommonDescriptorInstance::commandReadFrameBuffer (ut::BufferHandleAllocSp& content,
VkCommandBuffer commandBuffer,
const ut::FrameBufferSp& frameBuffer)
{
Move<VkBuffer> buffer;
de::MovePtr<Allocation> allocation;
const VkDeviceSize bufferSize = ut::computeImageSize(frameBuffer->image);
// create a buffer and an host allocation for it
{
const VkBufferCreateInfo bufferCreateInfo =
{
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
DE_NULL, // pNext
0u, // flags
bufferSize, // size
VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1u, // queueFamilyIndexCoun
&m_queueFamilyIndex // pQueueFamilyIndices
};
buffer = vk::createBuffer(m_vki, m_vkd, &bufferCreateInfo);
const VkMemoryRequirements memRequirements(vk::getBufferMemoryRequirements(m_vki, m_vkd, *buffer));
allocation = m_allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
VK_CHECK(m_vki.bindBufferMemory(m_vkd, *buffer, allocation->getMemory(), allocation->getOffset()));
}
const VkImage& image = *frameBuffer->image->image;
VkImageSubresourceRange subresourceRange =
{
VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
0u, // baseMipLevel
1u, // levelCount
0u, // baseArrayLayer
1u // layerCount
};
const VkImageMemoryBarrier barrierBefore =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
DE_NULL, // pNext;
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout;
VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
image, // image;
subresourceRange // subresourceRange;
};
const VkBufferImageCopy copyRegion =
{
0u, // bufferOffset
frameBuffer->image->extent.width, // bufferRowLength
frameBuffer->image->extent.height, // bufferImageHeight
{ // VkImageSubresourceLayers
VK_IMAGE_ASPECT_COLOR_BIT, // aspect
0u, // mipLevel
0u, // baseArrayLayer
1u, // layerCount
},
{ 0, 0, 0 }, // imageOffset
frameBuffer->image->extent // imageExtent
};
const VkBufferMemoryBarrier bufferBarrier =
{
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType;
DE_NULL, // pNext;
VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask;
VK_ACCESS_HOST_READ_BIT, // dstAccessMask;
VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
*buffer, // buffer;
0u, // offset;
bufferSize // size;
};
const VkImageMemoryBarrier barrierAfter =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
DE_NULL, // pNext;
VK_ACCESS_TRANSFER_READ_BIT, // srcAccessMask;
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask;
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // oldLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout;
VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex;
image, // image
subresourceRange // subresourceRange
};
m_vki.cmdPipelineBarrier(commandBuffer, // commandBuffer
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask, dstStageMask
(VkDependencyFlags)0, // dependencyFlags
0u, DE_NULL, // memoryBarrierCount, pMemoryBarriers
0u, DE_NULL, // bufferBarrierCount, pBufferBarriers
1u, &barrierBefore); // imageBarrierCount, pImageBarriers
m_vki.cmdCopyImageToBuffer(commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
m_vki.cmdPipelineBarrier(commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
(VkDependencyFlags)0,
0u, DE_NULL,
1u, &bufferBarrier,
1u, &barrierAfter);
content = ut::BufferHandleAllocSp(new ut::BufferHandleAlloc(buffer, allocation));
}
std::string CommonDescriptorInstance::getColorAccess (VkDescriptorType descriptorType,
const char* indexVariableName,
bool usesMipMaps)
{
std::string text;
std::map<std::string, std::string> vars;
vars["INDEX"] = indexVariableName;
switch (descriptorType)
{
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
text = "data[nonuniformEXT(${INDEX})].c";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
text = "data[nonuniformEXT(${INDEX})].cold";
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
text = "subpassLoad(data[nonuniformEXT(${INDEX})]).rgba";
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
text = "texelFetch(data[nonuniformEXT(${INDEX})], 0)";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
text = "imageLoad(data[nonuniformEXT(${INDEX})], 0)";
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
text = usesMipMaps
? "textureLod(nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos, 1)"
: "texture( nonuniformEXT(sampler2D(tex[0], data[${INDEX}])), normalpos )";
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
text = usesMipMaps
? "textureLod( nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0), textureQueryLevels(nonuniformEXT(sampler2D(data[${INDEX}], samp[0])))-1)"
: "texture( nonuniformEXT(sampler2D(data[${INDEX}], samp[0])), vec2(0,0) )";
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
text = usesMipMaps
? "textureLod( data[nonuniformEXT(${INDEX})], uvec2(0,0), textureQueryLevels(data[nonuniformEXT(${INDEX})])-1)"
: "texture( data[nonuniformEXT(${INDEX})], uvec2(0,0) )";
break;
default:
TCU_THROW(InternalError, "Not implemented descriptor type");
}
return tcu::StringTemplate(text).specialize(vars);
}
std::string CommonDescriptorInstance::getFragmentReturnSource (const std::string& colorAccess)
{
return " FragColor = " + colorAccess + ";\n";
}
std::string CommonDescriptorInstance::getFragmentLoopSource (const std::string& colorAccess1,
const std::string& colorAccess2)
{
std::map < std::string, std::string > vars;
vars["COLOR_ACCESS_1"] = colorAccess1;
vars["COLOR_ACCESS_2"] = colorAccess2;
const char* s =
" vec4 sumClr1 = vec4(0,0,0,0); \n"
" vec4 sumClr2 = vec4(0,0,0,0); \n"
" for (int i = pc.lowerBound; i < pc.upperBound; ++i) \n"
" {\n"
" int loopIdx = texelFetch(iter, i).x; \n"
" sumClr1 += ${COLOR_ACCESS_2} + ${COLOR_ACCESS_1}; \n"
" sumClr2 += ${COLOR_ACCESS_2}; \n"
" }\n"
" FragColor = vec4(((sumClr1 - sumClr2) / float(pc.upperBound - pc.lowerBound)).rgb, 1); \n";
return tcu::StringTemplate(s).specialize(vars);
}
bool CommonDescriptorInstance::performWritesInVertex (VkDescriptorType descriptorType)
{
bool result = false;
switch (descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
result = true;
break;
default:
result = false;
break;
}
return result;
}
bool CommonDescriptorInstance::performWritesInVertex (VkDescriptorType descriptorType,
const Context& context)
{
bool result = false;
ut::DeviceProperties dp (context);
const VkPhysicalDeviceFeatures& feats = dp.physicalDeviceFeatures();
if (feats.vertexPipelineStoresAndAtomics != DE_FALSE)
{
result = CommonDescriptorInstance::performWritesInVertex(descriptorType);
}
return result;
}
std::string CommonDescriptorInstance::getShaderAsm (VkShaderStageFlagBits shaderType,
const TestCaseParams& testCaseParams,
bool allowVertexStoring)
{
std::stringstream s;
switch (shaderType)
{
case VK_SHADER_STAGE_VERTEX_BIT:
switch (testCaseParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
s << " OpCapability Shader\n";
s << " OpCapability SampledBuffer\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
s << " OpName %_ \"\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %in_position \"in_position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %in_normalpos \"in_normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %index \"index\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
s << " OpDecorate %gl_PerVertex Block\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %in_position Location 0\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %in_normalpos Location 1\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
s << " OpDecorate %rIndex Location 3\n";
s << " OpDecorate %index Location 2\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << " %uint = OpTypeInt 32 0\n";
s << " %uint_1 = OpConstant %uint 1\n";
s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
s << " %int = OpTypeInt 32 1\n";
s << " %int_1 = OpConstant %int 1\n";
s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
s << "%_ptr_Output_float = OpTypePointer Output %float\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %position = OpVariable %_ptr_Output_v4float Output\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Output_int = OpTypePointer Output %int\n";
s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
s << " %v4int = OpTypeVector %int 4\n";
s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
s << " %index = OpVariable %_ptr_Input_v4int Input\n";
s << " %uint_0 = OpConstant %uint 0\n";
s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_2 = OpConstant %uint 2\n";
s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_3 = OpConstant %uint 3\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
s << " OpStore %18 %float_0_200000003\n";
s << " %23 = OpLoad %v4float %in_position\n";
s << " OpStore %position %23\n";
s << " %29 = OpLoad %v2float %in_normalpos\n";
s << " OpStore %normalpos %29\n";
s << " %31 = OpLoad %v4float %position\n";
s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
s << " OpStore %32 %31\n";
s << " %37 = OpLoad %int %gl_VertexIndex\n";
s << " OpStore %vIndex %37\n";
s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
s << " %44 = OpLoad %int %43\n";
s << " OpStore %rIndex %44\n";
s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
s << " %47 = OpLoad %int %46\n";
s << " OpStore %gIndex %47\n";
s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
s << " %51 = OpLoad %int %50\n";
s << " OpStore %bIndex %51\n";
s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
s << " %55 = OpLoad %int %54\n";
s << " OpStore %aIndex %55\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
s << " OpCapability Shader\n";
s << " OpCapability ImageBuffer\n";
if (allowVertexStoring)
{
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
}
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
s << " OpName %_ \"\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %in_position \"in_position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %in_normalpos \"in_normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %index \"index\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpName %data \"data\"\n";
s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
s << " OpDecorate %gl_PerVertex Block\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %in_position Location 0\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %in_normalpos Location 1\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
s << " OpDecorate %rIndex Location 3\n";
s << " OpDecorate %index Location 2\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Location 6\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 4\n";
if (allowVertexStoring)
{
// s << " OpDecorate %66 NonUniform\n";
// s << " OpDecorate %68 NonUniform\n";
s << " OpDecorate %69 NonUniform\n";
// s << " OpDecorate %71 NonUniform\n";
// s << " OpDecorate %72 NonUniform\n";
s << " OpDecorate %73 NonUniform\n";
}
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << " %uint = OpTypeInt 32 0\n";
s << " %uint_1 = OpConstant %uint 1\n";
s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
s << " %int = OpTypeInt 32 1\n";
s << " %int_1 = OpConstant %int 1\n";
s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
s << "%_ptr_Output_float = OpTypePointer Output %float\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %position = OpVariable %_ptr_Output_v4float Output\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Output_int = OpTypePointer Output %int\n";
s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
s << " %v4int = OpTypeVector %int 4\n";
s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
s << " %index = OpVariable %_ptr_Input_v4int Input\n";
s << " %uint_0 = OpConstant %uint 0\n";
s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_2 = OpConstant %uint 2\n";
s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_3 = OpConstant %uint 3\n";
if (allowVertexStoring)
{
s << " %bool = OpTypeBool\n";
s << " %61 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
s << " %_runtimearr_61 = OpTypeRuntimeArray %61\n";
s << " %_ptr_UniformConstant__runtimearr_61 = OpTypePointer UniformConstant %_runtimearr_61\n";
s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_61 UniformConstant\n";
s << " %_ptr_UniformConstant_61 = OpTypePointer UniformConstant %61\n";
}
else
{
s << " %56 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
s << "%_arr_56_uint_1 = OpTypeArray %56 %uint_1\n";
s << "%_ptr_UniformConstant__arr_56_uint_1 = OpTypePointer UniformConstant %_arr_56_uint_1\n";
s << " %data = OpVariable %_ptr_UniformConstant__arr_56_uint_1 UniformConstant\n";
}
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
s << " OpStore %18 %float_0_200000003\n";
s << " %23 = OpLoad %v4float %in_position\n";
s << " OpStore %position %23\n";
s << " %29 = OpLoad %v2float %in_normalpos\n";
s << " OpStore %normalpos %29\n";
s << " %31 = OpLoad %v4float %position\n";
s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
s << " OpStore %32 %31\n";
s << " %37 = OpLoad %int %gl_VertexIndex\n";
s << " OpStore %vIndex %37\n";
s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
s << " %44 = OpLoad %int %43\n";
s << " OpStore %rIndex %44\n";
s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
s << " %47 = OpLoad %int %46\n";
s << " OpStore %gIndex %47\n";
s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
s << " %51 = OpLoad %int %50\n";
s << " OpStore %bIndex %51\n";
s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
s << " %55 = OpLoad %int %54\n";
s << " OpStore %aIndex %55\n";
if (allowVertexStoring)
{
s << " %56 = OpLoad %int %gIndex\n";
s << " %58 = OpINotEqual %bool %56 %int_0\n";
s << " OpSelectionMerge %60 None\n";
s << " OpBranchConditional %58 %59 %60\n";
s << " %59 = OpLabel\n";
s << " %65 = OpLoad %int %gIndex\n";
s << " %66 = OpCopyObject %int %65\n";
s << " %68 = OpAccessChain %_ptr_UniformConstant_61 %data %66\n";
s << " %69 = OpLoad %61 %68\n";
s << " %70 = OpLoad %int %rIndex\n";
s << " %71 = OpCopyObject %int %70\n";
s << " %72 = OpAccessChain %_ptr_UniformConstant_61 %data %71\n";
s << " %73 = OpLoad %61 %72\n";
s << " %74 = OpImageRead %v4float %73 %int_0\n";
s << " OpImageWrite %69 %int_1 %74\n";
s << " OpBranch %60\n";
s << " %60 = OpLabel\n";
}
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
s << " OpCapability Shader\n";
if (allowVertexStoring)
{
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability StorageBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
}
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Vertex %main \"main\" %_ %position %in_position %normalpos %in_normalpos %vIndex %gl_VertexIndex %rIndex %index %gIndex %bIndex %aIndex %data\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %gl_PerVertex \"gl_PerVertex\"\n";
s << " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n";
s << " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n";
s << " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n";
s << " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n";
s << " OpName %_ \"\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %in_position \"in_position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %in_normalpos \"in_normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gl_VertexIndex \"gl_VertexIndex\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %index \"index\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpName %Data \"Data\"\n";
s << " OpMemberName %Data 0 \"cnew\"\n";
s << " OpMemberName %Data 1 \"cold\"\n";
s << " OpName %data \"data\"\n";
s << " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n";
s << " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n";
s << " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n";
s << " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n";
s << " OpDecorate %gl_PerVertex Block\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %in_position Location 0\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %in_normalpos Location 1\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gl_VertexIndex BuiltIn VertexIndex\n";
s << " OpDecorate %rIndex Location 3\n";
s << " OpDecorate %index Location 2\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Location 6\n";
s << " OpMemberDecorate %Data 0 Offset 0\n";
s << " OpMemberDecorate %Data 1 Offset 16\n";
s << " OpDecorate %Data Block\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 2\n";
if (allowVertexStoring)
{
// s << " OpDecorate %66 NonUniform\n";
// s << " OpDecorate %68 NonUniform\n";
s << " OpDecorate %70 NonUniform\n";
// s << " OpDecorate %71 NonUniform\n";
s << " OpDecorate %72 NonUniform\n";
}
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << " %uint = OpTypeInt 32 0\n";
s << " %uint_1 = OpConstant %uint 1\n";
s << "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n";
s << "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n";
s << "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n";
s << " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n";
s << " %int = OpTypeInt 32 1\n";
s << " %int_1 = OpConstant %int 1\n";
s << "%float_0_200000003 = OpConstant %float 0.200000003\n";
s << "%_ptr_Output_float = OpTypePointer Output %float\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %position = OpVariable %_ptr_Output_v4float Output\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << "%in_position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Output_v2float = OpTypePointer Output %v2float\n";
s << " %normalpos = OpVariable %_ptr_Output_v2float Output\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << "%in_normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Output_int = OpTypePointer Output %int\n";
s << " %vIndex = OpVariable %_ptr_Output_int Output\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << "%gl_VertexIndex = OpVariable %_ptr_Input_int Input\n";
s << " %rIndex = OpVariable %_ptr_Output_int Output\n";
s << " %v4int = OpTypeVector %int 4\n";
s << "%_ptr_Input_v4int = OpTypePointer Input %v4int\n";
s << " %index = OpVariable %_ptr_Input_v4int Input\n";
s << " %uint_0 = OpConstant %uint 0\n";
s << " %gIndex = OpVariable %_ptr_Output_int Output\n";
s << " %bIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_2 = OpConstant %uint 2\n";
s << " %aIndex = OpVariable %_ptr_Output_int Output\n";
s << " %uint_3 = OpConstant %uint 3\n";
s << " %Data = OpTypeStruct %v4float %v4float\n";
if (allowVertexStoring)
{
s << " %bool = OpTypeBool\n";
s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
s << " %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
}
else
{
s << "%_arr_Data_uint_1 = OpTypeArray %Data %uint_1\n";
s << "%_ptr_StorageBuffer__arr_Data_uint_1 = OpTypePointer StorageBuffer %_arr_Data_uint_1\n";
s << " %data = OpVariable %_ptr_StorageBuffer__arr_Data_uint_1 StorageBuffer\n";
}
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %18 = OpAccessChain %_ptr_Output_float %_ %int_1\n";
s << " OpStore %18 %float_0_200000003\n";
s << " %23 = OpLoad %v4float %in_position\n";
s << " OpStore %position %23\n";
s << " %29 = OpLoad %v2float %in_normalpos\n";
s << " OpStore %normalpos %29\n";
s << " %31 = OpLoad %v4float %position\n";
s << " %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n";
s << " OpStore %32 %31\n";
s << " %37 = OpLoad %int %gl_VertexIndex\n";
s << " OpStore %vIndex %37\n";
s << " %43 = OpAccessChain %_ptr_Input_int %index %uint_0\n";
s << " %44 = OpLoad %int %43\n";
s << " OpStore %rIndex %44\n";
s << " %46 = OpAccessChain %_ptr_Input_int %index %uint_1\n";
s << " %47 = OpLoad %int %46\n";
s << " OpStore %gIndex %47\n";
s << " %50 = OpAccessChain %_ptr_Input_int %index %uint_2\n";
s << " %51 = OpLoad %int %50\n";
s << " OpStore %bIndex %51\n";
s << " %54 = OpAccessChain %_ptr_Input_int %index %uint_3\n";
s << " %55 = OpLoad %int %54\n";
s << " OpStore %aIndex %55\n";
if (allowVertexStoring)
{
s << " %56 = OpLoad %int %gIndex\n";
s << " %58 = OpINotEqual %bool %56 %int_0\n";
s << " OpSelectionMerge %60 None\n";
s << " OpBranchConditional %58 %59 %60\n";
s << " %59 = OpLabel\n";
s << " %65 = OpLoad %int %gIndex\n";
s << " %66 = OpCopyObject %int %65\n";
s << " %67 = OpLoad %int %rIndex\n";
s << " %68 = OpCopyObject %int %67\n";
s << " %70 = OpAccessChain %_ptr_StorageBuffer_v4float %data %68 %int_1\n";
s << " %71 = OpLoad %v4float %70\n";
s << " %72 = OpAccessChain %_ptr_StorageBuffer_v4float %data %66 %int_0\n";
s << " OpStore %72 %71\n";
s << " OpBranch %60\n";
s << " %60 = OpLabel\n";
}
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
default:
TCU_THROW(InternalError, "Unexpected descriptor type");
}
break;
case VK_SHADER_STAGE_FRAGMENT_BIT:
switch (testCaseParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
s << " OpCapability Shader\n";
if (testCaseParams.usesMipMaps)
{
s << " OpCapability ImageQuery\n";
}
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability SampledImageArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
s << " OpExecutionMode %main OriginUpperLeft\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %FragColor \"FragColor\"\n";
s << " OpName %data \"data\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpDecorate %FragColor Location 0\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 7\n";
s << " OpDecorate %rIndex Flat\n";
s << " OpDecorate %rIndex Location 3\n";
// s << " OpDecorate %19 NonUniform\n";
// s << " OpDecorate %21 NonUniform\n";
s << " OpDecorate %22 NonUniform\n";
if (testCaseParams.usesMipMaps)
{
// s << " OpDecorate %27 NonUniform\n";
// s << " OpDecorate %28 NonUniform\n";
// s << " OpDecorate %29 NonUniform\n";
s << " OpDecorate %30 NonUniform\n";
}
s << " OpDecorate %position Flat\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %normalpos Flat\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %vIndex Flat\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gIndex Flat\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Flat\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Flat\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
s << " %10 = OpTypeImage %float 2D 0 0 0 1 Unknown\n";
s << " %11 = OpTypeSampledImage %10\n";
s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
s << " %int = OpTypeInt 32 1\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
s << " %v2float = OpTypeVector %float 2\n";
s << " %float_0 = OpConstant %float 0\n";
s << " %int_1 = OpConstant %int 1\n";
s << " %25 = OpConstantComposite %v2float %float_0 %float_0\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << " %position = OpVariable %_ptr_Input_v4float Input\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %18 = OpLoad %int %rIndex\n";
s << " %19 = OpCopyObject %int %18\n";
s << " %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
s << " %22 = OpLoad %11 %21\n";
if (testCaseParams.usesMipMaps)
{
s << " %26 = OpLoad %int %rIndex\n";
s << " %27 = OpCopyObject %int %26\n";
s << " %28 = OpAccessChain %_ptr_UniformConstant_11 %data %27\n";
s << " %29 = OpLoad %11 %28\n";
s << " %30 = OpImage %10 %29\n";
s << " %31 = OpImageQueryLevels %int %30\n";
s << " %33 = OpISub %int %31 %int_1\n";
s << " %34 = OpConvertSToF %float %33\n";
s << " %35 = OpImageSampleExplicitLod %v4float %22 %25 Lod %34\n";
s << " OpStore %FragColor %35\n";
}
else
{
s << " %26 = OpImageSampleImplicitLod %v4float %22 %25\n";
s << " OpStore %FragColor %26\n";
}
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
s << " OpCapability Shader\n";
s << " OpCapability SampledBuffer\n";
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability UniformTexelBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
s << " OpExecutionMode %main OriginUpperLeft\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpSourceExtension \"GL_EXT_texture_buffer\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %FragColor \"FragColor\"\n";
s << " OpName %data \"data\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpDecorate %FragColor Location 0\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 3\n";
s << " OpDecorate %rIndex Flat\n";
s << " OpDecorate %rIndex Location 3\n";
// s << " OpDecorate %19 NonUniform\n";
// s << " OpDecorate %21 NonUniform\n";
// s << " OpDecorate %22 NonUniform\n";
s << " OpDecorate %24 NonUniform\n";
s << " OpDecorate %position Flat\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %normalpos Flat\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %vIndex Flat\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gIndex Flat\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Flat\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Flat\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
s << " %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown\n";
s << " %11 = OpTypeSampledImage %10\n";
s << "%_runtimearr_11 = OpTypeRuntimeArray %11\n";
s << "%_ptr_UniformConstant__runtimearr_11 = OpTypePointer UniformConstant %_runtimearr_11\n";
s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_11 UniformConstant\n";
s << " %int = OpTypeInt 32 1\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
s << "%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << " %position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %18 = OpLoad %int %rIndex\n";
s << " %19 = OpCopyObject %int %18\n";
s << " %21 = OpAccessChain %_ptr_UniformConstant_11 %data %19\n";
s << " %22 = OpLoad %11 %21\n";
s << " %24 = OpImage %10 %22\n";
s << " %25 = OpImageFetch %v4float %24 %int_0\n";
s << " OpStore %FragColor %25\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
s << " OpCapability Shader\n";
s << " OpCapability ImageBuffer\n";
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability StorageTexelBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
s << " OpExecutionMode %main OriginUpperLeft\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %FragColor \"FragColor\"\n";
s << " OpName %data \"data\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpDecorate %FragColor Location 0\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 4\n";
s << " OpDecorate %rIndex Flat\n";
s << " OpDecorate %rIndex Location 3\n";
// s << " OpDecorate %18 NonUniform\n";
// s << " OpDecorate %20 NonUniform\n";
s << " OpDecorate %21 NonUniform\n";
s << " OpDecorate %position Flat\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %normalpos Flat\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %vIndex Flat\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gIndex Flat\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Flat\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Flat\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
s << " %10 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f\n";
s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
s << " %int = OpTypeInt 32 1\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << " %position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %17 = OpLoad %int %rIndex\n";
s << " %18 = OpCopyObject %int %17\n";
s << " %20 = OpAccessChain %_ptr_UniformConstant_10 %data %18\n";
s << " %21 = OpLoad %10 %20\n";
s << " %23 = OpImageRead %v4float %21 %int_0\n";
s << " OpStore %FragColor %23\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
s << " OpCapability Shader\n";
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability StorageBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
s << " OpExecutionMode %main OriginUpperLeft\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %FragColor \"FragColor\"\n";
s << " OpName %Data \"Data\"\n";
s << " OpMemberName %Data 0 \"cnew\"\n";
s << " OpMemberName %Data 1 \"cold\"\n";
s << " OpName %data \"data\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpDecorate %FragColor Location 0\n";
s << " OpMemberDecorate %Data 0 Offset 0\n";
s << " OpMemberDecorate %Data 1 Offset 16\n";
s << " OpDecorate %Data Block\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 2\n";
s << " OpDecorate %rIndex Flat\n";
s << " OpDecorate %rIndex Location 3\n";
// s << " OpDecorate %18 NonUniform\n";
s << " OpDecorate %21 NonUniform\n";
// s << " OpDecorate %22 NonUniform\n";
s << " OpDecorate %position Flat\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %normalpos Flat OpDecorate %normalpos Location 1\n";
s << " OpDecorate %vIndex Flat\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gIndex Flat\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Flat\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Flat\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
s << " %Data = OpTypeStruct %v4float %v4float\n";
s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
s << "%_ptr_StorageBuffer__runtimearr_Data = OpTypePointer StorageBuffer %_runtimearr_Data\n";
s << " %data = OpVariable %_ptr_StorageBuffer__runtimearr_Data StorageBuffer\n";
s << " %int = OpTypeInt 32 1\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
s << " %int_1 = OpConstant %int 1\n";
s << "%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << " %position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %17 = OpLoad %int %rIndex\n";
s << " %18 = OpCopyObject %int %17\n";
s << " %21 = OpAccessChain %_ptr_StorageBuffer_v4float %data %18 %int_1\n";
s << " %22 = OpLoad %v4float %21\n";
s << " OpStore %FragColor %22\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
s << " OpCapability Shader\n";
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability UniformBufferArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint Fragment %main \"main\" %FragColor %data %rIndex %position %normalpos %vIndex %gIndex %bIndex %aIndex\n";
s << " OpExecutionMode %main OriginUpperLeft\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %FragColor \"FragColor\"\n";
s << " OpName %Data \"Data\"\n";
s << " OpMemberName %Data 0 \"c\"\n";
s << " OpName %data \"data\"\n";
s << " OpName %rIndex \"rIndex\"\n";
s << " OpName %position \"position\"\n";
s << " OpName %normalpos \"normalpos\"\n";
s << " OpName %vIndex \"vIndex\"\n";
s << " OpName %gIndex \"gIndex\"\n";
s << " OpName %bIndex \"bIndex\"\n";
s << " OpName %aIndex \"aIndex\"\n";
s << " OpDecorate %FragColor Location 0\n";
s << " OpMemberDecorate %Data 0 Offset 0\n";
s << " OpDecorate %Data Block\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 1\n";
s << " OpDecorate %rIndex Flat\n";
s << " OpDecorate %rIndex Location 3\n";
// s << " OpDecorate %18 NonUniform\n";
s << " OpDecorate %21 NonUniform\n";
// s << " OpDecorate %22 NonUniform\n";
s << " OpDecorate %position Flat\n";
s << " OpDecorate %position Location 0\n";
s << " OpDecorate %normalpos Flat\n";
s << " OpDecorate %normalpos Location 1\n";
s << " OpDecorate %vIndex Flat\n";
s << " OpDecorate %vIndex Location 2\n";
s << " OpDecorate %gIndex Flat\n";
s << " OpDecorate %gIndex Location 4\n";
s << " OpDecorate %bIndex Flat\n";
s << " OpDecorate %bIndex Location 5\n";
s << " OpDecorate %aIndex Flat\n";
s << " OpDecorate %aIndex Location 6\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %float = OpTypeFloat 32\n";
s << " %v4float = OpTypeVector %float 4\n";
s << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n";
s << " %FragColor = OpVariable %_ptr_Output_v4float Output\n";
s << " %Data = OpTypeStruct %v4float\n";
s << "%_runtimearr_Data = OpTypeRuntimeArray %Data\n";
s << "%_ptr_Uniform__runtimearr_Data = OpTypePointer Uniform %_runtimearr_Data\n";
s << " %data = OpVariable %_ptr_Uniform__runtimearr_Data Uniform\n";
s << " %int = OpTypeInt 32 1\n";
s << "%_ptr_Input_int = OpTypePointer Input %int\n";
s << " %rIndex = OpVariable %_ptr_Input_int Input\n";
s << " %int_0 = OpConstant %int 0\n";
s << "%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float\n";
s << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n";
s << " %position = OpVariable %_ptr_Input_v4float Input\n";
s << " %v2float = OpTypeVector %float 2\n";
s << "%_ptr_Input_v2float = OpTypePointer Input %v2float\n";
s << " %normalpos = OpVariable %_ptr_Input_v2float Input\n";
s << " %vIndex = OpVariable %_ptr_Input_int Input\n";
s << " %gIndex = OpVariable %_ptr_Input_int Input\n";
s << " %bIndex = OpVariable %_ptr_Input_int Input\n";
s << " %aIndex = OpVariable %_ptr_Input_int Input\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %17 = OpLoad %int %rIndex\n";
s << " %18 = OpCopyObject %int %17\n";
s << " %21 = OpAccessChain %_ptr_Uniform_v4float %data %18 %int_0\n";
s << " %22 = OpLoad %v4float %21\n";
s << " OpStore %FragColor %22\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
default:
TCU_THROW(InternalError, "Unexpected descriptor type");
}
break;
case VK_SHADER_STAGE_COMPUTE_BIT:
switch (testCaseParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
s << " OpCapability Shader\n";
s << " OpCapability ShaderNonUniform\n";
s << " OpCapability RuntimeDescriptorArray\n";
s << " OpCapability StorageImageArrayNonUniformIndexing\n";
s << " OpExtension \"SPV_EXT_descriptor_indexing\"\n";
s << " %1 = OpExtInstImport \"GLSL.std.450\"\n";
s << " OpMemoryModel Logical GLSL450\n";
s << " OpEntryPoint GLCompute %main \"main\" %idxs %gl_WorkGroupID %data\n";
s << " OpExecutionMode %main LocalSize 1 1 1\n";
s << " OpSource GLSL 450\n";
s << " OpSourceExtension \"GL_EXT_nonuniform_qualifier\"\n";
s << " OpName %main \"main\"\n";
s << " OpName %c \"c\"\n";
s << " OpName %idxs \"idxs\"\n";
s << " OpName %gl_WorkGroupID \"gl_WorkGroupID\"\n";
s << " OpName %data \"data\"\n";
s << " OpDecorate %idxs DescriptorSet 0\n";
s << " OpDecorate %idxs Binding 12\n";
s << " OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId\n";
s << " OpDecorate %data DescriptorSet 0\n";
s << " OpDecorate %data Binding 11\n";
// s << " OpDecorate %36 NonUniform\n";
// s << " OpDecorate %37 NonUniform\n";
s << " OpDecorate %41 NonUniform\n";
s << " OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
s << " %void = OpTypeVoid\n";
s << " %3 = OpTypeFunction %void\n";
s << " %uint = OpTypeInt 32 0\n";
s << " %v4uint = OpTypeVector %uint 4\n";
s << "%_ptr_Function_v4uint = OpTypePointer Function %v4uint\n";
s << " %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui\n";
s << "%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10\n";
s << " %idxs = OpVariable %_ptr_UniformConstant_10 UniformConstant\n";
s << " %v3uint = OpTypeVector %uint 3\n";
s << "%_ptr_Input_v3uint = OpTypePointer Input %v3uint\n";
s << "%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input\n";
s << " %uint_0 = OpConstant %uint 0\n";
s << "%_ptr_Input_uint = OpTypePointer Input %uint\n";
s << " %int = OpTypeInt 32 1\n";
s << " %uint_1 = OpConstant %uint 1\n";
s << " %v2int = OpTypeVector %int 2\n";
s << "%_runtimearr_10 = OpTypeRuntimeArray %10\n";
s << "%_ptr_UniformConstant__runtimearr_10 = OpTypePointer UniformConstant %_runtimearr_10\n";
s << " %data = OpVariable %_ptr_UniformConstant__runtimearr_10 UniformConstant\n";
s << "%_ptr_Function_uint = OpTypePointer Function %uint\n";
s << " %int_0 = OpConstant %int 0\n";
s << " %39 = OpConstantComposite %v2int %int_0 %int_0\n";
s << "%_ptr_Image_uint = OpTypePointer Image %uint\n";
s << "%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1\n";
s << " %main = OpFunction %void None %3\n";
s << " %5 = OpLabel\n";
s << " %c = OpVariable %_ptr_Function_v4uint Function\n";
s << " %13 = OpLoad %10 %idxs\n";
s << " %19 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_0\n";
s << " %20 = OpLoad %uint %19\n";
s << " %22 = OpBitcast %int %20\n";
s << " %24 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %uint_1\n";
s << " %25 = OpLoad %uint %24\n";
s << " %26 = OpBitcast %int %25\n";
s << " %28 = OpCompositeConstruct %v2int %22 %26\n";
s << " %29 = OpImageRead %v4uint %13 %28 ZeroExtend\n";
s << " OpStore %c %29\n";
s << " %34 = OpAccessChain %_ptr_Function_uint %c %uint_0\n";
s << " %35 = OpLoad %uint %34\n";
s << " %36 = OpCopyObject %uint %35\n";
s << " %37 = OpAccessChain %_ptr_UniformConstant_10 %data %36\n";
s << " %41 = OpImageTexelPointer %_ptr_Image_uint %37 %39 %uint_0\n";
s << " %42 = OpAtomicIAdd %uint %41 %uint_1 %uint_0 %uint_1\n";
s << " OpReturn\n";
s << " OpFunctionEnd\n";
break;
default:
TCU_THROW(InternalError, "Unexpected descriptor type");
}
break;
default:
TCU_THROW(InternalError, "Unexpected stage");
}
return s.str();
}
std::string CommonDescriptorInstance::getShaderSource (VkShaderStageFlagBits shaderType,
const TestCaseParams& testCaseParams,
bool allowVertexStoring)
{
std::stringstream s;
s << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << '\n';
s << "#extension GL_EXT_nonuniform_qualifier : require \n";
if (testCaseParams.calculateInLoop)
{
s << "layout(push_constant) uniform Block { int lowerBound, upperBound; } pc;\n";
s << substBinding(BINDING_DescriptorEnumerator,
"layout(set=1,binding=${?}) uniform isamplerBuffer iter; \n");
}
switch (testCaseParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
s << substBinding(BINDING_StorageBuffer,
"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
s << substBinding(BINDING_StorageBufferDynamic,
"layout(set=0,binding=${?}) buffer Data { vec4 cnew, cold; } data[]; \n");
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
s << substBinding(BINDING_UniformBuffer,
"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
s << substBinding(BINDING_UniformBufferDynamic,
"layout(set=0,binding=${?}) uniform Data { vec4 c; } data[]; \n");
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
s << substBinding(BINDING_StorageTexelBuffer,
"layout(set=0,binding=${?},rgba32f) uniform imageBuffer data[];\n");
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
s << "#extension GL_EXT_texture_buffer : require \n";
s << substBinding(BINDING_UniformTexelBuffer,
"layout(set=0,binding=${?}) uniform samplerBuffer data[];\n");
break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
// Left for the consistent of code.
// Header is set one swicth below
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
s << "#extension GL_EXT_texture_buffer : require \n";
s << substBinding(BINDING_SampledImage,
"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n", 1, "tex");
s << substBinding(BINDING_Sampler,
"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n");
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
s << "#extension GL_EXT_texture_buffer : require \n";
s << substBinding(BINDING_Sampler,
"layout(set=0,binding=${?}) uniform sampler ${VAR}[${*}];\n", 1, "samp");
s << substBinding(BINDING_SampledImage,
"layout(set=0,binding=${?}) uniform texture2D ${VAR}[${*}];\n");
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
s << "#extension GL_EXT_texture_buffer : require \n";
s << substBinding(BINDING_CombinedImageSampler,
"layout(set=0,binding=${?}) uniform sampler2D data[];\n");
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
s << "layout(local_size_x=1,local_size_y=1,local_size_z=1) in; \n";
s << substBinding(BINDING_StorageImage + 1,
"layout(r32ui,set=0,binding=${?}) uniform uimage2D idxs; \n");
s << substBinding(BINDING_StorageImage,
"layout(r32ui,set=0,binding=${?}) uniform uimage2D data[]; \n");
break;
default:
TCU_THROW(InternalError, "Not implemented descriptor type");
}
switch (shaderType)
{
case VK_SHADER_STAGE_VERTEX_BIT: s << getVertexShaderProlog(); break;
case VK_SHADER_STAGE_FRAGMENT_BIT:
{
if (testCaseParams.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{
s << substBinding(BINDING_InputAttachment,
"layout(input_attachment_index=1,set=0,binding=${?}) uniform subpassInput data[]; \n");
}
s << getFragmentShaderProlog();
}
break;
case VK_SHADER_STAGE_COMPUTE_BIT:
break;
default:
TCU_THROW(InternalError, "Not implemented shader stage");
}
switch (shaderType)
{
case VK_SHADER_STAGE_VERTEX_BIT:
{
switch (testCaseParams.descriptorType)
{
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC