hlslcc outputs half precision types on metal

hlslcc outputs half precision types on metal and this becomes a problem on iOS.
Is there a way to disable the force to half option?
Here is the problem demonstrated:

/Input:
Texture2D<float4> _MainTex;
SamplerState sampler_MainTex;
float _Asd;
float4 frag (v2f i) : SV_Target
{
    float4 col = _MainTex.Sample(sampler_MainTex, i.uv);
    col = pow(col, _Asd);
    return col * 1000;
}
//Output (notice the u_xlat0 being float)
fragment Mtl_FragmentOut xlatMtlMain(
    constant FGlobals_Type& FGlobals [[ buffer(0) ]],
    sampler sampler_MainTex [[ sampler (0) ]],
    texture2d<half, access::sample > _MainTex [[ texture(0) ]] ,
    Mtl_FragmentIn input [[ stage_in ]])
{
    Mtl_FragmentOut output;
    float4 u_xlat0;
    half4 u_xlat16_0;
    u_xlat16_0 = _MainTex.sample(sampler_MainTex, input.TEXCOORD0.xy);
    u_xlat16_0 = log2(u_xlat16_0);
    u_xlat0 = float4(u_xlat16_0) * float4(FGlobals._Asd);
    u_xlat0 = exp2(u_xlat0);
    output.SV_Target0 = u_xlat0 * float4(1000.0, 1000.0, 1000.0, 1000.0);
    return output;
}
//Input:
Texture2D<float4> _MainTex;
SamplerState sampler_MainTex;
float _Asd;
float4 frag (v2f i) : SV_Target
{
    float4 col = _MainTex.Sample(sampler_MainTex, i.uv);
    col = pow(col, 4);
    return col * 1000;
}
//Output (notice the u_xlat16_0 being half):
fragment Mtl_FragmentOut xlatMtlMain(
    sampler sampler_MainTex [[ sampler (0) ]],
    texture2d<half, access::sample > _MainTex [[ texture(0) ]] ,
    Mtl_FragmentIn input [[ stage_in ]])
{
    Mtl_FragmentOut output;
    half4 u_xlat16_0;
    u_xlat16_0 = _MainTex.sample(sampler_MainTex, input.TEXCOORD0.xy);
    u_xlat16_0 = u_xlat16_0 * u_xlat16_0;
    u_xlat16_0 = u_xlat16_0 * u_xlat16_0;
    output.SV_Target0 = float4(u_xlat16_0) * float4(1000.0, 1000.0, 1000.0, 1000.0);
    return output;
}

another one is that sampler2D_float compiles to texture2d<float,…> but Texture2D compiles to texture2d<half,…>

If you’re talking about this, having the texture as float will fix it.

And this looks like a bug. Can you please report it? Thanks!

Could you do that? I don’t have the project any more.

You can still file a bug report, just without an attached project

It seems this might not be fixed yet or I need to update?

Pointing out key bits

           Texture2D<float4> _ShadowMapTex;
            SamplerState _ShadowMapSampler;

returning just the texture read in the fragment shader
return _ShadowMapTex.Sample(_ShadowMapSampler, shadow_uv).rrrr;
produces

    u_xlat10_0 = half(_ShadowMapTex.sample(_ShadowMapSampler, u_xlat0.xy).x);
    output.SV_Target0 = float4(float4(u_xlat10_0));

If i change the float4 from the texture definition to half4 i get this

 u_xlat16_1 = _ShadowMapTex.sample(_ShadowMapSampler, u_xlat0.xy).x;
    output.SV_Target0 = float4(half4(u_xlat16_1));

Doesn’t seem to matter, texture sampling is always half on metal.

@daxiongmao change _ShadowMapSampler to _ShadowMapTexSampler and it should work

I renamed my samplerstate to

Texture2D<float4> _ShadowMapTex;
SamplerState _ShadowMapTexSampler;

This was the fragment shader, i removed everything just to test

return _ShadowMapTex.Sample(_ShadowMapTexSampler , shadow_uv).rrrr;

But it still produces

-- Hardware tier variant: Tier 1
-- Fragment shader for "metal":
Set 2D Texture "_ShadowMapTex" to slot 0 sampler slot -1
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
#if !(__HAVE_FMA__)
#define fma(a,b,c) ((a) * (b) + (c))
#endif
#ifndef XLT_REMAP_O
    #define XLT_REMAP_O {0, 1, 2, 3, 4, 5, 6, 7}
#endif
constexpr constant uint xlt_remap_o[] = XLT_REMAP_O;
struct Mtl_FragmentIn
{
    float4 TEXCOORD3 [[ user(TEXCOORD3) ]] ;
};
struct Mtl_FragmentOut
{
    float4 SV_Target0 [[ color(xlt_remap_o[0]) ]];
};
fragment Mtl_FragmentOut xlatMtlMain(
    sampler sampler_ShadowMapTexSampler [[ sampler (0) ]],
    texture2d<float, access::sample > _ShadowMapTex [[ texture(0) ]] ,
    Mtl_FragmentIn input [[ stage_in ]])
{
    Mtl_FragmentOut output;
    float2 u_xlat0;
    half u_xlat10_0;
    u_xlat0.xy = input.TEXCOORD3.xy / input.TEXCOORD3.ww;
    u_xlat0.xy = fma(u_xlat0.xy, float2(0.5, 0.5), float2(0.5, 0.5));
    u_xlat0.xy = clamp(u_xlat0.xy, 0.0f, 1.0f);
    u_xlat10_0 = half(_ShadowMapTex.sample(_ShadowMapTexSampler, u_xlat0.xy).x);
    output.SV_Target0 = float4(float4(u_xlat10_0));
    return output;
}

Seems weird a name change might of fixed it? Am i missing something?
If i don’t define the samplerstate i get an error.

Looking closer at the metal shader it does seem to be setting it to float. Just the actual function is getting converted for some reason.

I am on Unity 2019.4.3f1 I am going to try the latest to see if anything changes.

So I went and looked at this page again more closely and it does mention the naming thing.

But its
“sampler”+TextureName
When i name it this way the half restriction is gone.
But that seems like it defeats the purpose of being able to reuse samplers with textures talked about in the same article.

Texture2D<float4> _ShadowMapTex;
SamplerState sampler_ShadowMapTex;

Is what seems to work and not force the output of the texture sample to be a half.

Sorry, I mixed postfix and prefix.

At the moment it’s not possible to specify the precision for a sampler, and a custom sampler overrides precision settings of the texture. We will add this functionality later.

Thanks for the help though. Wish it fixed the issue I was seeing.
Something seems up between pc and ios when reading from the texture. PC its smooth, IOS its blocky almost like nearest filtering is on.

Actually i think its a hardware thing. And filtering is not supported for that type.

This may well be the case. Try using a different texture format.
Filtering full float formats is usually not supported on mobile HW - those formats consume a lot of bandwidth and are usually to be avoided.

Yep, IOS supports filtering on R32, or RG16 not RG32.