Skip to content

Commit d235bd8

Browse files
committed
read storage buffer members
1 parent 58a2de1 commit d235bd8

File tree

3 files changed

+58
-30
lines changed

3 files changed

+58
-30
lines changed

source/ShaderCompilerContext.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ internal Compiler(spvc_compiler compiler)
193193
spvc_compiler_create_shader_resources(compiler, out resources);
194194
}
195195

196-
public readonly void ReadStorageBuffers(List<ShaderStorageBuffer> list)
196+
public readonly void ReadStorageBuffers(List<ShaderStorageBuffer> buffers, List<ShaderStorageBufferMember> members)
197197
{
198198
spvc_resources_get_resource_list_for_type(resources, ResourceType.StorageBuffer, out spvc_reflected_resource* resourceList, out nuint resourceCount);
199199
Span<spvc_reflected_resource> resourcesSpan = new(resourceList, (int)resourceCount);
@@ -229,11 +229,19 @@ public readonly void ReadStorageBuffers(List<ShaderStorageBuffer> list)
229229
spvc_type memberType = spvc_compiler_get_type_handle(compiler, memberTypeId);
230230
uint vectorSize = spvc_type_get_vector_size(memberType);
231231
TypeMetadata runtimeType = GetRuntimeType(memberType, vectorSize);
232+
ShaderStorageBufferMember.Flags memberFlags = default;
233+
if (spvc_type_array_dimension_is_literal(memberType, vectorSize))
234+
{
235+
memberFlags |= ShaderStorageBufferMember.Flags.Array;
236+
}
237+
238+
ShaderStorageBufferMember member = new(name.GetLongHashCode(), runtimeType, new ASCIIText256(spvc_compiler_get_member_name(compiler, baseTypeId, m)), byteLength, memberFlags);
239+
members.Add(member);
232240
byteLength += runtimeType.Size;
233241
}
234242

235243
ShaderStorageBuffer storageBuffer = new(name, baseTypeName, binding, set, byteLength, flags);
236-
list.Add(storageBuffer);
244+
buffers.Add(storageBuffer);
237245
}
238246
else
239247
{
@@ -242,18 +250,18 @@ public readonly void ReadStorageBuffers(List<ShaderStorageBuffer> list)
242250
}
243251
}
244252

245-
public readonly void ReadUniformProperties(List<ShaderUniformProperty> list, List<ShaderUniformPropertyMember> members)
253+
public readonly void ReadUniformProperties(List<ShaderUniformProperty> uniformProperties, List<ShaderUniformPropertyMember> members)
246254
{
247255
spvc_resources_get_resource_list_for_type(resources, ResourceType.UniformBuffer, out spvc_reflected_resource* resourceList, out nuint resourceCount);
248256
Span<spvc_reflected_resource> resourcesSpan = new(resourceList, (int)resourceCount);
249-
int startIndex = list.Count;
257+
int startIndex = uniformProperties.Count;
250258
foreach (spvc_reflected_resource resource in resourcesSpan)
251259
{
252260
uint set = spvc_compiler_get_decoration(compiler, resource.id, SpvDecoration.DescriptorSet);
253261
uint binding = spvc_compiler_get_decoration(compiler, resource.id, SpvDecoration.Binding);
254262
//uint location = spvc_compiler_get_decoration(compiler, resource.id, Vortice.SPIRV.SpvDecoration.Location);
255263
//uint offset = spvc_compiler_get_decoration(compiler, resource.id, Vortice.SPIRV.SpvDecoration.Offset);
256-
ASCIIText256 nameText = spvc_compiler_get_name(compiler, resource.id) ?? string.Empty;
264+
ASCIIText256 propertyName = spvc_compiler_get_name(compiler, resource.id) ?? string.Empty;
257265
spvc_type type = spvc_compiler_get_type_handle(compiler, resource.type_id);
258266
Basetype baseType = spvc_type_get_basetype(type);
259267
if (baseType == Basetype.Struct)
@@ -268,12 +276,13 @@ public readonly void ReadUniformProperties(List<ShaderUniformProperty> list, Lis
268276
spvc_type memberType = spvc_compiler_get_type_handle(compiler, memberTypeId);
269277
uint vectorSize = spvc_type_get_vector_size(memberType);
270278
TypeMetadata runtimeType = GetRuntimeType(memberType, vectorSize);
271-
members.Add(new(nameText, runtimeType, new ASCIIText256(spvc_compiler_get_member_name(compiler, baseTypeId, m))));
279+
ShaderUniformPropertyMember member = new(propertyName.GetLongHashCode(), runtimeType, new ASCIIText256(spvc_compiler_get_member_name(compiler, baseTypeId, m)), byteLength);
280+
members.Add(member);
272281
byteLength += runtimeType.Size;
273282
}
274283

275-
ShaderUniformProperty uniformBuffer = new(nameText, baseTypeName, binding, set, byteLength);
276-
list.Insert(startIndex, uniformBuffer);
284+
ShaderUniformProperty uniformBuffer = new(propertyName, baseTypeName, binding, set, byteLength);
285+
uniformProperties.Insert(startIndex, uniformBuffer);
277286
}
278287
else
279288
{

source/Systems/ShaderImportSystem.cs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void IListener<DataUpdate>.Receive(ref DataUpdate message)
9090

9191
private bool TryLoadShader(uint shaderEntity, IsShaderRequest request)
9292
{
93-
ThrowIfUnknownShaderType(request.type);
93+
ShaderType type = request.flags.GetShaderType();
9494

9595
//todo: should shaders be cached based on address? what if its loaded from file on disk and the file changes?
9696
LoadData message = new(request.address);
@@ -99,13 +99,13 @@ private bool TryLoadShader(uint shaderEntity, IsShaderRequest request)
9999
{
100100
Trace.WriteLine($"Loading shader data onto entity `{shaderEntity}`");
101101
Span<byte> bytes = data.GetBytes();
102-
Span<byte> spvBytes = shaderCompiler.GLSLToSPV(bytes, request.type);
102+
Span<byte> spvBytes = shaderCompiler.GLSLToSPV(bytes, type);
103103
data.Dispose();
104104

105105
operation.SetSelectedEntity(shaderEntity);
106106
world.TryGetComponent(shaderEntity, shaderType, out IsShader shader);
107107
shader.version++;
108-
shader.type = request.type;
108+
shader.type = type;
109109
operation.AddOrSetComponent(shader, shaderType);
110110
operation.CreateOrSetArray(spvBytes.As<byte, ShaderByte>(), byteArrayType);
111111

@@ -116,7 +116,8 @@ private bool TryLoadShader(uint shaderEntity, IsShaderRequest request)
116116
compiler.ReadUniformProperties(uniformProperties, uniformPropertyMembers);
117117
operation.CreateOrSetArray(uniformProperties.AsSpan());
118118
operation.CreateOrSetArray(uniformPropertyMembers.AsSpan());
119-
if (request.type == ShaderType.Vertex)
119+
120+
if (type == ShaderType.Vertex)
120121
{
121122
using List<ShaderPushConstant> pushConstants = new();
122123
using List<ShaderVertexInputAttribute> vertexInputAttributes = new();
@@ -126,29 +127,22 @@ private bool TryLoadShader(uint shaderEntity, IsShaderRequest request)
126127
operation.CreateOrSetArray(vertexInputAttributes.AsSpan());
127128
}
128129

129-
if (request.type == ShaderType.Fragment)
130+
if (type == ShaderType.Fragment)
130131
{
131132
using List<ShaderSamplerProperty> textureProperties = new();
132133
compiler.ReadTextureProperties(textureProperties);
133134
operation.CreateOrSetArray(textureProperties.AsSpan());
134135
}
135136

136137
using List<ShaderStorageBuffer> storageBuffers = new();
137-
compiler.ReadStorageBuffers(storageBuffers);
138+
using List<ShaderStorageBufferMember> storageBufferMembers = new();
139+
compiler.ReadStorageBuffers(storageBuffers, storageBufferMembers);
138140
operation.CreateOrSetArray(storageBuffers.AsSpan());
141+
operation.CreateOrSetArray(storageBufferMembers.AsSpan());
139142
return true;
140143
}
141144

142145
return false;
143146
}
144-
145-
[Conditional("DEBUG")]
146-
private static void ThrowIfUnknownShaderType(ShaderType type)
147-
{
148-
if (type == ShaderType.Unknown || type > ShaderType.Geometry)
149-
{
150-
throw new NotSupportedException($"Unknown shader type `{type}`");
151-
}
152-
}
153147
}
154148
}

tests/ImportTests.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ void main() {
8484

8585
Assert.That(vertexShader.UniformProperties.Length, Is.EqualTo(1));
8686
ShaderUniformProperty cameraInfo = vertexShader.UniformProperties[0];
87-
Assert.That(cameraInfo.label.ToString(), Is.EqualTo("cameraInfo"));
87+
Assert.That(cameraInfo.name.ToString(), Is.EqualTo("cameraInfo"));
8888
Assert.That(cameraInfo.typeName.ToString(), Is.EqualTo("CameraInfo"));
8989
Assert.That(cameraInfo.binding, Is.EqualTo(2));
9090
Assert.That(cameraInfo.set, Is.EqualTo(0));
91-
Assert.That(vertexShader.GetMemberCount("cameraInfo"), Is.EqualTo(2));
91+
Assert.That(vertexShader.GetUniformPropertyMemberCount("cameraInfo"), Is.EqualTo(2));
9292

93-
ShaderUniformPropertyMember member = vertexShader.GetMember("cameraInfo", 0);
93+
ShaderUniformPropertyMember member = vertexShader.GetUniformPropertyMember("cameraInfo", 0);
9494
Assert.That(member.name.ToString(), Is.EqualTo("proj"));
95-
member = vertexShader.GetMember("cameraInfo", 1);
95+
member = vertexShader.GetUniformPropertyMember("cameraInfo", 1);
9696
Assert.That(member.name.ToString(), Is.EqualTo("view"));
9797

9898
Assert.That(fragmentShader.SamplerProperties.Length, Is.EqualTo(1));
@@ -132,6 +132,9 @@ public async Task ImportInstancedShader(CancellationToken cancellation)
132132
133133
layout (binding = 3, set = 3) readonly buffer LotsOfData {
134134
vec2 offsets[];
135+
vec4 rotation;
136+
vec3 position;
137+
vec3 scale;
135138
} lotsOfData;
136139
137140
layout(location = 0) out vec3 fColor;
@@ -159,21 +162,43 @@ void main()
159162
Assert.That(storageBuffers.Length, Is.EqualTo(2));
160163

161164
ShaderStorageBuffer instanceData = storageBuffers[0];
162-
Assert.That(instanceData.label.ToString(), Is.EqualTo("instanceData"));
165+
Assert.That(instanceData.name.ToString(), Is.EqualTo("instanceData"));
163166
Assert.That(instanceData.typeName.ToString(), Is.EqualTo("InstanceData"));
164167
Assert.That(instanceData.binding, Is.EqualTo(2));
165168
Assert.That(instanceData.set, Is.EqualTo(1));
166169
Assert.That(instanceData.byteLength, Is.EqualTo(8));
167170
Assert.That(instanceData.flags, Is.EqualTo(ShaderStorageBuffer.Flags.ReadWrite));
168171

169172
ShaderStorageBuffer lotsOfData = storageBuffers[1];
170-
Assert.That(lotsOfData.label.ToString(), Is.EqualTo("lotsOfData"));
173+
Assert.That(lotsOfData.name.ToString(), Is.EqualTo("lotsOfData"));
171174
Assert.That(lotsOfData.typeName.ToString(), Is.EqualTo("LotsOfData"));
172175
Assert.That(lotsOfData.binding, Is.EqualTo(3));
173176
Assert.That(lotsOfData.set, Is.EqualTo(3));
174-
Assert.That(lotsOfData.byteLength, Is.EqualTo(8));
177+
Assert.That(lotsOfData.byteLength, Is.EqualTo(48));
175178
//Assert.That(lotsOfData.flags, Is.EqualTo(ShaderStorageBuffer.Flags.ReadOnly)); //spvc isnt able to read the decorations for some reason
176179

180+
Assert.That(vertexShader.GetStorageBufferMemberCount("lotsOfData"), Is.EqualTo(4));
181+
ShaderStorageBufferMember firstMember = vertexShader.GetStorageBufferMember("lotsOfData", 0);
182+
Assert.That(firstMember.name.ToString(), Is.EqualTo("offsets"));
183+
Assert.That(firstMember.type, Is.EqualTo(MetadataRegistry.GetType<Vector2>()));
184+
Assert.That(firstMember.offset, Is.EqualTo(0));
185+
//Assert.That(firstMember.flags.HasFlag(ShaderStorageBufferMember.Flags.Array), Is.True);
186+
187+
ShaderStorageBufferMember secondMember = vertexShader.GetStorageBufferMember("lotsOfData", 1);
188+
Assert.That(secondMember.name.ToString(), Is.EqualTo("rotation"));
189+
Assert.That(secondMember.type, Is.EqualTo(MetadataRegistry.GetType<Vector4>()));
190+
Assert.That(secondMember.offset, Is.EqualTo(8));
191+
192+
ShaderStorageBufferMember thirdMember = vertexShader.GetStorageBufferMember("lotsOfData", 2);
193+
Assert.That(thirdMember.name.ToString(), Is.EqualTo("position"));
194+
Assert.That(thirdMember.type, Is.EqualTo(MetadataRegistry.GetType<Vector3>()));
195+
Assert.That(thirdMember.offset, Is.EqualTo(24));
196+
197+
ShaderStorageBufferMember fourthMember = vertexShader.GetStorageBufferMember("lotsOfData", 3);
198+
Assert.That(fourthMember.name.ToString(), Is.EqualTo("scale"));
199+
Assert.That(fourthMember.type, Is.EqualTo(MetadataRegistry.GetType<Vector3>()));
200+
Assert.That(fourthMember.offset, Is.EqualTo(36));
201+
177202
Assert.That(vertexShader.VertexInputAttributes.Length, Is.EqualTo(2));
178203
ShaderVertexInputAttribute first = vertexShader.VertexInputAttributes[0];
179204
Assert.That(first.name.ToString(), Is.EqualTo("aPos"));

0 commit comments

Comments
 (0)