Added the initial set of glsl450 instructions.

Also rewrote the extended-instruction tests so that they would actually
make sure that the instruction actually appears in the output.
This commit is contained in:
Andrew Woloszyn 2015-08-21 13:39:34 -04:00 committed by Dejan Mircevski
parent fb76d81aa0
commit 1d2a87ed1b
5 changed files with 155 additions and 30 deletions

View File

@ -2,10 +2,33 @@
#include <string.h> #include <string.h>
#define GL450Inst(name) #name, GLSLstd450::GLSLstd450##name
static const spv_ext_inst_desc_t glslStd450Entries[] = { static const spv_ext_inst_desc_t glslStd450Entries[] = {
{ { GL450Inst(Round), {SPV_OPERAND_TYPE_ID}, },
"round", GLSLstd450::GLSLstd450Round, {SPV_OPERAND_TYPE_ID}, { GL450Inst(RoundEven), {SPV_OPERAND_TYPE_ID}, },
}, { GL450Inst(Trunc), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(FAbs), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(SAbs), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(FSign), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(SSign), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Floor), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Ceil), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Fract), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Radians), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Degrees), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Sin), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Cos), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Tan), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Asin), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Acos), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Atan), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Sinh), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Cosh), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Tanh), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Asinh), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Acosh), {SPV_OPERAND_TYPE_ID}, },
{ GL450Inst(Atanh), {SPV_OPERAND_TYPE_ID}, },
// TODO: Add remaining GLSL.std.450 instructions // TODO: Add remaining GLSL.std.450 instructions
}; };

View File

@ -124,29 +124,59 @@ TEST_F(BinaryToText, InvalidDiagnostic) {
operandTable, extInstTable, &text, nullptr)); operandTable, extInstTable, &text, nullptr));
} }
TEST(BinaryToTextExtInst, Default) { struct InstValue {
const char* inst;
uint32_t value;
};
class BinaryToTextGLExtSingleFloatInst
: public ::testing::TestWithParam<InstValue> {};
TEST_P(BinaryToTextGLExtSingleFloatInst, Default) {
spv_opcode_table opcodeTable; spv_opcode_table opcodeTable;
ASSERT_EQ(SPV_SUCCESS, spvOpcodeTableGet(&opcodeTable)); ASSERT_EQ(SPV_SUCCESS, spvOpcodeTableGet(&opcodeTable));
spv_operand_table operandTable; spv_operand_table operandTable;
ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable)); ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable));
spv_ext_inst_table extInstTable; spv_ext_inst_table extInstTable;
ASSERT_EQ(SPV_SUCCESS, spvExtInstTableGet(&extInstTable)); ASSERT_EQ(SPV_SUCCESS, spvExtInstTableGet(&extInstTable));
const char *spirv = R"( const std::string spirv = R"(
OpCapability Shader OpCapability Shader
OpExtInstImport %glsl450 "GLSL.std.450" OpExtInstImport %1 "GLSL.std.450"
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex $main "main" OpEntryPoint Vertex $2 "main"
OpTypeVoid %void OpTypeVoid %3
OpTypeFloat %float 32 OpTypeFloat %4 32
OpConstant $float %const1.5 1.5 OpConstant $4 %5 1
OpTypeFunction %fnMain %void OpTypeFunction %6 $3
OpFunction $void %main None $fnMain OpFunction $3 %2 None $6
OpLabel %lbMain OpLabel %8
OpExtInst $float %result $glsl450 round $const1.5 OpExtInst $4 %9 $1 )" + std::string(GetParam().inst) +
R"( $5
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)"; )";
spv_text_t text = {spirv, strlen(spirv)}; const std::string expected_spirv =
R"(; SPIR-V
; Version: 99
; Generator: Khronos
; Bound: 10
; Schema: 0
OpCapability Shader
OpExtInstImport %1 "GLSL.std.450"
OpMemoryModel Logical Simple
OpEntryPoint Vertex $2 "main"
OpTypeVoid %3
OpTypeFloat %4 32
OpConstant $4 %5 1
OpTypeFunction %6 $3
OpFunction $3 %2 None $6
OpLabel %8
OpExtInst $4 %9 $1 )" +
std::to_string(GetParam().value) + R"( $5
OpReturn
OpFunctionEnd
)";
spv_text_t text = {spirv.c_str(), spirv.size()};
spv_binary binary; spv_binary binary;
spv_diagnostic diagnostic; spv_diagnostic diagnostic;
spv_result_t error = spvTextToBinary(&text, opcodeTable, operandTable, spv_result_t error = spvTextToBinary(&text, opcodeTable, operandTable,
@ -154,16 +184,31 @@ OpFunctionEnd
if (error) { if (error) {
spvDiagnosticPrint(diagnostic); spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic); spvDiagnosticDestroy(diagnostic);
ASSERT_EQ(SPV_SUCCESS, error); ASSERT_EQ(SPV_SUCCESS, error) << "Source was: " << std::endl
<< spirv << std::endl
<< "Test case for : " << GetParam().inst
<< std::endl;
} }
spv_text output_text;
error = spvBinaryToText( error = spvBinaryToText(
binary, SPV_BINARY_TO_TEXT_OPTION_COLOR | SPV_BINARY_TO_TEXT_OPTION_PRINT, binary, SPV_BINARY_TO_TEXT_OPTION_NONE,
opcodeTable, operandTable, extInstTable, nullptr, &diagnostic); opcodeTable, operandTable, extInstTable, &output_text, &diagnostic);
if (error) { if (error) {
spvDiagnosticPrint(diagnostic); spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic); spvDiagnosticDestroy(diagnostic);
ASSERT_EQ(SPV_SUCCESS, error); ASSERT_EQ(SPV_SUCCESS, error);
} }
EXPECT_EQ(expected_spirv, output_text->str);
spvTextDestroy(output_text);
} }
INSTANTIATE_TEST_CASE_P(
SingleElementFloatingParams, BinaryToTextGLExtSingleFloatInst,
::testing::ValuesIn(std::vector<InstValue>({
{"Round", 1}, {"RoundEven", 2}, {"Trunc", 3}, {"FAbs", 4}, {"SAbs", 5},
{"FSign", 6}, {"SSign", 7}, {"Floor", 8}, {"Ceil", 9}, {"Fract", 10},
{"Radians", 11}, {"Degrees", 12}, {"Sin", 13}, {"Cos", 14}, {"Tan", 15},
{"Asin", 16}, {"Acos", 17}, {"Atan", 18}, {"Sinh", 19}, {"Cosh", 20},
{"Tanh", 21}, {"Asinh", 22}, {"Acosh", 23}, {"Atanh", 24}})));

View File

@ -23,14 +23,17 @@
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
#ifndef _TEST_FIXTURE_H_
#define _TEST_FIXTURE_H_
#include "UnitSPIRV.h" #include "UnitSPIRV.h"
// Common setup for TextToBinary tests. SetText() should be called to populate // Common setup for TextToBinary tests. SetText() should be called to populate
// the actual test text. // the actual test text.
class TextToBinaryTest : public ::testing::Test { template<typename T>
class TextToBinaryTestBase : public T {
public: public:
TextToBinaryTest() TextToBinaryTestBase()
: opcodeTable(nullptr), : opcodeTable(nullptr),
operandTable(nullptr), operandTable(nullptr),
diagnostic(nullptr), diagnostic(nullptr),
@ -64,3 +67,7 @@ class TextToBinaryTest : public ::testing::Test {
spv_text_t text; spv_text_t text;
spv_binary binary; spv_binary binary;
}; };
class TextToBinaryTest : public TextToBinaryTestBase<::testing::Test> {};
#endif// _TEXT_FIXTURE_H_

View File

@ -26,6 +26,10 @@
#include "TestFixture.h" #include "TestFixture.h"
#include "UnitSPIRV.h" #include "UnitSPIRV.h"
#include <algorithm>
#include <iomanip>
#include <utility>
#include <vector>
union char_word_t { union char_word_t {
char cs[4]; char cs[4];
@ -269,8 +273,16 @@ TEST_F(TextToBinaryTest, ImmediateIntOperand) {
} }
} }
TEST_F(TextToBinaryTest, ExtInst) { struct InstValue {
SetText(R"( const char* inst;
uint32_t value;
};
class GLSingleFloatTest
: public TextToBinaryTestBase<
::testing::TestWithParam<InstValue>> {};
TEST_P(GLSingleFloatTest, GLSLExtSingleFloatParamTest) {
const std::string spirv = R"(
OpCapability Shader OpCapability Shader
OpExtInstImport %glsl450 "GLSL.std.450" OpExtInstImport %glsl450 "GLSL.std.450"
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
@ -281,20 +293,44 @@ OpConstant $float %const1.5 1.5
OpTypeFunction %fnMain %void OpTypeFunction %fnMain %void
OpFunction $void %main None $fnMain OpFunction $void %main None $fnMain
OpLabel %lbMain OpLabel %lbMain
OpExtInst $float %result $glsl450 round $const1.5 OpExtInst $float %result $glsl450 )" +
std::string(GetParam().inst) + R"( $const1.5
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)"); )";
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(&text, opcodeTable, operandTable,
extInstTable, &binary, &diagnostic)); this->text.str = spirv.c_str();
if (binary) { this->text.length = spirv.size();
spvBinaryDestroy(binary); EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(&this->text, this->opcodeTable,
this->operandTable, this->extInstTable,
&this->binary, &this->diagnostic))
<< "Source was: " << std::endl
<< spirv << std::endl
<< "Test case for : " << GetParam().inst << std::endl;
std::vector<uint32_t> expected_contains({
12/*OpExtInst*/ | 6 << 16, 4/*%float*/, 9 /*%result*/, 1 /*%glsl450*/,
GetParam().value, 5 /*const1.5*/});
EXPECT_TRUE(std::search(this->binary->code,
this->binary->code + this->binary->wordCount,
expected_contains.begin(), expected_contains.end()) !=
this->binary->code + this->binary->wordCount);
if (this->binary) {
spvBinaryDestroy(this->binary);
} }
if (diagnostic) { if (this->diagnostic) {
spvDiagnosticPrint(diagnostic); spvDiagnosticPrint(this->diagnostic);
} }
} }
INSTANTIATE_TEST_CASE_P(
SingleElementFloatingParams, GLSingleFloatTest,
::testing::ValuesIn(std::vector<InstValue>({
{"Round", 1}, {"RoundEven", 2}, {"Trunc", 3}, {"FAbs", 4}, {"SAbs", 5},
{"FSign", 6}, {"SSign", 7}, {"Floor", 8}, {"Ceil", 9}, {"Fract", 10},
{"Radians", 11}, {"Degrees", 12}, {"Sin", 13}, {"Cos", 14}, {"Tan", 15},
{"Asin", 16}, {"Acos", 17}, {"Atan", 18}, {"Sinh", 19}, {"Cosh", 20},
{"Tanh", 21}, {"Asinh", 22}, {"Acosh", 23}, {"Atanh", 24}})));
TEST_F(TextToBinaryTest, StringSpace) { TEST_F(TextToBinaryTest, StringSpace) {
SetText("OpSourceExtension \"string with spaces\""); SetText("OpSourceExtension \"string with spaces\"");
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(&text, opcodeTable, operandTable, EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(&text, opcodeTable, operandTable,

View File

@ -34,6 +34,18 @@
#include "../source/text.h" #include "../source/text.h"
#include "../source/validate.h" #include "../source/validate.h"
#ifdef __ANDROID__
#include <sstream>
namespace std {
template<typename T>
std::string to_string(const T& val) {
std::ostringstream os;
os << val;
return os.str();
}
}
#endif
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <stdint.h> #include <stdint.h>
@ -49,6 +61,8 @@ static const union {
uint32_t value; uint32_t value;
} o32_host_order = {{0, 1, 2, 3}}; } o32_host_order = {{0, 1, 2, 3}};
#define I32_ENDIAN_HOST (o32_host_order.value) #define I32_ENDIAN_HOST (o32_host_order.value)
#endif #endif