Skip to content

Commit

Permalink
Refactor: Compatible compute and graphics VerifyIO
Browse files Browse the repository at this point in the history
Refactoring:
 * Compatibilize VerifyIO function declaration
 * Add isCoreFeatureSupported
 * Graphic shader can run over whole area

Affects tests:
 * dEQP-VK.spirv_assembly.*

Components: Vulkan

VK-GL-CTS issue: 1095

Change-Id: Iba9bab9d40a06f1eba90572cc60f1c334c4b8474
  • Loading branch information
Boris Zanin authored and alegal-arm committed Aug 23, 2018
1 parent 0aa95f4 commit 9a41fa4
Show file tree
Hide file tree
Showing 18 changed files with 732 additions and 661 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "deSharedPtr.hpp"
#include "deSTLUtil.hpp"

#include "vktSpvAsmUtils.hpp"

#include "vkBuilderUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
Expand Down Expand Up @@ -292,27 +294,32 @@ Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkdi, const Vk
/*--------------------------------------------------------------------*//*!
* \brief Create a compute pipeline based on the given shader
*//*--------------------------------------------------------------------*/
Move<VkPipeline> createComputePipeline (const DeviceInterface& vkdi, const VkDevice& device, VkPipelineLayout pipelineLayout, VkShaderModule shader, const char* entryPoint, const vector<deUint32>& specConstants)
Move<VkPipeline> createComputePipeline (const DeviceInterface& vkdi, const VkDevice& device, VkPipelineLayout pipelineLayout, VkShaderModule shader, const char* entryPoint, const vkt::SpirVAssembly::SpecConstants& specConstants)
{
const deUint32 numSpecConstants = (deUint32)specConstants.size();
const deUint32 numSpecConstants = (deUint32)specConstants.getValuesCount();
vector<VkSpecializationMapEntry> entries;
VkSpecializationInfo specInfo;
size_t offset = 0;

if (numSpecConstants != 0)
{
entries.resize(numSpecConstants);

for (deUint32 ndx = 0; ndx < numSpecConstants; ++ndx)
{
const size_t valueSize = specConstants.getValueSize(ndx);

entries[ndx].constantID = ndx;
entries[ndx].offset = ndx * (deUint32)sizeof(deUint32);
entries[ndx].size = sizeof(deUint32);
entries[ndx].offset = static_cast<deUint32>(offset);
entries[ndx].size = valueSize;

offset += valueSize;
}

specInfo.mapEntryCount = numSpecConstants;
specInfo.pMapEntries = &entries[0];
specInfo.dataSize = numSpecConstants * sizeof(deUint32);
specInfo.pData = specConstants.data();
specInfo.pData = specConstants.getValuesBuffer();
}

const VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo =
Expand Down Expand Up @@ -432,6 +439,15 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
TCU_THROW(NotSupportedError, "shaderFloat64 feature is not supported");
}

// Core features
{
const char* unsupportedFeature = DE_NULL;

if (!isCoreFeaturesSupported(m_context, m_shaderSpec.requestedVulkanFeatures.coreFeatures, &unsupportedFeature))
TCU_THROW(NotSupportedError, std::string("At least following requested core feature is not supported: ") + unsupportedFeature);
}

// Extension features
{
// 8bit storage features
{
Expand Down Expand Up @@ -463,12 +479,7 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)

for (deUint32 inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
{
if (m_shaderSpec.inputTypes.count(inputNdx) != 0)
descriptorTypes.push_back(m_shaderSpec.inputTypes.at(inputNdx));
else
descriptorTypes.push_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);

const VkDescriptorType descType = descriptorTypes[inputNdx];
const VkDescriptorType descType = m_shaderSpec.inputs[inputNdx].getDescriptorType();

const bool hasImage = (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
(descType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
Expand All @@ -478,10 +489,12 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
(descType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
(descType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

descriptorTypes.push_back(descType);

// Buffer
if (!hasImage && !hasSampler)
{
const BufferSp& input = m_shaderSpec.inputs[inputNdx];
const BufferSp& input = m_shaderSpec.inputs[inputNdx].getBuffer();
vector<deUint8> inputBytes;

input->getBytes(inputBytes);
Expand All @@ -498,7 +511,7 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
// Image
else if (hasImage)
{
const BufferSp& input = m_shaderSpec.inputs[inputNdx];
const BufferSp& input = m_shaderSpec.inputs[inputNdx].getBuffer();
vector<deUint8> inputBytes;

input->getBytes(inputBytes);
Expand Down Expand Up @@ -678,10 +691,12 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)

for (deUint32 outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
{
descriptorTypes.push_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
DE_ASSERT(m_shaderSpec.outputs[outputNdx].getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);

descriptorTypes.push_back(m_shaderSpec.outputs[outputNdx].getDescriptorType());

AllocationMp alloc;
const BufferSp& output = m_shaderSpec.outputs[outputNdx];
const BufferSp& output = m_shaderSpec.outputs[outputNdx].getBuffer();
vector<deUint8> outputBytes;

output->getBytes(outputBytes);
Expand Down Expand Up @@ -738,7 +753,7 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
// Invalidate output memory ranges before checking on host.
for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
{
invalidateMemory(vkdi, device, outputAllocs[outputNdx].get(), m_shaderSpec.outputs[outputNdx]->getByteSize(), m_shaderSpec.coherentMemory);
invalidateMemory(vkdi, device, outputAllocs[outputNdx].get(), m_shaderSpec.outputs[outputNdx].getByteSize(), m_shaderSpec.coherentMemory);
}

// Check output.
Expand All @@ -751,7 +766,7 @@ tcu::TestStatus SpvAsmComputeShaderInstance::iterate (void)
{
for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
{
const BufferSp& expectedOutput = m_shaderSpec.outputs[outputNdx];
const BufferSp& expectedOutput = m_shaderSpec.outputs[outputNdx].getBuffer();;
vector<deUint8> expectedBytes;

expectedOutput->getBytes(expectedBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ namespace SpirVAssembly
{
namespace
{
bool verifyOutputWithEpsilon (const std::vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, tcu::TestLog& log, const float epsilon)
bool verifyOutputWithEpsilon (const std::vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, tcu::TestLog& log, const float epsilon)
{
DE_ASSERT(outputAllocs.size() != 0);
DE_ASSERT(outputAllocs.size() == expectedOutputs.size());

for (size_t outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
{
std::vector<deUint8> expectedBytes;
expectedOutputs[outputNdx]->getBytes(expectedBytes);
expectedOutputs[outputNdx].getBytes(expectedBytes);

std::vector<float> expectedFloats (expectedBytes.size() / sizeof (float));
std::vector<float> actualFloats (expectedBytes.size() / sizeof (float));
Expand Down Expand Up @@ -123,7 +123,7 @@ const char* getComputeAsmInputOutputBufferTraits (void)
"OpMemberDecorate %buf 0 Offset 0\n";
}

bool verifyOutput (const std::vector<BufferSp>&, const std::vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, tcu::TestLog& log)
bool verifyOutput (const std::vector<Resource>&, const std::vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, tcu::TestLog& log)
{
const float epsilon = 0.001f;
return verifyOutputWithEpsilon(outputAllocs, expectedOutputs, log, epsilon);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "deDefs.h"
#include "deFloat16.h"
#include "deRandom.hpp"
#include "deSharedPtr.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
Expand Down Expand Up @@ -72,23 +71,6 @@ static void fillRandomScalars (de::Random& rnd, deInt32 minValue, deInt32 maxVal
dst[i] = rnd.getInt(minValue, maxValue);
}

typedef de::MovePtr<vk::Allocation> AllocationMp;
typedef de::SharedPtr<vk::Allocation> AllocationSp;

/*--------------------------------------------------------------------*//*!
* \brief Abstract class for an input/output storage buffer object
*//*--------------------------------------------------------------------*/
class BufferInterface
{
public:
virtual ~BufferInterface (void) {}

virtual void getBytes (std::vector<deUint8>& bytes) const = 0;
virtual size_t getByteSize (void) const = 0;
};

typedef de::SharedPtr<BufferInterface> BufferSp;

/*--------------------------------------------------------------------*//*!
* \brief Concrete class for an input/output storage buffer object used for OpAtomic tests
*//*--------------------------------------------------------------------*/
Expand Down Expand Up @@ -171,7 +153,7 @@ class OpAtomicBuffer : public BufferInterface
}

template <int OpAtomic>
static bool compareWithRetvals (const std::vector<BufferSp>& inputs, const std::vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, tcu::TestLog& log)
static bool compareWithRetvals (const std::vector<Resource>& inputs, const std::vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, tcu::TestLog& log)
{
if (outputAllocs.size() != 2 || inputs.size() != 1)
DE_FATAL("Wrong number of buffers to compare");
Expand All @@ -184,7 +166,7 @@ class OpAtomicBuffer : public BufferInterface
{
// BUFFERTYPE_ATOMIC_RET for arithmetic operations must be verified manually by matching return values to inputs
std::vector<deUint8> inputBytes;
inputs[0]->getBytes(inputBytes);
inputs[0].getBytes(inputBytes);

const deUint32* inputValues = reinterpret_cast<deUint32*>(&inputBytes.front());
const size_t inputValuesCount = inputBytes.size() / sizeof(deUint32);
Expand All @@ -200,7 +182,7 @@ class OpAtomicBuffer : public BufferInterface
}
else
{
const BufferSp& expectedOutput = expectedOutputs[i];
const BufferSp& expectedOutput = expectedOutputs[i].getBuffer();
std::vector<deUint8> expectedBytes;

expectedOutput->getBytes(expectedBytes);
Expand Down Expand Up @@ -309,11 +291,6 @@ typedef Buffer<deUint32> Uint32Buffer;
typedef Buffer<deUint64> Uint64Buffer;
typedef Buffer<tcu::Vec4> Vec4Buffer;

typedef bool (*ComputeVerifyIOFunc) (const std::vector<BufferSp>& inputs,
const std::vector<AllocationSp>& outputAllocations,
const std::vector<BufferSp>& expectedOutputs,
tcu::TestLog& log);

typedef bool (*ComputeVerifyBinaryFunc) (const ProgramBinary& binary);

/*--------------------------------------------------------------------*//*!
Expand All @@ -326,12 +303,10 @@ struct ComputeShaderSpec
{
std::string assembly;
std::string entryPoint;
std::vector<BufferSp> inputs;
// Mapping from input index (in the inputs field) to the descriptor type.
std::map<deUint32, VkDescriptorType> inputTypes;
std::vector<BufferSp> outputs;
std::vector<Resource> inputs;
std::vector<Resource> outputs;
tcu::IVec3 numWorkGroups;
std::vector<deUint32> specConstants;
SpecConstants specConstants;
BufferSp pushConstants;
std::vector<std::string> extensions;
VulkanFeatures requestedVulkanFeatures;
Expand All @@ -341,7 +316,7 @@ struct ComputeShaderSpec
// and the contents of expectedOutputs. Otherwise the function pointed to by verifyIO will be called.
// If true is returned, then the test case is assumed to have passed, if false is returned, then the test
// case is assumed to have failed. Exact meaning of failure can be customized with failResult.
ComputeVerifyIOFunc verifyIO;
VerifyIOFunc verifyIO;
ComputeVerifyBinaryFunc verifyBinary;
SpirvVersion spirvVersion;
bool coherentMemory;
Expand Down Expand Up @@ -380,11 +355,15 @@ const char* getComputeAsmInputOutputBuffer (void);
*//*--------------------------------------------------------------------*/
const char* getComputeAsmInputOutputBufferTraits (void);

bool verifyOutput (const std::vector<BufferSp>&,
const std::vector<AllocationSp>& outputAllocs,
const std::vector<BufferSp>& expectedOutputs,
bool verifyOutput (const std::vector<Resource>&,
const std::vector<AllocationSp>& outputAllocs,
const std::vector<Resource>& expectedOutputs,
tcu::TestLog& log);

// Creates vertex-shader assembly by specializing a boilerplate StringTemplate

std::string makeComputeShaderAssembly(const std::map<std::string, std::string>& fragments);

} // SpirVAssembly
} // vkt

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void addComputeSameLabelsTest (tcu::TestCaseGroup* group)
spec.assembly = shaderSource.specialize(specs);
spec.numWorkGroups = IVec3(numItems, 1, 1);

spec.outputs.push_back(BufferSp(new Buffer<deUint32>(outputData)));
spec.outputs.push_back(Resource(BufferSp(new Buffer<deUint32>(outputData))));

group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), "Tests both labels pointing to a same branch.", spec));
}
Expand All @@ -136,7 +136,7 @@ void addGraphicsSameLabelsTest (tcu::TestCaseGroup* group)
for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
outputData.push_back(numIdx);

resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Buffer<deUint32>(outputData))));
resources.outputs.push_back(Resource(BufferSp(new Buffer<deUint32>(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));

getDefaultColors(defaultColors);

Expand Down
Loading

0 comments on commit 9a41fa4

Please sign in to comment.