Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
e0a24778
Commit
e0a24778
authored
May 16, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #284 from antiagainst/gtest-hlsl
Tests: Add support for testing file-based HLSL source code in GTest.
parents
7a27de6d
d6f0ed2c
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
142 additions
and
38 deletions
+142
-38
AST.FromFile.cpp
gtests/AST.FromFile.cpp
+3
-2
CMakeLists.txt
gtests/CMakeLists.txt
+1
-0
Hlsl.FromFile.cpp
gtests/Hlsl.FromFile.cpp
+81
-0
Initializer.h
gtests/Initializer.h
+1
-1
Pp.FromFile.cpp
gtests/Pp.FromFile.cpp
+1
-1
Spv.FromFile.cpp
gtests/Spv.FromFile.cpp
+6
-4
TestFixture.cpp
gtests/TestFixture.cpp
+17
-7
TestFixture.h
gtests/TestFixture.h
+32
-23
No files found.
gtests/AST.FromFile.cpp
View file @
e0a24778
...
@@ -44,7 +44,8 @@ using CompileToAstTest = GlslangTest<::testing::TestWithParam<std::string>>;
...
@@ -44,7 +44,8 @@ using CompileToAstTest = GlslangTest<::testing::TestWithParam<std::string>>;
TEST_P
(
CompileToAstTest
,
FromFile
)
TEST_P
(
CompileToAstTest
,
FromFile
)
{
{
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
Semantics
::
OpenGL
,
Target
::
AST
);
Source
::
GLSL
,
Semantics
::
OpenGL
,
Target
::
AST
);
}
}
// clang-format off
// clang-format off
...
@@ -183,7 +184,7 @@ INSTANTIATE_TEST_CASE_P(
...
@@ -183,7 +184,7 @@ INSTANTIATE_TEST_CASE_P(
"nonVulkan.frag"
,
"nonVulkan.frag"
,
"spv.atomic.comp"
,
"spv.atomic.comp"
,
})),
})),
FileNameAsCustomTest
Name
FileNameAsCustomTest
Suffix
);
);
// clang-format on
// clang-format on
...
...
gtests/CMakeLists.txt
View file @
e0a24778
...
@@ -13,6 +13,7 @@ if (TARGET gmock)
...
@@ -13,6 +13,7 @@ if (TARGET gmock)
# Test related source files
# Test related source files
${
CMAKE_CURRENT_SOURCE_DIR
}
/AST.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/AST.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/BuiltInResource.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/BuiltInResource.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Hlsl.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Pp.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Pp.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Spv.FromFile.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Spv.FromFile.cpp
)
)
...
...
gtests/Hlsl.FromFile.cpp
0 → 100644
View file @
e0a24778
//
// Copyright (C) 2016 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <gtest/gtest.h>
#include "TestFixture.h"
namespace
glslangtest
{
namespace
{
struct
FileNameEntryPointPair
{
const
char
*
fileName
;
const
char
*
entryPoint
;
};
// We are using FileNameEntryPointPair objects as parameters for instantiating
// the template, so the global FileNameAsCustomTestSuffix() won't work since
// it assumes std::string as parameters. Thus, an overriding one here.
std
::
string
FileNameAsCustomTestSuffix
(
const
::
testing
::
TestParamInfo
<
FileNameEntryPointPair
>&
info
)
{
std
::
string
name
=
info
.
param
.
fileName
;
// A valid test case suffix cannot have '.' and '-' inside.
std
::
replace
(
name
.
begin
(),
name
.
end
(),
'.'
,
'_'
);
std
::
replace
(
name
.
begin
(),
name
.
end
(),
'-'
,
'_'
);
return
name
;
}
using
HlslCompileTest
=
GlslangTest
<::
testing
::
TestWithParam
<
FileNameEntryPointPair
>>
;
// Compiling HLSL to SPIR-V under Vulkan semantics. Expected to successfully
// generate SPIR-V.
TEST_P
(
HlslCompileTest
,
FromFile
)
{
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
().
fileName
,
Source
::
HLSL
,
Semantics
::
Vulkan
,
Target
::
BothASTAndSpv
,
GetParam
().
entryPoint
);
}
// clang-format off
INSTANTIATE_TEST_CASE_P
(
ToSpirv
,
HlslCompileTest
,
::
testing
::
ValuesIn
(
std
::
vector
<
FileNameEntryPointPair
>
{
{
"hlsl.frag"
,
"PixelShaderFunction"
},
}),
FileNameAsCustomTestSuffix
);
// clang-format on
}
// anonymous namespace
}
// namespace glslangtest
gtests/Initializer.h
View file @
e0a24778
...
@@ -69,7 +69,7 @@ public:
...
@@ -69,7 +69,7 @@ public:
InitializationToken
acquire
(
EShMessages
new_messages
)
InitializationToken
acquire
(
EShMessages
new_messages
)
{
{
if
((
lastMessages
^
new_messages
)
&
if
((
lastMessages
^
new_messages
)
&
(
EShMsgVulkanRules
|
EShMsgSpvRules
))
{
(
EShMsgVulkanRules
|
EShMsgSpvRules
|
EShMsgReadHlsl
))
{
glslang
::
FinalizeProcess
();
glslang
::
FinalizeProcess
();
glslang
::
InitializeProcess
();
glslang
::
InitializeProcess
();
}
}
...
...
gtests/Pp.FromFile.cpp
View file @
e0a24778
...
@@ -66,7 +66,7 @@ INSTANTIATE_TEST_CASE_P(
...
@@ -66,7 +66,7 @@ INSTANTIATE_TEST_CASE_P(
"preprocessor.defined.vert"
,
"preprocessor.defined.vert"
,
"preprocessor.many.endif.vert"
,
"preprocessor.many.endif.vert"
,
})),
})),
FileNameAsCustomTest
Name
FileNameAsCustomTest
Suffix
);
);
// clang-format on
// clang-format on
...
...
gtests/Spv.FromFile.cpp
View file @
e0a24778
...
@@ -49,7 +49,8 @@ using VulkanSemantics = GlslangTest<::testing::TestWithParam<std::string>>;
...
@@ -49,7 +49,8 @@ using VulkanSemantics = GlslangTest<::testing::TestWithParam<std::string>>;
TEST_P
(
CompileToSpirvTest
,
FromFile
)
TEST_P
(
CompileToSpirvTest
,
FromFile
)
{
{
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
Semantics
::
Vulkan
,
Target
::
Spirv
);
Source
::
GLSL
,
Semantics
::
Vulkan
,
Target
::
Spv
);
}
}
// GLSL-level Vulkan semantics test. Expected to error out before generating
// GLSL-level Vulkan semantics test. Expected to error out before generating
...
@@ -57,7 +58,8 @@ TEST_P(CompileToSpirvTest, FromFile)
...
@@ -57,7 +58,8 @@ TEST_P(CompileToSpirvTest, FromFile)
TEST_P
(
VulkanSemantics
,
FromFile
)
TEST_P
(
VulkanSemantics
,
FromFile
)
{
{
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
loadFileCompileAndCheck
(
GLSLANG_TEST_DIRECTORY
,
GetParam
(),
Semantics
::
Vulkan
,
Target
::
Spirv
);
Source
::
GLSL
,
Semantics
::
Vulkan
,
Target
::
Spv
);
}
}
// clang-format off
// clang-format off
...
@@ -173,7 +175,7 @@ INSTANTIATE_TEST_CASE_P(
...
@@ -173,7 +175,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.specConstant.comp"
,
"spv.specConstant.comp"
,
"spv.specConstantComposite.vert"
,
"spv.specConstantComposite.vert"
,
})),
})),
FileNameAsCustomTest
Name
FileNameAsCustomTest
Suffix
);
);
INSTANTIATE_TEST_CASE_P
(
INSTANTIATE_TEST_CASE_P
(
...
@@ -183,7 +185,7 @@ INSTANTIATE_TEST_CASE_P(
...
@@ -183,7 +185,7 @@ INSTANTIATE_TEST_CASE_P(
"vulkan.vert"
,
"vulkan.vert"
,
"vulkan.comp"
,
"vulkan.comp"
,
})),
})),
FileNameAsCustomTest
Name
FileNameAsCustomTest
Suffix
);
);
// clang-format on
// clang-format on
...
...
gtests/TestFixture.cpp
View file @
e0a24778
...
@@ -36,7 +36,7 @@
...
@@ -36,7 +36,7 @@
namespace
glslangtest
{
namespace
glslangtest
{
std
::
string
FileNameAsCustomTest
Name
(
std
::
string
FileNameAsCustomTest
Suffix
(
const
::
testing
::
TestParamInfo
<
std
::
string
>&
info
)
const
::
testing
::
TestParamInfo
<
std
::
string
>&
info
)
{
{
std
::
string
name
=
info
.
param
;
std
::
string
name
=
info
.
param
;
...
@@ -46,7 +46,7 @@ std::string FileNameAsCustomTestName(
...
@@ -46,7 +46,7 @@ std::string FileNameAsCustomTestName(
return
name
;
return
name
;
}
}
EShLanguage
Get
GlslLanguageFo
rStage
(
const
std
::
string
&
stage
)
EShLanguage
Get
Shade
rStage
(
const
std
::
string
&
stage
)
{
{
if
(
stage
==
"vert"
)
{
if
(
stage
==
"vert"
)
{
return
EShLangVertex
;
return
EShLangVertex
;
...
@@ -66,17 +66,27 @@ EShLanguage GetGlslLanguageForStage(const std::string& stage)
...
@@ -66,17 +66,27 @@ EShLanguage GetGlslLanguageForStage(const std::string& stage)
}
}
}
}
EShMessages
GetSpirvMessageOptionsForSemanticsAndTarget
(
Semantics
semantics
,
EShMessages
DeriveOptions
(
Source
source
,
Semantics
semantics
,
Target
target
)
Target
target
)
{
{
EShMessages
result
=
EShMsgDefault
;
EShMessages
result
=
EShMsgDefault
;
switch
(
source
)
{
case
Source
:
:
GLSL
:
break
;
case
Source
:
:
HLSL
:
result
=
EShMsgReadHlsl
;
break
;
}
switch
(
target
)
{
switch
(
target
)
{
case
Target
:
:
AST
:
case
Target
:
:
AST
:
result
=
EShMsgAST
;
result
=
static_cast
<
EShMessages
>
(
result
|
EShMsgAST
);
break
;
case
Target
:
:
Spv
:
result
=
static_cast
<
EShMessages
>
(
result
|
EShMsgSpvRules
);
break
;
break
;
case
Target
:
:
Spir
v
:
case
Target
:
:
BothASTAndSp
v
:
result
=
EShMsgSpvRules
;
result
=
static_cast
<
EShMessages
>
(
result
|
EShMsgSpvRules
|
EShMsgAST
)
;
break
;
break
;
};
};
...
...
gtests/TestFixture.h
View file @
e0a24778
...
@@ -65,9 +65,14 @@ namespace glslangtest {
...
@@ -65,9 +65,14 @@ namespace glslangtest {
// This function is used to provide custom test name suffixes based on the
// This function is used to provide custom test name suffixes based on the
// shader source file names. Otherwise, the test name suffixes will just be
// shader source file names. Otherwise, the test name suffixes will just be
// numbers, which are not quite obvious.
// numbers, which are not quite obvious.
std
::
string
FileNameAsCustomTest
Name
(
std
::
string
FileNameAsCustomTest
Suffix
(
const
::
testing
::
TestParamInfo
<
std
::
string
>&
info
);
const
::
testing
::
TestParamInfo
<
std
::
string
>&
info
);
enum
class
Source
{
GLSL
,
HLSL
,
};
// Enum for shader compilation semantics.
// Enum for shader compilation semantics.
enum
class
Semantics
{
enum
class
Semantics
{
OpenGL
,
OpenGL
,
...
@@ -77,13 +82,13 @@ enum class Semantics {
...
@@ -77,13 +82,13 @@ enum class Semantics {
// Enum for compilation target.
// Enum for compilation target.
enum
class
Target
{
enum
class
Target
{
AST
,
AST
,
Spirv
,
Spv
,
BothASTAndSpv
,
};
};
EShLanguage
Get
GlslLanguageFo
rStage
(
const
std
::
string
&
stage
);
EShLanguage
Get
Shade
rStage
(
const
std
::
string
&
stage
);
EShMessages
GetSpirvMessageOptionsForSemanticsAndTarget
(
Semantics
semantics
,
EShMessages
DeriveOptions
(
Source
,
Semantics
,
Target
);
Target
target
);
// Reads the content of the file at the given |path|. On success, returns true
// Reads the content of the file at the given |path|. On success, returns true
// and the contents; otherwise, returns false and an empty string.
// and the contents; otherwise, returns false and an empty string.
...
@@ -160,23 +165,23 @@ public:
...
@@ -160,23 +165,23 @@ public:
const
std
::
string
spirv
;
// Optional SPIR-V disassembly text.
const
std
::
string
spirv
;
// Optional SPIR-V disassembly text.
};
};
// Compiles and linkes the given
GLSL |source| code
of the given shader
// Compiles and linkes the given
source |code|
of the given shader
// |stage| into the given |target| under the given |semantics|. Returns
// |stage| into the given |target| under the given |semantics|. Returns
// a GlslangResult instance containing all the information generated
// a GlslangResult instance containing all the information generated
// during the process. If |target| is Target::Spirv, also disassembles
// during the process. If |target| is Target::Spirv, also disassembles
// the result and returns disassembly text.
// the result and returns disassembly text.
GlslangResult
compile
Glsl
(
const
std
::
string
&
source
,
GlslangResult
compile
(
const
std
::
string
&
code
,
Source
source
,
const
std
::
string
&
stage
,
Semantics
semantics
,
const
std
::
string
&
stage
,
Semantics
semantics
,
Target
target
)
Target
target
,
const
std
::
string
&
entryPointName
)
{
{
const
char
*
shaderStrings
=
sourc
e
.
data
();
const
char
*
shaderStrings
=
cod
e
.
data
();
const
int
shaderLengths
=
static_cast
<
int
>
(
sourc
e
.
size
());
const
int
shaderLengths
=
static_cast
<
int
>
(
cod
e
.
size
());
const
EShLanguage
language
=
GetGlslLanguageFo
rStage
(
stage
);
const
EShLanguage
kind
=
GetShade
rStage
(
stage
);
glslang
::
TShader
shader
(
language
);
glslang
::
TShader
shader
(
kind
);
shader
.
setStringsWithLengths
(
&
shaderStrings
,
&
shaderLengths
,
1
);
shader
.
setStringsWithLengths
(
&
shaderStrings
,
&
shaderLengths
,
1
);
const
EShMessages
messages
=
if
(
!
entryPointName
.
empty
())
shader
.
setEntryPoint
(
entryPointName
.
c_str
());
GetSpirvMessageOptionsForSemanticsAndTarget
(
semantics
,
target
);
const
EShMessages
messages
=
DeriveOptions
(
source
,
semantics
,
target
);
// Reinitialize glslang if the semantics change.
// Reinitialize glslang if the semantics change.
GlslangInitializer
::
InitializationToken
token
=
GlslangInitializer
::
InitializationToken
token
=
GlobalTestSettings
.
initializer
->
acquire
(
messages
);
GlobalTestSettings
.
initializer
->
acquire
(
messages
);
...
@@ -190,9 +195,9 @@ public:
...
@@ -190,9 +195,9 @@ public:
spv
::
SpvBuildLogger
logger
;
spv
::
SpvBuildLogger
logger
;
if
(
success
&&
target
==
Target
::
Spirv
)
{
if
(
success
&&
(
target
==
Target
::
Spv
||
target
==
Target
::
BothASTAndSpv
)
)
{
std
::
vector
<
uint32_t
>
spirv_binary
;
std
::
vector
<
uint32_t
>
spirv_binary
;
glslang
::
GlslangToSpv
(
*
program
.
getIntermediate
(
language
),
glslang
::
GlslangToSpv
(
*
program
.
getIntermediate
(
kind
),
spirv_binary
,
&
logger
);
spirv_binary
,
&
logger
);
std
::
ostringstream
disassembly_stream
;
std
::
ostringstream
disassembly_stream
;
...
@@ -210,7 +215,10 @@ public:
...
@@ -210,7 +215,10 @@ public:
void
loadFileCompileAndCheck
(
const
std
::
string
&
testDir
,
void
loadFileCompileAndCheck
(
const
std
::
string
&
testDir
,
const
std
::
string
&
testName
,
const
std
::
string
&
testName
,
Semantics
semantics
,
Target
target
)
Source
source
,
Semantics
semantics
,
Target
target
,
const
std
::
string
&
entryPointName
=
""
)
{
{
const
std
::
string
inputFname
=
testDir
+
"/"
+
testName
;
const
std
::
string
inputFname
=
testDir
+
"/"
+
testName
;
const
std
::
string
expectedOutputFname
=
const
std
::
string
expectedOutputFname
=
...
@@ -221,7 +229,8 @@ public:
...
@@ -221,7 +229,8 @@ public:
tryLoadFile
(
expectedOutputFname
,
"expected output"
,
&
expectedOutput
);
tryLoadFile
(
expectedOutputFname
,
"expected output"
,
&
expectedOutput
);
GlslangResult
result
=
GlslangResult
result
=
compileGlsl
(
input
,
GetSuffix
(
testName
),
semantics
,
target
);
compile
(
input
,
source
,
GetSuffix
(
testName
),
semantics
,
target
,
entryPointName
);
// Generate the hybrid output in the way of glslangValidator.
// Generate the hybrid output in the way of glslangValidator.
std
::
ostringstream
stream
;
std
::
ostringstream
stream
;
...
@@ -236,7 +245,7 @@ public:
...
@@ -236,7 +245,7 @@ public:
outputIfNotEmpty
(
result
.
linkingOutput
);
outputIfNotEmpty
(
result
.
linkingOutput
);
outputIfNotEmpty
(
result
.
linkingError
);
outputIfNotEmpty
(
result
.
linkingError
);
stream
<<
result
.
spirvWarningsErrors
;
stream
<<
result
.
spirvWarningsErrors
;
if
(
target
==
Target
::
Sp
ir
v
)
{
if
(
target
==
Target
::
Sp
v
||
target
==
Target
::
BothASTAndSp
v
)
{
stream
stream
<<
(
result
.
spirv
.
empty
()
<<
(
result
.
spirv
.
empty
()
?
"SPIR-V is not generated for failed compile or link
\n
"
?
"SPIR-V is not generated for failed compile or link
\n
"
...
@@ -247,10 +256,10 @@ public:
...
@@ -247,10 +256,10 @@ public:
expectedOutputFname
);
expectedOutputFname
);
}
}
// Preprocesses the given
GLSL
|source| code. On success, returns true, the
// Preprocesses the given |source| code. On success, returns true, the
// preprocessed shader, and warning messages. Otherwise, returns false, an
// preprocessed shader, and warning messages. Otherwise, returns false, an
// empty string, and error messages.
// empty string, and error messages.
std
::
tuple
<
bool
,
std
::
string
,
std
::
string
>
preprocess
Glsl
(
std
::
tuple
<
bool
,
std
::
string
,
std
::
string
>
preprocess
(
const
std
::
string
&
source
)
const
std
::
string
&
source
)
{
{
const
char
*
shaderStrings
=
source
.
data
();
const
char
*
shaderStrings
=
source
.
data
();
...
@@ -290,7 +299,7 @@ public:
...
@@ -290,7 +299,7 @@ public:
bool
ppOk
;
bool
ppOk
;
std
::
string
output
,
error
;
std
::
string
output
,
error
;
std
::
tie
(
ppOk
,
output
,
error
)
=
preprocess
Glsl
(
input
);
std
::
tie
(
ppOk
,
output
,
error
)
=
preprocess
(
input
);
if
(
!
output
.
empty
())
output
+=
'\n'
;
if
(
!
output
.
empty
())
output
+=
'\n'
;
if
(
!
error
.
empty
())
error
+=
'\n'
;
if
(
!
error
.
empty
())
error
+=
'\n'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment