Vulkan driver doesnt draw when there are many uniform matrices
Please, see the attached sample. It tries to draw a 2d image using following shader:
//-----------------------------------------------------------------------------
// SpriteEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
BEGIN_CONSTANTS
MATRIX_CONSTANTS
float4x4 MatrixTransform;
float4x4 OtherTransforms[128];
int4 OtherTransformsIndices;
END_CONSTANTS
void SpriteVertexShader(inout float2 texCoord : TEXCOORD0,
inout float4 position : SV_Position)
{
position = mul(position, MatrixTransform);
position = mul(position, OtherTransforms[OtherTransformsIndices.x]);
position = mul(position, OtherTransforms[OtherTransformsIndices.y]);
position = mul(position, OtherTransforms[OtherTransformsIndices.z]);
position = mul(position, OtherTransforms[OtherTransformsIndices.w]);
}
float4 SpritePixelShader(float2 texCoord : TEXCOORD0) : SV_Target0
{
return tex2D(TextureSampler, texCoord);
}
TECHNIQUE(Default, SpriteVertexShader, SpritePixelShader);
Which is pretty much copy of the original SpriteEffect. The only difference is that it processes input position by OtherTransforms. However all those matrices are set to Identity in the C# part of the sample, so they shouldn't affect the end result.
Unfortunately it draws nothing with the default Vulkan driver:
But works correctly when using D311 or OpenGL drivers:
Full Sample: ManyMatricesTest.zip
OS: Windows 11 Latest FNA 25.10 from the master branch Latest fnalibs downloaded from fnalibs-daily at 15.10.2025
Going to guess that this is either preshaders or the int4 uniform, the floats should be fine but the ints may behave differently. See if a RenderDoc capture shows anything interesting.
Replacing int4 with float4 didnt help. But the problem goes away if I lower amount of OtherTransforms to 32.
Interesting - this may be SDL_GPU uploads; RenderDoc will definitely show if we're uploading the full 4x4 buffer when it's higher than 32 elements.
Preshader:
mul c516.x, c0.x, (4)
mul c517.x, c0.y, (4)
mul c518.x, c0.z, (4)
mul c519.x, c0.w, (4)
GLSL output...
#version 110
uniform vec4 vs_uniforms_vec4[520];
uniform float vpFlip;
vec4 vs_r0;
vec4 vs_r1;
ivec4 vs_a0;
#define ARRAYBASE_0 0
#define vs_c0 vs_uniforms_vec4[0]
#define vs_c1 vs_uniforms_vec4[1]
#define vs_c2 vs_uniforms_vec4[2]
#define vs_c3 vs_uniforms_vec4[3]
#define vs_c512 vs_uniforms_vec4[512]
#define vs_c513 vs_uniforms_vec4[513]
#define vs_c514 vs_uniforms_vec4[514]
#define vs_c515 vs_uniforms_vec4[515]
#define vs_c516 vs_uniforms_vec4[516]
#define vs_c517 vs_uniforms_vec4[517]
#define vs_c518 vs_uniforms_vec4[518]
#define vs_c519 vs_uniforms_vec4[519]
attribute vec4 vs_v0;
attribute vec4 vs_v1;
#define vs_o0 gl_TexCoord[0]
#define vs_o1 gl_Position
void main()
{
vs_r0.x = dot(vs_v1, vs_c512);
vs_r0.y = dot(vs_v1, vs_c513);
vs_r0.z = dot(vs_v1, vs_c514);
vs_r0.w = dot(vs_v1, vs_c515);
vs_a0.w = int(floor(abs(vs_c516.x) + 0.5) * sign(vs_c516.x));
vs_r1.x = dot(vs_r0, vs_uniforms_vec4[ARRAYBASE_0 + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c516.x) + 0.5) * sign(vs_c516.x));
vs_r1.y = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 1) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c516.x) + 0.5) * sign(vs_c516.x));
vs_r1.z = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 2) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c516.x) + 0.5) * sign(vs_c516.x));
vs_r1.w = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 3) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c517.x) + 0.5) * sign(vs_c517.x));
vs_r0.x = dot(vs_r1, vs_uniforms_vec4[ARRAYBASE_0 + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c517.x) + 0.5) * sign(vs_c517.x));
vs_r0.y = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 1) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c517.x) + 0.5) * sign(vs_c517.x));
vs_r0.z = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 2) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c517.x) + 0.5) * sign(vs_c517.x));
vs_r0.w = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 3) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c518.x) + 0.5) * sign(vs_c518.x));
vs_r1.x = dot(vs_r0, vs_uniforms_vec4[ARRAYBASE_0 + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c518.x) + 0.5) * sign(vs_c518.x));
vs_r1.y = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 1) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c518.x) + 0.5) * sign(vs_c518.x));
vs_r1.z = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 2) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c518.x) + 0.5) * sign(vs_c518.x));
vs_r1.w = dot(vs_r0, vs_uniforms_vec4[(ARRAYBASE_0 + 3) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c519.x) + 0.5) * sign(vs_c519.x));
vs_o1.x = dot(vs_r1, vs_uniforms_vec4[ARRAYBASE_0 + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c519.x) + 0.5) * sign(vs_c519.x));
vs_o1.y = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 1) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c519.x) + 0.5) * sign(vs_c519.x));
vs_o1.z = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 2) + vs_a0.w]);
vs_a0.w = int(floor(abs(vs_c519.x) + 0.5) * sign(vs_c519.x));
vs_o1.w = dot(vs_r1, vs_uniforms_vec4[(ARRAYBASE_0 + 3) + vs_a0.w]);
vs_o0.xy = vs_v0.xy;
gl_Position.y = gl_Position.y * vpFlip;
gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;
SPIR-V
; SPIR-V
; Version: 1.0
; Generator: Khronos; 0
; Bound: 368
; Schema: 0
OpCapability Shader
%59 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical Simple
OpEntryPoint Vertex %ShaderFunction3 "ShaderFunction3" %vs_v0 %vs_v1 %vs_o0 %vs_o1
OpName %ShaderFunction3 "ShaderFunction3"
OpName %vs_r0 "vs_r0"
OpName %vs_r1 "vs_r1"
OpName %vs_a0 "vs_a0"
OpName %c0 "c0"
OpName %c1 "c1"
OpName %c2 "c2"
OpName %c3 "c3"
OpName %c512 "c512"
OpName %c513 "c513"
OpName %c514 "c514"
OpName %c515 "c515"
OpName %c516 "c516"
OpName %c517 "c517"
OpName %c518 "c518"
OpName %c519 "c519"
OpName %vs_v0 "vs_v0"
OpName %vs_v1 "vs_v1"
OpName %vs_o0 "vs_o0"
OpName %vs_o1 "vs_o1"
OpName %vs_uniforms "vs_uniforms"
OpDecorate %vs_v0 Location 0
OpDecorate %vs_v1 Location 1
OpDecorate %vs_o0 Location 3735928559
OpDecorate %vs_o1 BuiltIn Position
OpDecorate %_struct_366 Block
OpDecorate %vs_uniforms DescriptorSet 1
OpDecorate %vs_uniforms Binding 0
OpDecorate %_arr_v4float_int_520 ArrayStride 16
OpMemberDecorate %_struct_366 0 Offset 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
%int = OpTypeInt 32 1
%v4int = OpTypeVector %int 4
%_ptr_Private_int = OpTypePointer Private %int
%int_3 = OpConstant %int 3
%int_1 = OpConstant %int 1
%int_2 = OpConstant %int 2
%_ptr_Private_v4float = OpTypePointer Private %v4float
%vs_r0 = OpVariable %_ptr_Private_v4float Private
%vs_r1 = OpVariable %_ptr_Private_v4float Private
%_ptr_Private_v4int = OpTypePointer Private %v4int
%vs_a0 = OpVariable %_ptr_Private_v4int Private
%c0 = OpConstant %int 0
%c1 = OpConstant %int 0
%c2 = OpConstant %int 0
%c3 = OpConstant %int 0
%c512 = OpConstant %int 512
%c513 = OpConstant %int 513
%c514 = OpConstant %int 514
%c515 = OpConstant %int 515
%c516 = OpConstant %int 516
%c517 = OpConstant %int 517
%c518 = OpConstant %int 518
%c519 = OpConstant %int 519
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Input_v4int = OpTypePointer Input %v4int
%uint = OpTypeInt 32 0
%v4uint = OpTypeVector %uint 4
%_ptr_Input_v4uint = OpTypePointer Input %v4uint
%vs_v0 = OpVariable %_ptr_Input_v4float Input
%vs_v1 = OpVariable %_ptr_Input_v4float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%vs_o0 = OpVariable %_ptr_Output_v4float Output
%vs_o1 = OpVariable %_ptr_Output_v4float Output
%int_520 = OpConstant %int 520
%_arr_v4float_int_520 = OpTypeArray %v4float %int_520
%int_0 = OpConstant %int 0
%_struct_366 = OpTypeStruct %_arr_v4float_int_520
%_ptr_Uniform__struct_366 = OpTypePointer Uniform %_struct_366
%vs_uniforms = OpVariable %_ptr_Uniform__struct_366 Uniform
%ShaderFunction3 = OpFunction %void None %3
%4 = OpLabel
%11 = OpLoad %v4float %vs_v1
%12 = OpCopyObject %v4float %11
%16 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c512
%18 = OpLoad %v4float %16
%19 = OpDot %float %12 %18
%20 = OpCompositeConstruct %v4float %19 %19 %19 %19
%23 = OpLoad %v4float %vs_r0
%22 = OpVectorShuffle %v4float %20 %23 0 5 6 7
OpStore %vs_r0 %22
%24 = OpLoad %v4float %vs_v1
%25 = OpCopyObject %v4float %24
%27 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c513
%28 = OpLoad %v4float %27
%29 = OpDot %float %25 %28
%30 = OpCompositeConstruct %v4float %29 %29 %29 %29
%32 = OpLoad %v4float %vs_r0
%31 = OpVectorShuffle %v4float %30 %32 4 1 6 7
OpStore %vs_r0 %31
%33 = OpLoad %v4float %vs_v1
%34 = OpCopyObject %v4float %33
%36 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c514
%37 = OpLoad %v4float %36
%38 = OpDot %float %34 %37
%39 = OpCompositeConstruct %v4float %38 %38 %38 %38
%41 = OpLoad %v4float %vs_r0
%40 = OpVectorShuffle %v4float %39 %41 4 5 2 7
OpStore %vs_r0 %40
%42 = OpLoad %v4float %vs_v1
%43 = OpCopyObject %v4float %42
%45 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c515
%46 = OpLoad %v4float %45
%47 = OpDot %float %43 %46
%48 = OpCompositeConstruct %v4float %47 %47 %47 %47
%50 = OpLoad %v4float %vs_r0
%49 = OpVectorShuffle %v4float %48 %50 4 5 6 3
OpStore %vs_r0 %49
%52 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c516
%53 = OpLoad %v4float %52
%54 = OpVectorShuffle %v4float %53 %53 0 0 0 0
%55 = OpExtInst %v4float %59 Round %54
%58 = OpConvertFToS %v4int %55
%62 = OpLoad %v4int %vs_a0
%61 = OpVectorShuffle %v4int %58 %62 4 5 6 3
OpStore %vs_a0 %61
%63 = OpLoad %v4float %vs_r0
%67 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%68 = OpLoad %int %67
%69 = OpIAdd %int %68 %c0
%70 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %69
%71 = OpLoad %v4float %70
%72 = OpDot %float %63 %71
%73 = OpCompositeConstruct %v4float %72 %72 %72 %72
%76 = OpLoad %v4float %vs_r1
%75 = OpVectorShuffle %v4float %73 %76 0 5 6 7
OpStore %vs_r1 %75
%77 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c516
%78 = OpLoad %v4float %77
%79 = OpVectorShuffle %v4float %78 %78 0 0 0 0
%80 = OpExtInst %v4float %59 Round %79
%81 = OpConvertFToS %v4int %80
%83 = OpLoad %v4int %vs_a0
%82 = OpVectorShuffle %v4int %81 %83 4 5 6 3
OpStore %vs_a0 %82
%84 = OpLoad %v4float %vs_r0
%86 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%87 = OpLoad %int %86
%88 = OpIAdd %int %87 %c1
%90 = OpIAdd %int %88 %int_1
%91 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %90
%92 = OpLoad %v4float %91
%93 = OpDot %float %84 %92
%94 = OpCompositeConstruct %v4float %93 %93 %93 %93
%96 = OpLoad %v4float %vs_r1
%95 = OpVectorShuffle %v4float %94 %96 4 1 6 7
OpStore %vs_r1 %95
%97 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c516
%98 = OpLoad %v4float %97
%99 = OpVectorShuffle %v4float %98 %98 0 0 0 0
%100 = OpExtInst %v4float %59 Round %99
%101 = OpConvertFToS %v4int %100
%103 = OpLoad %v4int %vs_a0
%102 = OpVectorShuffle %v4int %101 %103 4 5 6 3
OpStore %vs_a0 %102
%104 = OpLoad %v4float %vs_r0
%106 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%107 = OpLoad %int %106
%108 = OpIAdd %int %107 %c2
%110 = OpIAdd %int %108 %int_2
%111 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %110
%112 = OpLoad %v4float %111
%113 = OpDot %float %104 %112
%114 = OpCompositeConstruct %v4float %113 %113 %113 %113
%116 = OpLoad %v4float %vs_r1
%115 = OpVectorShuffle %v4float %114 %116 4 5 2 7
OpStore %vs_r1 %115
%117 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c516
%118 = OpLoad %v4float %117
%119 = OpVectorShuffle %v4float %118 %118 0 0 0 0
%120 = OpExtInst %v4float %59 Round %119
%121 = OpConvertFToS %v4int %120
%123 = OpLoad %v4int %vs_a0
%122 = OpVectorShuffle %v4int %121 %123 4 5 6 3
OpStore %vs_a0 %122
%124 = OpLoad %v4float %vs_r0
%126 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%127 = OpLoad %int %126
%128 = OpIAdd %int %127 %c3
%129 = OpIAdd %int %128 %int_3
%130 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %129
%131 = OpLoad %v4float %130
%132 = OpDot %float %124 %131
%133 = OpCompositeConstruct %v4float %132 %132 %132 %132
%135 = OpLoad %v4float %vs_r1
%134 = OpVectorShuffle %v4float %133 %135 4 5 6 3
OpStore %vs_r1 %134
%137 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c517
%138 = OpLoad %v4float %137
%139 = OpVectorShuffle %v4float %138 %138 0 0 0 0
%140 = OpExtInst %v4float %59 Round %139
%141 = OpConvertFToS %v4int %140
%143 = OpLoad %v4int %vs_a0
%142 = OpVectorShuffle %v4int %141 %143 4 5 6 3
OpStore %vs_a0 %142
%144 = OpLoad %v4float %vs_r1
%145 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%146 = OpLoad %int %145
%147 = OpIAdd %int %146 %c0
%148 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %147
%149 = OpLoad %v4float %148
%150 = OpDot %float %144 %149
%151 = OpCompositeConstruct %v4float %150 %150 %150 %150
%153 = OpLoad %v4float %vs_r0
%152 = OpVectorShuffle %v4float %151 %153 0 5 6 7
OpStore %vs_r0 %152
%154 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c517
%155 = OpLoad %v4float %154
%156 = OpVectorShuffle %v4float %155 %155 0 0 0 0
%157 = OpExtInst %v4float %59 Round %156
%158 = OpConvertFToS %v4int %157
%160 = OpLoad %v4int %vs_a0
%159 = OpVectorShuffle %v4int %158 %160 4 5 6 3
OpStore %vs_a0 %159
%161 = OpLoad %v4float %vs_r1
%162 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%163 = OpLoad %int %162
%164 = OpIAdd %int %163 %c1
%165 = OpIAdd %int %164 %int_1
%166 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %165
%167 = OpLoad %v4float %166
%168 = OpDot %float %161 %167
%169 = OpCompositeConstruct %v4float %168 %168 %168 %168
%171 = OpLoad %v4float %vs_r0
%170 = OpVectorShuffle %v4float %169 %171 4 1 6 7
OpStore %vs_r0 %170
%172 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c517
%173 = OpLoad %v4float %172
%174 = OpVectorShuffle %v4float %173 %173 0 0 0 0
%175 = OpExtInst %v4float %59 Round %174
%176 = OpConvertFToS %v4int %175
%178 = OpLoad %v4int %vs_a0
%177 = OpVectorShuffle %v4int %176 %178 4 5 6 3
OpStore %vs_a0 %177
%179 = OpLoad %v4float %vs_r1
%180 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%181 = OpLoad %int %180
%182 = OpIAdd %int %181 %c2
%183 = OpIAdd %int %182 %int_2
%184 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %183
%185 = OpLoad %v4float %184
%186 = OpDot %float %179 %185
%187 = OpCompositeConstruct %v4float %186 %186 %186 %186
%189 = OpLoad %v4float %vs_r0
%188 = OpVectorShuffle %v4float %187 %189 4 5 2 7
OpStore %vs_r0 %188
%190 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c517
%191 = OpLoad %v4float %190
%192 = OpVectorShuffle %v4float %191 %191 0 0 0 0
%193 = OpExtInst %v4float %59 Round %192
%194 = OpConvertFToS %v4int %193
%196 = OpLoad %v4int %vs_a0
%195 = OpVectorShuffle %v4int %194 %196 4 5 6 3
OpStore %vs_a0 %195
%197 = OpLoad %v4float %vs_r1
%198 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%199 = OpLoad %int %198
%200 = OpIAdd %int %199 %c3
%201 = OpIAdd %int %200 %int_3
%202 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %201
%203 = OpLoad %v4float %202
%204 = OpDot %float %197 %203
%205 = OpCompositeConstruct %v4float %204 %204 %204 %204
%207 = OpLoad %v4float %vs_r0
%206 = OpVectorShuffle %v4float %205 %207 4 5 6 3
OpStore %vs_r0 %206
%209 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c518
%210 = OpLoad %v4float %209
%211 = OpVectorShuffle %v4float %210 %210 0 0 0 0
%212 = OpExtInst %v4float %59 Round %211
%213 = OpConvertFToS %v4int %212
%215 = OpLoad %v4int %vs_a0
%214 = OpVectorShuffle %v4int %213 %215 4 5 6 3
OpStore %vs_a0 %214
%216 = OpLoad %v4float %vs_r0
%217 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%218 = OpLoad %int %217
%219 = OpIAdd %int %218 %c0
%220 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %219
%221 = OpLoad %v4float %220
%222 = OpDot %float %216 %221
%223 = OpCompositeConstruct %v4float %222 %222 %222 %222
%225 = OpLoad %v4float %vs_r1
%224 = OpVectorShuffle %v4float %223 %225 0 5 6 7
OpStore %vs_r1 %224
%226 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c518
%227 = OpLoad %v4float %226
%228 = OpVectorShuffle %v4float %227 %227 0 0 0 0
%229 = OpExtInst %v4float %59 Round %228
%230 = OpConvertFToS %v4int %229
%232 = OpLoad %v4int %vs_a0
%231 = OpVectorShuffle %v4int %230 %232 4 5 6 3
OpStore %vs_a0 %231
%233 = OpLoad %v4float %vs_r0
%234 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%235 = OpLoad %int %234
%236 = OpIAdd %int %235 %c1
%237 = OpIAdd %int %236 %int_1
%238 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %237
%239 = OpLoad %v4float %238
%240 = OpDot %float %233 %239
%241 = OpCompositeConstruct %v4float %240 %240 %240 %240
%243 = OpLoad %v4float %vs_r1
%242 = OpVectorShuffle %v4float %241 %243 4 1 6 7
OpStore %vs_r1 %242
%244 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c518
%245 = OpLoad %v4float %244
%246 = OpVectorShuffle %v4float %245 %245 0 0 0 0
%247 = OpExtInst %v4float %59 Round %246
%248 = OpConvertFToS %v4int %247
%250 = OpLoad %v4int %vs_a0
%249 = OpVectorShuffle %v4int %248 %250 4 5 6 3
OpStore %vs_a0 %249
%251 = OpLoad %v4float %vs_r0
%252 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%253 = OpLoad %int %252
%254 = OpIAdd %int %253 %c2
%255 = OpIAdd %int %254 %int_2
%256 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %255
%257 = OpLoad %v4float %256
%258 = OpDot %float %251 %257
%259 = OpCompositeConstruct %v4float %258 %258 %258 %258
%261 = OpLoad %v4float %vs_r1
%260 = OpVectorShuffle %v4float %259 %261 4 5 2 7
OpStore %vs_r1 %260
%262 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c518
%263 = OpLoad %v4float %262
%264 = OpVectorShuffle %v4float %263 %263 0 0 0 0
%265 = OpExtInst %v4float %59 Round %264
%266 = OpConvertFToS %v4int %265
%268 = OpLoad %v4int %vs_a0
%267 = OpVectorShuffle %v4int %266 %268 4 5 6 3
OpStore %vs_a0 %267
%269 = OpLoad %v4float %vs_r0
%270 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%271 = OpLoad %int %270
%272 = OpIAdd %int %271 %c3
%273 = OpIAdd %int %272 %int_3
%274 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %273
%275 = OpLoad %v4float %274
%276 = OpDot %float %269 %275
%277 = OpCompositeConstruct %v4float %276 %276 %276 %276
%279 = OpLoad %v4float %vs_r1
%278 = OpVectorShuffle %v4float %277 %279 4 5 6 3
OpStore %vs_r1 %278
%281 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c519
%282 = OpLoad %v4float %281
%283 = OpVectorShuffle %v4float %282 %282 0 0 0 0
%284 = OpExtInst %v4float %59 Round %283
%285 = OpConvertFToS %v4int %284
%287 = OpLoad %v4int %vs_a0
%286 = OpVectorShuffle %v4int %285 %287 4 5 6 3
OpStore %vs_a0 %286
%288 = OpLoad %v4float %vs_r1
%289 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%290 = OpLoad %int %289
%291 = OpIAdd %int %290 %c0
%292 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %291
%293 = OpLoad %v4float %292
%294 = OpDot %float %288 %293
%295 = OpCompositeConstruct %v4float %294 %294 %294 %294
%297 = OpLoad %v4float %vs_o1
%296 = OpVectorShuffle %v4float %295 %297 0 5 6 7
OpStore %vs_o1 %296
%298 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c519
%299 = OpLoad %v4float %298
%300 = OpVectorShuffle %v4float %299 %299 0 0 0 0
%301 = OpExtInst %v4float %59 Round %300
%302 = OpConvertFToS %v4int %301
%304 = OpLoad %v4int %vs_a0
%303 = OpVectorShuffle %v4int %302 %304 4 5 6 3
OpStore %vs_a0 %303
%305 = OpLoad %v4float %vs_r1
%306 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%307 = OpLoad %int %306
%308 = OpIAdd %int %307 %c1
%309 = OpIAdd %int %308 %int_1
%310 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %309
%311 = OpLoad %v4float %310
%312 = OpDot %float %305 %311
%313 = OpCompositeConstruct %v4float %312 %312 %312 %312
%315 = OpLoad %v4float %vs_o1
%314 = OpVectorShuffle %v4float %313 %315 4 1 6 7
OpStore %vs_o1 %314
%316 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c519
%317 = OpLoad %v4float %316
%318 = OpVectorShuffle %v4float %317 %317 0 0 0 0
%319 = OpExtInst %v4float %59 Round %318
%320 = OpConvertFToS %v4int %319
%322 = OpLoad %v4int %vs_a0
%321 = OpVectorShuffle %v4int %320 %322 4 5 6 3
OpStore %vs_a0 %321
%323 = OpLoad %v4float %vs_r1
%324 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%325 = OpLoad %int %324
%326 = OpIAdd %int %325 %c2
%327 = OpIAdd %int %326 %int_2
%328 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %327
%329 = OpLoad %v4float %328
%330 = OpDot %float %323 %329
%331 = OpCompositeConstruct %v4float %330 %330 %330 %330
%333 = OpLoad %v4float %vs_o1
%332 = OpVectorShuffle %v4float %331 %333 4 5 2 7
OpStore %vs_o1 %332
%334 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %c519
%335 = OpLoad %v4float %334
%336 = OpVectorShuffle %v4float %335 %335 0 0 0 0
%337 = OpExtInst %v4float %59 Round %336
%338 = OpConvertFToS %v4int %337
%340 = OpLoad %v4int %vs_a0
%339 = OpVectorShuffle %v4int %338 %340 4 5 6 3
OpStore %vs_a0 %339
%341 = OpLoad %v4float %vs_r1
%342 = OpAccessChain %_ptr_Private_int %vs_a0 %int_3
%343 = OpLoad %int %342
%344 = OpIAdd %int %343 %c3
%345 = OpIAdd %int %344 %int_3
%346 = OpAccessChain %_ptr_Uniform_v4float %vs_uniforms %int_0 %345
%347 = OpLoad %v4float %346
%348 = OpDot %float %341 %347
%349 = OpCompositeConstruct %v4float %348 %348 %348 %348
%351 = OpLoad %v4float %vs_o1
%350 = OpVectorShuffle %v4float %349 %351 4 5 6 3
OpStore %vs_o1 %350
%352 = OpLoad %v4float %vs_v0
%353 = OpCopyObject %v4float %352
%355 = OpLoad %v4float %vs_o0
%354 = OpVectorShuffle %v4float %353 %355 0 1 6 7
OpStore %vs_o0 %354
OpReturn
OpFunctionEnd
In Discord we determined that the cause is SDL_GPU having a 4KB limit on uniform buffer size, the matrix array alone is 8k... this is an SDL issue, we likely need to set the internal max to 16KB instead.
Is there an SDL issue open for this yet? I didn't find one
Not yet - I think we ultimately decided to keep the limit but add validation and expose a property to set the limit, since D3D9 needs 64K(!) to support the max constant register size.