GLSL icon indicating copy to clipboard operation
GLSL copied to clipboard

should samplerND(samplerND, sampler) be added?

Open pixeljetstream opened this issue 5 years ago • 4 comments

SPIR-V has language that allows to extract the OpTypeImage via OpImage from OpTypeSampledImage, which allows the recombination to a new OpTypeSampledImage with a different OpTypeSampler

therefore shouldn't the language also allow samplerND constructors from existing combined samplers? samplerND(samplerND, sampler)

pixeljetstream avatar Dec 05 '19 17:12 pixeljetstream

Might be more flexible to support textureND(samplerND) and then you can combine the textureND with a new sampler.

jeffbolznv avatar Dec 05 '19 17:12 jeffbolznv

This sounds like a good proposal. Someone would need to add a new extension against the GL_KHR_vulkan_glsl extension to add textureND(samplesND) support.

pdaniell-nv avatar Dec 11 '19 16:12 pdaniell-nv

I logged in to propose exactly this, and it solves a very real problem.

I maintain Ogre 2.x codebase, and we use a set of macros to help unify shader code across all of our backends. Our macros look like this:

// GLSL (OpenGL, ignores the sampler parameter)
#define OGRE_Sample( tex, sampler, uv ) texture( tex, uv )
// D3D11
#define OGRE_Sample( tex, sampler, uv ) tex.Sample( sampler, uv )
// Metal
#define OGRE_Sample( tex, sampler, uv ) tex.sample( sampler, uv )

In Vulkan however this is impossible, as we need to know whether the texture is 2D/3D/2DArray/etc

I tried the following solution:

#define OGRE_Sample( tex, sampler, uv ) texture( samplerMerge( tex, sampler ), uv )

sampler2D samplerMerge( texture2D t, sampler s ) { return sampler2D( t, s ); }
sampler2DArray samplerMerge( texture2DArray t, sampler s ) { return sampler2DArray( t, s ); }
sampler3D samplerMerge( texture3D t, sampler s ) { return sampler3D( t, s ); }
samplerCube samplerMerge( textureCube t, sampler s ) { return samplerCube( t, s ); }
samplerCubeArray samplerMerge( textureCubeArray t, sampler s ) { return samplerCubeArray( t, s ); }

This compiles fine by glslang however the validation layers complain the resulting SPIRV is not valid:

ERROR: [Validation] Code 0 :  [ UNASSIGNED-CoreValidation-Shader-InconsistentSpirv ] Object: VK_NULL_HANDLE (Type = 0) | SPIR-V module not valid: Result <id> from OpSampledImage instruction must not appear as operand for OpReturnValue, since it is not specificed as taking an OpTypeSampledImage. Found result <id> '19[%19]' as an operand of <id> '0[%0]'.
  %19 = OpSampledImage %11 %17 %18

Therefore samplerND( texture, sampler ) would be highly benefitial

For the time being I will be forced to split the macros into OGRE_Sample2D, OGRE_Sample3D, etc.

darksylinc avatar Aug 01 '20 18:08 darksylinc

Yes, to avoid complex analysis, we require the image/sampler pairing to be done in the same block it gets used:

All OpSampledImage instructions must be in the same block in which their Result <id> are consumed. Result from OpSampledImage instructions must not appear as operands to OpPhi instructions or OpSelect instructions, or any instructions other than the image lookup and query instructions specified to take an operand whose type is OpTypeSampledImage.

johnkslang avatar Aug 06 '20 07:08 johnkslang