Commit 3a137966 by Chao Chen

0003-Add-support-for-SPV_NV_shader_image_footprint

parent beae2251
......@@ -33,7 +33,7 @@ enum Op;
enum Capability;
static const int GLSLextNVVersion = 100;
static const int GLSLextNVRevision = 7;
static const int GLSLextNVRevision = 8;
//SPV_NV_sample_mask_override_coverage
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
......@@ -60,4 +60,7 @@ const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader
//SPV_NV_compute_shader_derivatives
const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives";
//SPV_NV_shader_image_footprint
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";
#endif // #ifndef GLSLextNV_H
\ No newline at end of file
......@@ -3668,6 +3668,25 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
lvalue = true;
break;
#endif
#ifdef NV_EXTENSIONS
case glslang::EOpImageSampleFootprintNV:
if (i == 4)
lvalue = true;
break;
case glslang::EOpImageSampleFootprintClampNV:
case glslang::EOpImageSampleFootprintLodNV:
if (i == 5)
lvalue = true;
break;
case glslang::EOpImageSampleFootprintGradNV:
if (i == 6)
lvalue = true;
break;
case glslang::EOpImageSampleFootprintGradClampNV:
if (i == 7)
lvalue = true;
break;
#endif
default:
break;
}
......@@ -4020,6 +4039,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
// Check for texture functions other than queries
bool sparse = node->isSparseTexture();
#ifdef NV_EXTENSIONS
bool imageFootprint = node->isImageFootprint();
#endif
bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
// check for bias argument
......@@ -4049,7 +4072,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
++nonBiasArgCount;
if (sparse)
++nonBiasArgCount;
#ifdef NV_EXTENSIONS
if (imageFootprint)
//Following three extra arguments
// int granularity, bool coarse, out gl_TextureFootprint2DNV footprint
nonBiasArgCount += 3;
#endif
if ((int)arguments.size() > nonBiasArgCount)
bias = true;
}
......@@ -4142,7 +4170,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
params.lodClamp = arguments[2 + extraArgs];
++extraArgs;
}
// sparse
if (sparse) {
params.texelOut = arguments[2 + extraArgs];
......@@ -4158,13 +4185,81 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} else
params.component = builder.makeIntConstant(0);
}
#ifdef NV_EXTENSIONS
spv::Id resultStruct = spv::NoResult;
if (imageFootprint) {
//Following three extra arguments
// int granularity, bool coarse, out gl_TextureFootprint2DNV footprint
params.granularity = arguments[2 + extraArgs];
params.coarse = arguments[3 + extraArgs];
resultStruct = arguments[4 + extraArgs];
extraArgs += 3;
}
#endif
// bias
if (bias) {
params.bias = arguments[2 + extraArgs];
++extraArgs;
}
#ifdef NV_EXTENSIONS
if (imageFootprint) {
builder.addExtension(spv::E_SPV_NV_shader_image_footprint);
builder.addCapability(spv::CapabilityImageFootprintNV);
//resultStructType(OpenGL type) contains 5 elements:
//struct gl_TextureFootprint2DNV {
// uvec2 anchor;
// uvec2 offset;
// uvec2 mask;
// uint lod;
// uint granularity;
//};
//or
//struct gl_TextureFootprint3DNV {
// uvec3 anchor;
// uvec3 offset;
// uvec2 mask;
// uint lod;
// uint granularity;
//};
spv::Id resultStructType = builder.getContainedTypeId(builder.getTypeId(resultStruct));
assert(builder.isStructType(resultStructType));
//resType (SPIR-V type) contains 6 elements:
//Member 0 must be a Boolean type scalar(LOD),
//Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor),
//Member 2 must be a vector of integer type, whose Signedness operand is 0(offset),
//Member 3 must be a vector of integer type, whose Signedness operand is 0(mask),
//Member 4 must be a scalar of integer type, whose Signedness operand is 0(lod),
//Member 5 must be a scalar of integer type, whose Signedness operand is 0(granularity).
std::vector<spv::Id> members;
members.push_back(resultType());
for (int i = 0; i < 5; i++) {
members.push_back(builder.getContainedTypeId(resultStructType, i));
}
spv::Id resType = builder.makeStructType(members, "ResType");
//call ImageFootprintNV
spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params);
//copy resType (SPIR-V type) to resultStructType(OpenGL type)
for (int i = 0; i < 5; i++) {
builder.clearAccessChain();
builder.setAccessChainLValue(resultStruct);
//Accessing to a struct we created, no coherent flag is set
spv::Builder::AccessChain::CoherentFlags flags;
flags.clear();
builder.accessChainPush(builder.makeIntConstant(i), flags);
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
}
return builder.createCompositeExtract(res, resultType(), 0);
}
#endif
// projective component (might not to move)
// GLSL: "The texture coordinates consumed from P, not including the last component of P,
// are divided by the last component of P."
......
......@@ -1654,6 +1654,13 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
if (parameters.component != NoResult)
texArgs[numArgs++] = parameters.component;
#ifdef NV_EXTENSIONS
if (parameters.granularity != NoResult)
texArgs[numArgs++] = parameters.granularity;
if (parameters.coarse != NoResult)
texArgs[numArgs++] = parameters.coarse;
#endif
//
// Set up the optional arguments
//
......@@ -1725,6 +1732,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
opCode = OpImageSparseFetch;
else
opCode = OpImageFetch;
#ifdef NV_EXTENSIONS
} else if (parameters.granularity && parameters.coarse) {
opCode = OpImageSampleFootprintNV;
#endif
} else if (gather) {
if (parameters.Dref)
if (sparse)
......
......@@ -366,6 +366,10 @@ public:
Id component;
Id texelOut;
Id lodClamp;
#ifdef NV_EXTENSIONS
Id granularity;
Id coarse;
#endif
bool nonprivate;
bool volatil;
};
......
......@@ -1251,7 +1251,9 @@ const char* OpcodeString(int op)
#ifdef NV_EXTENSIONS
case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV";
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
#endif
default:
return "Bad";
}
......@@ -2596,6 +2598,12 @@ void Parameterize()
#ifdef NV_EXTENSIONS
InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coarse'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandVariableIds, "", true);
#endif
}
......
#version 450
#extension GL_NV_shader_texture_footprint : require
layout (location = 0) in vec2 P2;
layout (location = 2) in vec3 P3;
layout (location = 3) in flat int granularity;
layout (location = 4) in float lodClamp;
layout (location = 5) in float lod;
layout (location = 6) in vec2 dx;
layout (location = 8) in vec2 dy;
layout (location = 9) in float bias;
uniform sampler2D sample2D;
uniform sampler3D sample3D;
buffer result2D {
bool ret2D;
uvec2 anchor2D;
uvec2 offset2D;
uvec2 mask2D;
uint lod2D;
uint granularity2D;
};
buffer result3D {
bool ret3D;
uvec3 anchor3D;
uvec3 offset3D;
uvec2 mask3D;
uint lod3D;
uint granularity3D;
};
void main() {
gl_TextureFootprint2DNV fp2D;
gl_TextureFootprint3DNV fp3D;
ret2D = textureFootprintNV(sample2D, P2, granularity, true, fp2D);
anchor2D = fp2D.anchor;
offset2D = fp2D.offset;
mask2D = fp2D.mask;
lod2D = fp2D.lod;
granularity2D = fp2D.granularity;
ret2D = textureFootprintNV(sample2D, P2, granularity, true, fp2D, bias);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret2D = textureFootprintClampNV(sample2D, P2, lodClamp, granularity, true, fp2D);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret2D = textureFootprintClampNV(sample2D, P2, lodClamp, granularity, true, fp2D, bias);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret2D = textureFootprintLodNV(sample2D, P2, lod, granularity, true, fp2D);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret2D = textureFootprintGradNV(sample2D, P2, dx, dy, granularity, true, fp2D);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret2D = textureFootprintGradClampNV(sample2D, P2, dx, dy, lodClamp, granularity, true, fp2D);
anchor2D += fp2D.anchor;
offset2D += fp2D.offset;
mask2D += fp2D.mask;
lod2D += fp2D.lod;
granularity2D += fp2D.granularity;
ret3D = textureFootprintNV(sample3D, P3, granularity, true, fp3D);
anchor3D = fp3D.anchor;
offset3D = fp3D.offset;
mask3D = fp3D.mask;
lod3D = fp3D.lod;
granularity3D = fp3D.granularity;
ret3D = textureFootprintNV(sample3D, P3, granularity, true, fp3D, bias);
anchor3D += fp3D.anchor;
offset3D += fp3D.offset;
mask3D += fp3D.mask;
lod3D += fp3D.lod;
granularity3D += fp3D.granularity;
ret3D = textureFootprintClampNV(sample3D, P3, lodClamp, granularity, true, fp3D);
anchor3D += fp3D.anchor;
offset3D += fp3D.offset;
mask3D += fp3D.mask;
lod3D += fp3D.lod;
granularity3D += fp3D.granularity;
ret3D = textureFootprintClampNV(sample3D, P3, lodClamp, granularity, true, fp3D, bias);
anchor3D += fp3D.anchor;
offset3D += fp3D.offset;
mask3D += fp3D.mask;
lod3D += fp3D.lod;
granularity3D += fp3D.granularity;
ret3D = textureFootprintLodNV(sample3D, P3, lod, granularity, true, fp3D);
anchor3D += fp3D.anchor;
offset3D += fp3D.offset;
mask3D += fp3D.mask;
lod3D += fp3D.lod;
granularity3D += fp3D.granularity;
}
\ No newline at end of file
......@@ -865,6 +865,16 @@ enum TOperator {
#endif
EOpSparseTextureGuardEnd,
#ifdef NV_EXTENSIONS
EOpImageFootprintGuardBegin,
EOpImageSampleFootprintNV,
EOpImageSampleFootprintClampNV,
EOpImageSampleFootprintLodNV,
EOpImageSampleFootprintGradNV,
EOpImageSampleFootprintGradClampNV,
EOpImageFootprintGuardEnd,
#endif
EOpSamplingGuardEnd,
EOpTextureGuardEnd,
......@@ -1248,6 +1258,9 @@ public:
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
#ifdef NV_EXTENSIONS
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
#endif
bool isSparseImage() const { return op == EOpSparseImageLoad; }
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
......@@ -1421,6 +1434,23 @@ public:
cracked.fragMask = true;
break;
#endif
#ifdef NV_EXTENSIONS
case EOpImageSampleFootprintNV:
break;
case EOpImageSampleFootprintClampNV:
cracked.lodClamp = true;
break;
case EOpImageSampleFootprintLodNV:
cracked.lod = true;
break;
case EOpImageSampleFootprintGradNV:
cracked.grad = true;
break;
case EOpImageSampleFootprintGradClampNV:
cracked.lodClamp = true;
cracked.grad = true;
break;
#endif
case EOpSubpassLoad:
case EOpSubpassLoadMS:
cracked.subpass = true;
......
......@@ -3850,6 +3850,42 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
#endif // AMD_EXTENSIONS
#ifdef NV_EXTENSIONS
if ((profile != EEsProfile && version >= 450) ||
(profile == EEsProfile && version >= 320)) {
commonBuiltins.append(
"struct gl_TextureFootprint2DNV {"
"uvec2 anchor;"
"uvec2 offset;"
"uvec2 mask;"
"uint lod;"
"uint granularity;"
"};"
"struct gl_TextureFootprint3DNV {"
"uvec3 anchor;"
"uvec3 offset;"
"uvec2 mask;"
"uint lod;"
"uint granularity;"
"};"
"bool textureFootprintNV(sampler2D, vec2, int, bool, out gl_TextureFootprint2DNV);"
"bool textureFootprintNV(sampler3D, vec3, int, bool, out gl_TextureFootprint3DNV);"
"bool textureFootprintNV(sampler2D, vec2, int, bool, out gl_TextureFootprint2DNV, float);"
"bool textureFootprintNV(sampler3D, vec3, int, bool, out gl_TextureFootprint3DNV, float);"
"bool textureFootprintClampNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV);"
"bool textureFootprintClampNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV);"
"bool textureFootprintClampNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV, float);"
"bool textureFootprintClampNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV, float);"
"bool textureFootprintLodNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV);"
"bool textureFootprintLodNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV);"
"bool textureFootprintGradNV(sampler2D, vec2, vec2, vec2, int, bool, out gl_TextureFootprint2DNV);"
"bool textureFootprintGradClampNV(sampler2D, vec2, vec2, vec2, float, int, bool, out gl_TextureFootprint2DNV);"
"\n");
}
#endif // NV_EXTENSIONS
// GL_AMD_gpu_shader_half_float/Explicit types
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
......@@ -7545,6 +7581,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
#endif
#ifdef NV_EXTENSIONS
symbolTable.setFunctionExtensions("textureFootprintNV", 1, &E_GL_NV_shader_texture_footprint);
symbolTable.setFunctionExtensions("textureFootprintClampNV", 1, &E_GL_NV_shader_texture_footprint);
symbolTable.setFunctionExtensions("textureFootprintLodNV", 1, &E_GL_NV_shader_texture_footprint);
symbolTable.setFunctionExtensions("textureFootprintGradNV", 1, &E_GL_NV_shader_texture_footprint);
symbolTable.setFunctionExtensions("textureFootprintGradClampNV", 1, &E_GL_NV_shader_texture_footprint);
#endif
// Compatibility variables, vertex only
if (spvVersion.spv == 0) {
BuiltInVariable("gl_Color", EbvColor, symbolTable);
......@@ -8501,6 +8544,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("noise3", EOpNoise);
symbolTable.relateToOperator("noise4", EOpNoise);
#ifdef NV_EXTENSIONS
symbolTable.relateToOperator("textureFootprintNV", EOpImageSampleFootprintNV);
symbolTable.relateToOperator("textureFootprintClampNV", EOpImageSampleFootprintClampNV);
symbolTable.relateToOperator("textureFootprintLodNV", EOpImageSampleFootprintLodNV);
symbolTable.relateToOperator("textureFootprintGradNV", EOpImageSampleFootprintGradNV);
symbolTable.relateToOperator("textureFootprintGradClampNV", EOpImageSampleFootprintGradClampNV);
#endif
if (spvVersion.spv == 0 && (IncludeLegacy(version, profile, spvVersion) ||
(profile == EEsProfile && version == 100))) {
symbolTable.relateToOperator("ftransform", EOpFtransform);
......
......@@ -237,6 +237,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
#endif
// AEP
......@@ -409,6 +410,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_subgroup_partitioned 1\n"
"#define GL_NV_fragment_shader_barycentric 1\n"
"#define GL_NV_compute_shader_derivatives 1\n"
"#define GL_NV_shader_texture_footprint 1\n"
#endif
"#define GL_KHX_shader_explicit_arithmetic_types 1\n"
"#define GL_KHX_shader_explicit_arithmetic_types_int8 1\n"
......
......@@ -209,6 +209,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
// Arrays of extensions for the above viewportEXTs duplications
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
......
......@@ -956,7 +956,13 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
#endif
#ifdef NV_EXTENSIONS
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
#endif
case EOpAddCarry: out.debug << "addCarry"; break;
case EOpSubBorrow: out.debug << "subBorrow"; break;
case EOpUMulExtended: out.debug << "uMulExtended"; break;
......
......@@ -505,6 +505,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.fragmentShaderBarycentric2.frag",
"spv.computeShaderDerivatives.comp",
"spv.computeShaderDerivatives2.comp",
"spv.shaderImageFootprint.frag",
})),
FileNameAsCustomTestSuffix
);
......
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