Commit f2451019 by LoopDawg

HLSL: Add texture Load method & decomposition

parent 83768cb5
...@@ -34,51 +34,31 @@ struct PS_OUTPUT ...@@ -34,51 +34,31 @@ struct PS_OUTPUT
float Depth : SV_Depth; float Depth : SV_Depth;
}; };
uniform int c1;
uniform int2 c2;
uniform int3 c3;
uniform int4 c4;
uniform int o1;
uniform int2 o2;
uniform int3 o3;
uniform int4 o4;
PS_OUTPUT main() PS_OUTPUT main()
{ {
PS_OUTPUT psout; PS_OUTPUT psout;
// Load, no offset // 1DArray
g_tTex1df4.Load(int2(1,2)); g_tTex1df4a.Load(c3);
g_tTex1di4.Load(int2(1,2)); g_tTex1di4a.Load(c3);
g_tTex1du4.Load(int2(1,2)); g_tTex1du4a.Load(c3);
g_tTex2df4.Load(int3(1,2,3));
g_tTex2di4.Load(int3(1,2,3));
g_tTex2du4.Load(int3(1,2,3));
g_tTex3df4.Load(int4(1,2,3,4));
g_tTex3di4.Load(int4(1,2,3,4));
g_tTex3du4.Load(int4(1,2,3,4));
g_tTex1df4a.Load(int3(1,2,3));
g_tTex1di4a.Load(int3(1,2,3));
g_tTex1du4a.Load(int3(1,2,3));
g_tTex2df4a.Load(int4(1,2,3,4));
g_tTex2di4a.Load(int4(1,2,3,4));
g_tTex2du4a.Load(int4(1,2,3,4));
// Load, offset
g_tTex1df4.Load(int2(1,2), 3);
g_tTex1di4.Load(int2(1,2), 3);
g_tTex1du4.Load(int2(1,2), 3);
g_tTex2df4.Load(int3(1,2,3), int2(4,5));
g_tTex2di4.Load(int3(1,2,3), int2(4,5));
g_tTex2du4.Load(int3(1,2,3), int2(4,5));
g_tTex3df4.Load(int4(1,2,3,4), int3(5,6,7));
g_tTex3di4.Load(int4(1,2,3,4), int3(5,6,7));
g_tTex3du4.Load(int4(1,2,3,4), int3(5,6,7));
g_tTex1df4a.Load(int3(1,2,3), 4); // 2DArray
g_tTex1di4a.Load(int3(1,2,3), 4); g_tTex2df4a.Load(c4);
g_tTex1du4a.Load(int3(1,2,3), 4); g_tTex2di4a.Load(c4);
g_tTex2du4a.Load(c4);
g_tTex2df4a.Load(int4(1,2,3,4), int2(4,5)); // Offset has no Cube or CubeArray forms
g_tTex2di4a.Load(int4(1,2,3,4), int2(4,5));
g_tTex2du4a.Load(int4(1,2,3,4), int2(4,5));
// TODO: // TODO:
// Load, SampleIndex // Load, SampleIndex
......
SamplerState g_sSamp : register(s0);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
Texture1DArray <float4> g_tTex1df4a;
Texture1DArray <int4> g_tTex1di4a;
Texture1DArray <uint4> g_tTex1du4a;
Texture2DArray <float4> g_tTex2df4a;
Texture2DArray <int4> g_tTex2di4a;
Texture2DArray <uint4> g_tTex2du4a;
TextureCubeArray <float4> g_tTexcdf4a;
TextureCubeArray <int4> g_tTexcdi4a;
TextureCubeArray <uint4> g_tTexcdu4a;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
uniform int c1;
uniform int2 c2;
uniform int3 c3;
uniform int4 c4;
uniform int o1;
uniform int2 o2;
uniform int3 o3;
uniform int4 o4;
PS_OUTPUT main()
{
PS_OUTPUT psout;
// 1D
g_tTex1df4.Load(c2);
g_tTex1di4.Load(c2);
g_tTex1du4.Load(c2);
// 2D
g_tTex2df4.Load(c3);
g_tTex2di4.Load(c3);
g_tTex2du4.Load(c3);
// 3D
g_tTex3df4.Load(c4);
g_tTex3di4.Load(c4);
g_tTex3du4.Load(c4);
// Offset has no Cube or CubeArray forms
// TODO:
// Load, SampleIndex
// Load, SampleIndex, Offset
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
Texture1DArray <float4> g_tTex1df4a;
Texture1DArray <int4> g_tTex1di4a;
Texture1DArray <uint4> g_tTex1du4a;
Texture2DArray <float4> g_tTex2df4a;
Texture2DArray <int4> g_tTex2di4a;
Texture2DArray <uint4> g_tTex2du4a;
TextureCubeArray <float4> g_tTexcdf4a;
TextureCubeArray <int4> g_tTexcdi4a;
TextureCubeArray <uint4> g_tTexcdu4a;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
uniform int c1;
uniform int2 c2;
uniform int3 c3;
uniform int4 c4;
uniform int o1;
uniform int2 o2;
uniform int3 o3;
uniform int4 o4;
PS_OUTPUT main()
{
PS_OUTPUT psout;
// 1D
g_tTex1df4.Load(c2, o1);
g_tTex1di4.Load(c2, o1);
g_tTex1du4.Load(c2, o1);
// 2D
g_tTex2df4.Load(c3, o2);
g_tTex2di4.Load(c3, o2);
g_tTex2du4.Load(c3, o2);
// 3D
g_tTex3df4.Load(c4, o3);
g_tTex3di4.Load(c4, o3);
g_tTex3du4.Load(c4, o3);
// Offset has no Cube or CubeArray forms
// TODO:
// Load, SampleIndex
// Load, SampleIndex, Offset
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
Texture1DArray <float4> g_tTex1df4a;
Texture1DArray <int4> g_tTex1di4a;
Texture1DArray <uint4> g_tTex1du4a;
Texture2DArray <float4> g_tTex2df4a;
Texture2DArray <int4> g_tTex2di4a;
Texture2DArray <uint4> g_tTex2du4a;
TextureCubeArray <float4> g_tTexcdf4a;
TextureCubeArray <int4> g_tTexcdi4a;
TextureCubeArray <uint4> g_tTexcdu4a;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
uniform int c1;
uniform int2 c2;
uniform int3 c3;
uniform int4 c4;
uniform int o1;
uniform int2 o2;
uniform int3 o3;
uniform int4 o4;
PS_OUTPUT main()
{
PS_OUTPUT psout;
// 1DArray
g_tTex1df4a.Load(c3, o1);
g_tTex1di4a.Load(c3, o1);
g_tTex1du4a.Load(c3, o1);
// 2DArray
g_tTex2df4a.Load(c4, o2);
g_tTex2di4a.Load(c4, o2);
g_tTex2du4a.Load(c4, o2);
// TODO:
// Load, SampleIndex
// Load, SampleIndex, Offset
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
...@@ -86,6 +86,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, ...@@ -86,6 +86,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool isTexture() const { return !sampler && !image; } bool isTexture() const { return !sampler && !image; }
bool isShadow() const { return shadow; } bool isShadow() const { return shadow; }
bool isArrayed() const { return arrayed; } bool isArrayed() const { return arrayed; }
bool isMultiSample() const { return ms; }
void clear() void clear()
{ {
......
// //
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//Copyright (C) 2016 LunarG, Inc.
//All rights reserved. //All rights reserved.
// //
//Redistribution and use in source and binary forms, with or without //Redistribution and use in source and binary forms, with or without
...@@ -47,6 +48,16 @@ class TInfoSink; ...@@ -47,6 +48,16 @@ class TInfoSink;
namespace glslang { namespace glslang {
struct TVectorFields { struct TVectorFields {
TVectorFields() { }
TVectorFields(int c0, int c1, int c2, int c3) : num(4)
{
offsets[0] = c0;
offsets[1] = c1;
offsets[2] = c2;
offsets[3] = c3;
}
int offsets[4]; int offsets[4];
int num; int num;
}; };
......
...@@ -96,6 +96,10 @@ INSTANTIATE_TEST_CASE_P( ...@@ -96,6 +96,10 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"}, {"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"}, {"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
{"hlsl.load.array.dx10.frag", "main"},
{"hlsl.load.basic.dx10.frag", "main"},
{"hlsl.load.offset.dx10.frag", "main"},
{"hlsl.load.offsetarray.dx10.frag", "main"},
{"hlsl.sample.array.dx10.frag", "main"}, {"hlsl.sample.array.dx10.frag", "main"},
{"hlsl.sample.basic.dx10.frag", "main"}, {"hlsl.sample.basic.dx10.frag", "main"},
{"hlsl.sample.offset.dx10.frag", "main"}, {"hlsl.sample.offset.dx10.frag", "main"},
......
...@@ -1124,6 +1124,71 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType ...@@ -1124,6 +1124,71 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
break; break;
} }
case EOpMethodLoad:
{
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* argCoord = argAggregate->getSequence()[1]->getAsTyped();
TIntermTyped* argOffset = nullptr;
TIntermTyped* lodComponent = nullptr;
TIntermTyped* coordSwizzle = nullptr;
const bool isMS = argTex->getType().getSampler().isMultiSample();
const TBasicType coordBaseType = argCoord->getType().getBasicType();
// Last component of coordinate is the mip level, for non-MS. we separate them here:
if (isMS) {
// MS has no LOD
coordSwizzle = argTex;
} else {
// Extract coordinate
TVectorFields coordFields(0,1,2,3);
coordFields.num = argCoord->getType().getVectorSize() - (isMS ? 0 : 1);
TIntermTyped* coordIdx = intermediate.addSwizzle(coordFields, loc);
coordSwizzle = intermediate.addIndex(EOpVectorSwizzle, argCoord, coordIdx, loc);
coordSwizzle->setType(TType(coordBaseType, EvqTemporary, coordFields.num));
// Extract LOD
TIntermTyped* lodIdx = intermediate.addConstantUnion(coordFields.num, loc, true);
lodComponent = intermediate.addIndex(EOpIndexDirect, argCoord, lodIdx, loc);
lodComponent->setType(TType(coordBaseType, EvqTemporary, 1));
}
const int numArgs = argAggregate->getSequence().size();
const bool hasOffset = ((!isMS && numArgs == 3) || (isMS && numArgs == 4));
// Obtain offset arg, if there is one.
if (hasOffset) {
const int offsetPos = (isMS ? 3 : 2);
argOffset = argAggregate->getSequence()[offsetPos]->getAsTyped();
}
// Create texel fetch
const TOperator fetchOp = (hasOffset ? EOpTextureFetchOffset : EOpTextureFetch);
TIntermAggregate* txfetch = new TIntermAggregate(fetchOp);
const TSamplerDim dim = argTex->getType().getSampler().dim;
if (dim == EsdBuffer) // TODO: buffers
assert(0);
if (isMS) // TODO: 2DMS sample number
assert(0);
// Build up the fetch
txfetch->getSequence().push_back(argTex);
txfetch->getSequence().push_back(coordSwizzle);
if (!isMS) // MS has no LOD
txfetch->getSequence().push_back(lodComponent);
if (hasOffset)
txfetch->getSequence().push_back(argOffset);
txfetch->setType(node->getType());
txfetch->setLoc(loc);
node = txfetch;
break;
}
default: default:
break; // most pass through unchanged break; // most pass through unchanged
} }
......
...@@ -593,10 +593,10 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c ...@@ -593,10 +593,10 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
// { "SampleLevel", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangAll }, // { "SampleLevel", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangAll },
// { "SampleLevel", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangAll }, // { "SampleLevel", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangAll },
// { "Load", "V4", nullptr, "%V,V", "FIU,I", EShLangAll }, { "Load", /*!O !A*/ "V4", nullptr, "%V,V", "FIU,I", EShLangAll },
// { "Load", "V4", nullptr, "@V,V", "FIU,I", EShLangAll }, { "Load", /*!O A*/ "V4", nullptr, "@V,V", "FIU,I", EShLangAll },
// { "Load", /* offset*/ "V4", nullptr, "%V,V,V", "FIU,I,I", EShLangAll }, { "Load", /* O !A*/ "V4", nullptr, "%V,V,V", "FIU,I,I", EShLangAll },
// { "Load", /* offset*/ "V4", nullptr, "@V,V,V", "FIU,I,I", EShLangAll }, { "Load", /* O A*/ "V4", nullptr, "@V,V,V", "FIU,I,I", EShLangAll },
// TODO: MS variants of Load // TODO: MS variants of Load
// { "Load", /* +sampleidex*/ "V4", nullptr, "$V,V,S", "FIU,I,I", EShLangAll }, // { "Load", /* +sampleidex*/ "V4", nullptr, "$V,V,S", "FIU,I,I", EShLangAll },
// { "Load", /* +samplindex, offset*/ "V4", nullptr, "$V,V,S,V", "FIU,I,I,I", EShLangAll }, // { "Load", /* +samplindex, offset*/ "V4", nullptr, "$V,V,S,V", "FIU,I,I,I", EShLangAll },
...@@ -944,7 +944,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil ...@@ -944,7 +944,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
symbolTable.relateToOperator("SampleCmpLevelZero", EOpMethodSampleCmpLevelZero); symbolTable.relateToOperator("SampleCmpLevelZero", EOpMethodSampleCmpLevelZero);
symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad); symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad);
// symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel); // symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel);
// symbolTable.relateToOperator("Load", EOpMethodLoad); symbolTable.relateToOperator("Load", EOpMethodLoad);
symbolTable.relateToOperator("GetDimensions", EOpMethodGetDimensions); symbolTable.relateToOperator("GetDimensions", EOpMethodGetDimensions);
} }
......
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