diff options
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp | 1108 |
1 files changed, 1108 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp new file mode 100644 index 0000000000..11e337dabd --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp @@ -0,0 +1,1108 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// UtilsHLSL.cpp: +// Utility methods for GLSL to HLSL translation. +// + +#include "compiler/translator/UtilsHLSL.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/StructureHLSL.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +void DisambiguateFunctionNameForParameterType(const TType ¶mType, + TString *disambiguatingStringOut) +{ + // Parameter types are only added to function names if they are ambiguous according to the + // native HLSL compiler. Other parameter types are not added to function names to avoid + // making function names longer. + if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat) + { + // Disambiguation is needed for float2x2 and float4 parameters. These are the only + // built-in types that HLSL thinks are identical. float2x3 and float3x2 are different + // types, for example. + *disambiguatingStringOut += "_" + TypeString(paramType); + } + else if (paramType.getBasicType() == EbtStruct) + { + // Disambiguation is needed for struct parameters, since HLSL thinks that structs with + // the same fields but a different name are identical. + ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty); + *disambiguatingStringOut += "_" + TypeString(paramType); + } +} + +} // anonymous namespace + +const char *SamplerString(const TBasicType type) +{ + if (IsShadowSampler(type)) + { + return "SamplerComparisonState"; + } + else + { + return "SamplerState"; + } +} + +const char *SamplerString(HLSLTextureGroup type) +{ + if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END) + { + return "SamplerComparisonState"; + } + else + { + return "SamplerState"; + } +} + +HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) + +{ + switch (type) + { + case EbtSampler2D: + return HLSL_TEXTURE_2D; + case EbtSamplerCube: + return HLSL_TEXTURE_CUBE; + case EbtSamplerExternalOES: + return HLSL_TEXTURE_2D; + case EbtSampler2DArray: + return HLSL_TEXTURE_2D_ARRAY; + case EbtSampler3D: + return HLSL_TEXTURE_3D; + case EbtSampler2DMS: + return HLSL_TEXTURE_2D_MS; + case EbtSampler2DMSArray: + return HLSL_TEXTURE_2D_MS_ARRAY; + case EbtISampler2D: + return HLSL_TEXTURE_2D_INT4; + case EbtISampler3D: + return HLSL_TEXTURE_3D_INT4; + case EbtISamplerCube: + return HLSL_TEXTURE_2D_ARRAY_INT4; + case EbtISampler2DArray: + return HLSL_TEXTURE_2D_ARRAY_INT4; + case EbtISampler2DMS: + return HLSL_TEXTURE_2D_MS_INT4; + case EbtISampler2DMSArray: + return HLSL_TEXTURE_2D_MS_ARRAY_INT4; + case EbtUSampler2D: + return HLSL_TEXTURE_2D_UINT4; + case EbtUSampler3D: + return HLSL_TEXTURE_3D_UINT4; + case EbtUSamplerCube: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + case EbtUSampler2DArray: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + case EbtUSampler2DMS: + return HLSL_TEXTURE_2D_MS_UINT4; + case EbtUSampler2DMSArray: + return HLSL_TEXTURE_2D_MS_ARRAY_UINT4; + case EbtSampler2DShadow: + return HLSL_TEXTURE_2D_COMPARISON; + case EbtSamplerCubeShadow: + return HLSL_TEXTURE_CUBE_COMPARISON; + case EbtSampler2DArrayShadow: + return HLSL_TEXTURE_2D_ARRAY_COMPARISON; + case EbtImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_2D; + case EiifRGBA8: + return HLSL_TEXTURE_2D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_2D_SNORM; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtIImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_2D_INT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtUImage2D: + { + switch (imageInternalFormat) + { + + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_2D_UINT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_3D; + case EiifRGBA8: + return HLSL_TEXTURE_3D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_3D_SNORM; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtIImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_3D_INT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtUImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_3D_UINT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtImage2DArray: + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_2D_ARRAY; + case EiifRGBA8: + return HLSL_TEXTURE_2D_ARRAY_UNORN; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_2D_ARRAY_SNORM; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtIImage2DArray: + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_2D_ARRAY_INT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + case EbtUImage2DArray: + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } + } + default: + UNREACHABLE(); +#if !UNREACHABLE_IS_NORETURN + return HLSL_TEXTURE_UNKNOWN; +#endif + } +} + +const char *TextureString(const HLSLTextureGroup textureGroup) +{ + switch (textureGroup) + { + case HLSL_TEXTURE_2D: + return "Texture2D<float4>"; + case HLSL_TEXTURE_CUBE: + return "TextureCube<float4>"; + case HLSL_TEXTURE_2D_ARRAY: + return "Texture2DArray<float4>"; + case HLSL_TEXTURE_3D: + return "Texture3D<float4>"; + case HLSL_TEXTURE_2D_UNORM: + return "Texture2D<unorm float4>"; + case HLSL_TEXTURE_CUBE_UNORM: + return "TextureCube<unorm float4>"; + case HLSL_TEXTURE_2D_ARRAY_UNORN: + return "Texture2DArray<unorm float4>"; + case HLSL_TEXTURE_3D_UNORM: + return "Texture3D<unorm float4>"; + case HLSL_TEXTURE_2D_SNORM: + return "Texture2D<snorm float4>"; + case HLSL_TEXTURE_CUBE_SNORM: + return "TextureCube<snorm float4>"; + case HLSL_TEXTURE_2D_ARRAY_SNORM: + return "Texture2DArray<snorm float4>"; + case HLSL_TEXTURE_3D_SNORM: + return "Texture3D<snorm float4>"; + case HLSL_TEXTURE_2D_MS: + return "Texture2DMS<float4>"; + case HLSL_TEXTURE_2D_MS_ARRAY: + return "Texture2DMSArray<float4>"; + case HLSL_TEXTURE_2D_INT4: + return "Texture2D<int4>"; + case HLSL_TEXTURE_3D_INT4: + return "Texture3D<int4>"; + case HLSL_TEXTURE_2D_ARRAY_INT4: + return "Texture2DArray<int4>"; + case HLSL_TEXTURE_2D_MS_INT4: + return "Texture2DMS<int4>"; + case HLSL_TEXTURE_2D_MS_ARRAY_INT4: + return "Texture2DMSArray<int4>"; + case HLSL_TEXTURE_2D_UINT4: + return "Texture2D<uint4>"; + case HLSL_TEXTURE_3D_UINT4: + return "Texture3D<uint4>"; + case HLSL_TEXTURE_2D_ARRAY_UINT4: + return "Texture2DArray<uint4>"; + case HLSL_TEXTURE_2D_MS_UINT4: + return "Texture2DMS<uint4>"; + case HLSL_TEXTURE_2D_MS_ARRAY_UINT4: + return "Texture2DMSArray<uint4>"; + case HLSL_TEXTURE_2D_COMPARISON: + return "Texture2D"; + case HLSL_TEXTURE_CUBE_COMPARISON: + return "TextureCube"; + case HLSL_TEXTURE_2D_ARRAY_COMPARISON: + return "Texture2DArray"; + default: + UNREACHABLE(); + } + + return "<unknown read texture type>"; +} + +const char *TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + return TextureString(TextureGroup(type, imageInternalFormat)); +} + +const char *TextureGroupSuffix(const HLSLTextureGroup type) +{ + switch (type) + { + case HLSL_TEXTURE_2D: + return "2D"; + case HLSL_TEXTURE_CUBE: + return "Cube"; + case HLSL_TEXTURE_2D_ARRAY: + return "2DArray"; + case HLSL_TEXTURE_3D: + return "3D"; + case HLSL_TEXTURE_2D_UNORM: + return "2D_unorm_float4_"; + case HLSL_TEXTURE_CUBE_UNORM: + return "Cube_unorm_float4_"; + case HLSL_TEXTURE_2D_ARRAY_UNORN: + return "2DArray_unorm_float4_"; + case HLSL_TEXTURE_3D_UNORM: + return "3D_unorm_float4_"; + case HLSL_TEXTURE_2D_SNORM: + return "2D_snorm_float4_"; + case HLSL_TEXTURE_CUBE_SNORM: + return "Cube_snorm_float4_"; + case HLSL_TEXTURE_2D_ARRAY_SNORM: + return "2DArray_snorm_float4_"; + case HLSL_TEXTURE_3D_SNORM: + return "3D_snorm_float4_"; + case HLSL_TEXTURE_2D_MS: + return "2DMS"; + case HLSL_TEXTURE_2D_MS_ARRAY: + return "2DMSArray"; + case HLSL_TEXTURE_2D_INT4: + return "2D_int4_"; + case HLSL_TEXTURE_3D_INT4: + return "3D_int4_"; + case HLSL_TEXTURE_2D_ARRAY_INT4: + return "2DArray_int4_"; + case HLSL_TEXTURE_2D_MS_INT4: + return "2DMS_int4_"; + case HLSL_TEXTURE_2D_MS_ARRAY_INT4: + return "2DMSArray_int4_"; + case HLSL_TEXTURE_2D_UINT4: + return "2D_uint4_"; + case HLSL_TEXTURE_3D_UINT4: + return "3D_uint4_"; + case HLSL_TEXTURE_2D_ARRAY_UINT4: + return "2DArray_uint4_"; + case HLSL_TEXTURE_2D_MS_UINT4: + return "2DMS_uint4_"; + case HLSL_TEXTURE_2D_MS_ARRAY_UINT4: + return "2DMSArray_uint4_"; + case HLSL_TEXTURE_2D_COMPARISON: + return "2D_comparison"; + case HLSL_TEXTURE_CUBE_COMPARISON: + return "Cube_comparison"; + case HLSL_TEXTURE_2D_ARRAY_COMPARISON: + return "2DArray_comparison"; + default: + UNREACHABLE(); + } + + return "<unknown texture type>"; +} + +const char *TextureGroupSuffix(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat) +{ + return TextureGroupSuffix(TextureGroup(type, imageInternalFormat)); +} + +const char *TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + switch (type) + { + case EbtISamplerCube: + return "Cube_int4_"; + case EbtUSamplerCube: + return "Cube_uint4_"; + case EbtSamplerExternalOES: + return "_External"; + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return "Cube_float4_"; + case EiifRGBA8: + return "Cube_unorm_float4_"; + case EiifRGBA8_SNORM: + return "Cube_snorm_float4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return "Cube_int4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return "Cube_uint4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + default: + // All other types are identified by their group suffix + return TextureGroupSuffix(type, imageInternalFormat); + } +#if !UNREACHABLE_IS_NORETURN + UNREACHABLE(); + return "_TTS_invalid_"; +#endif +} + +HLSLRWTextureGroup RWTextureGroup(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat) + +{ + switch (type) + { + case EbtImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_2D_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_2D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_2D_SNORM; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtIImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_2D_INT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtUImage2D: + { + switch (imageInternalFormat) + { + + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_2D_UINT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_3D_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_3D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_3D_SNORM; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtIImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_3D_INT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtUImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_3D_UINT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtImage2DArray: + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_2D_ARRAY_UNORN; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_2D_ARRAY_SNORM; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtIImage2DArray: + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_2D_ARRAY_INT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtUImage2DArray: + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_2D_ARRAY_UINT4; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + default: + UNREACHABLE(); + } + return HLSL_RWTEXTURE_UNKNOWN; +} + +const char *RWTextureString(const HLSLRWTextureGroup RWTextureGroup) +{ + switch (RWTextureGroup) + { + case HLSL_RWTEXTURE_2D_FLOAT4: + return "RWTexture2D<float4>"; + case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4: + return "RWTexture2DArray<float4>"; + case HLSL_RWTEXTURE_3D_FLOAT4: + return "RWTexture3D<float4>"; + case HLSL_RWTEXTURE_2D_UNORM: + return "RWTexture2D<unorm float4>"; + case HLSL_RWTEXTURE_2D_ARRAY_UNORN: + return "RWTexture2DArray<unorm float4>"; + case HLSL_RWTEXTURE_3D_UNORM: + return "RWTexture3D<unorm float4>"; + case HLSL_RWTEXTURE_2D_SNORM: + return "RWTexture2D<snorm float4>"; + case HLSL_RWTEXTURE_2D_ARRAY_SNORM: + return "RWTexture2DArray<snorm float4>"; + case HLSL_RWTEXTURE_3D_SNORM: + return "RWTexture3D<snorm float4>"; + case HLSL_RWTEXTURE_2D_UINT4: + return "RWTexture2D<uint4>"; + case HLSL_RWTEXTURE_2D_ARRAY_UINT4: + return "RWTexture2DArray<uint4>"; + case HLSL_RWTEXTURE_3D_UINT4: + return "RWTexture3D<uint4>"; + case HLSL_RWTEXTURE_2D_INT4: + return "RWTexture2D<int4>"; + case HLSL_RWTEXTURE_2D_ARRAY_INT4: + return "RWTexture2DArray<int4>"; + case HLSL_RWTEXTURE_3D_INT4: + return "RWTexture3D<int4>"; + default: + UNREACHABLE(); + } + + return "<unknown read and write texture type>"; +} + +const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + return RWTextureString(RWTextureGroup(type, imageInternalFormat)); +} + +const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type) +{ + switch (type) + { + case HLSL_RWTEXTURE_2D_FLOAT4: + return "RW2D_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4: + return "RW2DArray_float4_"; + case HLSL_RWTEXTURE_3D_FLOAT4: + return "RW3D_float4_"; + case HLSL_RWTEXTURE_2D_UNORM: + return "RW2D_unorm_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_UNORN: + return "RW2DArray_unorm_float4_"; + case HLSL_RWTEXTURE_3D_UNORM: + return "RW3D_unorm_float4_"; + case HLSL_RWTEXTURE_2D_SNORM: + return "RW2D_snorm_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_SNORM: + return "RW2DArray_snorm_float4_"; + case HLSL_RWTEXTURE_3D_SNORM: + return "RW3D_snorm_float4_"; + case HLSL_RWTEXTURE_2D_UINT4: + return "RW2D_uint4_"; + case HLSL_RWTEXTURE_2D_ARRAY_UINT4: + return "RW2DArray_uint4_"; + case HLSL_RWTEXTURE_3D_UINT4: + return "RW3D_uint4_"; + case HLSL_RWTEXTURE_2D_INT4: + return "RW2D_int4_"; + case HLSL_RWTEXTURE_2D_ARRAY_INT4: + return "RW2DArray_int4_"; + case HLSL_RWTEXTURE_3D_INT4: + return "RW3D_int4_"; + default: + UNREACHABLE(); + } + + return "<unknown read and write resource>"; +} + +const char *RWTextureGroupSuffix(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat) +{ + return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat)); +} + +const char *RWTextureTypeSuffix(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat) +{ + switch (type) + { + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return "RWCube_float4_"; + case EiifRGBA8: + return "RWCube_unorm_float4_"; + case EiifRGBA8_SNORM: + return "RWCube_unorm_float4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return "RWCube_int4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return "RWCube_uint4_"; + default: + UNREACHABLE(); + } +#if !UNREACHABLE_IS_NORETURN + break; +#endif + } + default: + // All other types are identified by their group suffix + return RWTextureGroupSuffix(type, imageInternalFormat); + } +#if !UNREACHABLE_IS_NORETURN + UNREACHABLE(); + return "_RWTS_invalid_"; +#endif +} + +TString DecorateField(const ImmutableString &string, const TStructure &structure) +{ + if (structure.symbolType() != SymbolType::BuiltIn) + { + return Decorate(string); + } + + return TString(string.data()); +} + +TString DecoratePrivate(const ImmutableString &privateText) +{ + return "dx_" + TString(privateText.data()); +} + +TString Decorate(const ImmutableString &string) +{ + if (!string.beginsWith("gl_")) + { + return "_" + TString(string.data()); + } + + return TString(string.data()); +} + +TString DecorateVariableIfNeeded(const TVariable &variable) +{ + if (variable.symbolType() == SymbolType::AngleInternal || + variable.symbolType() == SymbolType::Empty) + { + // Besides handling internal variables, we generate names for nameless parameters here. + const ImmutableString &name = variable.name(); + // The name should not have a prefix reserved for user-defined variables or functions. + ASSERT(!name.beginsWith("f_")); + ASSERT(!name.beginsWith("_")); + return TString(name.data()); + } + // For user defined variables, combine variable name with unique id + // so variables of the same name in different scopes do not get overwritten. + else if (variable.symbolType() == SymbolType::UserDefined && + variable.getType().getQualifier() == EvqTemporary) + { + return Decorate(variable.name()) + str(variable.uniqueId().get()); + } + else + { + return Decorate(variable.name()); + } +} + +TString DecorateFunctionIfNeeded(const TFunction *func) +{ + if (func->symbolType() == SymbolType::AngleInternal) + { + // The name should not have a prefix reserved for user-defined variables or functions. + ASSERT(!func->name().beginsWith("f_")); + ASSERT(!func->name().beginsWith("_")); + return TString(func->name().data()); + } + ASSERT(!func->name().beginsWith("gl_")); + // Add an additional f prefix to functions so that they're always disambiguated from variables. + // This is necessary in the corner case where a variable declaration hides a function that it + // uses in its initializer. + return "f_" + TString(func->name().data()); +} + +TString TypeString(const TType &type) +{ + const TStructure *structure = type.getStruct(); + if (structure) + { + if (structure->symbolType() != SymbolType::Empty) + { + return StructNameString(*structure); + } + else // Nameless structure, define in place + { + return StructureHLSL::defineNameless(*structure); + } + } + else if (type.isMatrix()) + { + int cols = type.getCols(); + int rows = type.getRows(); + return "float" + str(cols) + "x" + str(rows); + } + else + { + switch (type.getBasicType()) + { + case EbtFloat: + switch (type.getNominalSize()) + { + case 1: + return "float"; + case 2: + return "float2"; + case 3: + return "float3"; + case 4: + return "float4"; + } + case EbtInt: + switch (type.getNominalSize()) + { + case 1: + return "int"; + case 2: + return "int2"; + case 3: + return "int3"; + case 4: + return "int4"; + } + case EbtUInt: + switch (type.getNominalSize()) + { + case 1: + return "uint"; + case 2: + return "uint2"; + case 3: + return "uint3"; + case 4: + return "uint4"; + } + case EbtBool: + switch (type.getNominalSize()) + { + case 1: + return "bool"; + case 2: + return "bool2"; + case 3: + return "bool3"; + case 4: + return "bool4"; + } + case EbtVoid: + return "void"; + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + return "sampler2D"; + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + return "samplerCUBE"; + case EbtSamplerExternalOES: + return "sampler2D"; + case EbtAtomicCounter: + // Multiple atomic_uints will be implemented as a single RWByteAddressBuffer + return "RWByteAddressBuffer"; + default: + break; + } + } + + UNREACHABLE(); + return "<unknown type>"; +} + +TString StructNameString(const TStructure &structure) +{ + if (structure.symbolType() == SymbolType::Empty) + { + return ""; + } + + // For structures at global scope we use a consistent + // translation so that we can link between shader stages. + if (structure.atGlobalScope()) + { + return Decorate(structure.name()); + } + + return "ss" + str(structure.uniqueId().get()) + "_" + TString(structure.name().data()); +} + +TString QualifiedStructNameString(const TStructure &structure, + bool useHLSLRowMajorPacking, + bool useStd140Packing) +{ + if (structure.symbolType() == SymbolType::Empty) + { + return ""; + } + + TString prefix = ""; + + // Structs packed with row-major matrices in HLSL are prefixed with "rm" + // GLSL column-major maps to HLSL row-major, and the converse is true + + if (useStd140Packing) + { + prefix += "std_"; + } + + if (useHLSLRowMajorPacking) + { + prefix += "rm_"; + } + + return prefix + StructNameString(structure); +} + +const char *InterpolationString(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqVaryingIn: + return ""; + case EvqFragmentIn: + return ""; + case EvqSmoothIn: + return "linear"; + case EvqFlatIn: + return "nointerpolation"; + case EvqCentroidIn: + return "centroid"; + case EvqVaryingOut: + return ""; + case EvqVertexOut: + return ""; + case EvqSmoothOut: + return "linear"; + case EvqFlatOut: + return "nointerpolation"; + case EvqCentroidOut: + return "centroid"; + default: + UNREACHABLE(); + } + + return ""; +} + +const char *QualifierString(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqIn: + return "in"; + case EvqOut: + return "inout"; // 'out' results in an HLSL error if not all fields are written, for + // GLSL it's undefined + case EvqInOut: + return "inout"; + case EvqConstReadOnly: + return "const"; + default: + UNREACHABLE(); + } + + return ""; +} + +TString DisambiguateFunctionName(const TFunction *func) +{ + TString disambiguatingString; + size_t paramCount = func->getParamCount(); + for (size_t i = 0; i < paramCount; ++i) + { + DisambiguateFunctionNameForParameterType(func->getParam(i)->getType(), + &disambiguatingString); + } + return disambiguatingString; +} + +TString DisambiguateFunctionName(const TIntermSequence *args) +{ + TString disambiguatingString; + for (TIntermNode *arg : *args) + { + ASSERT(arg->getAsTyped()); + DisambiguateFunctionNameForParameterType(arg->getAsTyped()->getType(), + &disambiguatingString); + } + return disambiguatingString; +} + +} // namespace sh |