Commit dc4fe2d6 by John Kessenich

Merge branch 'ClemensRognerSD-dx9-sampler'

parents 5d43c4aa bd1c1831
...@@ -160,6 +160,7 @@ const char* sourceEntryPointName = nullptr; ...@@ -160,6 +160,7 @@ const char* sourceEntryPointName = nullptr;
const char* shaderStageName = nullptr; const char* shaderStageName = nullptr;
const char* variableName = nullptr; const char* variableName = nullptr;
bool HlslEnable16BitTypes = false; bool HlslEnable16BitTypes = false;
bool HlslDX9compatible = false;
std::vector<std::string> IncludeDirectoryList; std::vector<std::string> IncludeDirectoryList;
// Source environment // Source environment
...@@ -509,6 +510,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem ...@@ -509,6 +510,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options |= EOptionHlslIoMapping; Options |= EOptionHlslIoMapping;
} else if (lowerword == "hlsl-enable-16bit-types") { } else if (lowerword == "hlsl-enable-16bit-types") {
HlslEnable16BitTypes = true; HlslEnable16BitTypes = true;
} else if (lowerword == "hlsl-dx9-compatible") {
HlslDX9compatible = true;
} else if (lowerword == "invert-y" || // synonyms } else if (lowerword == "invert-y" || // synonyms
lowerword == "iy") { lowerword == "iy") {
Options |= EOptionInvertY; Options |= EOptionInvertY;
...@@ -815,6 +818,8 @@ void SetMessageOptions(EShMessages& messages) ...@@ -815,6 +818,8 @@ void SetMessageOptions(EShMessages& messages)
messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes); messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes);
if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT) if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT)
messages = (EShMessages)(messages | EShMsgHlslLegalization); messages = (EShMessages)(messages | EShMsgHlslLegalization);
if (HlslDX9compatible)
messages = (EShMessages)(messages | EShMsgHlslDX9Compatible);
} }
// //
...@@ -1509,6 +1514,7 @@ void usage() ...@@ -1509,6 +1514,7 @@ void usage()
" works independently of source language\n" " works independently of source language\n"
" --hlsl-iomap perform IO mapping in HLSL register space\n" " --hlsl-iomap perform IO mapping in HLSL register space\n"
" --hlsl-enable-16bit-types allow 16-bit types in SPIR-V for HLSL\n" " --hlsl-enable-16bit-types allow 16-bit types in SPIR-V for HLSL\n"
" --hlsl-dx9-compatible interprets sampler declarations as a texture/sampler combo like DirectX9 would."
" --invert-y | --iy invert position.Y output in vertex shader\n" " --invert-y | --iy invert position.Y output in vertex shader\n"
" --keep-uncalled | --ku don't eliminate uncalled functions\n" " --keep-uncalled | --ku don't eliminate uncalled functions\n"
" --no-storage-format | --nsf use Unknown image format\n" " --no-storage-format | --nsf use Unknown image format\n"
......
sampler g_sam : register(t0);
sampler1D g_sam1D : register(t1);
sampler2D g_sam2D : register(t2);
sampler3D g_sam3D : register(t3);
samplerCube g_samCube : register(t4);
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 ColorOut = float4(0,0,0,0);
ColorOut += tex2D( g_sam , float2(0.4,0.3));
ColorOut += tex1D( g_sam1D, 0.5);
ColorOut += tex2D( g_sam2D, float2(0.5,0.6));
ColorOut += tex3D( g_sam3D, float3(0.5,0.6,0.4));
ColorOut += texCUBE( g_samCube, float3(0.5,0.6,0.4));
ColorOut += tex2Dlod( g_sam , float4(0.4,0.3,0.0,0.0));
ColorOut += tex1Dlod( g_sam1D, float4(0.5,0.0,0.0,0.0));
ColorOut += tex2Dlod( g_sam2D, float4(0.5,0.6,0.0,0.0));
ColorOut += tex3Dlod( g_sam3D, float4(0.5,0.6,0.4,0.0));
ColorOut += texCUBElod( g_samCube, float4(0.5,0.6,0.4,0.0));
psout.Color = ColorOut / 10.0f;
psout.Depth = 1.0;
return psout;
}
sampler g_sam : register(t0);
sampler2D g_sam2D : register(t1);
struct VS_OUTPUT
{
float4 Pos : SV_Position;
};
VS_OUTPUT main()
{
VS_OUTPUT vsout;
float4 PosOut = float4(0,0,0,0);
PosOut += tex2Dlod( g_sam , float4(0.3f, 0.4f, 0.0f, 1.0f));
PosOut += tex2Dlod( g_sam2D, float4(0.5f, 0.6f, 0.0f, 1.0f));
vsout.Pos = PosOut / 2.0f;
return vsout;
}
...@@ -130,6 +130,7 @@ public: ...@@ -130,6 +130,7 @@ public:
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
TInfoSink& infoSink; TInfoSink& infoSink;
......
...@@ -235,6 +235,7 @@ enum EShMessages { ...@@ -235,6 +235,7 @@ enum EShMessages {
EShMsgDebugInfo = (1 << 10), // save debug information EShMsgDebugInfo = (1 << 10), // save debug information
EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
}; };
// //
......
...@@ -62,6 +62,7 @@ using HlslVulkan1_1CompileTest = GlslangTest<::testing::TestWithParam<FileNameEn ...@@ -62,6 +62,7 @@ using HlslVulkan1_1CompileTest = GlslangTest<::testing::TestWithParam<FileNameEn
using HlslCompileAndFlattenTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>; using HlslCompileAndFlattenTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslLegalizeTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>; using HlslLegalizeTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslDebugTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>; using HlslDebugTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
using HlslDX9CompatibleTest = GlslangTest<::testing::TestWithParam<FileNameEntryPointPair>>;
// Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected // Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected
// to successfully generate both AST and SPIR-V. // to successfully generate both AST and SPIR-V.
...@@ -106,6 +107,14 @@ TEST_P(HlslDebugTest, FromFile) ...@@ -106,6 +107,14 @@ TEST_P(HlslDebugTest, FromFile)
"/baseResults/", false, true); "/baseResults/", false, true);
} }
TEST_P(HlslDX9CompatibleTest, FromFile)
{
loadFileCompileAndCheckWithOptions(GlobalTestSettings.testRoot, GetParam().fileName, Source::HLSL,
Semantics::Vulkan, glslang::EShTargetVulkan_1_0, Target::BothASTAndSpv, true,
GetParam().entryPoint, "/baseResults/",
EShMessages::EShMsgHlslDX9Compatible);
}
// clang-format off // clang-format off
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
ToSpirv, HlslCompileTest, ToSpirv, HlslCompileTest,
...@@ -457,6 +466,15 @@ INSTANTIATE_TEST_CASE_P( ...@@ -457,6 +466,15 @@ INSTANTIATE_TEST_CASE_P(
FileNameAsCustomTestSuffix FileNameAsCustomTestSuffix
); );
INSTANTIATE_TEST_CASE_P(
ToSpirv, HlslDX9CompatibleTest,
::testing::ValuesIn(std::vector<FileNameEntryPointPair>{
{"hlsl.sample.dx9.frag", "main"},
{"hlsl.sample.dx9.vert", "main"},
}),
FileNameAsCustomTestSuffix
);
// clang-format on // clang-format on
} // anonymous namespace } // anonymous namespace
} // namespace glslangtest } // namespace glslangtest
...@@ -460,6 +460,34 @@ public: ...@@ -460,6 +460,34 @@ public:
expectedOutputFname, result.spirvWarningsErrors); expectedOutputFname, result.spirvWarningsErrors);
} }
void loadFileCompileAndCheckWithOptions(const std::string &testDir,
const std::string &testName,
Source source,
Semantics semantics,
glslang::EShTargetClientVersion clientTargetVersion,
Target target, bool automap = true, const std::string &entryPointName = "",
const std::string &baseDir = "/baseResults/",
const EShMessages additionalOptions = EShMessages::EShMsgDefault)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname = testDir + baseDir + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
EShMessages controls = DeriveOptions(source, semantics, target);
controls = static_cast<EShMessages>(controls | additionalOptions);
GlslangResult result = compileAndLink(testName, input, entryPointName, controls, clientTargetVersion, false,
EShTexSampTransKeep, false, automap);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname);
}
void loadFileCompileFlattenUniformsAndCheck(const std::string& testDir, void loadFileCompileFlattenUniformsAndCheck(const std::string& testDir,
const std::string& testName, const std::string& testName,
Source source, Source source,
......
...@@ -1163,6 +1163,49 @@ bool HlslGrammar::acceptSubpassInputType(TType& type) ...@@ -1163,6 +1163,49 @@ bool HlslGrammar::acceptSubpassInputType(TType& type)
return true; return true;
} }
// sampler_type for DX9 compatibility
// : SAMPLER
// | SAMPLER1D
// | SAMPLER2D
// | SAMPLER3D
// | SAMPLERCUBE
bool HlslGrammar::acceptSamplerTypeDX9(TType &type)
{
// read sampler type
const EHlslTokenClass samplerType = peek();
TSamplerDim dim = EsdNone;
TType txType(EbtFloat, EvqUniform, 4); // default type is float4
bool isShadow = false;
switch (samplerType)
{
case EHTokSampler: dim = Esd2D; break;
case EHTokSampler1d: dim = Esd1D; break;
case EHTokSampler2d: dim = Esd2D; break;
case EHTokSampler3d: dim = Esd3D; break;
case EHTokSamplerCube: dim = EsdCube; break;
default:
return false; // not a dx9 sampler declaration
}
advanceToken(); // consume the sampler type keyword
TArraySizes *arraySizes = nullptr; // TODO: array
TSampler sampler;
sampler.set(txType.getBasicType(), dim, false, isShadow, false);
if (!parseContext.setTextureReturnType(sampler, txType, token.loc))
return false;
type.shallowCopy(TType(sampler, EvqUniform, arraySizes));
type.getQualifier().layoutFormat = ElfNone;
return true;
}
// sampler_type // sampler_type
// : SAMPLER // : SAMPLER
// | SAMPLER1D // | SAMPLER1D
...@@ -1445,7 +1488,13 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList) ...@@ -1445,7 +1488,13 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList)
case EHTokSampler2d: // ... case EHTokSampler2d: // ...
case EHTokSampler3d: // ... case EHTokSampler3d: // ...
case EHTokSamplerCube: // ... case EHTokSamplerCube: // ...
case EHTokSamplerState: // ... if (parseContext.hlslDX9Compatible())
return acceptSamplerTypeDX9(type);
else
return acceptSamplerType(type);
break;
case EHTokSamplerState: // fall through
case EHTokSamplerComparisonState: // ... case EHTokSamplerComparisonState: // ...
return acceptSamplerType(type); return acceptSamplerType(type);
break; break;
......
...@@ -84,6 +84,7 @@ namespace glslang { ...@@ -84,6 +84,7 @@ namespace glslang {
bool acceptStreamOutTemplateType(TType&, TLayoutGeometry&); bool acceptStreamOutTemplateType(TType&, TLayoutGeometry&);
bool acceptOutputPrimitiveGeometry(TLayoutGeometry&); bool acceptOutputPrimitiveGeometry(TLayoutGeometry&);
bool acceptAnnotations(TQualifier&); bool acceptAnnotations(TQualifier&);
bool acceptSamplerTypeDX9(TType &);
bool acceptSamplerType(TType&); bool acceptSamplerType(TType&);
bool acceptTextureType(TType&); bool acceptTextureType(TType&);
bool acceptSubpassInputType(TType&); bool acceptSubpassInputType(TType&);
......
...@@ -3770,6 +3770,43 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType ...@@ -3770,6 +3770,43 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
break; break;
} }
case EOpTextureLod: //is almost EOpTextureBias (only args & operations are different)
{
TIntermTyped *argSamp = argAggregate->getSequence()[0]->getAsTyped(); // sampler
TIntermTyped *argCoord = argAggregate->getSequence()[1]->getAsTyped(); // coord
assert(argCoord->getVectorSize() == 4);
TIntermTyped *w = intermediate.addConstantUnion(3, loc, true);
TIntermTyped *argLod = intermediate.addIndex(EOpIndexDirect, argCoord, w, loc);
TOperator constructOp = EOpNull;
const TSampler &sampler = argSamp->getType().getSampler();
int coordSize = 0;
switch (sampler.dim)
{
case Esd1D: constructOp = EOpConstructFloat; coordSize = 1; break; // 1D
case Esd2D: constructOp = EOpConstructVec2; coordSize = 2; break; // 2D
case Esd3D: constructOp = EOpConstructVec3; coordSize = 3; break; // 3D
case EsdCube: constructOp = EOpConstructVec3; coordSize = 3; break; // also 3D
default:
break;
}
TIntermAggregate *constructCoord = new TIntermAggregate(constructOp);
constructCoord->getSequence().push_back(argCoord);
constructCoord->setLoc(loc);
constructCoord->setType(TType(argCoord->getBasicType(), EvqTemporary, coordSize));
TIntermAggregate *tex = new TIntermAggregate(EOpTextureLod);
tex->getSequence().push_back(argSamp); // sampler
tex->getSequence().push_back(constructCoord); // coordinate
tex->getSequence().push_back(argLod); // lod
node = convertReturn(tex, sampler);
break;
}
case EOpTextureBias: case EOpTextureBias:
{ {
......
...@@ -698,17 +698,17 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c ...@@ -698,17 +698,17 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
{ "step", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, { "step", nullptr, nullptr, "SVM,", "F,", EShLangAll, false },
{ "tan", nullptr, nullptr, "SVM", "F", EShLangAll, false }, { "tan", nullptr, nullptr, "SVM", "F", EShLangAll, false },
{ "tanh", nullptr, nullptr, "SVM", "F", EShLangAll, false }, { "tanh", nullptr, nullptr, "SVM", "F", EShLangAll, false },
{ "tex1D", "V4", "F", "V1,S", "S,F", EShLangPS, false }, { "tex1D", "V4", "F", "S,S", "S,F", EShLangPS, false },
{ "tex1D", "V4", "F", "V1,S,V1,", "S,F,,", EShLangPS, false }, { "tex1D", "V4", "F", "S,S,V1,", "S,F,,", EShLangPS, false },
{ "tex1Dbias", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, { "tex1Dbias", "V4", "F", "S,V4", "S,F", EShLangPS, false },
{ "tex1Dgrad", "V4", "F", "V1,,,", "S,F,,", EShLangPS, false }, { "tex1Dgrad", "V4", "F", "S,,,", "S,F,,", EShLangPS, false },
{ "tex1Dlod", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, { "tex1Dlod", "V4", "F", "S,V4", "S,F", EShLangPS, false },
{ "tex1Dproj", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, { "tex1Dproj", "V4", "F", "S,V4", "S,F", EShLangPS, false },
{ "tex2D", "V4", "F", "V2,", "S,F", EShLangPS, false }, { "tex2D", "V4", "F", "V2,", "S,F", EShLangPS, false },
{ "tex2D", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, { "tex2D", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false },
{ "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, { "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangPS, false },
{ "tex2Dgrad", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, { "tex2Dgrad", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false },
{ "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, { "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangAll, false },
{ "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, { "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangPS, false },
{ "tex3D", "V4", "F", "V3,", "S,F", EShLangPS, false }, { "tex3D", "V4", "F", "V3,", "S,F", EShLangPS, false },
{ "tex3D", "V4", "F", "V3,,,", "S,F,,", EShLangPS, false }, { "tex3D", "V4", "F", "V3,,,", "S,F,,", EShLangPS, false },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment