| // |
| // Copyright 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 |