Browse Source

shaderpipeline: Add missing sampler types and functions to Cg preamble

Also map half and fixed types to reduced-precision
rdb 2 years ago
parent
commit
510a584abf

+ 404 - 7
panda/src/shaderpipeline/cg_preamble.hlsl

@@ -17,14 +17,75 @@
  * and types that were supported in Cg but are not available in HLSL.
  * and types that were supported in Cg but are not available in HLSL.
  */
  */
 
 
-// We implement shadow samplers by mapping them to DX10 syntax, since there is
-// no syntax for them in DX9.
+// DX10 just maps half to float, but Cg defined it as float>=16.
+// This makes glslang recognize them as relaxed-precision floats.
+#define half min16float
+#define half1 min16float1
+#define half2 min16float2
+#define half3 min16float3
+#define half4 min16float4
+#define half1x1 min16float1x1
+#define half1x2 min16float1x2
+#define half1x3 min16float1x3
+#define half1x4 min16float1x4
+#define half2x1 min16float2x1
+#define half2x2 min16float2x2
+#define half2x3 min16float2x3
+#define half2x4 min16float2x4
+#define half3x1 min16float3x1
+#define half3x2 min16float3x2
+#define half3x3 min16float3x3
+#define half3x4 min16float3x4
+#define half4x1 min16float4x1
+#define half4x2 min16float4x2
+#define half4x3 min16float4x3
+#define half4x4 min16float4x4
+
+// Cg also had a fixed-precision type, corresponding to lowp/10-bit.
+#define fixed min10float
+#define fixed1 min10float1
+#define fixed2 min10float2
+#define fixed3 min10float3
+#define fixed4 min10float4
+#define fixed1x1 min10float1x1
+#define fixed1x2 min10float1x2
+#define fixed1x3 min10float1x3
+#define fixed1x4 min10float1x4
+#define fixed2x1 min10float2x1
+#define fixed2x2 min10float2x2
+#define fixed2x3 min10float2x3
+#define fixed2x4 min10float2x4
+#define fixed3x1 min10float3x1
+#define fixed3x2 min10float3x2
+#define fixed3x3 min10float3x3
+#define fixed3x4 min10float3x4
+#define fixed4x1 min10float4x1
+#define fixed4x2 min10float4x2
+#define fixed4x3 min10float4x3
+#define fixed4x4 min10float4x4
+
+// Define these DX10 samplers, used below.  They are removed by a glslang pass.
+SamplerState __builtin_sampler;
+SamplerComparisonState __builtin_shadow_sampler;
+
+// These sampler types have no syntax in DX9, so we map them to DX10 types.
 typedef Texture1D sampler1DShadow;
 typedef Texture1D sampler1DShadow;
+typedef Texture1DArray<float4> sampler1DARRAY;
+typedef Texture1DArray<int4> isampler1DARRAY;
+typedef Texture1DArray<uint4> usampler1DARRAY;
 typedef Texture2D sampler2DShadow;
 typedef Texture2D sampler2DShadow;
+typedef Texture2DArray<float4> sampler2DARRAY;
+typedef Texture2DArray<int4> isampler2DARRAY;
+typedef Texture2DArray<uint4> usampler2DARRAY;
 typedef TextureCube samplerCubeShadow;
 typedef TextureCube samplerCubeShadow;
-
-SamplerComparisonState __builtin_shadow_sampler;
-
+typedef TextureCubeArray<float4> samplerCUBEARRAY;
+typedef TextureCubeArray<int4> isamplerCUBEARRAY;
+typedef TextureCubeArray<uint4> usamplerCUBEARRAY;
+typedef Buffer<float4> samplerBUF;
+typedef Buffer<int4> isamplerBUF;
+typedef Buffer<uint4> usamplerBUF;
+
+// Define texture functions not available in HLSL.
 float4 shadow1D(sampler1DShadow samp, float3 s) {
 float4 shadow1D(sampler1DShadow samp, float3 s) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.x, s.z);
   return samp.SampleCmp(__builtin_shadow_sampler, s.x, s.z);
 }
 }
@@ -45,6 +106,282 @@ float4 shadowCube(samplerCubeShadow samp, float4 s) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.xyz, s.w);
   return samp.SampleCmp(__builtin_shadow_sampler, s.xyz, s.w);
 }
 }
 
 
+float4 tex1DARRAY(sampler1DARRAY samp, float2 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+float4 tex1DARRAY(sampler1DARRAY samp, float2 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+float4 tex1DARRAY(sampler1DARRAY samp, float2 s, float dx, float dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+float4 tex1DARRAY(sampler1DARRAY samp, float2 s, float dx, float dy, int texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+float4 tex1DARRAY(sampler1DARRAY samp, float3 s) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z);
+}
+
+float4 tex1DARRAY(sampler1DARRAY samp, float3 s, int texelOff) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z, texelOff);
+}
+
+int4 tex1DARRAY(isampler1DARRAY samp, float2 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+int4 tex1DARRAY(isampler1DARRAY samp, float2 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+int4 tex1DARRAY(isampler1DARRAY samp, float2 s, float dx, float dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+int4 tex1DARRAY(isampler1DARRAY samp, float2 s, float dx, float dy, int texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+uint4 tex1DARRAY(usampler1DARRAY samp, float2 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+uint4 tex1DARRAY(usampler1DARRAY samp, float2 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+uint4 tex1DARRAY(usampler1DARRAY samp, float2 s, float dx, float dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+uint4 tex1DARRAY(usampler1DARRAY samp, float2 s, float dx, float dy, int texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+float4 tex1DARRAYproj(sampler1DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z);
+}
+
+float4 tex1DARRAYproj(sampler1DARRAY samp, float3 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z, texelOff);
+}
+
+int4 tex1DARRAYproj(isampler1DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z);
+}
+
+int4 tex1DARRAYproj(isampler1DARRAY samp, float3 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z, texelOff);
+}
+
+uint4 tex1DARRAYproj(usampler1DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z);
+}
+
+uint4 tex1DARRAYproj(usampler1DARRAY samp, float3 s, int texelOff) {
+  return samp.Sample(__builtin_sampler, s.xy / s.z, texelOff);
+}
+
+float4 tex1DARRAYproj(sampler1DARRAY samp, float4 s) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w);
+}
+
+float4 tex1DARRAYproj(sampler1DARRAY samp, float4 s, int texelOff) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w, texelOff);
+}
+
+int3 tex1DARRAYsize(sampler1DARRAY samp, int lod) {
+  uint width, elems, levels;
+  samp.GetDimensions(lod, width, elems, levels);
+  return int3(width, 0, 0); // sic
+}
+
+int3 tex1DARRAYsize(isampler1DARRAY samp, int lod) {
+  uint width, elems, levels;
+  samp.GetDimensions(lod, width, elems, levels);
+  return int3(width, 0, 0); // sic
+}
+
+int3 tex1DARRAYsize(usampler1DARRAY samp, int lod) {
+  uint width, elems, levels;
+  samp.GetDimensions(lod, width, elems, levels);
+  return int3(width, 0, 0); // sic
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float3 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float3 s, float2 dx, float2 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float3 s, float2 dx, float2 dy, int2 texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float4 s) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xyz, s.w);
+}
+
+float4 tex2DARRAY(sampler2DARRAY samp, float4 s, int2 texelOff) {
+  return samp.SampleCmp(__builtin_shadow_sampler, s.xyz, s.w, texelOff);
+}
+
+int4 tex2DARRAY(isampler2DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+int4 tex2DARRAY(isampler2DARRAY samp, float3 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+int4 tex2DARRAY(isampler2DARRAY samp, float3 s, float2 dx, float2 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+int4 tex2DARRAY(isampler2DARRAY samp, float3 s, float2 dx, float2 dy, int2 texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+uint4 tex2DARRAY(usampler2DARRAY samp, float3 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+uint4 tex2DARRAY(usampler2DARRAY samp, float3 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s, texelOff);
+}
+
+uint4 tex2DARRAY(usampler2DARRAY samp, float3 s, float2 dx, float2 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+uint4 tex2DARRAY(usampler2DARRAY samp, float3 s, float2 dx, float2 dy, int2 texelOff) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy, texelOff);
+}
+
+float4 tex2DARRAYproj(sampler2DARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w);
+}
+
+float4 tex2DARRAYproj(sampler2DARRAY samp, float4 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w, texelOff);
+}
+
+int4 tex2DARRAYproj(isampler2DARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w);
+}
+
+int4 tex2DARRAYproj(isampler2DARRAY samp, float4 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w, texelOff);
+}
+
+uint4 tex2DARRAYproj(usampler2DARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w);
+}
+
+uint4 tex2DARRAYproj(usampler2DARRAY samp, float4 s, int2 texelOff) {
+  return samp.Sample(__builtin_sampler, s.xyz / s.w, texelOff);
+}
+
+int3 tex2DARRAYsize(sampler2DARRAY samp, int lod) {
+  uint width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+int3 tex2DARRAYsize(isampler2DARRAY samp, int lod) {
+  uint width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+int3 tex2DARRAYsize(usampler2DARRAY samp, int lod) {
+  uint width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+float4 texCUBEARRAY(samplerCUBEARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+float4 texCUBEARRAY(samplerCUBEARRAY samp, float4 s, float3 dx, float3 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+int4 texCUBEARRAY(isamplerCUBEARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+int4 texCUBEARRAY(isamplerCUBEARRAY samp, float4 s, float3 dx, float3 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+uint4 texCUBEARRAY(usamplerCUBEARRAY samp, float4 s) {
+  return samp.Sample(__builtin_sampler, s);
+}
+
+uint4 texCUBEARRAY(usamplerCUBEARRAY samp, float4 s, float3 dx, float3 dy) {
+  return samp.SampleGrad(__builtin_sampler, s, dx, dy);
+}
+
+int3 texCUBEARRAYsize(samplerCUBEARRAY samp, int lod) {
+  int width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+int3 texCUBEARRAYsize(isamplerCUBEARRAY samp, int lod) {
+  int width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+int3 texCUBEARRAYsize(usamplerCUBEARRAY samp, int lod) {
+  int width, height, elems, levels;
+  samp.GetDimensions(lod, width, height, elems, levels);
+  return int3(width, height, 0); // sic
+}
+
+float4 texBUF(samplerBUF samp, int s) {
+  return samp.Load(s);
+}
+
+int4 texBUF(isamplerBUF samp, int s) {
+  return samp.Load(s);
+}
+
+uint4 texBUF(usamplerBUF samp, int s) {
+  return samp.Load(s);
+}
+
+uint texBUFsize(samplerBUF samp, int lod) {
+  uint dim;
+  samp.GetDimensions(dim);
+  return dim;
+}
+
+uint texBUFsize(isamplerBUF samp, int lod) {
+  uint dim;
+  samp.GetDimensions(dim);
+  return dim;
+}
+
+uint texBUFsize(usamplerBUF samp, int lod) {
+  uint dim;
+  samp.GetDimensions(dim);
+  return dim;
+}
+
 // Redefine overloads for built-in texturing functions to match the Cg
 // Redefine overloads for built-in texturing functions to match the Cg
 // parameterization.  We can't overload tex2D, but we'll define them as
 // parameterization.  We can't overload tex2D, but we'll define them as
 // f4tex2D et al and use macros to redefine tex2D et al to that.
 // f4tex2D et al and use macros to redefine tex2D et al to that.
@@ -108,7 +445,7 @@ float4 f4tex2D(sampler2DShadow samp, float3 s) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z);
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z);
 }
 }
 
 
-float4 f4tex2D(sampler2DShadow samp, float3 s, int texelOff) {
+float4 f4tex2D(sampler2DShadow samp, float3 s, int2 texelOff) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z, texelOff);
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy, s.z, texelOff);
 }
 }
 
 
@@ -132,7 +469,7 @@ float4 f4tex2Dproj(sampler2DShadow samp, float4 s) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w);
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w);
 }
 }
 
 
-float4 f4tex2Dproj(sampler2DShadow samp, float4 s, int texelOff) {
+float4 f4tex2Dproj(sampler2DShadow samp, float4 s, int2 texelOff) {
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w, texelOff);
   return samp.SampleCmp(__builtin_shadow_sampler, s.xy / s.w, s.z / s.w, texelOff);
 }
 }
 
 
@@ -164,26 +501,85 @@ float4 f4texCUBE(samplerCUBE samp, float4 s, float3 dx, float3 dy) {
   return texCUBE(samp, s.xyz, dx, dy);
   return texCUBE(samp, s.xyz, dx, dy);
 }
 }
 
 
+// Narrowing overloads (not defined for newer types)
 #define f1tex1D(x, y) (f4tex1D((x), (y)).r)
 #define f1tex1D(x, y) (f4tex1D((x), (y)).r)
+#define f2tex1D(x, y) (f4tex1D((x), (y)).rg)
 #define f3tex1D(x, y) (f4tex1D((x), (y)).rgb)
 #define f3tex1D(x, y) (f4tex1D((x), (y)).rgb)
 #define tex1D f4tex1D
 #define tex1D f4tex1D
 
 
 #define f1tex1Dproj(x, y) (f4tex1Dproj((x), (y)).r)
 #define f1tex1Dproj(x, y) (f4tex1Dproj((x), (y)).r)
+#define f2tex1Dproj(x, y) (f4tex1Dproj((x), (y)).rg)
 #define f3tex1Dproj(x, y) (f4tex1Dproj((x), (y)).rgb)
 #define f3tex1Dproj(x, y) (f4tex1Dproj((x), (y)).rgb)
 #define tex1Dproj f4tex1Dproj
 #define tex1Dproj f4tex1Dproj
 
 
 #define f1tex2D(x, y) (f4tex2D((x), (y)).r)
 #define f1tex2D(x, y) (f4tex2D((x), (y)).r)
+#define f2tex2D(x, y) (f4tex2D((x), (y)).rg)
 #define f3tex2D(x, y) (f4tex2D((x), (y)).rgb)
 #define f3tex2D(x, y) (f4tex2D((x), (y)).rgb)
 #define tex2D f4tex2D
 #define tex2D f4tex2D
 
 
 #define f1tex2Dproj(x, y) (f4tex2Dproj((x), (y)).r)
 #define f1tex2Dproj(x, y) (f4tex2Dproj((x), (y)).r)
+#define f2tex2Dproj(x, y) (f4tex2Dproj((x), (y)).rg)
 #define f3tex2Dproj(x, y) (f4tex2Dproj((x), (y)).rgb)
 #define f3tex2Dproj(x, y) (f4tex2Dproj((x), (y)).rgb)
 #define tex2Dproj f4tex2Dproj
 #define tex2Dproj f4tex2Dproj
 
 
 #define f1texCUBE(x, y) (f4texCUBE((x), (y)).r)
 #define f1texCUBE(x, y) (f4texCUBE((x), (y)).r)
+#define f2texCUBE(x, y) (f2texCUBE((x), (y)).rg)
 #define f3texCUBE(x, y) (f4texCUBE((x), (y)).rgb)
 #define f3texCUBE(x, y) (f4texCUBE((x), (y)).rgb)
 #define texCUBE f4texCUBE
 #define texCUBE f4texCUBE
 
 
+// Legacy half-precision overloads
+#define h1tex1D(x, y) (half(f1tex1D((x), (y))))
+#define h2tex1D(x, y) (half2(f2tex1D((x), (y))))
+#define h3tex1D(x, y) (half3(f3tex1D((x), (y))))
+#define h4tex1D(x, y) (half3(f4tex1D((x), (y))))
+#define h1tex1Dproj(x, y) (half(f1tex1Dproj((x), (y))))
+#define h2tex1Dproj(x, y) (half2(f2tex1Dproj((x), (y))))
+#define h3tex1Dproj(x, y) (half3(f3tex1Dproj((x), (y))))
+#define h4tex1Dproj(x, y) (half3(f4tex1Dproj((x), (y))))
+#define h1tex2D(x, y) (half(f1tex2D((x), (y))))
+#define h2tex2D(x, y) (half2(f2tex2D((x), (y))))
+#define h3tex2D(x, y) (half3(f3tex2D((x), (y))))
+#define h4tex2D(x, y) (half3(f4tex2D((x), (y))))
+#define h1tex2Dproj(x, y) (half(f1tex2Dproj((x), (y))))
+#define h2tex2Dproj(x, y) (half2(f2tex2Dproj((x), (y))))
+#define h3tex2Dproj(x, y) (half3(f3tex2Dproj((x), (y))))
+#define h4tex2Dproj(x, y) (half3(f4tex2Dproj((x), (y))))
+#define h1tex3D(x, y) (half(f1tex3D((x), (y))))
+#define h2tex3D(x, y) (half2(f2tex3D((x), (y))))
+#define h3tex3D(x, y) (half3(f3tex3D((x), (y))))
+#define h4tex3D(x, y) (half3(f4tex3D((x), (y))))
+#define h1texCUBE(x, y) (half(f1texCUBE((x), (y))))
+#define h2texCUBE(x, y) (half2(f2texCUBE((x), (y))))
+#define h3texCUBE(x, y) (half3(f3texCUBE((x), (y))))
+#define h4texCUBE(x, y) (half3(f4texCUBE((x), (y))))
+
+// Legacy fixed-precision overloads
+#define x1tex1D(x, y) (fixed(f1tex1D((x), (y))))
+#define x2tex1D(x, y) (fixed2(f2tex1D((x), (y))))
+#define x3tex1D(x, y) (fixed3(f3tex1D((x), (y))))
+#define x4tex1D(x, y) (fixed3(f4tex1D((x), (y))))
+#define x1tex1Dproj(x, y) (fixed(f1tex1Dproj((x), (y))))
+#define x2tex1Dproj(x, y) (fixed2(f2tex1Dproj((x), (y))))
+#define x3tex1Dproj(x, y) (fixed3(f3tex1Dproj((x), (y))))
+#define x4tex1Dproj(x, y) (fixed3(f4tex1Dproj((x), (y))))
+#define x1tex2D(x, y) (fixed(f1tex2D((x), (y))))
+#define x2tex2D(x, y) (fixed2(f2tex2D((x), (y))))
+#define x3tex2D(x, y) (fixed3(f3tex2D((x), (y))))
+#define x4tex2D(x, y) (fixed3(f4tex2D((x), (y))))
+#define x1tex2Dproj(x, y) (fixed(f1tex2Dproj((x), (y))))
+#define x2tex2Dproj(x, y) (fixed2(f2tex2Dproj((x), (y))))
+#define x3tex2Dproj(x, y) (fixed3(f3tex2Dproj((x), (y))))
+#define x4tex2Dproj(x, y) (fixed3(f4tex2Dproj((x), (y))))
+#define x1tex3D(x, y) (fixed(f1tex3D((x), (y))))
+#define x2tex3D(x, y) (fixed2(f2tex3D((x), (y))))
+#define x3tex3D(x, y) (fixed3(f3tex3D((x), (y))))
+#define x4tex3D(x, y) (fixed3(f4tex3D((x), (y))))
+#define x1texCUBE(x, y) (fixed(f1texCUBE((x), (y))))
+#define x2texCUBE(x, y) (fixed2(f2texCUBE((x), (y))))
+#define x3texCUBE(x, y) (fixed3(f3texCUBE((x), (y))))
+#define x4texCUBE(x, y) (fixed3(f4texCUBE((x), (y))))
+
+// Bit manipulation functions
 uint bitfieldExtract(uint val, int off, int size) {
 uint bitfieldExtract(uint val, int off, int size) {
   uint mask = uint((1 << size) - 1);
   uint mask = uint((1 << size) - 1);
   return uint(val >> off) & mask;
   return uint(val >> off) & mask;
@@ -197,6 +593,7 @@ uint bitfieldExtract(uint val, int off, int size) {
 #define floatToRawIntBits(x) (asint(x))
 #define floatToRawIntBits(x) (asint(x))
 #define intBitsToFloat(x) (asfloat(x))
 #define intBitsToFloat(x) (asfloat(x))
 
 
+// Matrix inverse functions
 float2x2 inverse(float2x2 m) {
 float2x2 inverse(float2x2 m) {
   return float2x2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0f / determinant(m));
   return float2x2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0f / determinant(m));
 }
 }

+ 19 - 5
panda/src/shaderpipeline/shaderCompilerGlslang.cxx

@@ -290,8 +290,8 @@ compile_now(ShaderModule::Stage stage, std::istream &in,
     extern const char cg_preamble[];
     extern const char cg_preamble[];
     shader.setPreamble(cg_preamble);
     shader.setPreamble(cg_preamble);
 
 
-    // We map shadow samplers to DX10 syntax, but those use separate samplers/
-    // images, so we need to ask glslang to kindly combine these back.
+    // We map some sampler types to DX10 syntax, but those use separate
+    // samplers/images, so we need to ask glslang to combine these back.
     shader.setTextureSamplerTransformMode(EShTexSampTransUpgradeTextureRemoveSampler);
     shader.setTextureSamplerTransformMode(EShTexSampTransUpgradeTextureRemoveSampler);
 
 
     shader.setEnvInput(glslang::EShSource::EShSourceHlsl, (EShLanguage)stage, glslang::EShClient::EShClientOpenGL, 120);
     shader.setEnvInput(glslang::EShSource::EShSourceHlsl, (EShLanguage)stage, glslang::EShClient::EShClientOpenGL, 120);
@@ -737,18 +737,32 @@ postprocess_cg(ShaderModuleSpirV::InstructionStream &stream) {
   pset<uint32_t> glsl_imports;
   pset<uint32_t> glsl_imports;
 
 
   for (ShaderModuleSpirV::Instruction op : stream) {
   for (ShaderModuleSpirV::Instruction op : stream) {
-    if (op.opcode == spv::OpExtInstImport) {
+    switch (op.opcode) {
+    case spv::OpExtInstImport:
       if (strcmp((const char*)&op.args[1], "GLSL.std.450") == 0) {
       if (strcmp((const char*)&op.args[1], "GLSL.std.450") == 0) {
         glsl_imports.insert(op.args[0]);
         glsl_imports.insert(op.args[0]);
       }
       }
-    }
-    else if (op.opcode == spv::OpExtInst) {
+      break;
+
+    case spv::OpExtInst:
       // glslang maps round() to roundEven(), which is correct for SM 4.0+ but
       // glslang maps round() to roundEven(), which is correct for SM 4.0+ but
       // not supported on pre-DX10 hardware, and Cg made no guarantee of
       // not supported on pre-DX10 hardware, and Cg made no guarantee of
       // round-to-even behavior to begin with, so we switch it back to round().
       // round-to-even behavior to begin with, so we switch it back to round().
       if (glsl_imports.count(op.args[2]) && op.args[3] == 2) {
       if (glsl_imports.count(op.args[2]) && op.args[3] == 2) {
         op.args[3] = 1;
         op.args[3] = 1;
       }
       }
+      break;
+
+    case spv::OpTypeImage:
+      // glslang marks buffer textures as having a specific format, but we want
+      // to allow the use of any format, so wipe this field.
+      if (op.args[6] == 1) {
+        op.args[7] = spv::ImageFormatUnknown;
+      }
+      break;
+
+    default:
+      break;
     }
     }
   }
   }