1 #ifndef _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP
2 #define _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
7 * Copyright (c) 2015 Google Inc.
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Compute Shader Based Test Case Utility Structs/Functions
24 *//*--------------------------------------------------------------------*/
27 #include "deFloat16.h"
28 #include "deRandom.hpp"
29 #include "deSharedPtr.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuVector.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vktSpvAsmUtils.hpp"
43 namespace SpirVAssembly
67 static void fillRandomScalars (de::Random& rnd, deInt32 minValue, deInt32 maxValue, deInt32* dst, deInt32 numValues)
69 for (int i = 0; i < numValues; i++)
70 dst[i] = rnd.getInt(minValue, maxValue);
73 typedef de::MovePtr<vk::Allocation> AllocationMp;
74 typedef de::SharedPtr<vk::Allocation> AllocationSp;
76 /*--------------------------------------------------------------------*//*!
77 * \brief Abstract class for an input/output storage buffer object
78 *//*--------------------------------------------------------------------*/
82 virtual ~BufferInterface (void) {}
84 virtual void getBytes (std::vector<deUint8>& bytes) const = 0;
85 virtual size_t getByteSize (void) const = 0;
88 typedef de::SharedPtr<BufferInterface> BufferSp;
90 /*--------------------------------------------------------------------*//*!
91 * \brief Concrete class for an input/output storage buffer object used for OpAtomic tests
92 *//*--------------------------------------------------------------------*/
93 class OpAtomicBuffer : public BufferInterface
96 OpAtomicBuffer (const deUint32 numInputElements, const deUint32 numOuptutElements, const OpAtomicType opAtomic, const BufferType type)
97 : m_numInputElements (numInputElements)
98 , m_numOutputElements (numOuptutElements)
99 , m_opAtomic (opAtomic)
103 void getBytes (std::vector<deUint8>& bytes) const
105 std::vector<deInt32> inputInts (m_numInputElements, 0);
106 de::Random rnd (m_opAtomic);
108 fillRandomScalars(rnd, 1, 100, &inputInts.front(), m_numInputElements);
110 // Return input values as is
111 if (m_type == BUFFERTYPE_INPUT)
113 size_t inputSize = m_numInputElements * sizeof(deInt32);
115 bytes.resize(inputSize);
116 deMemcpy(&bytes.front(), &inputInts.front(), inputSize);
118 // Calculate expected output values
119 else if (m_type == BUFFERTYPE_EXPECTED)
121 size_t outputSize = m_numOutputElements * sizeof(deInt32);
122 bytes.resize(outputSize, 0xffu);
124 for (size_t ndx = 0; ndx < m_numInputElements; ndx++)
126 deInt32* const bytesAsInt = reinterpret_cast<deInt32* const>(&bytes.front());
130 case OPATOMIC_IADD: bytesAsInt[0] += inputInts[ndx]; break;
131 case OPATOMIC_ISUB: bytesAsInt[0] -= inputInts[ndx]; break;
132 case OPATOMIC_IINC: bytesAsInt[0]++; break;
133 case OPATOMIC_IDEC: bytesAsInt[0]--; break;
134 case OPATOMIC_LOAD: bytesAsInt[ndx] = inputInts[ndx]; break;
135 case OPATOMIC_STORE: bytesAsInt[ndx] = inputInts[ndx]; break;
136 case OPATOMIC_COMPEX: bytesAsInt[ndx] = (inputInts[ndx] % 2) == 0 ? -1 : 1; break;
137 default: DE_FATAL("Unknown OpAtomic type");
142 DE_FATAL("Unknown buffer type");
145 size_t getByteSize (void) const
149 case BUFFERTYPE_INPUT:
150 return m_numInputElements * sizeof(deInt32);
151 case BUFFERTYPE_EXPECTED:
152 return m_numOutputElements * sizeof(deInt32);
154 DE_FATAL("Unknown buffer type");
160 const deUint32 m_numInputElements;
161 const deUint32 m_numOutputElements;
162 const OpAtomicType m_opAtomic;
163 const BufferType m_type;
166 /*--------------------------------------------------------------------*//*!
167 * \brief Concrete class for an input/output storage buffer object
168 *//*--------------------------------------------------------------------*/
170 class Buffer : public BufferInterface
173 Buffer (const std::vector<E>& elements)
174 : m_elements(elements)
177 void getBytes (std::vector<deUint8>& bytes) const
179 const size_t size = m_elements.size() * sizeof(E);
181 deMemcpy(&bytes.front(), &m_elements.front(), size);
184 size_t getByteSize (void) const
186 return m_elements.size() * sizeof(E);
190 std::vector<E> m_elements;
193 DE_STATIC_ASSERT(sizeof(tcu::Vec4) == 4 * sizeof(float));
195 typedef Buffer<float> Float32Buffer;
196 typedef Buffer<deFloat16> Float16Buffer;
197 typedef Buffer<deInt64> Int64Buffer;
198 typedef Buffer<deInt32> Int32Buffer;
199 typedef Buffer<deInt16> Int16Buffer;
200 typedef Buffer<tcu::Vec4> Vec4Buffer;
202 typedef bool (*ComputeVerifyIOFunc) (const std::vector<BufferSp>& inputs,
203 const std::vector<AllocationSp>& outputAllocations,
204 const std::vector<BufferSp>& expectedOutputs,
207 typedef bool (*ComputeVerifyBinaryFunc) (const ProgramBinary& binary);
209 /*--------------------------------------------------------------------*//*!
210 * \brief Specification for a compute shader.
212 * This struct bundles SPIR-V assembly code, input and expected output
214 *//*--------------------------------------------------------------------*/
215 struct ComputeShaderSpec
217 std::string assembly;
218 std::string entryPoint;
219 std::vector<BufferSp> inputs;
220 // Mapping from input index (in the inputs field) to the descriptor type.
221 std::map<deUint32, VkDescriptorType> inputTypes;
222 std::vector<BufferSp> outputs;
223 tcu::IVec3 numWorkGroups;
224 std::vector<deUint32> specConstants;
225 BufferSp pushConstants;
226 std::vector<std::string> extensions;
227 VulkanFeatures requestedVulkanFeatures;
228 qpTestResult failResult;
229 std::string failMessage;
230 // If null, a default verification will be performed by comparing the memory pointed to by outputAllocations
231 // and the contents of expectedOutputs. Otherwise the function pointed to by verifyIO will be called.
232 // If true is returned, then the test case is assumed to have passed, if false is returned, then the test
233 // case is assumed to have failed. Exact meaning of failure can be customized with failResult.
234 ComputeVerifyIOFunc verifyIO;
235 ComputeVerifyBinaryFunc verifyBinary;
236 SpirvVersion spirvVersion;
238 ComputeShaderSpec (void)
239 : entryPoint ("main")
240 , pushConstants (DE_NULL)
241 , requestedVulkanFeatures ()
242 , failResult (QP_TEST_RESULT_FAIL)
243 , failMessage ("Output doesn't match with expected")
245 , verifyBinary (DE_NULL)
246 , spirvVersion (SPIRV_VERSION_1_0)
250 /*--------------------------------------------------------------------*//*!
251 * \brief Helper functions for SPIR-V assembly shared by various tests
252 *//*--------------------------------------------------------------------*/
254 const char* getComputeAsmShaderPreamble (void);
255 std::string getComputeAsmCommonTypes (std::string blockStorageClass = "Uniform");
256 const char* getComputeAsmCommonInt64Types (void);
258 /*--------------------------------------------------------------------*//*!
259 * Declares two uniform variables (indata, outdata) of type
260 * "struct { float[] }". Depends on type "f32arr" (for "float[]").
261 *//*--------------------------------------------------------------------*/
262 const char* getComputeAsmInputOutputBuffer (void);
263 /*--------------------------------------------------------------------*//*!
264 * Declares buffer type and layout for uniform variables indata and
265 * outdata. Both of them are SSBO bounded to descriptor set 0.
266 * indata is at binding point 0, while outdata is at 1.
267 *//*--------------------------------------------------------------------*/
268 const char* getComputeAsmInputOutputBufferTraits (void);
273 #endif // _VKTSPVASMCOMPUTESHADERTESTUTIL_HPP