In the Shader I want to use uint as the array index type (because my array index is calculated based on some uint data).
But when I look at the result of Shader compilation on GLES3.x I see that array indices are all converted to int.
So, Is there any way to disable this conversion?
Does this conversion between int and uint affect actual performance?
Please check that all operands are uint
. It looks like there’s some math happening before using them.
Ok, I write a simple example:
Shader "Unlit/TestShader"
{
Properties
{
_UintIndex("_UintIndex", Int) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
HLSLPROGRAM
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#include "Assets/Shaders/ShaderLibrarys/BXPipelineCommon.hlsl"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
CBUFFER_START(UnityPerMaterial)
uint _UintIndex;
CBUFFER_END
CBUFFER_START(MLIGHTS)
half4 _MLightColors[32];
CBUFFER_END
v2f vert (appdata v)
{
v2f o;
float3 pos_world = TransformObjectToWorld(v.vertex.xyz);
o.vertex = mul(UNITY_MATRIX_VP, float4(pos_world, 1.0));
return o;
}
half4 frag (v2f i) : SV_Target
{
uint index = _UintIndex;
half4 lightColor = _MLightColors[index];
return lightColor;
}
ENDHLSL
}
}
}
Compilation result for GLES3.x:
// Compiled shader for custom platforms
//////////////////////////////////////////////////////////////////////////
//
// NOTE: This is *not* a valid shader file, the contents are provided just
// for information and for debugging purposes only.
//
//////////////////////////////////////////////////////////////////////////
Shader "Unlit/TestShader" {
Properties {
_UintIndex ("_UintIndex", Float) = 1.000000
}
SubShader {
Tags { "RenderType"="Opaque" }
Pass {
Tags { "RenderType"="Opaque" }
//////////////////////////////////
// //
// Compiled programs //
// //
//////////////////////////////////
//////////////////////////////////////////////////////
Keywords: <none>
-- Hardware tier variant: Tier 1
-- Vertex shader for "gles3":
Constant Buffer "UnityPerFrame" (420 bytes) on slot 2 {
Matrix4x4 unity_MatrixVP at 304
}
Constant Buffer "UnityPerMaterial" (4 bytes) on slot 0 {
ScalarInt _UintIndex at 0
}
Constant Buffer "UnityPerDraw" (592 bytes) on slot 3 {
Matrix4x4 unity_ObjectToWorld at 0
}
Constant Buffer "MLIGHTS" (512 bytes) on slot 1 {
Vector4 _MLightColors[32] at 0
}
Shader Disassembly:
#ifdef VERTEX
#version 310 es
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
UNITY_BINDING(2) uniform UnityPerFrame {
mediump vec4 Xhlslcc_UnusedXglstate_lightmodel_ambient;
mediump vec4 Xhlslcc_UnusedXunity_AmbientSky;
mediump vec4 Xhlslcc_UnusedXunity_AmbientEquator;
mediump vec4 Xhlslcc_UnusedXunity_AmbientGround;
mediump vec4 Xhlslcc_UnusedXunity_IndirectSpecColorl;
vec4 Xhlslcc_UnusedXunity_FogParams;
mediump vec4 Xhlslcc_UnusedXunity_FogColor;
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4glstate_matrix_projection[4];
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4unity_MatrixV[4];
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4unity_MatrixInvV[4];
vec4 hlslcc_mtx4x4unity_MatrixVP[4];
vec4 Xhlslcc_UnusedXunity_StereoScaleOffset;
int Xhlslcc_UnusedXunity_StereoEyeIndex;
mediump vec4 Xhlslcc_UnusedXunity_ShadowColor;
uint Xhlslcc_UnusedX_TaaFrameIndex;
};
UNITY_BINDING(3) uniform UnityPerDraw {
vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4unity_WorldToObject[4];
vec4 Xhlslcc_UnusedXunity_LODFade;
mediump vec4 Xhlslcc_UnusedXunity_WorldTransformParams;
mediump vec4 Xhlslcc_UnusedXunity_RenderingLayer;
mediump vec4 Xhlslcc_UnusedXunity_LightData;
mediump vec4 Xhlslcc_UnusedXunity_LightIndices[2];
mediump vec4 Xhlslcc_UnusedXunity_ProbesOcclusion;
vec4 Xhlslcc_UnusedXunity_LightmapST;
vec4 Xhlslcc_UnusedXunity_DynamicLightmapST;
mediump vec4 Xhlslcc_UnusedXunity_SHAr;
mediump vec4 Xhlslcc_UnusedXunity_SHAg;
mediump vec4 Xhlslcc_UnusedXunity_SHAb;
mediump vec4 Xhlslcc_UnusedXunity_SHBr;
mediump vec4 Xhlslcc_UnusedXunity_SHBg;
mediump vec4 Xhlslcc_UnusedXunity_SHBb;
mediump vec4 Xhlslcc_UnusedXunity_SHC;
vec4 Xhlslcc_UnusedXunity_RendererBounds_Min;
vec4 Xhlslcc_UnusedXunity_RendererBounds_Max;
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4unity_MatrixPreviousM[4];
vec4 Xhlslcc_UnusedXhlslcc_mtx4x4unity_MatrixPreviousMI[4];
vec4 Xhlslcc_UnusedXunity_MotionVectorsParams;
mediump vec4 Xhlslcc_UnusedXunity_SpriteColor;
mediump vec4 Xhlslcc_UnusedXunity_SpriteProps;
};
in highp vec4 in_POSITION0;
vec4 u_xlat0;
vec4 u_xlat1;
void main()
{
u_xlat0.xyz = in_POSITION0.yyy * hlslcc_mtx4x4unity_ObjectToWorld[1].xyz;
u_xlat0.xyz = hlslcc_mtx4x4unity_ObjectToWorld[0].xyz * in_POSITION0.xxx + u_xlat0.xyz;
u_xlat0.xyz = hlslcc_mtx4x4unity_ObjectToWorld[2].xyz * in_POSITION0.zzz + u_xlat0.xyz;
u_xlat0.xyz = u_xlat0.xyz + hlslcc_mtx4x4unity_ObjectToWorld[3].xyz;
u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
u_xlat0 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
gl_Position = u_xlat0 + hlslcc_mtx4x4unity_MatrixVP[3];
return;
}
#endif
#ifdef FRAGMENT
#version 310 es
precision highp float;
precision highp int;
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
UNITY_BINDING(0) uniform UnityPerMaterial {
uint _UintIndex;
};
UNITY_BINDING(1) uniform MLIGHTS {
mediump vec4 _MLightColors[32];
};
layout(location = 0) out mediump vec4 SV_Target0;
uint u_xlatu0;
void main()
{
u_xlatu0 = _UintIndex;
SV_Target0 = _MLightColors[int(u_xlatu0)];
return;
}
#endif
}
}
}
What worries me more is that some of the uint calculations and the final array indices share intermediate int variables, as in my original screenshot, which leads to a lot of uint to int conversions in the previous uint calculations
However, given that GPU uses the same hardware unit for the int and uint computations, I’m not sure if these conversions really affect performance
I’m pretty sure there’s no noticeable effect on the performance from those conversions.