blob: 0d34f2b94c6aec01c82c057b3a3534e42f715f40 [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 Google 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 SPIR-V Assembly tests for composite insert.
*//*--------------------------------------------------------------------*/
#include "vktSpvAsmCompositeInsertTests.hpp"
#include "vktSpvAsmComputeShaderCase.hpp"
#include "vktSpvAsmComputeShaderTestUtil.hpp"
#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
namespace vkt
{
namespace SpirVAssembly
{
using namespace vk;
using std::map;
using std::string;
using std::vector;
using tcu::IVec3;
using tcu::RGBA;
namespace
{
string getColType (deUint32 rows)
{
return string("%v") + de::toString(rows) + "f32";
}
string getMatrixType (deUint32 cols, deUint32 rows)
{
return string("%mat") + de::toString(cols) + "v" + de::toString(rows) + "f";
}
string getMatrixDeclarations (deUint32 cols, deUint32 rows, bool skipColDecl = false)
{
string colType = getColType(rows);
string colDecl = skipColDecl ? "" : string(" ") + colType + " = OpTypeVector %f32 " + de::toString(rows) + "\n";
string matType = getMatrixType(cols, rows);
string matDecl = string(" ") + matType + " = OpTypeMatrix " + colType + " " + de::toString(cols) + "\n";
string outputDecl = string(" %Output = OpTypeStruct ") + matType + "\n";
return colDecl + matDecl + outputDecl;
}
string getIdentityVectors (deUint32 cols, deUint32 rows)
{
string ret;
for (deUint32 c = 0; c < cols; c++)
{
string identity = " %identity" + de::toString(c) + " = OpConstantComposite " + getColType(rows) + " ";
for (deUint32 r = 0; r < rows; r++)
{
identity += string("%c_f32_") + (c == r ? "1" : "0") + " ";
}
identity += "\n";
ret += identity;
}
return ret;
}
string getVectorCompositeInserts (deUint32 elements)
{
string ret = " %tmp0 = OpLoad %v" + de::toString(elements) + "f32 %vec\n";
for (deUint32 e = 0; e < elements; e++)
ret += " %tmp" + de::toString(e + 1) + " = OpCompositeInsert %v" + de::toString(elements) + "f32 %c_f32_" + de::toString(e) + " %tmp" + de::toString(e) + " " + de::toString(e) + "\n";
return ret;
}
string getMatrixCompositeInserts (deUint32 cols, deUint32 rows)
{
string matType = getMatrixType(cols, rows);
string ret = " %tmp0 = OpLoad " + matType + " %mat\n";
for (deUint32 c = 0; c < cols; c++)
ret += " %tmp" + de::toString(c + 1) + " = OpCompositeInsert " + matType + " %identity" + de::toString(c) + " %tmp" + de::toString(c) + " " + de::toString(c) + "\n";
return ret;
}
bool verifyMatrixOutput (const std::vector<Resource>& inputs, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, tcu::TestLog& log)
{
DE_UNREF(inputs);
if (outputAllocs.size() != 1)
return false;
vector<deUint8> expectedBytes;
expectedOutputs[0].getBytes(expectedBytes);
const float* const expectedOutputAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
const float* const outputAsFloat = static_cast<const float*>(outputAllocs[0]->getHostPtr());
bool ret = true;
for (size_t idx = 0; idx < expectedBytes.size() / sizeof(float); ++idx)
{
if (outputAsFloat[idx] != expectedOutputAsFloat[idx] && expectedOutputAsFloat[idx] != -1.0f)
{
log << tcu::TestLog::Message << "ERROR: Result data at index " << idx << " failed. Expected: " << expectedOutputAsFloat[idx] << ", got: " << outputAsFloat[idx] << tcu::TestLog::EndMessage;
ret = false;
}
}
return ret;
}
string getNestedStructCompositeInserts (deUint32 arraySize)
{
string ret;
for (deUint32 arrayIdx = 0; arrayIdx < arraySize; arrayIdx++)
for (deUint32 vectorIdx = 0; vectorIdx < 4; vectorIdx++)
ret += string("%tmp") + de::toString(arrayIdx * 4 + vectorIdx + 1) + " = OpCompositeInsert %Output %identity" + de::toString(vectorIdx) + " %tmp" + de::toString(arrayIdx * 4 + vectorIdx) + " 0 0 " + de::toString(arrayIdx) + " " + de::toString(vectorIdx) + "\n";
return ret;
}
void addComputeVectorCompositeInsertTests (tcu::TestCaseGroup* group)
{
tcu::TestContext& testCtx = group->getTestContext();
for (deUint32 elements = 2; elements <= 4; elements++)
{
ComputeShaderSpec spec;
vector<float> refData;
const string vecType = string("%v") + de::toString(elements) + "f32";
// Generate a vector using OpCompositeInsert
const string shaderSource =
" OpCapability Shader\n"
" %1 = OpExtInstImport \"GLSL.std.450\"\n"
" OpMemoryModel Logical GLSL450\n"
" OpEntryPoint GLCompute %main \"main\"\n"
" OpExecutionMode %main LocalSize 1 1 1\n"
" OpSource GLSL 430\n"
" OpMemberDecorate %Output 0 Offset 0\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n"
" %f32 = OpTypeFloat 32\n"
" %v2f32 = OpTypeVector %f32 2\n"
" %v3f32 = OpTypeVector %f32 3\n"
" %v4f32 = OpTypeVector %f32 4\n"
" %Output = OpTypeStruct " + vecType + "\n"
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %_ptr_Function_vec = OpTypePointer Function " + vecType + "\n"
" %_ptr_Uniform_vec = OpTypePointer Uniform " + vecType + "\n"
" %c_f32_0 = OpConstant %f32 0\n"
" %c_f32_1 = OpConstant %f32 1\n"
" %c_f32_2 = OpConstant %f32 2\n"
" %c_f32_3 = OpConstant %f32 3\n"
" %i32 = OpTypeInt 32 1\n"
" %c_i32_0 = OpConstant %i32 0\n"
" %void = OpTypeVoid\n"
" %3 = OpTypeFunction %void\n"
" %main = OpFunction %void None %3\n"
" %entry = OpLabel\n"
" %vec = OpVariable %_ptr_Function_vec Function\n"
+ getVectorCompositeInserts(elements) +
" %vecOutPtr = OpAccessChain %_ptr_Uniform_vec %dataOutput %c_i32_0\n"
" OpStore %vecOutPtr %tmp" + de::toString(elements) + "\n"
" OpReturn\n"
" OpFunctionEnd\n";
spec.assembly = shaderSource;
spec.numWorkGroups = IVec3(1, 1, 1);
// Expect running counter
for (deUint32 e = 0; e < elements; e++)
refData.push_back((float)e);
spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(refData))));
string testName = string("vec") + de::toString(elements);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), "Tests vector composite insert.", spec));
}
}
void addGraphicsVectorCompositeInsertTests (tcu::TestCaseGroup* group)
{
for (deUint32 elements = 2; elements <= 4; elements++)
{
map<string, string> fragments;
RGBA defaultColors[4];
GraphicsResources resources;
SpecConstants noSpecConstants;
PushConstants noPushConstants;
GraphicsInterfaces noInterfaces;
vector<string> noExtensions;
VulkanFeatures vulkanFeatures = VulkanFeatures();
vector<float> refData;
const string testName = string("vec") + de::toString(elements);
const string vecType = string("%v") + de::toString(elements) + "f32";
// Expect running counter
for (deUint32 e = 0; e < elements; e++)
refData.push_back((float)e);
resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(refData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
getDefaultColors(defaultColors);
// Generate a vector using OpCompositeInsert
fragments["pre_main"] =
" %Output = OpTypeStruct " + vecType + "\n"
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %fp_v2f32 = OpTypePointer Function %v2f32\n"
" %fp_v3f32 = OpTypePointer Function %v3f32\n"
" %_ptr_Uniform_vec = OpTypePointer Uniform " + vecType + "\n"
" %c_f32_2 = OpConstant %f32 2\n"
" %c_f32_3 = OpConstant %f32 3\n";
fragments["decoration"] =
" OpMemberDecorate %Output 0 Offset 0\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n";
fragments["testfun"] =
" %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
" %param = OpFunctionParameter %v4f32\n"
" %entry = OpLabel\n"
" %vec = OpVariable %fp_v" + de::toString(elements) + "f32 Function\n"
+ getVectorCompositeInserts(elements) +
" %vecOutPtr = OpAccessChain %_ptr_Uniform_vec %dataOutput %c_i32_0\n"
" OpStore %vecOutPtr %tmp" + de::toString(elements) + "\n"
" OpReturnValue %param\n"
" OpFunctionEnd\n";
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_FALSE;
createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, (testName + "_vert").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, (testName + "_tessc").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, (testName + "_tesse").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, (testName + "_geom").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, (testName + "_frag").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
}
}
void addComputeMatrixCompositeInsertTests (tcu::TestCaseGroup* group)
{
tcu::TestContext& testCtx = group->getTestContext();
for (deUint32 rows = 2; rows <= 4; rows++)
{
const deUint32 matrixStride = rows == 3 ? 16 : rows * 4;
for (deUint32 cols = 2; cols <= 4; cols++)
{
ComputeShaderSpec spec;
vector<float> identityData;
string colType = getColType(rows);
string matType = getMatrixType(cols, rows);
// Generate a matrix using OpCompositeInsert with identity vectors and write the matrix into output storage buffer.
const string shaderSource =
" OpCapability Shader\n"
" %1 = OpExtInstImport \"GLSL.std.450\"\n"
" OpMemoryModel Logical GLSL450\n"
" OpEntryPoint GLCompute %main \"main\"\n"
" OpExecutionMode %main LocalSize 1 1 1\n"
" OpSource GLSL 430\n"
" OpMemberDecorate %Output 0 Offset 0\n"
" OpMemberDecorate %Output 0 ColMajor\n"
" OpMemberDecorate %Output 0 MatrixStride " + de::toString(matrixStride) + "\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n"
" %f32 = OpTypeFloat 32\n"
+ getMatrixDeclarations(cols, rows) +
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %_ptr_Function_mat = OpTypePointer Function " + matType + "\n"
" %_ptr_Uniform_mat = OpTypePointer Uniform " + matType + "\n"
" %c_f32_0 = OpConstant %f32 0\n"
" %c_f32_1 = OpConstant %f32 1\n"
" %i32 = OpTypeInt 32 1\n"
" %c_i32_0 = OpConstant %i32 0\n"
+ getIdentityVectors(cols, rows) +
" %void = OpTypeVoid\n"
" %3 = OpTypeFunction %void\n"
" %main = OpFunction %void None %3\n"
" %entry = OpLabel\n"
" %mat = OpVariable %_ptr_Function_mat Function\n"
+ getMatrixCompositeInserts(cols, rows) +
" %matOutPtr = OpAccessChain %_ptr_Uniform_mat %dataOutput %c_i32_0\n"
" OpStore %matOutPtr %tmp" + de::toString(cols) + "\n"
" OpReturn\n"
" OpFunctionEnd\n";
spec.assembly = shaderSource;
spec.numWorkGroups = IVec3(1, 1, 1);
// Expect identity matrix as output
for (deUint32 c = 0; c < cols; c++)
{
for (deUint32 r = 0; r < rows; r++)
identityData.push_back(c == r ? 1.0f : 0.0f);
if (rows == 3)
identityData.push_back(-1.0f); // Padding
}
spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(identityData))));
spec.verifyIO = verifyMatrixOutput;
string testName = string("mat") + de::toString(cols) + "x" + de::toString(rows);
group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), "Tests matrix composite insert.", spec));
}
}
}
void addGraphicsMatrixCompositeInsertTests (tcu::TestCaseGroup* group)
{
for (deUint32 rows = 2; rows <= 4; rows++)
{
const deUint32 matrixStride = rows == 3 ? 16 : rows * 4;
for (deUint32 cols = 2; cols <= 4; cols++)
{
map<string, string> fragments;
RGBA defaultColors[4];
GraphicsResources resources;
SpecConstants noSpecConstants;
PushConstants noPushConstants;
GraphicsInterfaces noInterfaces;
vector<string> noExtensions;
VulkanFeatures vulkanFeatures = VulkanFeatures();
vector<float> identityData;
string testName = string("mat") + de::toString(cols) + "x" + de::toString(rows);
string matType = getMatrixType(cols, rows);
// Expect identity matrix as output
for (deUint32 c = 0; c < cols; c++)
{
for (deUint32 r = 0; r < rows; r++)
identityData.push_back(c == r ? 1.0f : 0.0f);
if (rows == 3)
identityData.push_back(-1.0f); // Padding
}
resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(identityData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
resources.verifyIO = verifyMatrixOutput;
getDefaultColors(defaultColors);
// Generate a matrix using OpCompositeInsert with identity vectors and write the matrix into output storage buffer.
fragments["pre_main"] =
getMatrixDeclarations(cols, rows, true) +
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %_ptr_Function_mat = OpTypePointer Function " + matType + "\n"
" %_ptr_Uniform_mat = OpTypePointer Uniform " + matType + "\n"
+ getIdentityVectors(cols, rows);
fragments["decoration"] =
" OpMemberDecorate %Output 0 Offset 0\n"
" OpMemberDecorate %Output 0 ColMajor\n"
" OpMemberDecorate %Output 0 MatrixStride " + de::toString(matrixStride) + "\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n";
fragments["testfun"] =
" %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
" %param = OpFunctionParameter %v4f32\n"
" %entry = OpLabel\n"
" %mat = OpVariable %_ptr_Function_mat Function\n"
+ getMatrixCompositeInserts(cols, rows) +
" %matOutPtr = OpAccessChain %_ptr_Uniform_mat %dataOutput %c_i32_0\n"
" OpStore %matOutPtr %tmp" + de::toString(cols) + "\n"
" OpReturnValue %param\n"
" OpFunctionEnd\n";
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_FALSE;
createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, (testName + "_vert").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, (testName + "_tessc").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, (testName + "_tesse").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, (testName + "_geom").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, (testName + "_frag").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
}
}
}
void addComputeNestedStructCompositeInsertTests (tcu::TestCaseGroup* group)
{
tcu::TestContext& testCtx = group->getTestContext();
ComputeShaderSpec spec;
vector<float> identityData;
const deUint32 arraySize = 8u;
const string shaderSource =
" OpCapability Shader\n"
" %1 = OpExtInstImport \"GLSL.std.450\"\n"
" OpMemoryModel Logical GLSL450\n"
" OpEntryPoint GLCompute %main \"main\"\n"
" OpExecutionMode %main LocalSize 1 1 1\n"
" OpSource GLSL 430\n"
" OpDecorate %_arr_mat4v4f32_uint_8 ArrayStride 64\n"
" OpMemberDecorate %S 0 ColMajor\n"
" OpMemberDecorate %S 0 Offset 0\n"
" OpMemberDecorate %S 0 MatrixStride 16\n"
" OpMemberDecorate %Output 0 Offset 0\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n"
" %f32 = OpTypeFloat 32\n"
" %v4f32 = OpTypeVector %f32 4\n"
" %mat4v4f32 = OpTypeMatrix %v4f32 4\n"
" %uint = OpTypeInt 32 0\n"
" %uint_8 = OpConstant %uint 8\n"
"%_arr_mat4v4f32_uint_8 = OpTypeArray %mat4v4f32 %uint_8\n"
" %S = OpTypeStruct %_arr_mat4v4f32_uint_8\n"
" %Output = OpTypeStruct %S\n"
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %_ptr_Function_Output = OpTypePointer Function %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %c_f32_0 = OpConstant %f32 0\n"
" %c_f32_1 = OpConstant %f32 1\n"
" %i32 = OpTypeInt 32 1\n"
" %c_i32_0 = OpConstant %i32 0\n"
+ getIdentityVectors(4, 4) +
" %void = OpTypeVoid\n"
" %3 = OpTypeFunction %void\n"
" %main = OpFunction %void None %3\n"
" %entry = OpLabel\n"
" %nestedstruct = OpVariable %_ptr_Function_Output Function\n"
" %tmp0 = OpLoad %Output %nestedstruct\n"
+ getNestedStructCompositeInserts(arraySize) +
" OpStore %dataOutput %tmp" + de::toString(arraySize * 4) + "\n"
" OpReturn\n"
" OpFunctionEnd\n";
spec.assembly = shaderSource;
spec.numWorkGroups = IVec3(1, 1, 1);
// Expect an array of identity matrix as output
for (deUint32 a = 0; a < arraySize; a++)
for (deUint32 c = 0; c < 4; c++)
for (deUint32 r = 0; r < 4; r++)
identityData.push_back(c == r ? 1.0f : 0.0f);
spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(identityData))));
group->addChild(new SpvAsmComputeShaderCase(testCtx, "nested_struct", "Tests nested struct composite insert.", spec));
}
void addGraphicsNestedStructCompositeInsertTests (tcu::TestCaseGroup* group)
{
map<string, string> fragments;
RGBA defaultColors[4];
GraphicsResources resources;
SpecConstants noSpecConstants;
PushConstants noPushConstants;
GraphicsInterfaces noInterfaces;
vector<string> noExtensions;
VulkanFeatures vulkanFeatures = VulkanFeatures();
vector<float> identityData;
const deUint32 arraySize = 8u;
const string testName = "nested_struct";
// Expect an array of identity matrix as output
for (deUint32 a = 0; a < arraySize; a++)
for (deUint32 c = 0; c < 4; c++)
for (deUint32 r = 0; r < 4; r++)
identityData.push_back(c == r ? 1.0f : 0.0f);
resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(identityData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
getDefaultColors(defaultColors);
fragments["pre_main"] =
" %uint_8 = OpConstant %u32 8\n"
" %mat4v4f32 = OpTypeMatrix %v4f32 4\n"
"%_arr_mat4v4f32_uint_8 = OpTypeArray %mat4v4f32 %uint_8\n"
" %S = OpTypeStruct %_arr_mat4v4f32_uint_8\n"
" %Output = OpTypeStruct %S\n"
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %_ptr_Function_Output = OpTypePointer Function %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
+ getIdentityVectors(4, 4);
fragments["decoration"] =
" OpDecorate %_arr_mat4v4f32_uint_8 ArrayStride 64\n"
" OpMemberDecorate %S 0 ColMajor\n"
" OpMemberDecorate %S 0 Offset 0\n"
" OpMemberDecorate %S 0 MatrixStride 16\n"
" OpMemberDecorate %Output 0 Offset 0\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n";
fragments["testfun"] =
" %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
" %param = OpFunctionParameter %v4f32\n"
" %entry = OpLabel\n"
" %nestedstruct = OpVariable %_ptr_Function_Output Function\n"
" %tmp0 = OpLoad %Output %nestedstruct\n"
+ getNestedStructCompositeInserts(arraySize) +
" OpStore %dataOutput %tmp" + de::toString(arraySize * 4) + "\n"
" OpReturnValue %param\n"
" OpFunctionEnd\n";
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_FALSE;
createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, (testName + "_vert").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, (testName + "_tessc").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, (testName + "_tesse").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, (testName + "_geom").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, (testName + "_frag").c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
noPushConstants, resources, noInterfaces, noExtensions, vulkanFeatures, group);
}
} // anonymous
tcu::TestCaseGroup* createCompositeInsertComputeGroup (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "composite_insert", "Compute tests for composite insert."));
addComputeVectorCompositeInsertTests(group.get());
addComputeMatrixCompositeInsertTests(group.get());
addComputeNestedStructCompositeInsertTests(group.get());
return group.release();
}
tcu::TestCaseGroup* createCompositeInsertGraphicsGroup (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "composite_insert", "Graphics tests for composite insert."));
addGraphicsVectorCompositeInsertTests(group.get());
addGraphicsMatrixCompositeInsertTests(group.get());
addGraphicsNestedStructCompositeInsertTests(group.get());
return group.release();
}
} // SpirVAssembly
} // vkt