LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - TextureFunctionHLSL.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 526 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
       3             : // Use of this source code is governed by a BSD-style license that can be
       4             : // found in the LICENSE file.
       5             : //
       6             : // TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL
       7             : // output. Some of the implementations are straightforward and just call the HLSL equivalent of the
       8             : // ESSL texture function, others do more work to emulate ESSL texture sampling or size query
       9             : // behavior.
      10             : //
      11             : 
      12             : #include "compiler/translator/TextureFunctionHLSL.h"
      13             : 
      14             : #include "compiler/translator/UtilsHLSL.h"
      15             : 
      16             : namespace sh
      17             : {
      18             : 
      19             : namespace
      20             : {
      21             : 
      22           0 : void OutputIntTexCoordWrap(TInfoSinkBase &out,
      23             :                            const char *wrapMode,
      24             :                            const char *size,
      25             :                            const TString &texCoord,
      26             :                            const TString &texCoordOffset,
      27             :                            const char *texCoordOutName)
      28             : {
      29             :     // GLES 3.0.4 table 3.22 specifies how the wrap modes work. We don't use the formulas verbatim
      30             :     // but rather use equivalent formulas that map better to HLSL.
      31           0 :     out << "int " << texCoordOutName << ";\n";
      32           0 :     out << "float " << texCoordOutName << "Offset = " << texCoord << " + float(" << texCoordOffset
      33           0 :         << ") / " << size << ";\n";
      34             : 
      35             :     // CLAMP_TO_EDGE
      36           0 :     out << "if (" << wrapMode << " == 1)\n";
      37           0 :     out << "{\n";
      38           0 :     out << "    " << texCoordOutName << " = clamp(int(floor(" << size << " * " << texCoordOutName
      39           0 :         << "Offset)), 0, int(" << size << ") - 1);\n";
      40           0 :     out << "}\n";
      41             : 
      42             :     // MIRRORED_REPEAT
      43           0 :     out << "else if (" << wrapMode << " == 3)\n";
      44           0 :     out << "{\n";
      45           0 :     out << "    float coordWrapped = 1.0 - abs(frac(abs(" << texCoordOutName
      46           0 :         << "Offset) * 0.5) * 2.0 - 1.0);\n";
      47           0 :     out << "    " << texCoordOutName << " = int(floor(" << size << " * coordWrapped));\n";
      48           0 :     out << "}\n";
      49             : 
      50             :     // REPEAT
      51           0 :     out << "else\n";
      52           0 :     out << "{\n";
      53           0 :     out << "    " << texCoordOutName << " = int(floor(" << size << " * frac(" << texCoordOutName
      54           0 :         << "Offset)));\n";
      55           0 :     out << "}\n";
      56           0 : }
      57             : 
      58           0 : void OutputIntTexCoordWraps(TInfoSinkBase &out,
      59             :                             const TextureFunctionHLSL::TextureFunction &textureFunction,
      60             :                             TString *texCoordX,
      61             :                             TString *texCoordY,
      62             :                             TString *texCoordZ)
      63             : {
      64             :     // Convert from normalized floating-point to integer
      65           0 :     out << "int wrapS = samplerMetadata[samplerIndex].wrapModes & 0x3;\n";
      66           0 :     if (textureFunction.offset)
      67             :     {
      68           0 :         OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "offset.x", "tix");
      69             :     }
      70             :     else
      71             :     {
      72           0 :         OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "0", "tix");
      73             :     }
      74           0 :     *texCoordX = "tix";
      75           0 :     out << "int wrapT = (samplerMetadata[samplerIndex].wrapModes >> 2) & 0x3;\n";
      76           0 :     if (textureFunction.offset)
      77             :     {
      78           0 :         OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "offset.y", "tiy");
      79             :     }
      80             :     else
      81             :     {
      82           0 :         OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "0", "tiy");
      83             :     }
      84           0 :     *texCoordY = "tiy";
      85             : 
      86           0 :     if (IsSamplerArray(textureFunction.sampler))
      87             :     {
      88           0 :         *texCoordZ = "int(max(0, min(layers - 1, floor(0.5 + t.z))))";
      89             :     }
      90           0 :     else if (!IsSamplerCube(textureFunction.sampler) && !IsSampler2D(textureFunction.sampler))
      91             :     {
      92           0 :         out << "int wrapR = (samplerMetadata[samplerIndex].wrapModes >> 4) & 0x3;\n";
      93           0 :         if (textureFunction.offset)
      94             :         {
      95           0 :             OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "offset.z", "tiz");
      96             :         }
      97             :         else
      98             :         {
      99           0 :             OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "0", "tiz");
     100             :         }
     101           0 :         *texCoordZ = "tiz";
     102             :     }
     103           0 : }
     104             : 
     105           0 : void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out,
     106             :                                      const TextureFunctionHLSL::TextureFunction &textureFunction,
     107             :                                      const TString &textureReference,
     108             :                                      const TString &samplerReference)
     109             : {
     110           0 :     out << textureReference;
     111           0 :     if (IsIntegerSampler(textureFunction.sampler) ||
     112           0 :         textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
     113             :     {
     114           0 :         out << ".Load(";
     115           0 :         return;
     116             :     }
     117             : 
     118           0 :     if (IsShadowSampler(textureFunction.sampler))
     119             :     {
     120           0 :         switch (textureFunction.method)
     121             :         {
     122             :             case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     123             :             case TextureFunctionHLSL::TextureFunction::BIAS:
     124             :             case TextureFunctionHLSL::TextureFunction::LOD:
     125           0 :                 out << ".SampleCmp(";
     126           0 :                 break;
     127             :             case TextureFunctionHLSL::TextureFunction::LOD0:
     128             :             case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     129             :             case TextureFunctionHLSL::TextureFunction::GRAD:
     130           0 :                 out << ".SampleCmpLevelZero(";
     131           0 :                 break;
     132             :             default:
     133           0 :                 UNREACHABLE();
     134             :         }
     135             :     }
     136             :     else
     137             :     {
     138           0 :         switch (textureFunction.method)
     139             :         {
     140             :             case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     141           0 :                 out << ".Sample(";
     142           0 :                 break;
     143             :             case TextureFunctionHLSL::TextureFunction::BIAS:
     144           0 :                 out << ".SampleBias(";
     145           0 :                 break;
     146             :             case TextureFunctionHLSL::TextureFunction::LOD:
     147             :             case TextureFunctionHLSL::TextureFunction::LOD0:
     148             :             case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     149           0 :                 out << ".SampleLevel(";
     150           0 :                 break;
     151             :             case TextureFunctionHLSL::TextureFunction::GRAD:
     152           0 :                 out << ".SampleGrad(";
     153           0 :                 break;
     154             :             default:
     155           0 :                 UNREACHABLE();
     156             :         }
     157             :     }
     158           0 :     out << samplerReference << ", ";
     159             : }
     160             : 
     161           0 : const char *GetSamplerCoordinateTypeString(
     162             :     const TextureFunctionHLSL::TextureFunction &textureFunction,
     163             :     int hlslCoords)
     164             : {
     165           0 :     if (IsIntegerSampler(textureFunction.sampler) ||
     166           0 :         textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
     167             :     {
     168           0 :         switch (hlslCoords)
     169             :         {
     170             :             case 2:
     171           0 :                 return "int3";
     172             :             case 3:
     173           0 :                 return "int4";
     174             :             default:
     175           0 :                 UNREACHABLE();
     176             :         }
     177             :     }
     178             :     else
     179             :     {
     180           0 :         switch (hlslCoords)
     181             :         {
     182             :             case 2:
     183           0 :                 return "float2";
     184             :             case 3:
     185           0 :                 return "float3";
     186             :             case 4:
     187           0 :                 return "float4";
     188             :             default:
     189           0 :                 UNREACHABLE();
     190             :         }
     191             :     }
     192             :     return "";
     193             : }
     194             : 
     195           0 : int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunction,
     196             :                       ShShaderOutput outputType)
     197             : {
     198           0 :     if (outputType == SH_HLSL_3_0_OUTPUT)
     199             :     {
     200           0 :         int hlslCoords = 2;
     201           0 :         switch (textureFunction.sampler)
     202             :         {
     203             :             case EbtSampler2D:
     204             :             case EbtSamplerExternalOES:
     205           0 :                 hlslCoords = 2;
     206           0 :                 break;
     207             :             case EbtSamplerCube:
     208           0 :                 hlslCoords = 3;
     209           0 :                 break;
     210             :             default:
     211           0 :                 UNREACHABLE();
     212             :         }
     213             : 
     214           0 :         switch (textureFunction.method)
     215             :         {
     216             :             case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     217           0 :                 return hlslCoords;
     218             :             case TextureFunctionHLSL::TextureFunction::BIAS:
     219             :             case TextureFunctionHLSL::TextureFunction::LOD:
     220             :             case TextureFunctionHLSL::TextureFunction::LOD0:
     221             :             case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     222           0 :                 return 4;
     223             :             default:
     224           0 :                 UNREACHABLE();
     225             :         }
     226             :     }
     227             :     else
     228             :     {
     229           0 :         switch (textureFunction.sampler)
     230             :         {
     231             :             case EbtSampler2D:
     232           0 :                 return 2;
     233             :             case EbtSampler3D:
     234           0 :                 return 3;
     235             :             case EbtSamplerCube:
     236           0 :                 return 3;
     237             :             case EbtSampler2DArray:
     238           0 :                 return 3;
     239             :             case EbtSamplerExternalOES:
     240           0 :                 return 2;
     241             :             case EbtISampler2D:
     242           0 :                 return 2;
     243             :             case EbtISampler3D:
     244           0 :                 return 3;
     245             :             case EbtISamplerCube:
     246           0 :                 return 3;
     247             :             case EbtISampler2DArray:
     248           0 :                 return 3;
     249             :             case EbtUSampler2D:
     250           0 :                 return 2;
     251             :             case EbtUSampler3D:
     252           0 :                 return 3;
     253             :             case EbtUSamplerCube:
     254           0 :                 return 3;
     255             :             case EbtUSampler2DArray:
     256           0 :                 return 3;
     257             :             case EbtSampler2DShadow:
     258           0 :                 return 2;
     259             :             case EbtSamplerCubeShadow:
     260           0 :                 return 3;
     261             :             case EbtSampler2DArrayShadow:
     262           0 :                 return 3;
     263             :             default:
     264           0 :                 UNREACHABLE();
     265             :         }
     266             :     }
     267             :     return 0;
     268             : }
     269             : 
     270           0 : void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
     271             :                                        const TextureFunctionHLSL::TextureFunction &textureFunction,
     272             :                                        const ShShaderOutput outputType)
     273             : {
     274           0 :     if (outputType == SH_HLSL_3_0_OUTPUT)
     275             :     {
     276           0 :         switch (textureFunction.sampler)
     277             :         {
     278             :             case EbtSampler2D:
     279             :             case EbtSamplerExternalOES:
     280           0 :                 out << "sampler2D s";
     281           0 :                 break;
     282             :             case EbtSamplerCube:
     283           0 :                 out << "samplerCUBE s";
     284           0 :                 break;
     285             :             default:
     286           0 :                 UNREACHABLE();
     287             :         }
     288             :     }
     289             :     else
     290             :     {
     291           0 :         if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
     292             :         {
     293           0 :             out << TextureString(textureFunction.sampler) << " x, "
     294           0 :                 << SamplerString(textureFunction.sampler) << " s";
     295             :         }
     296             :         else
     297             :         {
     298           0 :             ASSERT(outputType == SH_HLSL_4_1_OUTPUT);
     299           0 :             out << "const uint samplerIndex";
     300             :         }
     301             :     }
     302             : 
     303           0 :     if (textureFunction.method ==
     304             :         TextureFunctionHLSL::TextureFunction::FETCH)  // Integer coordinates
     305             :     {
     306           0 :         switch (textureFunction.coords)
     307             :         {
     308             :             case 2:
     309           0 :                 out << ", int2 t";
     310           0 :                 break;
     311             :             case 3:
     312           0 :                 out << ", int3 t";
     313           0 :                 break;
     314             :             default:
     315           0 :                 UNREACHABLE();
     316             :         }
     317             :     }
     318             :     else  // Floating-point coordinates (except textureSize)
     319             :     {
     320           0 :         switch (textureFunction.coords)
     321             :         {
     322             :             case 1:
     323           0 :                 out << ", int lod";
     324           0 :                 break;  // textureSize()
     325             :             case 2:
     326           0 :                 out << ", float2 t";
     327           0 :                 break;
     328             :             case 3:
     329           0 :                 out << ", float3 t";
     330           0 :                 break;
     331             :             case 4:
     332           0 :                 out << ", float4 t";
     333           0 :                 break;
     334             :             default:
     335           0 :                 UNREACHABLE();
     336             :         }
     337             :     }
     338             : 
     339           0 :     if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     340             :     {
     341           0 :         switch (textureFunction.sampler)
     342             :         {
     343             :             case EbtSampler2D:
     344             :             case EbtISampler2D:
     345             :             case EbtUSampler2D:
     346             :             case EbtSampler2DArray:
     347             :             case EbtISampler2DArray:
     348             :             case EbtUSampler2DArray:
     349             :             case EbtSampler2DShadow:
     350             :             case EbtSampler2DArrayShadow:
     351             :             case EbtSamplerExternalOES:
     352           0 :                 out << ", float2 ddx, float2 ddy";
     353           0 :                 break;
     354             :             case EbtSampler3D:
     355             :             case EbtISampler3D:
     356             :             case EbtUSampler3D:
     357             :             case EbtSamplerCube:
     358             :             case EbtISamplerCube:
     359             :             case EbtUSamplerCube:
     360             :             case EbtSamplerCubeShadow:
     361           0 :                 out << ", float3 ddx, float3 ddy";
     362           0 :                 break;
     363             :             default:
     364           0 :                 UNREACHABLE();
     365             :         }
     366             :     }
     367             : 
     368           0 :     switch (textureFunction.method)
     369             :     {
     370             :         case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     371           0 :             break;
     372             :         case TextureFunctionHLSL::TextureFunction::BIAS:
     373           0 :             break;  // Comes after the offset parameter
     374             :         case TextureFunctionHLSL::TextureFunction::LOD:
     375           0 :             out << ", float lod";
     376           0 :             break;
     377             :         case TextureFunctionHLSL::TextureFunction::LOD0:
     378           0 :             break;
     379             :         case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     380           0 :             break;  // Comes after the offset parameter
     381             :         case TextureFunctionHLSL::TextureFunction::SIZE:
     382           0 :             break;
     383             :         case TextureFunctionHLSL::TextureFunction::FETCH:
     384           0 :             out << ", int mip";
     385           0 :             break;
     386             :         case TextureFunctionHLSL::TextureFunction::GRAD:
     387           0 :             break;
     388             :         default:
     389           0 :             UNREACHABLE();
     390             :     }
     391             : 
     392           0 :     if (textureFunction.offset)
     393             :     {
     394           0 :         switch (textureFunction.sampler)
     395             :         {
     396             :             case EbtSampler3D:
     397             :             case EbtISampler3D:
     398             :             case EbtUSampler3D:
     399           0 :                 out << ", int3 offset";
     400           0 :                 break;
     401             :             case EbtSampler2D:
     402             :             case EbtSampler2DArray:
     403             :             case EbtISampler2D:
     404             :             case EbtISampler2DArray:
     405             :             case EbtUSampler2D:
     406             :             case EbtUSampler2DArray:
     407             :             case EbtSampler2DShadow:
     408             :             case EbtSampler2DArrayShadow:
     409             :             case EbtSamplerExternalOES:
     410           0 :                 out << ", int2 offset";
     411           0 :                 break;
     412             :             default:
     413           0 :                 UNREACHABLE();
     414             :         }
     415             :     }
     416             : 
     417           0 :     if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS ||
     418           0 :         textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
     419             :     {
     420           0 :         out << ", float bias";
     421             :     }
     422           0 : }
     423             : 
     424           0 : void GetTextureReference(TInfoSinkBase &out,
     425             :                          const TextureFunctionHLSL::TextureFunction &textureFunction,
     426             :                          const ShShaderOutput outputType,
     427             :                          TString *textureReference,
     428             :                          TString *samplerReference)
     429             : {
     430           0 :     if (outputType == SH_HLSL_4_1_OUTPUT)
     431             :     {
     432           0 :         TString suffix = TextureGroupSuffix(textureFunction.sampler);
     433           0 :         if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D)
     434             :         {
     435           0 :             *textureReference = TString("textures") + suffix + "[samplerIndex]";
     436           0 :             *samplerReference = TString("samplers") + suffix + "[samplerIndex]";
     437             :         }
     438             :         else
     439             :         {
     440           0 :             out << "    const uint textureIndex = samplerIndex - textureIndexOffset" << suffix
     441           0 :                 << ";\n";
     442           0 :             *textureReference = TString("textures") + suffix + "[textureIndex]";
     443           0 :             out << "    const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" << suffix
     444           0 :                 << ";\n";
     445           0 :             *samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]";
     446             :         }
     447             :     }
     448             :     else
     449             :     {
     450           0 :         *textureReference = "x";
     451           0 :         *samplerReference = "s";
     452             :     }
     453           0 : }
     454             : 
     455           0 : void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
     456             :                                    const TextureFunctionHLSL::TextureFunction &textureFunction,
     457             :                                    const TString &textureReference,
     458             :                                    bool getDimensionsIgnoresBaseLevel)
     459             : {
     460           0 :     if (getDimensionsIgnoresBaseLevel)
     461             :     {
     462           0 :         out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
     463             :     }
     464             :     else
     465             :     {
     466           0 :         out << "int baseLevel = 0;\n";
     467             :     }
     468             : 
     469           0 :     if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) ||
     470           0 :         (IsIntegerSampler(textureFunction.sampler) && IsSamplerCube(textureFunction.sampler)))
     471             :     {
     472             :         // "depth" stores either the number of layers in an array texture or 3D depth
     473           0 :         out << "    uint width; uint height; uint depth; uint numberOfLevels;\n"
     474           0 :             << "    " << textureReference
     475           0 :             << ".GetDimensions(baseLevel, width, height, depth, numberOfLevels);\n"
     476           0 :             << "    width = max(width >> lod, 1);\n"
     477           0 :             << "    height = max(height >> lod, 1);\n";
     478             : 
     479           0 :         if (!IsSamplerArray(textureFunction.sampler))
     480             :         {
     481           0 :             out << "    depth = max(depth >> lod, 1);\n";
     482             :         }
     483             :     }
     484           0 :     else if (IsSampler2D(textureFunction.sampler) || IsSamplerCube(textureFunction.sampler))
     485             :     {
     486           0 :         out << "    uint width; uint height; uint numberOfLevels;\n"
     487           0 :             << "    " << textureReference
     488           0 :             << ".GetDimensions(baseLevel, width, height, numberOfLevels);\n"
     489           0 :             << "    width = max(width >> lod, 1);\n"
     490           0 :             << "    height = max(height >> lod, 1);\n";
     491             :     }
     492             :     else
     493           0 :         UNREACHABLE();
     494             : 
     495           0 :     if (strcmp(textureFunction.getReturnType(), "int3") == 0)
     496             :     {
     497           0 :         out << "    return int3(width, height, depth);";
     498             :     }
     499             :     else
     500             :     {
     501           0 :         out << "    return int2(width, height);";
     502             :     }
     503           0 : }
     504             : 
     505           0 : void ProjectTextureCoordinates(const TextureFunctionHLSL::TextureFunction &textureFunction,
     506             :                                TString *texCoordX,
     507             :                                TString *texCoordY,
     508             :                                TString *texCoordZ)
     509             : {
     510           0 :     if (textureFunction.proj)
     511             :     {
     512           0 :         TString proj("");
     513           0 :         switch (textureFunction.coords)
     514             :         {
     515             :             case 3:
     516           0 :                 proj = " / t.z";
     517           0 :                 break;
     518             :             case 4:
     519           0 :                 proj = " / t.w";
     520           0 :                 break;
     521             :             default:
     522           0 :                 UNREACHABLE();
     523             :         }
     524           0 :         *texCoordX = "(" + *texCoordX + proj + ")";
     525           0 :         *texCoordY = "(" + *texCoordY + proj + ")";
     526           0 :         *texCoordZ = "(" + *texCoordZ + proj + ")";
     527             :     }
     528           0 : }
     529             : 
     530           0 : void OutputIntegerTextureSampleFunctionComputations(
     531             :     TInfoSinkBase &out,
     532             :     const TextureFunctionHLSL::TextureFunction &textureFunction,
     533             :     const ShShaderOutput outputType,
     534             :     const TString &textureReference,
     535             :     TString *texCoordX,
     536             :     TString *texCoordY,
     537             :     TString *texCoordZ)
     538             : {
     539           0 :     if (!IsIntegerSampler(textureFunction.sampler))
     540             :     {
     541           0 :         return;
     542             :     }
     543           0 :     if (IsSamplerCube(textureFunction.sampler))
     544             :     {
     545           0 :         out << "    float width; float height; float layers; float levels;\n";
     546             : 
     547           0 :         out << "    uint mip = 0;\n";
     548             : 
     549           0 :         out << "    " << textureReference
     550           0 :             << ".GetDimensions(mip, width, height, layers, levels);\n";
     551             : 
     552           0 :         out << "    bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n";
     553           0 :         out << "    bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n";
     554           0 :         out << "    bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n";
     555             :         out << "    bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || "
     556           0 :                "(zMajor && t.z < 0.0f);\n";
     557             : 
     558             :         // FACE_POSITIVE_X = 000b
     559             :         // FACE_NEGATIVE_X = 001b
     560             :         // FACE_POSITIVE_Y = 010b
     561             :         // FACE_NEGATIVE_Y = 011b
     562             :         // FACE_POSITIVE_Z = 100b
     563             :         // FACE_NEGATIVE_Z = 101b
     564           0 :         out << "    int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n";
     565             : 
     566           0 :         out << "    float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n";
     567           0 :         out << "    float v = yMajor ? t.z : (negative ? t.y : -t.y);\n";
     568           0 :         out << "    float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n";
     569             : 
     570           0 :         out << "    t.x = (u * 0.5f / m) + 0.5f;\n";
     571           0 :         out << "    t.y = (v * 0.5f / m) + 0.5f;\n";
     572             : 
     573             :         // Mip level computation.
     574           0 :         if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
     575           0 :             textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD ||
     576           0 :             textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     577             :         {
     578           0 :             if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT)
     579             :             {
     580             :                 out << "    float2 tSized = float2(t.x * width, t.y * height);\n"
     581             :                        "    float2 dx = ddx(tSized);\n"
     582             :                        "    float2 dy = ddy(tSized);\n"
     583           0 :                        "    float lod = 0.5f * log2(max(dot(dx, dx), dot(dy, dy)));\n";
     584             :             }
     585           0 :             else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     586             :             {
     587             :                 // ESSL 3.00.6 spec section 8.8: "For the cube version, the partial
     588             :                 // derivatives of P are assumed to be in the coordinate system used before
     589             :                 // texture coordinates are projected onto the appropriate cube face."
     590             :                 // ddx[0] and ddy[0] are the derivatives of t.x passed into the function
     591             :                 // ddx[1] and ddy[1] are the derivatives of t.y passed into the function
     592             :                 // ddx[2] and ddy[2] are the derivatives of t.z passed into the function
     593             :                 // Determine the derivatives of u, v and m
     594             :                 out << "    float dudx = xMajor ? ddx[2] : (yMajor && t.y < 0.0f ? -ddx[0] "
     595             :                        ": ddx[0]);\n"
     596             :                        "    float dudy = xMajor ? ddy[2] : (yMajor && t.y < 0.0f ? -ddy[0] "
     597             :                        ": ddy[0]);\n"
     598             :                        "    float dvdx = yMajor ? ddx[2] : (negative ? ddx[1] : -ddx[1]);\n"
     599             :                        "    float dvdy = yMajor ? ddy[2] : (negative ? ddy[1] : -ddy[1]);\n"
     600             :                        "    float dmdx = xMajor ? ddx[0] : (yMajor ? ddx[1] : ddx[2]);\n"
     601           0 :                        "    float dmdy = xMajor ? ddy[0] : (yMajor ? ddy[1] : ddy[2]);\n";
     602             :                 // Now determine the derivatives of the face coordinates, using the
     603             :                 // derivatives calculated above.
     604             :                 // d / dx (u(x) * 0.5 / m(x) + 0.5)
     605             :                 // = 0.5 * (m(x) * u'(x) - u(x) * m'(x)) / m(x)^2
     606             :                 out << "    float dfacexdx = 0.5f * (m * dudx - u * dmdx) / (m * m);\n"
     607             :                        "    float dfaceydx = 0.5f * (m * dvdx - v * dmdx) / (m * m);\n"
     608             :                        "    float dfacexdy = 0.5f * (m * dudy - u * dmdy) / (m * m);\n"
     609             :                        "    float dfaceydy = 0.5f * (m * dvdy - v * dmdy) / (m * m);\n"
     610             :                        "    float2 sizeVec = float2(width, height);\n"
     611             :                        "    float2 faceddx = float2(dfacexdx, dfaceydx) * sizeVec;\n"
     612           0 :                        "    float2 faceddy = float2(dfacexdy, dfaceydy) * sizeVec;\n";
     613             :                 // Optimization: instead of: log2(max(length(faceddx), length(faceddy)))
     614             :                 // we compute: log2(max(length(faceddx)^2, length(faceddy)^2)) / 2
     615             :                 out << "    float lengthfaceddx2 = dot(faceddx, faceddx);\n"
     616             :                        "    float lengthfaceddy2 = dot(faceddy, faceddy);\n"
     617           0 :                        "    float lod = log2(max(lengthfaceddx2, lengthfaceddy2)) * 0.5f;\n";
     618             :             }
     619           0 :             out << "    mip = uint(min(max(round(lod), 0), levels - 1));\n"
     620           0 :                 << "    " << textureReference
     621           0 :                 << ".GetDimensions(mip, width, height, layers, levels);\n";
     622             :         }
     623             : 
     624             :         // Convert from normalized floating-point to integer
     625           0 :         *texCoordX = "int(floor(width * frac(" + *texCoordX + ")))";
     626           0 :         *texCoordY = "int(floor(height * frac(" + *texCoordY + ")))";
     627           0 :         *texCoordZ = "face";
     628             :     }
     629           0 :     else if (textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH)
     630             :     {
     631           0 :         if (IsSampler2D(textureFunction.sampler))
     632             :         {
     633           0 :             if (IsSamplerArray(textureFunction.sampler))
     634             :             {
     635           0 :                 out << "    float width; float height; float layers; float levels;\n";
     636             : 
     637           0 :                 if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
     638             :                 {
     639           0 :                     out << "    uint mip = 0;\n";
     640             :                 }
     641           0 :                 else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
     642             :                 {
     643           0 :                     out << "    uint mip = bias;\n";
     644             :                 }
     645             :                 else
     646             :                 {
     647             : 
     648           0 :                     out << "    " << textureReference
     649           0 :                         << ".GetDimensions(0, width, height, layers, levels);\n";
     650           0 :                     if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
     651           0 :                         textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     652             :                     {
     653             :                         out << "    float2 tSized = float2(t.x * width, t.y * height);\n"
     654             :                                "    float dx = length(ddx(tSized));\n"
     655             :                                "    float dy = length(ddy(tSized));\n"
     656           0 :                                "    float lod = log2(max(dx, dy));\n";
     657             : 
     658           0 :                         if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     659             :                         {
     660           0 :                             out << "    lod += bias;\n";
     661             :                         }
     662             :                     }
     663           0 :                     else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     664             :                     {
     665             :                         out << "    float2 sizeVec = float2(width, height);\n"
     666             :                                "    float2 sizeDdx = ddx * sizeVec;\n"
     667             :                                "    float2 sizeDdy = ddy * sizeVec;\n"
     668             :                                "    float lod = log2(max(dot(sizeDdx, sizeDdx), "
     669           0 :                                "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
     670             :                     }
     671             : 
     672           0 :                     out << "    uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
     673             :                 }
     674             : 
     675           0 :                 out << "    " << textureReference
     676           0 :                     << ".GetDimensions(mip, width, height, layers, levels);\n";
     677             :             }
     678             :             else
     679             :             {
     680           0 :                 out << "    float width; float height; float levels;\n";
     681             : 
     682           0 :                 if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
     683             :                 {
     684           0 :                     out << "    uint mip = 0;\n";
     685             :                 }
     686           0 :                 else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
     687             :                 {
     688           0 :                     out << "    uint mip = bias;\n";
     689             :                 }
     690             :                 else
     691             :                 {
     692           0 :                     out << "    " << textureReference
     693           0 :                         << ".GetDimensions(0, width, height, levels);\n";
     694             : 
     695           0 :                     if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
     696           0 :                         textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     697             :                     {
     698             :                         out << "    float2 tSized = float2(t.x * width, t.y * height);\n"
     699             :                                "    float dx = length(ddx(tSized));\n"
     700             :                                "    float dy = length(ddy(tSized));\n"
     701           0 :                                "    float lod = log2(max(dx, dy));\n";
     702             : 
     703           0 :                         if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     704             :                         {
     705           0 :                             out << "    lod += bias;\n";
     706             :                         }
     707             :                     }
     708           0 :                     else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     709             :                     {
     710             :                         out << "    float2 sizeVec = float2(width, height);\n"
     711             :                                "    float2 sizeDdx = ddx * sizeVec;\n"
     712             :                                "    float2 sizeDdy = ddy * sizeVec;\n"
     713             :                                "    float lod = log2(max(dot(sizeDdx, sizeDdx), "
     714           0 :                                "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
     715             :                     }
     716             : 
     717           0 :                     out << "    uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
     718             :                 }
     719             : 
     720           0 :                 out << "    " << textureReference
     721           0 :                     << ".GetDimensions(mip, width, height, levels);\n";
     722             :             }
     723             :         }
     724           0 :         else if (IsSampler3D(textureFunction.sampler))
     725             :         {
     726           0 :             out << "    float width; float height; float depth; float levels;\n";
     727             : 
     728           0 :             if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
     729             :             {
     730           0 :                 out << "    uint mip = 0;\n";
     731             :             }
     732           0 :             else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
     733             :             {
     734           0 :                 out << "    uint mip = bias;\n";
     735             :             }
     736             :             else
     737             :             {
     738           0 :                 out << "    " << textureReference
     739           0 :                     << ".GetDimensions(0, width, height, depth, levels);\n";
     740             : 
     741           0 :                 if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
     742           0 :                     textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     743             :                 {
     744             :                     out << "    float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n"
     745             :                            "    float dx = length(ddx(tSized));\n"
     746             :                            "    float dy = length(ddy(tSized));\n"
     747           0 :                            "    float lod = log2(max(dx, dy));\n";
     748             : 
     749           0 :                     if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
     750             :                     {
     751           0 :                         out << "    lod += bias;\n";
     752             :                     }
     753             :                 }
     754           0 :                 else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     755             :                 {
     756             :                     out << "    float3 sizeVec = float3(width, height, depth);\n"
     757             :                            "    float3 sizeDdx = ddx * sizeVec;\n"
     758             :                            "    float3 sizeDdy = ddy * sizeVec;\n"
     759             :                            "    float lod = log2(max(dot(sizeDdx, sizeDdx), dot(sizeDdy, "
     760           0 :                            "sizeDdy))) * 0.5f;\n";
     761             :                 }
     762             : 
     763           0 :                 out << "    uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
     764             :             }
     765             : 
     766           0 :             out << "    " << textureReference
     767           0 :                 << ".GetDimensions(mip, width, height, depth, levels);\n";
     768             :         }
     769             :         else
     770           0 :             UNREACHABLE();
     771             : 
     772           0 :         OutputIntTexCoordWraps(out, textureFunction, texCoordX, texCoordY, texCoordZ);
     773             :     }
     774             : }
     775             : 
     776           0 : void OutputTextureSampleFunctionReturnStatement(
     777             :     TInfoSinkBase &out,
     778             :     const TextureFunctionHLSL::TextureFunction &textureFunction,
     779             :     const ShShaderOutput outputType,
     780             :     const TString &textureReference,
     781             :     const TString &samplerReference,
     782             :     const TString &texCoordX,
     783             :     const TString &texCoordY,
     784             :     const TString &texCoordZ)
     785             : {
     786           0 :     out << "    return ";
     787             : 
     788             :     // HLSL intrinsic
     789           0 :     if (outputType == SH_HLSL_3_0_OUTPUT)
     790             :     {
     791           0 :         switch (textureFunction.sampler)
     792             :         {
     793             :             case EbtSampler2D:
     794             :             case EbtSamplerExternalOES:
     795           0 :                 out << "tex2D";
     796           0 :                 break;
     797             :             case EbtSamplerCube:
     798           0 :                 out << "texCUBE";
     799           0 :                 break;
     800             :             default:
     801           0 :                 UNREACHABLE();
     802             :         }
     803             : 
     804           0 :         switch (textureFunction.method)
     805             :         {
     806             :             case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     807           0 :                 out << "(" << samplerReference << ", ";
     808           0 :                 break;
     809             :             case TextureFunctionHLSL::TextureFunction::BIAS:
     810           0 :                 out << "bias(" << samplerReference << ", ";
     811           0 :                 break;
     812             :             case TextureFunctionHLSL::TextureFunction::LOD:
     813           0 :                 out << "lod(" << samplerReference << ", ";
     814           0 :                 break;
     815             :             case TextureFunctionHLSL::TextureFunction::LOD0:
     816           0 :                 out << "lod(" << samplerReference << ", ";
     817           0 :                 break;
     818             :             case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     819           0 :                 out << "lod(" << samplerReference << ", ";
     820           0 :                 break;
     821             :             default:
     822           0 :                 UNREACHABLE();
     823             :         }
     824             :     }
     825           0 :     else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
     826             :     {
     827           0 :         OutputHLSL4SampleFunctionPrefix(out, textureFunction, textureReference, samplerReference);
     828             :     }
     829             :     else
     830           0 :         UNREACHABLE();
     831             : 
     832           0 :     const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
     833             : 
     834           0 :     out << GetSamplerCoordinateTypeString(textureFunction, hlslCoords) << "(" << texCoordX << ", "
     835           0 :         << texCoordY;
     836             : 
     837           0 :     if (outputType == SH_HLSL_3_0_OUTPUT)
     838             :     {
     839           0 :         if (hlslCoords >= 3)
     840             :         {
     841           0 :             if (textureFunction.coords < 3)
     842             :             {
     843           0 :                 out << ", 0";
     844             :             }
     845             :             else
     846             :             {
     847           0 :                 out << ", " << texCoordZ;
     848             :             }
     849             :         }
     850             : 
     851           0 :         if (hlslCoords == 4)
     852             :         {
     853           0 :             switch (textureFunction.method)
     854             :             {
     855             :                 case TextureFunctionHLSL::TextureFunction::BIAS:
     856           0 :                     out << ", bias";
     857           0 :                     break;
     858             :                 case TextureFunctionHLSL::TextureFunction::LOD:
     859           0 :                     out << ", lod";
     860           0 :                     break;
     861             :                 case TextureFunctionHLSL::TextureFunction::LOD0:
     862           0 :                     out << ", 0";
     863           0 :                     break;
     864             :                 case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     865           0 :                     out << ", bias";
     866           0 :                     break;
     867             :                 default:
     868           0 :                     UNREACHABLE();
     869             :             }
     870             :         }
     871             : 
     872           0 :         out << ")";
     873             :     }
     874           0 :     else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
     875             :     {
     876           0 :         if (hlslCoords >= 3)
     877             :         {
     878           0 :             ASSERT(!IsIntegerSampler(textureFunction.sampler) ||
     879             :                    !IsSamplerCube(textureFunction.sampler) || texCoordZ == "face");
     880           0 :             out << ", " << texCoordZ;
     881             :         }
     882             : 
     883           0 :         if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
     884             :         {
     885           0 :             if (IsIntegerSampler(textureFunction.sampler))
     886             :             {
     887           0 :                 out << ", mip)";
     888             :             }
     889           0 :             else if (IsShadowSampler(textureFunction.sampler))
     890             :             {
     891             :                 // Compare value
     892           0 :                 if (textureFunction.proj)
     893             :                 {
     894             :                     // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
     895             :                     // The resulting third component of P' in the shadow forms is used as
     896             :                     // Dref
     897           0 :                     out << "), " << texCoordZ;
     898             :                 }
     899             :                 else
     900             :                 {
     901           0 :                     switch (textureFunction.coords)
     902             :                     {
     903             :                         case 3:
     904           0 :                             out << "), t.z";
     905           0 :                             break;
     906             :                         case 4:
     907           0 :                             out << "), t.w";
     908           0 :                             break;
     909             :                         default:
     910           0 :                             UNREACHABLE();
     911             :                     }
     912             :                 }
     913             :             }
     914             :             else
     915             :             {
     916           0 :                 out << "), ddx, ddy";
     917             :             }
     918             :         }
     919           0 :         else if (IsIntegerSampler(textureFunction.sampler) ||
     920           0 :                  textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
     921             :         {
     922           0 :             out << ", mip)";
     923             :         }
     924           0 :         else if (IsShadowSampler(textureFunction.sampler))
     925             :         {
     926             :             // Compare value
     927           0 :             if (textureFunction.proj)
     928             :             {
     929             :                 // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
     930             :                 // The resulting third component of P' in the shadow forms is used as Dref
     931           0 :                 out << "), " << texCoordZ;
     932             :             }
     933             :             else
     934             :             {
     935           0 :                 switch (textureFunction.coords)
     936             :                 {
     937             :                     case 3:
     938           0 :                         out << "), t.z";
     939           0 :                         break;
     940             :                     case 4:
     941           0 :                         out << "), t.w";
     942           0 :                         break;
     943             :                     default:
     944           0 :                         UNREACHABLE();
     945             :                 }
     946             :             }
     947             :         }
     948             :         else
     949             :         {
     950           0 :             switch (textureFunction.method)
     951             :             {
     952             :                 case TextureFunctionHLSL::TextureFunction::IMPLICIT:
     953           0 :                     out << ")";
     954           0 :                     break;
     955             :                 case TextureFunctionHLSL::TextureFunction::BIAS:
     956           0 :                     out << "), bias";
     957           0 :                     break;
     958             :                 case TextureFunctionHLSL::TextureFunction::LOD:
     959           0 :                     out << "), lod";
     960           0 :                     break;
     961             :                 case TextureFunctionHLSL::TextureFunction::LOD0:
     962           0 :                     out << "), 0";
     963           0 :                     break;
     964             :                 case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
     965           0 :                     out << "), bias";
     966           0 :                     break;
     967             :                 default:
     968           0 :                     UNREACHABLE();
     969             :             }
     970             :         }
     971             : 
     972           0 :         if (textureFunction.offset &&
     973           0 :             (!IsIntegerSampler(textureFunction.sampler) ||
     974           0 :              textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH))
     975             :         {
     976           0 :             out << ", offset";
     977             :         }
     978             :     }
     979             :     else
     980           0 :         UNREACHABLE();
     981             : 
     982           0 :     out << ");\n";  // Close the sample function call and return statement
     983           0 : }
     984             : 
     985             : }  // Anonymous namespace
     986             : 
     987           0 : TString TextureFunctionHLSL::TextureFunction::name() const
     988             : {
     989           0 :     TString name = "gl_texture";
     990             : 
     991             :     // We need to include full the sampler type in the function name to make the signature unique
     992             :     // on D3D11, where samplers are passed to texture functions as indices.
     993           0 :     name += TextureTypeSuffix(this->sampler);
     994             : 
     995           0 :     if (proj)
     996             :     {
     997           0 :         name += "Proj";
     998             :     }
     999             : 
    1000           0 :     if (offset)
    1001             :     {
    1002           0 :         name += "Offset";
    1003             :     }
    1004             : 
    1005           0 :     switch (method)
    1006             :     {
    1007             :         case IMPLICIT:
    1008           0 :             break;
    1009             :         case BIAS:
    1010           0 :             break;  // Extra parameter makes the signature unique
    1011             :         case LOD:
    1012           0 :             name += "Lod";
    1013           0 :             break;
    1014             :         case LOD0:
    1015           0 :             name += "Lod0";
    1016           0 :             break;
    1017             :         case LOD0BIAS:
    1018           0 :             name += "Lod0";
    1019           0 :             break;  // Extra parameter makes the signature unique
    1020             :         case SIZE:
    1021           0 :             name += "Size";
    1022           0 :             break;
    1023             :         case FETCH:
    1024           0 :             name += "Fetch";
    1025           0 :             break;
    1026             :         case GRAD:
    1027           0 :             name += "Grad";
    1028           0 :             break;
    1029             :         default:
    1030           0 :             UNREACHABLE();
    1031             :     }
    1032             : 
    1033           0 :     return name;
    1034             : }
    1035             : 
    1036           0 : const char *TextureFunctionHLSL::TextureFunction::getReturnType() const
    1037             : {
    1038           0 :     if (method == TextureFunction::SIZE)
    1039             :     {
    1040           0 :         switch (sampler)
    1041             :         {
    1042             :             case EbtSampler2D:
    1043             :             case EbtISampler2D:
    1044             :             case EbtUSampler2D:
    1045             :             case EbtSampler2DShadow:
    1046             :             case EbtSamplerCube:
    1047             :             case EbtISamplerCube:
    1048             :             case EbtUSamplerCube:
    1049             :             case EbtSamplerCubeShadow:
    1050             :             case EbtSamplerExternalOES:
    1051           0 :                 return "int2";
    1052             :             case EbtSampler3D:
    1053             :             case EbtISampler3D:
    1054             :             case EbtUSampler3D:
    1055             :             case EbtSampler2DArray:
    1056             :             case EbtISampler2DArray:
    1057             :             case EbtUSampler2DArray:
    1058             :             case EbtSampler2DArrayShadow:
    1059           0 :                 return "int3";
    1060             :             default:
    1061           0 :                 UNREACHABLE();
    1062             :         }
    1063             :     }
    1064             :     else  // Sampling function
    1065             :     {
    1066           0 :         switch (sampler)
    1067             :         {
    1068             :             case EbtSampler2D:
    1069             :             case EbtSampler3D:
    1070             :             case EbtSamplerCube:
    1071             :             case EbtSampler2DArray:
    1072             :             case EbtSamplerExternalOES:
    1073           0 :                 return "float4";
    1074             :             case EbtISampler2D:
    1075             :             case EbtISampler3D:
    1076             :             case EbtISamplerCube:
    1077             :             case EbtISampler2DArray:
    1078           0 :                 return "int4";
    1079             :             case EbtUSampler2D:
    1080             :             case EbtUSampler3D:
    1081             :             case EbtUSamplerCube:
    1082             :             case EbtUSampler2DArray:
    1083           0 :                 return "uint4";
    1084             :             case EbtSampler2DShadow:
    1085             :             case EbtSamplerCubeShadow:
    1086             :             case EbtSampler2DArrayShadow:
    1087           0 :                 return "float";
    1088             :             default:
    1089           0 :                 UNREACHABLE();
    1090             :         }
    1091             :     }
    1092             :     return "";
    1093             : }
    1094             : 
    1095           0 : bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
    1096             : {
    1097           0 :     return std::tie(sampler, coords, proj, offset, method) <
    1098           0 :            std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method);
    1099             : }
    1100             : 
    1101           0 : TString TextureFunctionHLSL::useTextureFunction(const TString &name,
    1102             :                                                 TBasicType samplerType,
    1103             :                                                 int coords,
    1104             :                                                 size_t argumentCount,
    1105             :                                                 bool lod0,
    1106             :                                                 sh::GLenum shaderType)
    1107             : {
    1108             :     TextureFunction textureFunction;
    1109           0 :     textureFunction.sampler = samplerType;
    1110           0 :     textureFunction.coords  = coords;
    1111           0 :     textureFunction.method  = TextureFunction::IMPLICIT;
    1112           0 :     textureFunction.proj    = false;
    1113           0 :     textureFunction.offset  = false;
    1114             : 
    1115           0 :     if (name == "texture2D" || name == "textureCube" || name == "texture")
    1116             :     {
    1117           0 :         textureFunction.method = TextureFunction::IMPLICIT;
    1118             :     }
    1119           0 :     else if (name == "texture2DProj" || name == "textureProj")
    1120             :     {
    1121           0 :         textureFunction.method = TextureFunction::IMPLICIT;
    1122           0 :         textureFunction.proj   = true;
    1123             :     }
    1124           0 :     else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" ||
    1125           0 :              name == "texture2DLodEXT" || name == "textureCubeLodEXT")
    1126             :     {
    1127           0 :         textureFunction.method = TextureFunction::LOD;
    1128             :     }
    1129           0 :     else if (name == "texture2DProjLod" || name == "textureProjLod" ||
    1130           0 :              name == "texture2DProjLodEXT")
    1131             :     {
    1132           0 :         textureFunction.method = TextureFunction::LOD;
    1133           0 :         textureFunction.proj   = true;
    1134             :     }
    1135           0 :     else if (name == "textureSize")
    1136             :     {
    1137           0 :         textureFunction.method = TextureFunction::SIZE;
    1138             :     }
    1139           0 :     else if (name == "textureOffset")
    1140             :     {
    1141           0 :         textureFunction.method = TextureFunction::IMPLICIT;
    1142           0 :         textureFunction.offset = true;
    1143             :     }
    1144           0 :     else if (name == "textureProjOffset")
    1145             :     {
    1146           0 :         textureFunction.method = TextureFunction::IMPLICIT;
    1147           0 :         textureFunction.offset = true;
    1148           0 :         textureFunction.proj   = true;
    1149             :     }
    1150           0 :     else if (name == "textureLodOffset")
    1151             :     {
    1152           0 :         textureFunction.method = TextureFunction::LOD;
    1153           0 :         textureFunction.offset = true;
    1154             :     }
    1155           0 :     else if (name == "textureProjLodOffset")
    1156             :     {
    1157           0 :         textureFunction.method = TextureFunction::LOD;
    1158           0 :         textureFunction.proj   = true;
    1159           0 :         textureFunction.offset = true;
    1160             :     }
    1161           0 :     else if (name == "texelFetch")
    1162             :     {
    1163           0 :         textureFunction.method = TextureFunction::FETCH;
    1164             :     }
    1165           0 :     else if (name == "texelFetchOffset")
    1166             :     {
    1167           0 :         textureFunction.method = TextureFunction::FETCH;
    1168           0 :         textureFunction.offset = true;
    1169             :     }
    1170           0 :     else if (name == "textureGrad" || name == "texture2DGradEXT")
    1171             :     {
    1172           0 :         textureFunction.method = TextureFunction::GRAD;
    1173             :     }
    1174           0 :     else if (name == "textureGradOffset")
    1175             :     {
    1176           0 :         textureFunction.method = TextureFunction::GRAD;
    1177           0 :         textureFunction.offset = true;
    1178             :     }
    1179           0 :     else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" ||
    1180           0 :              name == "textureCubeGradEXT")
    1181             :     {
    1182           0 :         textureFunction.method = TextureFunction::GRAD;
    1183           0 :         textureFunction.proj   = true;
    1184             :     }
    1185           0 :     else if (name == "textureProjGradOffset")
    1186             :     {
    1187           0 :         textureFunction.method = TextureFunction::GRAD;
    1188           0 :         textureFunction.proj   = true;
    1189           0 :         textureFunction.offset = true;
    1190             :     }
    1191             :     else
    1192           0 :         UNREACHABLE();
    1193             : 
    1194           0 :     if (textureFunction.method ==
    1195             :         TextureFunction::IMPLICIT)  // Could require lod 0 or have a bias argument
    1196             :     {
    1197           0 :         size_t mandatoryArgumentCount = 2;  // All functions have sampler and coordinate arguments
    1198             : 
    1199           0 :         if (textureFunction.offset)
    1200             :         {
    1201           0 :             mandatoryArgumentCount++;
    1202             :         }
    1203             : 
    1204           0 :         bool bias = (argumentCount > mandatoryArgumentCount);  // Bias argument is optional
    1205             : 
    1206           0 :         if (lod0 || shaderType == GL_VERTEX_SHADER)
    1207             :         {
    1208           0 :             if (bias)
    1209             :             {
    1210           0 :                 textureFunction.method = TextureFunction::LOD0BIAS;
    1211             :             }
    1212             :             else
    1213             :             {
    1214           0 :                 textureFunction.method = TextureFunction::LOD0;
    1215             :             }
    1216             :         }
    1217           0 :         else if (bias)
    1218             :         {
    1219           0 :             textureFunction.method = TextureFunction::BIAS;
    1220             :         }
    1221             :     }
    1222             : 
    1223           0 :     mUsesTexture.insert(textureFunction);
    1224           0 :     return textureFunction.name();
    1225             : }
    1226             : 
    1227           0 : void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
    1228             :                                                 const ShShaderOutput outputType,
    1229             :                                                 bool getDimensionsIgnoresBaseLevel)
    1230             : {
    1231           0 :     for (const TextureFunction &textureFunction : mUsesTexture)
    1232             :     {
    1233             :         // Function header
    1234           0 :         out << textureFunction.getReturnType() << " " << textureFunction.name() << "(";
    1235             : 
    1236           0 :         OutputTextureFunctionArgumentList(out, textureFunction, outputType);
    1237             : 
    1238             :         out << ")\n"
    1239           0 :                "{\n";
    1240             : 
    1241             :         // In some cases we use a variable to store the texture/sampler objects, but to work around
    1242             :         // a D3D11 compiler bug related to discard inside a loop that is conditional on texture
    1243             :         // sampling we need to call the function directly on references to the texture and sampler
    1244             :         // arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture*
    1245             :         // tests.
    1246           0 :         TString textureReference;
    1247           0 :         TString samplerReference;
    1248           0 :         GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference);
    1249             : 
    1250           0 :         if (textureFunction.method == TextureFunction::SIZE)
    1251             :         {
    1252           0 :             OutputTextureSizeFunctionBody(out, textureFunction, textureReference,
    1253           0 :                                           getDimensionsIgnoresBaseLevel);
    1254             :         }
    1255             :         else
    1256             :         {
    1257           0 :             TString texCoordX("t.x");
    1258           0 :             TString texCoordY("t.y");
    1259           0 :             TString texCoordZ("t.z");
    1260           0 :             ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
    1261             :             OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType,
    1262             :                                                            textureReference, &texCoordX, &texCoordY,
    1263           0 :                                                            &texCoordZ);
    1264             :             OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
    1265             :                                                        textureReference, samplerReference,
    1266           0 :                                                        texCoordX, texCoordY, texCoordZ);
    1267             :         }
    1268             : 
    1269             :         out << "}\n"
    1270           0 :                "\n";
    1271             :     }
    1272           0 : }
    1273             : 
    1274             : }  // namespace sh

Generated by: LCOV version 1.13