11using SDL3 ;
22using System ;
3+ using System . Numerics ;
4+ using System . Runtime . InteropServices ;
35
46namespace Staple . Internal ;
57
@@ -245,6 +247,156 @@ public void DestroyIndexBuffer(ResourceHandle<IndexBuffer> buffer)
245247 AddCommand ( new SDLGPUDestroyIndexBufferCommand ( buffer ) ) ;
246248 }
247249
250+ private void UpdateEntityTransformBuffer ( )
251+ {
252+ var elementCount = RenderSystem . Instance . entityTransforms . Length ;
253+
254+ var targetLength = elementCount * Marshal . SizeOf < Matrix4x4 > ( ) ;
255+
256+ if ( entityTransformsBuffer != nint . Zero &&
257+ entityTransformsBufferLength >= targetLength &&
258+ RenderSystem . Instance . changedEntityTransformRanges . Count == 0 )
259+ {
260+ return ;
261+ }
262+
263+ if ( entityTransformsBuffer == nint . Zero || entityTransformsBufferLength != targetLength )
264+ {
265+ entityTransformsBufferLength = targetLength ;
266+
267+ if ( entityTransformsBuffer != nint . Zero )
268+ {
269+ SDL . ReleaseGPUBuffer ( device , entityTransformsBuffer ) ;
270+
271+ entityTransformsBuffer = nint . Zero ;
272+ }
273+
274+ var createInfo = new SDL . GPUBufferCreateInfo ( )
275+ {
276+ Size = ( uint ) targetLength ,
277+ Usage = SDL . GPUBufferUsageFlags . Vertex | SDL . GPUBufferUsageFlags . GraphicsStorageRead ,
278+ } ;
279+
280+ entityTransformsBuffer = SDL . CreateGPUBuffer ( device , in createInfo ) ;
281+
282+ if ( entityTransformsBuffer == nint . Zero )
283+ {
284+ return ;
285+ }
286+
287+ var transferBuffer = GetTransferBuffer ( false , targetLength ) ;
288+
289+ if ( transferBuffer == nint . Zero )
290+ {
291+ SDL . ReleaseGPUBuffer ( device , entityTransformsBuffer ) ;
292+
293+ entityTransformsBuffer = nint . Zero ;
294+
295+ return ;
296+ }
297+
298+ if ( renderPass != nint . Zero )
299+ {
300+ FinishPasses ( ) ;
301+ }
302+
303+ if ( copyPass == nint . Zero )
304+ {
305+ copyPass = SDL . BeginGPUCopyPass ( commandBuffer ) ;
306+ }
307+
308+ if ( copyPass == nint . Zero )
309+ {
310+ return ;
311+ }
312+
313+ var mapData = SDL . MapGPUTransferBuffer ( device , transferBuffer , true ) ;
314+
315+ unsafe
316+ {
317+ var from = RenderSystem . Instance . entityTransforms . AsSpan ( ) ;
318+ var to = new Span < Matrix4x4 > ( ( void * ) mapData , elementCount ) ;
319+
320+ from . CopyTo ( to ) ;
321+ }
322+
323+ SDL . UnmapGPUTransferBuffer ( device , transferBuffer ) ;
324+
325+ var location = new SDL . GPUTransferBufferLocation ( )
326+ {
327+ TransferBuffer = transferBuffer ,
328+ Offset = 0 ,
329+ } ;
330+
331+ var region = new SDL . GPUBufferRegion ( )
332+ {
333+ Buffer = entityTransformsBuffer ,
334+ Size = ( uint ) targetLength ,
335+ } ;
336+
337+ SDL . UploadToGPUBuffer ( copyPass , in location , in region , false ) ;
338+ }
339+ else
340+ {
341+ if ( renderPass != nint . Zero )
342+ {
343+ FinishPasses ( ) ;
344+ }
345+
346+ if ( copyPass == nint . Zero )
347+ {
348+ copyPass = SDL . BeginGPUCopyPass ( commandBuffer ) ;
349+ }
350+
351+ if ( copyPass == nint . Zero )
352+ {
353+ return ;
354+ }
355+
356+ foreach ( var ( start , length ) in RenderSystem . Instance . changedEntityTransformRanges )
357+ {
358+ targetLength = length * Marshal . SizeOf < Matrix4x4 > ( ) ;
359+
360+ var transferBuffer = GetTransferBuffer ( false , targetLength ) ;
361+
362+ if ( transferBuffer == nint . Zero )
363+ {
364+ SDL . ReleaseGPUBuffer ( device , entityTransformsBuffer ) ;
365+
366+ entityTransformsBuffer = nint . Zero ;
367+
368+ return ;
369+ }
370+
371+ var mapData = SDL . MapGPUTransferBuffer ( device , transferBuffer , true ) ;
372+
373+ unsafe
374+ {
375+ var from = RenderSystem . Instance . entityTransforms . AsSpan ( ) . Slice ( start , length ) ;
376+ var to = new Span < Matrix4x4 > ( ( void * ) mapData , length ) ;
377+
378+ from . CopyTo ( to ) ;
379+ }
380+
381+ SDL . UnmapGPUTransferBuffer ( device , transferBuffer ) ;
382+
383+ var location = new SDL . GPUTransferBufferLocation ( )
384+ {
385+ TransferBuffer = transferBuffer ,
386+ Offset = ( uint ) ( start * Marshal . SizeOf < Matrix4x4 > ( ) ) ,
387+ } ;
388+
389+ var region = new SDL . GPUBufferRegion ( )
390+ {
391+ Buffer = entityTransformsBuffer ,
392+ Size = ( uint ) targetLength ,
393+ } ;
394+
395+ SDL . UploadToGPUBuffer ( copyPass , in location , in region , false ) ;
396+ }
397+ }
398+ }
399+
248400 public void UpdateStaticMeshVertexBuffer < T > ( BufferAttributeSource < T , VertexBuffer > buffer ) where T : unmanaged
249401 {
250402 if ( renderPass != nint . Zero )
@@ -253,7 +405,6 @@ public void UpdateStaticMeshVertexBuffer<T>(BufferAttributeSource<T, VertexBuffe
253405 }
254406
255407 var index = buffer . index ;
256- var transferBuffer = nint . Zero ;
257408 var targetLength = buffer . allocator . buffer . Length * buffer . allocator . elementSize ;
258409
259410 ref var vertexBuffer = ref staticMeshVertexBuffers [ index ] ;
@@ -270,12 +421,10 @@ public void UpdateStaticMeshVertexBuffer<T>(BufferAttributeSource<T, VertexBuffe
270421 vertexBuffer = nint . Zero ;
271422 }
272423
273- var usageFlags = SDL . GPUBufferUsageFlags . Vertex ;
274-
275424 var createInfo = new SDL . GPUBufferCreateInfo ( )
276425 {
277426 Size = ( uint ) vertexBufferLength ,
278- Usage = usageFlags ,
427+ Usage = SDL . GPUBufferUsageFlags . Vertex ,
279428 } ;
280429
281430 vertexBuffer = SDL . CreateGPUBuffer ( device , in createInfo ) ;
@@ -286,7 +435,7 @@ public void UpdateStaticMeshVertexBuffer<T>(BufferAttributeSource<T, VertexBuffe
286435 }
287436 }
288437
289- transferBuffer = GetTransferBuffer ( false , vertexBufferLength ) ;
438+ var transferBuffer = GetTransferBuffer ( false , vertexBufferLength ) ;
290439
291440 if ( transferBuffer == nint . Zero )
292441 {
@@ -348,7 +497,6 @@ public void UpdateStaticMeshIndexBuffer(BufferAttributeSource<uint, IndexBuffer>
348497 FinishPasses ( ) ;
349498 }
350499
351- var transferBuffer = nint . Zero ;
352500 var targetLength = buffer . allocator . buffer . Length * buffer . allocator . elementSize ;
353501
354502 ref var indexBuffer = ref staticMeshIndexBuffer ;
@@ -365,12 +513,10 @@ public void UpdateStaticMeshIndexBuffer(BufferAttributeSource<uint, IndexBuffer>
365513 indexBuffer = nint . Zero ;
366514 }
367515
368- var usageFlags = SDL . GPUBufferUsageFlags . Index ;
369-
370516 var createInfo = new SDL . GPUBufferCreateInfo ( )
371517 {
372518 Size = ( uint ) bufferLength ,
373- Usage = usageFlags ,
519+ Usage = SDL . GPUBufferUsageFlags . Index ,
374520 } ;
375521
376522 indexBuffer = SDL . CreateGPUBuffer ( device , in createInfo ) ;
@@ -381,7 +527,7 @@ public void UpdateStaticMeshIndexBuffer(BufferAttributeSource<uint, IndexBuffer>
381527 }
382528 }
383529
384- transferBuffer = GetTransferBuffer ( false , bufferLength ) ;
530+ var transferBuffer = GetTransferBuffer ( false , bufferLength ) ;
385531
386532 if ( transferBuffer == nint . Zero )
387533 {
0 commit comments