return group.release();
}
-
// Assembly code used for testing OpUnreachable is based on GLSL source code:
//
// #version 430
cases.push_back(SpecConstantTwoIntCase("logicalnot", "False %bool", "False %bool", "%bool", "LogicalNot %sc_0", 1, 0, selectFalseUsingSc, outputInts2));
cases.push_back(SpecConstantTwoIntCase("select", "False %bool", " %i32 0", "%i32", "Select %sc_0 %sc_1 %zero", 1, 42, addScToInput, outputInts1));
// OpSConvert, OpFConvert: these two instructions involve ints/floats of different bitwidths.
- // \todo[2015-12-1 antiagainst] OpQuantizeToF16
for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
{
return group.release();
}
-
tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opphi", "Test the OpPhi instruction"));
return group.release();
}
-
typedef std::pair<std::string, VkShaderStageFlagBits> EntryToStage;
typedef map<string, vector<EntryToStage> > ModuleMap;
+typedef map<VkShaderStageFlagBits, vector<deInt32> > StageToSpecConstantMap;
// Context for a specific test instantiation. For example, an instantiation
// may test colors yellow/magenta/cyan/mauve in a tesselation shader
RGBA outputColors[4];
// Concrete SPIR-V code to test via boilerplate specialization.
map<string, string> testCodeFragments;
+ StageToSpecConstantMap specConstants;
bool hasTessellation;
- InstanceContext (const RGBA (&inputs)[4], const RGBA (&outputs)[4], const map<string, string>& testCodeFragments_)
- : testCodeFragments (testCodeFragments_)
- , hasTessellation(false)
+ InstanceContext (const RGBA (&inputs)[4], const RGBA (&outputs)[4], const map<string, string>& testCodeFragments_, const StageToSpecConstantMap& specConstants_)
+ : testCodeFragments (testCodeFragments_)
+ , specConstants (specConstants_)
+ , hasTessellation (false)
{
inputColors[0] = inputs[0];
inputColors[1] = inputs[1];
InstanceContext (const InstanceContext& other)
: moduleMap (other.moduleMap)
, testCodeFragments (other.testCodeFragments)
- , hasTessellation(other.hasTessellation)
+ , specConstants (other.specConstants)
+ , hasTessellation (other.hasTessellation)
{
inputColors[0] = other.inputColors[0];
inputColors[1] = other.inputColors[1];
// by setting up the mapping of modules to their contained shaders and stages.
// The inputs and expected outputs are given by inputColors and outputColors
template<size_t N>
-InstanceContext createInstanceContext (const ShaderElement (&elements)[N], const RGBA (&inputColors)[4], const RGBA (&outputColors)[4], const map<string, string>& testCodeFragments)
+InstanceContext createInstanceContext (const ShaderElement (&elements)[N], const RGBA (&inputColors)[4], const RGBA (&outputColors)[4], const map<string, string>& testCodeFragments, const StageToSpecConstantMap& specConstants)
{
- InstanceContext ctx (inputColors, outputColors, testCodeFragments);
+ InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants);
for (size_t i = 0; i < N; ++i)
{
ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage));
return ctx;
}
+template<size_t N>
+inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N], const RGBA (&inputColors)[4], const RGBA (&outputColors)[4], const map<string, string>& testCodeFragments)
+{
+ return createInstanceContext(elements, inputColors, outputColors, testCodeFragments, StageToSpecConstantMap());
+}
+
// The same as createInstanceContext above, but with default colors.
template<size_t N>
InstanceContext createInstanceContext (const ShaderElement (&elements)[N], const map<string, string>& testCodeFragments)
for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
{
const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
-
modules.push_back(ModuleHandleSp(mod));
-
for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
{
const EntryToStage& stage = *shaderNdx;
stage.first.c_str(), // const char* pName;
(const VkSpecializationInfo*)DE_NULL,
};
-
createInfos.push_back(shaderParam);
}
}
"%fp_i32 = OpTypePointer Function %i32\n" \
"%fp_v4f32 = OpTypePointer Function %v4f32\n"
-
#define SPIRV_ASSEMBLY_CONSTANTS \
"%c_f32_1 = OpConstant %f32 1.0\n" \
"%c_f32_0 = OpConstant %f32 0.0\n" \
"%c_u32_3 = OpConstant %u32 3\n" \
"%c_u32_32 = OpConstant %u32 32\n" \
"%c_u32_4 = OpConstant %u32 4\n" \
+ "%c_u32_31_bits = OpConstant %u32 0x7FFFFFFF\n" \
"%c_v4f32_1_1_1_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n" \
+ "%c_v4f32_1_0_0_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_1\n" \
"%c_v4f32_0_5_0_5_0_5_0_5 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5\n"
#define SPIRV_ASSEMBLY_ARRAYS \
"OpName %BP_Position \"position\"\n"
"OpName %BP_vtxColor \"vtxColor\"\n"
"OpName %BP_color \"color\"\n"
- "OpName %vertex_id \"gl_VertexID\"\n"
- "OpName %instance_id \"gl_InstanceID\"\n"
+ "OpName %BP_vertex_id \"gl_VertexID\"\n"
+ "OpName %BP_instance_id \"gl_InstanceID\"\n"
"OpName %test_code \"testfun(vf4;\"\n"
"OpDecorate %BP_vtxPosition Location 2\n"
"OpDecorate %BP_Position Location 0\n"
"OpDecorate %BP_color Location 1\n"
"OpDecorate %BP_vertex_id BuiltIn VertexId\n"
"OpDecorate %BP_instance_id BuiltIn InstanceId\n"
+ "${decoration:opt}\n"
SPIRV_ASSEMBLY_TYPES
SPIRV_ASSEMBLY_CONSTANTS
SPIRV_ASSEMBLY_ARRAYS
"OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
"OpDecorate %BP_gl_TessLevelInner Patch\n"
"OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
+ "${decoration:opt}\n"
SPIRV_ASSEMBLY_TYPES
SPIRV_ASSEMBLY_CONSTANTS
SPIRV_ASSEMBLY_ARRAYS
"OpDecorate %BP_in_position Location 2\n"
"OpDecorate %BP_out_color Location 1\n"
"OpDecorate %BP_in_color Location 1\n"
+ "${decoration:opt}\n"
SPIRV_ASSEMBLY_TYPES
SPIRV_ASSEMBLY_CONSTANTS
SPIRV_ASSEMBLY_ARRAYS
"%BP_out_color = OpVariable %op_v4f32 Output\n"
"%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
"${pre_main:opt}\n"
+
"%BP_main = OpFunction %void None %fun\n"
"%BP_label = OpLabel\n"
"%BP_tc_0_ptr = OpAccessChain %ip_f32 %BP_gl_tessCoord %c_u32_0\n"
"OpDecorate %BP_out_color Location 1\n"
"OpDecorate %BP_out_color Stream 0\n"
"OpDecorate %BP_in_color Location 1\n"
+ "${decoration:opt}\n"
SPIRV_ASSEMBLY_TYPES
SPIRV_ASSEMBLY_CONSTANTS
SPIRV_ASSEMBLY_ARRAYS
"%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
"%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
+
"OpStore %BP_out_gl_position %BP_in_position_0\n"
"OpStore %BP_out_color %BP_transformed_in_color_0\n"
"OpEmitVertex\n"
"OpName %test_code \"testfun(vf4;\"\n"
"OpDecorate %BP_fragColor Location 0\n"
"OpDecorate %BP_vtxColor Location 1\n"
+ "${decoration:opt}\n"
SPIRV_ASSEMBLY_TYPES
SPIRV_ASSEMBLY_CONSTANTS
SPIRV_ASSEMBLY_ARRAYS
"OpReturn\n"
"OpFunctionEnd\n";
}
+
// Sets up and runs a Vulkan pipeline, then spot-checks the resulting image.
// Feeds the pipeline a set of colored triangles, which then must occur in the
// rendered image. The surface is cleared before executing the pipeline, so
DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
0u, // deUint32 preserveCount;
DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
+
};
const VkRenderPassCreateInfo renderPassParams =
{
};
const Unique<VkImageView> colorAttView (createImageView(vk, vkDevice, &colorAttViewParams));
+
// Pipeline layout
const VkPipelineLayoutCreateInfo pipelineLayoutParams =
{
const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
// Pipeline
- vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
-
+ vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
+ // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
+ vector<vector<VkSpecializationMapEntry> > specConstantEntries;
+ vector<VkSpecializationInfo> specializationInfos;
createPipelineShaderStages(vk, vkDevice, instance, context, modules, shaderStageParams);
+ // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
+ specConstantEntries.reserve(shaderStageParams.size());
+ specializationInfos.reserve(shaderStageParams.size());
+
+ // Patch the specialization info field in PipelineShaderStageCreateInfos.
+ for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
+ {
+ const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
+
+ if (stageIt != instance.specConstants.end())
+ {
+ const size_t numSpecConstants = stageIt->second.size();
+ vector<VkSpecializationMapEntry> entries;
+ VkSpecializationInfo specInfo;
+
+ entries.reserve(numSpecConstants);
+
+ // Only support 32-bit integers as spec constants now. And their constant IDs are numbered sequentially starting from 0.
+ for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
+ {
+ entries[ndx].constantID = (deUint32)ndx;
+ entries[ndx].offset = deUint32(ndx * sizeof(deInt32));
+ entries[ndx].size = sizeof(deInt32);
+ }
+
+ specConstantEntries.push_back(entries);
+
+ specInfo.mapEntryCount = (deUint32)numSpecConstants;
+ specInfo.pMapEntries = specConstantEntries.back().data();
+ specInfo.dataSize = numSpecConstants * sizeof(deInt32);
+ specInfo.pData = stageIt->second.data();
+ specializationInfos.push_back(specInfo);
+
+ stageInfo->pSpecializationInfo = &specializationInfos.back();
+ }
+ }
const VkPipelineDepthStencilStateCreateInfo depthStencilParams =
{
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
0.0f, // float slopeScaledDepthBias;
1.0f, // float lineWidth;
};
-
const VkPrimitiveTopology topology = instance.hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams =
{
return TestStatus::pass("Rendered output matches input");
}
-void createTestsForAllStages(const std::string& name,
- const RGBA (&inputColors)[4],
- const RGBA (&outputColors)[4],
- const map<string, string>& testCodeFragments,
- tcu::TestCaseGroup* tests)
+void createTestsForAllStages (const std::string& name, const RGBA (&inputColors)[4], const RGBA (&outputColors)[4], const map<string, string>& testCodeFragments, const vector<deInt32>& specConstants, tcu::TestCaseGroup* tests)
{
const ShaderElement pipelineStages[] =
{
ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
};
+ StageToSpecConstantMap specConstantMap;
+
+ specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(tests, name + "-vert", "", addShaderCodeCustomVertex, runAndVerifyDefaultPipeline,
- createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments));
+ createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments, specConstantMap));
+ specConstantMap.clear();
+ specConstantMap[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(tests, name + "-tessc", "", addShaderCodeCustomTessControl, runAndVerifyDefaultPipeline,
- createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments));
+ createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments, specConstantMap));
+ specConstantMap.clear();
+ specConstantMap[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(tests, name + "-tesse", "", addShaderCodeCustomTessEval, runAndVerifyDefaultPipeline,
- createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments));
+ createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments, specConstantMap));
+ specConstantMap.clear();
+ specConstantMap[VK_SHADER_STAGE_GEOMETRY_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(tests, name + "-geom", "", addShaderCodeCustomGeometry, runAndVerifyDefaultPipeline,
- createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments));
+ createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments, specConstantMap));
+ specConstantMap.clear();
+ specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = specConstants;
addFunctionCaseWithPrograms<InstanceContext>(tests, name + "-frag", "", addShaderCodeCustomFragment, runAndVerifyDefaultPipeline,
- createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments));
+ createInstanceContext(pipelineStages, inputColors, outputColors, testCodeFragments, specConstantMap));
}
+
+inline void createTestsForAllStages (const std::string& name, const RGBA (&inputColors)[4], const RGBA (&outputColors)[4], const map<string, string>& testCodeFragments, tcu::TestCaseGroup* tests)
+{
+ vector<deInt32> noSpecConstants;
+ createTestsForAllStages(name, inputColors, outputColors, testCodeFragments, noSpecConstants, tests);
+}
+
} // anonymous
tcu::TestCaseGroup* createOpSourceTests (tcu::TestContext& testCtx)
tcu::TestCaseGroup* createOpSourceContinuedTests (tcu::TestContext& testCtx)
{
struct NameCodePair { string name, code; };
-
RGBA defaultColors[4];
de::MovePtr<tcu::TestCaseGroup> opSourceTests (new tcu::TestCaseGroup(testCtx, "opsourcecontinued", "OpSourceContinued instruction"));
map<string, string> fragments = passthruFragments();
RGBA defaultColors[4];
de::MovePtr<tcu::TestCaseGroup> opLineTests (new tcu::TestCaseGroup(testCtx, "opNoLine", "OpNoLine instruction"));
map<string, string> fragments;
-
getDefaultColors(defaultColors);
fragments["debug"] =
"%name = OpString \"name\"\n";
return opLineTests.release();
}
+
tcu::TestCaseGroup* createOpLineTests(tcu::TestContext& testCtx)
{
RGBA defaultColors[4];
de::MovePtr<tcu::TestCaseGroup> opConstantNullTests (new tcu::TestCaseGroup(testCtx, "opConstantNull", "OpConstantNull instruction"));
RGBA colors[4];
+
const char functionStart[] =
"%test_code = OpFunction %v4f32 None %v4f32_function\n"
"%param1 = OpFunctionParameter %v4f32\n"
RGBA inputColors[4];
RGBA outputColors[4];
+
const char functionStart[] =
"%test_code = OpFunction %v4f32 None %v4f32_function\n"
"%param1 = OpFunctionParameter %v4f32\n"
return group.release();
}
+struct SpecConstantTwoIntGraphicsCase
+{
+ const char* caseName;
+ const char* scDefinition0;
+ const char* scDefinition1;
+ const char* scResultType;
+ const char* scOperation;
+ deInt32 scActualValue0;
+ deInt32 scActualValue1;
+ const char* resultOperation;
+ RGBA expectedColors[4];
+
+ SpecConstantTwoIntGraphicsCase (const char* name,
+ const char* definition0,
+ const char* definition1,
+ const char* resultType,
+ const char* operation,
+ deInt32 value0,
+ deInt32 value1,
+ const char* resultOp,
+ const RGBA (&output)[4])
+ : caseName (name)
+ , scDefinition0 (definition0)
+ , scDefinition1 (definition1)
+ , scResultType (resultType)
+ , scOperation (operation)
+ , scActualValue0 (value0)
+ , scActualValue1 (value1)
+ , resultOperation (resultOp)
+ {
+ expectedColors[0] = output[0];
+ expectedColors[1] = output[1];
+ expectedColors[2] = output[2];
+ expectedColors[3] = output[3];
+ }
+};
+
+tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opspecconstantop", "Test the OpSpecConstantOp instruction"));
+ vector<SpecConstantTwoIntGraphicsCase> cases;
+ RGBA inputColors[4];
+ RGBA outputColors0[4];
+ RGBA outputColors1[4];
+ RGBA outputColors2[4];
+
+ const char decorations1[] =
+ "OpDecorate %sc_0 SpecId 0\n"
+ "OpDecorate %sc_1 SpecId 1\n";
+
+ const char typesAndConstants1[] =
+ "%sc_0 = OpSpecConstant${SC_DEF0}\n"
+ "%sc_1 = OpSpecConstant${SC_DEF1}\n"
+ "%sc_op = OpSpecConstantOp ${SC_RESULT_TYPE} ${SC_OP}\n";
+
+ const char function1[] =
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param = OpFunctionParameter %v4f32\n"
+ "%label = OpLabel\n"
+ "%result = OpVariable %fp_v4f32 Function\n"
+ " OpStore %result %param\n"
+ "%gen = ${GEN_RESULT}\n"
+ "%index = OpIAdd %i32 %gen %c_i32_1\n"
+ "%loc = OpAccessChain %fp_f32 %result %index\n"
+ "%val = OpLoad %f32 %loc\n"
+ "%add = OpFAdd %f32 %val %c_f32_0_5\n"
+ " OpStore %loc %add\n"
+ "%ret = OpLoad %v4f32 %result\n"
+ " OpReturnValue %ret\n"
+ " OpFunctionEnd\n";
+
+ inputColors[0] = RGBA(127, 127, 127, 255);
+ inputColors[1] = RGBA(127, 0, 0, 255);
+ inputColors[2] = RGBA(0, 127, 0, 255);
+ inputColors[3] = RGBA(0, 0, 127, 255);
+
+ // Derived from inputColors[x] by adding 128 to inputColors[x][0].
+ outputColors0[0] = RGBA(255, 127, 127, 255);
+ outputColors0[1] = RGBA(255, 0, 0, 255);
+ outputColors0[2] = RGBA(128, 127, 0, 255);
+ outputColors0[3] = RGBA(128, 0, 127, 255);
+
+ // Derived from inputColors[x] by adding 128 to inputColors[x][1].
+ outputColors1[0] = RGBA(127, 255, 127, 255);
+ outputColors1[1] = RGBA(127, 128, 0, 255);
+ outputColors1[2] = RGBA(0, 255, 0, 255);
+ outputColors1[3] = RGBA(0, 128, 127, 255);
+
+ // Derived from inputColors[x] by adding 128 to inputColors[x][2].
+ outputColors2[0] = RGBA(127, 127, 255, 255);
+ outputColors2[1] = RGBA(127, 0, 128, 255);
+ outputColors2[2] = RGBA(0, 127, 128, 255);
+ outputColors2[3] = RGBA(0, 0, 255, 255);
+
+ const char addZeroToSc[] = "OpIAdd %i32 %c_i32_0 %sc_op";
+ const char selectTrueUsingSc[] = "OpSelect %i32 %sc_op %c_i32_1 %c_i32_0";
+ const char selectFalseUsingSc[] = "OpSelect %i32 %sc_op %c_i32_0 %c_i32_1";
+
+ cases.push_back(SpecConstantTwoIntGraphicsCase("iadd", " %i32 0", " %i32 0", "%i32", "IAdd %sc_0 %sc_1", 19, -20, addZeroToSc, outputColors0));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("isub", " %i32 0", " %i32 0", "%i32", "ISub %sc_0 %sc_1", 19, 20, addZeroToSc, outputColors0));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("imul", " %i32 0", " %i32 0", "%i32", "IMul %sc_0 %sc_1", -1, -1, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("sdiv", " %i32 0", " %i32 0", "%i32", "SDiv %sc_0 %sc_1", -126, 126, addZeroToSc, outputColors0));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("udiv", " %i32 0", " %i32 0", "%i32", "UDiv %sc_0 %sc_1", 126, 126, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("srem", " %i32 0", " %i32 0", "%i32", "SRem %sc_0 %sc_1", -3, 2, addZeroToSc, outputColors0));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("smod", " %i32 0", " %i32 0", "%i32", "SMod %sc_0 %sc_1", -3, 2, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("umod", " %i32 0", " %i32 0", "%i32", "UMod %sc_0 %sc_1", 1001, 500, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("bitwiseand", " %i32 0", " %i32 0", "%i32", "BitwiseAnd %sc_0 %sc_1", 0x33, 0x0d, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("bitwiseor", " %i32 0", " %i32 0", "%i32", "BitwiseOr %sc_0 %sc_1", 0, 1, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("bitwisexor", " %i32 0", " %i32 0", "%i32", "BitwiseAnd %sc_0 %sc_1", 0x2e, 0x2f, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("shiftrightlogical", " %i32 0", " %i32 0", "%i32", "ShiftRightLogical %sc_0 %sc_1", 2, 1, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("shiftrightarithmetic", " %i32 0", " %i32 0", "%i32", "ShiftRightArithmetic %sc_0 %sc_1", -4, 2, addZeroToSc, outputColors0));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("shiftleftlogical", " %i32 0", " %i32 0", "%i32", "ShiftLeftLogical %sc_0 %sc_1", 1, 0, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("slessthan", " %i32 0", " %i32 0", "%bool", "SLessThan %sc_0 %sc_1", -20, -10, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("ulessthan", " %i32 0", " %i32 0", "%bool", "ULessThan %sc_0 %sc_1", 10, 20, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("sgreaterthan", " %i32 0", " %i32 0", "%bool", "SGreaterThan %sc_0 %sc_1", -1000, 50, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("ugreaterthan", " %i32 0", " %i32 0", "%bool", "UGreaterThan %sc_0 %sc_1", 10, 5, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("slessthanequal", " %i32 0", " %i32 0", "%bool", "SLessThanEqual %sc_0 %sc_1", -10, -10, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("ulessthanequal", " %i32 0", " %i32 0", "%bool", "ULessThanEqual %sc_0 %sc_1", 50, 100, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("sgreaterthanequal", " %i32 0", " %i32 0", "%bool", "SGreaterThanEqual %sc_0 %sc_1", -1000, 50, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("ugreaterthanequal", " %i32 0", " %i32 0", "%bool", "UGreaterThanEqual %sc_0 %sc_1", 10, 10, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("iequal", " %i32 0", " %i32 0", "%bool", "IEqual %sc_0 %sc_1", 42, 24, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("logicaland", "True %bool", "True %bool", "%bool", "LogicalAnd %sc_0 %sc_1", 0, 1, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("logicalor", "False %bool", "False %bool", "%bool", "LogicalOr %sc_0 %sc_1", 1, 0, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("logicalequal", "True %bool", "True %bool", "%bool", "LogicalEqual %sc_0 %sc_1", 0, 1, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("logicalnotequal", "False %bool", "False %bool", "%bool", "LogicalNotEqual %sc_0 %sc_1", 1, 0, selectTrueUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("snegate", " %i32 0", " %i32 0", "%i32", "SNegate %sc_0", -1, 0, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("not", " %i32 0", " %i32 0", "%i32", "Not %sc_0", -2, 0, addZeroToSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("logicalnot", "False %bool", "False %bool", "%bool", "LogicalNot %sc_0", 1, 0, selectFalseUsingSc, outputColors2));
+ cases.push_back(SpecConstantTwoIntGraphicsCase("select", "False %bool", " %i32 0", "%i32", "Select %sc_0 %sc_1 %c_i32_0", 1, 1, addZeroToSc, outputColors2));
+ // OpSConvert, OpFConvert: these two instructions involve ints/floats of different bitwidths.
+ // \todo[2015-12-1 antiagainst] OpQuantizeToF16
+
+ for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+ {
+ map<string, string> specializations;
+ map<string, string> fragments;
+ vector<deInt32> specConstants;
+
+ specializations["SC_DEF0"] = cases[caseNdx].scDefinition0;
+ specializations["SC_DEF1"] = cases[caseNdx].scDefinition1;
+ specializations["SC_RESULT_TYPE"] = cases[caseNdx].scResultType;
+ specializations["SC_OP"] = cases[caseNdx].scOperation;
+ specializations["GEN_RESULT"] = cases[caseNdx].resultOperation;
+
+ fragments["decoration"] = tcu::StringTemplate(decorations1).specialize(specializations);
+ fragments["pre_main"] = tcu::StringTemplate(typesAndConstants1).specialize(specializations);
+ fragments["testfun"] = tcu::StringTemplate(function1).specialize(specializations);
+
+ specConstants.push_back(cases[caseNdx].scActualValue0);
+ specConstants.push_back(cases[caseNdx].scActualValue1);
+
+ createTestsForAllStages(cases[caseNdx].caseName, inputColors, cases[caseNdx].expectedColors, fragments, specConstants, group.get());
+ }
+
+ const char decorations2[] =
+ "OpDecorate %sc_0 SpecId 0\n"
+ "OpDecorate %sc_1 SpecId 1\n"
+ "OpDecorate %sc_2 SpecId 2\n";
+
+ const char typesAndConstants2[] =
+ "%v3i32 = OpTypeVector %i32 3\n"
+
+ "%sc_0 = OpSpecConstant %i32 0\n"
+ "%sc_1 = OpSpecConstant %i32 0\n"
+ "%sc_2 = OpSpecConstant %i32 0\n"
+
+ "%vec3_0 = OpConstantComposite %v3i32 %c_i32_0 %c_i32_0 %c_i32_0\n"
+ "%sc_vec3_0 = OpSpecConstantOp %v3i32 CompositeInsert %sc_0 %vec3_0 0\n" // (sc_0, 0, 0)
+ "%sc_vec3_1 = OpSpecConstantOp %v3i32 CompositeInsert %sc_1 %vec3_0 1\n" // (0, sc_1, 0)
+ "%sc_vec3_2 = OpSpecConstantOp %v3i32 CompositeInsert %sc_2 %vec3_0 2\n" // (0, 0, sc_2)
+ "%sc_vec3_01 = OpSpecConstantOp %v3i32 VectorShuffle %sc_vec3_0 %sc_vec3_1 1 0 4\n" // (0, sc_0, sc_1)
+ "%sc_vec3_012 = OpSpecConstantOp %v3i32 VectorShuffle %sc_vec3_01 %sc_vec3_2 5 1 2\n" // (sc_2, sc_0, sc_1)
+ "%sc_ext_0 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 0\n" // sc_2
+ "%sc_ext_1 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 1\n" // sc_0
+ "%sc_ext_2 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 2\n" // sc_1
+ "%sc_sub = OpSpecConstantOp %i32 ISub %sc_ext_0 %sc_ext_1\n" // (sc_2 - sc_0)
+ "%sc_final = OpSpecConstantOp %i32 IMul %sc_sub %sc_ext_2\n"; // (sc_2 - sc_0) * sc_1
+
+ const char function2[] =
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param = OpFunctionParameter %v4f32\n"
+ "%label = OpLabel\n"
+ "%result = OpVariable %fp_v4f32 Function\n"
+ " OpStore %result %param\n"
+ "%loc = OpAccessChain %fp_f32 %result %sc_final\n"
+ "%val = OpLoad %f32 %loc\n"
+ "%add = OpFAdd %f32 %val %c_f32_0_5\n"
+ " OpStore %loc %add\n"
+ "%ret = OpLoad %v4f32 %result\n"
+ " OpReturnValue %ret\n"
+ " OpFunctionEnd\n";
+
+ map<string, string> fragments;
+ vector<deInt32> specConstants;
+
+ fragments["decoration"] = decorations2;
+ fragments["pre_main"] = typesAndConstants2;
+ fragments["testfun"] = function2;
+
+ specConstants.push_back(56789);
+ specConstants.push_back(-2);
+ specConstants.push_back(56788);
+
+ createTestsForAllStages("vector_related", inputColors, outputColors2, fragments, specConstants, group.get());
+
+ return group.release();
+}
+
tcu::TestCaseGroup* createOpPhiTests(tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opphi", "Test the OpPhi instruction"));
return group.release();
}
-
tcu::TestCaseGroup* createMemoryAccessTests(tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> memoryAccessTests (new tcu::TestCaseGroup(testCtx, "opMemoryAccess", "Memory Semantics"));
string accessType;
};
+
NameMemoryAccess tests[] =
{
{ "none", "" },
}
return memoryAccessTests.release();
}
-
tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> opUndefTests (new tcu::TestCaseGroup(testCtx, "opundef", "Test OpUndef"));
RGBA defaultColors[4];
map<string, string> fragments;
-
getDefaultColors(defaultColors);
+
// First, simple cases that don't do anything with the OpUndef result.
fragments["testfun"] =
"%test_code = OpFunction %v4f32 None %v4f32_function\n"
return opUndefTests.release();
}
+void createOpQuantizeSingleOptionTests(tcu::TestCaseGroup* testCtx)
+{
+ const RGBA inputColors[4] = {
+ RGBA(0, 0, 0, 255),
+ RGBA(0, 0, 255, 255),
+ RGBA(0, 255, 0, 255),
+ RGBA(0, 255, 255, 255)
+ };
+
+ const RGBA expectedColors[4] =
+ {
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255)
+ };
+
+ const struct SingleFP16Possibility
+ {
+ const char* name;
+ const char* constant;
+ const char* condition;
+ // condition must evaluate to true after %test_constant = OpQuantizeToF16(%constant)
+ } tests[] = {
+ {
+ "negative",
+ "-0x1.3p1\n",
+ "%cond = OpFOrdEqual %bool %c %test_constant\n"
+ }, // -19
+ {
+ "positive",
+ "0x1.0p7\n",
+ "%cond = OpFOrdEqual %bool %c %test_constant\n"
+ }, // +128
+ // SPIR-V requires that OpQuantizeToF16 flushes
+ // any numbers that would end up denormalized in F16 to zero.
+ {
+ "denorm",
+ "0x0.0006p-126\n",
+ "%cond = OpFOrdEqual %bool %c %c_f32_0\n"
+ }, // denorm
+ {
+ "negative_denorm",
+ "-0x0.0006p-126\n",
+ "%cond = OpFOrdEqual %bool %c %c_f32_0\n"
+ }, // -denorm
+ {
+ "too_small",
+ "0x1.0p-16\n",
+ "%cond = OpFOrdEqual %bool %c %c_f32_0\n"
+ }, // too small negative
+ {
+ "negative_too_small",
+ "-0x1.0p-32\n",
+ "%cond = OpFOrdEqual %bool %c %c_f32_0\n"
+ }, // too small positive
+ {
+ "negative_inf",
+ "-0x1.0p128\n",
+
+ "%gz = OpFOrdLessThan %bool %c %c_f32_0\n"
+ "%inf = OpIsInf %bool %c\n"
+ "%cond = OpLogicalAnd %bool %gz %inf\n"
+ }, // -inf to -inf
+ {
+ "inf",
+ "0x1.0p128\n",
+
+ "%gz = OpFOrdGreaterThan %bool %c %c_f32_0\n"
+ "%inf = OpIsInf %bool %c\n"
+ "%cond = OpLogicalAnd %bool %gz %inf\n"
+ }, // +inf to +inf
+ {
+ "round_to_negative_inf",
+ "-0x1.0p32\n",
+
+ "%gz = OpFOrdLessThan %bool %c %c_f32_0\n"
+ "%inf = OpIsInf %bool %c\n"
+ "%comp = OpLogicalAnd %bool %gz %inf\n"
+ }, // round to -inf
+ {
+ "round_to_inf",
+ "0x1.0p16\n",
+
+ "%gz = OpFOrdGreaterThan %bool %c %c_f32_0\n"
+ "%inf = OpIsInf %bool %c\n"
+ "%cond = OpLogicalAnd %bool %gz %inf\n"
+ }, // round to +inf
+ {
+ "nan",
+ "0x1.1p128\n",
+
+ "%nan = OpIsNan %bool %c\n"
+ "%as_int = OpBitcast %i32 %c\n"
+ "%positive = OpSGreaterThan %bool %as_int %c_i32_0\n"
+ "%cond = OpLogicalAnd %bool %nan %positive\n"
+ }, // nan
+ {
+ "negative_nan",
+ "-0x1.0001p128\n",
+
+ "%nan = OpIsNan %bool %c\n"
+ "%as_int = OpBitcast %i32 %c\n"
+ "%negative = OpSLessThan %bool %as_int %c_i32_0\n"
+ "%cond = OpLogicalAnd %bool %nan %negative\n"
+ } // -nan
+ };
+ StringTemplate constants(
+ "%test_constant = OpConstant %f32 ${constant}\n");
+ StringTemplate function(
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param1 = OpFunctionParameter %v4f32\n"
+ "%label_testfun = OpLabel\n"
+ "%a = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+ "%b = OpFAdd %f32 %test_constant %a\n"
+ "%c = OpQuantizeToF16 %f32 %b\n"
+ "${condition}\n"
+ "%retval = OpSelect %v4f32 %cond %c_v4f32_1_0_0_1 %param1"
+ " OpReturnValue %retval\n"
+ "");
+
+ for(size_t i = 0; i < (sizeof(tests)/sizeof(tests[0])); ++i) {
+ map<string, string> code_specialization;
+ map<string, string> constant_specialization;
+ map<string, string> fragments;
+ code_specialization["condition"] = tests[i].condition;
+ constant_specialization["constant"] = tests[i].constant;
+ fragments["testfun"] = function.specialize(code_specialization);
+ fragments["pre_main"] = constants.specialize(constant_specialization);
+ createTestsForAllStages(tests[i].name, inputColors, expectedColors, fragments, testCtx);
+ }
+}
+
+void createOpQuantizeTwoPossibilityTests(tcu::TestCaseGroup* testCtx)
+{
+ RGBA inputColors[4] = {
+ RGBA(0, 0, 0, 255),
+ RGBA(0, 0, 255, 255),
+ RGBA(0, 255, 0, 255),
+ RGBA(0, 255, 255, 255)
+ };
+
+ RGBA expectedColors[4] =
+ {
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255),
+ RGBA(255, 0, 0, 255)
+ };
+
+ struct DualFP16Possibility
+ {
+ const char* name;
+ const char* input;
+ const char* possible_output1;
+ const char* possible_output2;
+ } tests[] = {
+ {
+ "positive_round_up_or_round_down",
+ "0x1.3003p8",
+ "0x1.304p8",
+ "0x1.3p8"
+ },
+ {
+ "negative_round_up_or_round_down",
+ "-0x1.6008p-7",
+ "-0x1.6p-7",
+ "-0x1.604p-7"
+ },
+ {
+ "carry_bit",
+ "0x1.01ep2",
+ "0x1.01cp2",
+ "0x1.02p2"
+ },
+ {
+ "carry_to_exponent",
+ "0x1.feep1",
+ "0x1.ffcp1",
+ "0x1.0p2"
+ },
+ };
+ StringTemplate constants (
+ "%input_const = OpConstant %f32 ${input}\n"
+ "%possible_solution1 = OpConstant %f32 ${output1}\n"
+ "%possible_solution2 = OpConstant %f32 ${output2}\n"
+ );
+ const char* function =
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param1 = OpFunctionParameter %v4f32\n"
+ "%label_testfun = OpLabel\n"
+ "%a = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+ // For the purposes of this test we assume that 0.f will always get
+ // faithfully passed through the pipeline stages.
+ "%b = OpFAdd %f32 %test_constant %a\n"
+ "%c = OpQuantizeToF16 %f32 %b\n"
+ "%eq_1 = OpFOrdEqual %bool %c %possible_solution1\n"
+ "%eq_2 = OpFOrdEqual %bool %c %possible_solution2\n"
+ "%cond = OpLogicalOr %bool %eq_1 %eq_2\n"
+ "%retval = OpSelect %v4f32 %cond %c_v4f32_1_0_0_1 %param1"
+ " OpReturnValue %retval\n";
+
+ for(size_t i = 0; i < (sizeof(tests)/sizeof(tests[0])); ++i) {
+ map<string, string> fragments;
+ map<string, string> constant_specialization;
+ constant_specialization["input"] = tests[i].input;
+ constant_specialization["output1"] = tests[i].possible_output1;
+ constant_specialization["output2"] = tests[i].possible_output2;
+ fragments["testfun"] = function;
+ fragments["pre_main"] = constants.specialize(constant_specialization);
+ createTestsForAllStages(tests[i].name, inputColors, expectedColors, fragments, testCtx);
+ }
+}
+
+tcu::TestCaseGroup* createOpQuantizeTests(tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> opQuantizeTests (new tcu::TestCaseGroup(testCtx, "opquantize", "Test OpQuantizeToF16"));
+ createOpQuantizeSingleOptionTests(opQuantizeTests.get());
+ createOpQuantizeTwoPossibilityTests(opQuantizeTests.get());
+ return opQuantizeTests.release();
+}
+
struct ShaderPermutation
{
deUint8 vertexPermutation;
}
return moduleTests.release();
}
+
+
+tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "loop", "Looping control flow"));
+ RGBA defaultColors[4];
+ getDefaultColors(defaultColors);
+ map<string, string> fragments;
+
+ // A loop with a single block. The Continue Target is the loop block
+ // itself. In SPIR-V terms, the "loop construct" contains no blocks at all
+ // -- the "continue construct" forms the entire loop.
+ fragments["testfun"] =
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param1 = OpFunctionParameter %v4f32\n"
+
+ "%entry = OpLabel\n"
+ "%val0 = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+ "OpBranch %loop\n"
+
+ ";adds and subtracts 1.0 to %val in alternate iterations\n"
+ "%loop = OpLabel\n"
+ "%count = OpPhi %i32 %c_i32_4 %entry %count__ %loop\n"
+ "%delta = OpPhi %f32 %c_f32_1 %entry %minus_delta %loop\n"
+ "%val1 = OpPhi %f32 %val0 %entry %val %loop\n"
+ "%val = OpFAdd %f32 %val1 %delta\n"
+ "%minus_delta = OpFSub %f32 %c_f32_0 %delta\n"
+ "%count__ = OpISub %i32 %count %c_i32_1\n"
+ "%again = OpSGreaterThan %bool %count__ %c_i32_0\n"
+ "OpLoopMerge %exit %loop None\n"
+ "OpBranchConditional %again %loop %exit\n"
+
+ "%exit = OpLabel\n"
+ "%result = OpVectorInsertDynamic %v4f32 %param1 %val %c_i32_0\n"
+ "OpReturnValue %result\n"
+
+ "OpFunctionEnd\n"
+ ;
+ createTestsForAllStages("single-block", defaultColors, defaultColors, fragments, testGroup.get());
+
+ fragments["pre_main"] = "%c_f32_neg1 = OpConstant %f32 -1.0\n";
+
+ // Body comprised of multiple basic blocks.
+ const StringTemplate multiBlock(
+ "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+ "%param1 = OpFunctionParameter %v4f32\n"
+
+ "%entry = OpLabel\n"
+ "%val0 = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+ "OpBranch %loop\n"
+
+ ";adds and subtracts 1.0 to %val in alternate iterations\n"
+ "%loop = OpLabel\n"
+ "%count = OpPhi %i32 %c_i32_4 %entry %count__ %gather\n"
+ "%delta = OpPhi %f32 %c_f32_1 %entry %delta_next %gather\n"
+ "%val1 = OpPhi %f32 %val0 %entry %val %gather\n"
+ // There are several possibilities for the Continue Target below. Each
+ // will be specialized into a separate test case.
+ "OpLoopMerge %exit ${continue_target} None\n"
+ "OpBranch %if\n"
+
+ "%if = OpLabel\n"
+ ";delta_next = (delta > 0) ? -1 : 1;\n"
+ "%gt0 = OpFOrdGreaterThan %bool %delta %c_f32_0\n"
+ "OpSelectionMerge %gather DontFlatten\n"
+ "OpBranchConditional %gt0 %even %odd ;tells us if %count is even or odd\n"
+
+ "%odd = OpLabel\n"
+ "OpBranch %gather\n"
+
+ "%even = OpLabel\n"
+ "OpBranch %gather\n"
+
+ "%gather = OpLabel\n"
+ "%delta_next = OpPhi %f32 %c_f32_neg1 %even %c_f32_1 %odd\n"
+ "%val = OpFAdd %f32 %val1 %delta\n"
+ "%count__ = OpISub %i32 %count %c_i32_1\n"
+ "%again = OpSGreaterThan %bool %count__ %c_i32_0\n"
+ "OpBranchConditional %again %loop %exit\n"
+
+ "%exit = OpLabel\n"
+ "%result = OpVectorInsertDynamic %v4f32 %param1 %val %c_i32_0\n"
+ "OpReturnValue %result\n"
+
+ "OpFunctionEnd\n");
+
+ map<string, string> continue_target;
+
+ // The Continue Target is the loop block itself.
+ continue_target["continue_target"] = "%loop";
+ fragments["testfun"] = multiBlock.specialize(continue_target);
+ createTestsForAllStages("multi-block-continue-construct", defaultColors, defaultColors, fragments, testGroup.get());
+
+ // The Continue Target is at the end of the loop.
+ continue_target["continue_target"] = "%gather";
+ fragments["testfun"] = multiBlock.specialize(continue_target);
+ createTestsForAllStages("multi-block-loop-construct", defaultColors, defaultColors, fragments, testGroup.get());
+
+ // \todo [2015-12-14 dekimir] More cases:
+ // - continue
+ // - early exit
+ // - non-uniform control flow
+ // - uniform control flow despite using invocation ID
+
+ return testGroup.release();
+}
+
tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> instructionTests (new tcu::TestCaseGroup(testCtx, "instruction", "Instructions with special opcodes/operands"));
RGBA defaultColors[4];
getDefaultColors(defaultColors);
+
de::MovePtr<tcu::TestCaseGroup> opnopTests (new tcu::TestCaseGroup(testCtx, "opnop", "Test OpNop"));
map<string, string> opNopFragments;
opNopFragments["testfun"] =
;
createTestsForAllStages("opnop", defaultColors, defaultColors, opNopFragments, opnopTests.get());
+
graphicsTests->addChild(opnopTests.release());
graphicsTests->addChild(createOpSourceTests(testCtx));
graphicsTests->addChild(createOpSourceContinuedTests(testCtx));
graphicsTests->addChild(createModuleTests(testCtx));
graphicsTests->addChild(createSwitchBlockOrderTests(testCtx));
graphicsTests->addChild(createOpPhiTests(testCtx));
+ graphicsTests->addChild(createOpQuantizeTests(testCtx));
+ graphicsTests->addChild(createLoopTests(testCtx));
+ graphicsTests->addChild(createSpecConstantTests(testCtx));
+
instructionTests->addChild(computeTests.release());
instructionTests->addChild(graphicsTests.release());
+
return instructionTests.release();
}