blob: 8e995bf4300fb3c56de17ba2376d39a95ec0c177 [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 varying names.
*//*--------------------------------------------------------------------*/
#include "vktSpvAsmVaryingNameTests.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::RGBA;
namespace
{
struct TestParams
{
string name;
FunctionPrograms1<InstanceContext>::Function createShaders;
};
void createShaders (SourceCollections& dst, InstanceContext& context, string dataNameVertShader, string dataNameFragShader)
{
SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
const deUint32 vulkanVersion = dst.usedVulkanVersion;
const string opNameVert = dataNameVertShader.empty() ? "" : string(" OpName %dataOut \"") + dataNameVertShader + "\"\n";
const string opNameFrag = dataNameFragShader.empty() ? "" : string(" OpName %dataIn \"") + dataNameFragShader + "\"\n";
// A float data of 1.0 is passed from vertex shader to fragment shader. This test checks the
// mapping between shaders is based on location index and not using the name of the varying.
// Variations of this test include same OpName in both shader, different OpNames and no
// OpNames at all.
const string vertexShader = string(
" OpCapability Shader\n"
" %1 = OpExtInstImport \"GLSL.std.450\"\n"
" OpMemoryModel Logical GLSL450\n"
" OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %dataOut\n"
" OpSource GLSL 450\n"
" OpName %main \"main\"\n"
" OpName %gl_PerVertex \"gl_PerVertex\"\n"
" OpMemberName %gl_PerVertex 0 \"gl_Position\"\n"
" OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n"
" OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n"
" OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n"
" OpName %_ \"\"\n"
" OpName %position \"position\"\n"
" OpName %vtxColor \"vtxColor\"\n"
" OpName %color \"color\"\n")
+ opNameVert +
" OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
" OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
" OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
" OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n"
" OpDecorate %gl_PerVertex Block\n"
" OpDecorate %position Location 0\n"
" OpDecorate %vtxColor Location 1\n"
" OpDecorate %color Location 1\n"
" OpDecorate %dataOut Location 0\n"
" %void = OpTypeVoid\n"
" %3 = OpTypeFunction %void\n"
" %float = OpTypeFloat 32\n"
" %v4float = OpTypeVector %float 4\n"
" %uint = OpTypeInt 32 0\n"
" %uint_1 = OpConstant %uint 1\n"
" %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
" %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n"
" %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
" %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
" %int = OpTypeInt 32 1\n"
" %int_0 = OpConstant %int 0\n"
" %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
" %position = OpVariable %_ptr_Input_v4float Input\n"
" %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
" %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
" %color = OpVariable %_ptr_Input_v4float Input\n"
" %_ptr_Output_float = OpTypePointer Output %float\n"
" %dataOut = OpVariable %_ptr_Output_float Output\n"
" %float_1 = OpConstant %float 1\n"
" %main = OpFunction %void None %3\n"
" %5 = OpLabel\n"
" %18 = OpLoad %v4float %position\n"
" %20 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
" OpStore %20 %18\n"
" %23 = OpLoad %v4float %color\n"
" OpStore %vtxColor %23\n"
" OpStore %dataOut %float_1\n"
" OpReturn\n"
" OpFunctionEnd\n";
const string fragmentShader = string(
" OpCapability Shader\n"
" %1 = OpExtInstImport \"GLSL.std.450\"\n"
" OpMemoryModel Logical GLSL450\n"
" OpEntryPoint Fragment %main \"main\" %dataIn %fragColor %vtxColor\n"
" OpExecutionMode %main OriginUpperLeft\n"
" OpSource GLSL 450\n"
" OpName %main \"main\"\n"
" OpName %Output \"Output\"\n"
" OpMemberName %Output 0 \"dataOut\"\n"
" OpName %dataOutput \"dataOutput\"\n")
+ opNameFrag +
" OpName %fragColor \"fragColor\"\n"
" OpName %vtxColor \"vtxColor\"\n"
" OpMemberDecorate %Output 0 Offset 0\n"
" OpDecorate %Output BufferBlock\n"
" OpDecorate %dataOutput DescriptorSet 0\n"
" OpDecorate %dataOutput Binding 0\n"
" OpDecorate %dataIn Location 0\n"
" OpDecorate %fragColor Location 0\n"
" OpDecorate %vtxColor Location 1\n"
" %void = OpTypeVoid\n"
" %3 = OpTypeFunction %void\n"
" %float = OpTypeFloat 32\n"
" %Output = OpTypeStruct %float\n"
" %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
" %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
" %int = OpTypeInt 32 1\n"
" %int_0 = OpConstant %int 0\n"
" %_ptr_Input_float = OpTypePointer Input %float\n"
" %dataIn = OpVariable %_ptr_Input_float Input\n"
" %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
" %v4float = OpTypeVector %float 4\n"
" %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
" %fragColor = OpVariable %_ptr_Output_v4float Output\n"
" %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
" %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
" %main = OpFunction %void None %3\n"
" %5 = OpLabel\n"
" %14 = OpLoad %float %dataIn\n"
" %16 = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0\n"
" OpStore %16 %14\n"
" %22 = OpLoad %v4float %vtxColor\n"
" OpStore %fragColor %22\n"
" OpReturn\n"
" OpFunctionEnd\n";
dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
}
void createShadersNamesMatch (vk::SourceCollections& dst, InstanceContext context)
{
createShaders(dst, context, "data", "data");
}
void createShadersNamesDiffer (vk::SourceCollections& dst, InstanceContext context)
{
createShaders(dst, context, "dataOut", "dataIn");
}
void createShadersNoNames (vk::SourceCollections& dst, InstanceContext context)
{
createShaders(dst, context, "", "");
}
void addGraphicsVaryingNameTest (tcu::TestCaseGroup* group, const TestParams& params)
{
map<string, string> fragments;
RGBA defaultColors[4];
SpecConstants noSpecConstants;
PushConstants noPushConstants;
GraphicsInterfaces noInterfaces;
vector<string> extensions;
VulkanFeatures features;
map<string, string> noFragments;
StageToSpecConstantMap specConstantMap;
GraphicsResources resources;
const vector<float> expectedOutput(1, 1.0f);
const ShaderElement pipelineStages[] =
{
ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
};
specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = noSpecConstants;
specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = noSpecConstants;
getDefaultColors(defaultColors);
features.coreFeatures.fragmentStoresAndAtomics = VK_TRUE;
extensions.push_back("VK_KHR_storage_buffer_storage_class");
resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
{
const InstanceContext& instanceContext = createInstanceContext(pipelineStages,
defaultColors,
defaultColors,
noFragments,
specConstantMap,
noPushConstants,
resources,
noInterfaces,
extensions,
features,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
QP_TEST_RESULT_FAIL,
string());
addFunctionCaseWithPrograms<InstanceContext>(group,
params.name.c_str(),
"",
params.createShaders,
runAndVerifyDefaultPipeline,
instanceContext);
}
}
} // anonymous
tcu::TestCaseGroup* createVaryingNameGraphicsGroup (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "varying_name", "Graphics tests for varying names."));
static const TestParams params[] =
{
{ "names_match", createShadersNamesMatch },
{ "names_differ", createShadersNamesDiffer },
{ "no_names", createShadersNoNames }
};
for (deUint32 paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
addGraphicsVaryingNameTest(group.get(), params[paramIdx]);
return group.release();
}
} // SpirVAssembly
} // vkt