@@ -416,7 +416,7 @@ private void DrawBatchPerTexture(Texture texture, ElementInfo[] sprites, int off
416416 DrawBatchPerTextureAndPass ( sprites , offset , count ) ;
417417 }
418418
419- private void DrawBatchPerTextureAndPass ( ElementInfo [ ] sprites , int offset , int count )
419+ private unsafe void DrawBatchPerTextureAndPass ( ElementInfo [ ] sprites , int offset , int count )
420420 {
421421 while ( count > 0 )
422422 {
@@ -462,67 +462,48 @@ private void DrawBatchPerTextureAndPass(ElementInfo[] sprites, int offset, int c
462462 {
463463 if ( ResourceContext . VertexBuffer != null )
464464 GraphicsContext . Allocator . ReleaseReference ( ResourceContext . VertexBuffer ) ;
465- ResourceContext . VertexBuffer = GraphicsContext . Allocator . GetTemporaryBuffer ( new BufferDescription ( ResourceContext . VertexCount * vertexStructSize , BufferFlags . VertexBuffer , GraphicsResourceUsage . Dynamic ) ) ;
465+ ResourceContext . VertexBuffer = GraphicsContext . Allocator . GetTemporaryBuffer ( new BufferDescription ( ResourceContext . VertexCount * vertexStructSize , BufferFlags . VertexBuffer , GraphicsResourceUsage . Default ) ) ;
466466 GraphicsContext . CommandList . SetVertexBuffer ( 0 , ResourceContext . VertexBuffer , 0 , vertexStructSize ) ;
467467 }
468468
469469 if ( ResourceContext . IsIndexBufferDynamic && ResourceContext . IndexBufferPosition == 0 )
470470 {
471471 if ( ResourceContext . IndexBuffer != null )
472472 GraphicsContext . Allocator . ReleaseReference ( ResourceContext . IndexBuffer ) ;
473- ResourceContext . IndexBuffer = GraphicsContext . Allocator . GetTemporaryBuffer ( new BufferDescription ( ResourceContext . IndexCount * indexStructSize , BufferFlags . IndexBuffer , GraphicsResourceUsage . Dynamic ) ) ;
473+ ResourceContext . IndexBuffer = GraphicsContext . Allocator . GetTemporaryBuffer ( new BufferDescription ( ResourceContext . IndexCount * indexStructSize , BufferFlags . IndexBuffer , GraphicsResourceUsage . Default ) ) ;
474474 GraphicsContext . CommandList . SetIndexBuffer ( ResourceContext . IndexBuffer , 0 , indexStructSize == sizeof ( int ) ) ;
475475 }
476476
477- // ------------------------------------------------------------------------------------------------------------
478- // CAUTION: Performance problem under x64 resolved by this special codepath:
479- // For some unknown reasons, It seems that writing directly to the pointer returned by the MapSubresource is
480- // extremely inefficient using x64 but using a temporary buffer and performing a mempcy to the locked region
481- // seems to be running at the same speed than x86
482- // ------------------------------------------------------------------------------------------------------------
483- // TODO Check again why we need this code
484- //if (IntPtr.Size == 8)
485- //{
486- // if (x64TempBuffer == null)
487- // {
488- // x64TempBuffer = ToDispose(new DataBuffer(Utilities.SizeOf<VertexPositionColorTexture>() * MaxBatchSize * VerticesPerSprite));
489- // }
490-
491- // // Perform the update of all vertices on a temporary buffer
492- // var texturePtr = (VertexPositionColorTexture*)x64TempBuffer.DataPointer;
493- // for (int i = 0; i < batchSize; i++)
494- // {
495- // UpdateBufferValuesFromElementInfo(ref sprites[offset + i], ref texturePtr, deltaX, deltaY);
496- // }
497-
498- // // Then copy this buffer in one shot
499- // resourceContext.VertexBuffer.SetData(GraphicsDevice, new DataPointer(x64TempBuffer.DataPointer, batchSize * VerticesPerSprite * Utilities.SizeOf<VertexPositionColorTexture>()), offsetInBytes, noOverwrite);
500- //}
501- //else
502477 {
503- var mappedIndices = new MappedResource ( ) ;
504- var mappedVertices = GraphicsContext . CommandList . MapSubresource ( ResourceContext . VertexBuffer , 0 , MapMode . WriteNoOverwrite , false , offsetVertexInBytes , vertexCount * vertexStructSize ) ;
505- if ( ResourceContext . IsIndexBufferDynamic )
506- mappedIndices = GraphicsContext . CommandList . MapSubresource ( ResourceContext . IndexBuffer , 0 , MapMode . WriteNoOverwrite , false , offsetIndexInBytes , indexCount * indexStructSize ) ;
507-
508- var vertexPointer = mappedVertices . DataBox . DataPointer ;
509- var indexPointer = mappedIndices . DataBox . DataPointer ;
478+ byte [ ] vArr = System . Buffers . ArrayPool < byte > . Shared . Rent ( vertexCount * vertexStructSize ) ;
479+ byte [ ] iArr = ResourceContext . IsIndexBufferDynamic == false ? null : System . Buffers . ArrayPool < byte > . Shared . Rent ( indexCount * indexStructSize ) ;
480+ var vSpan = vArr . AsSpan ( 0 , vertexCount * vertexStructSize ) ;
481+ var iSpan = ResourceContext . IsIndexBufferDynamic == false ? default : iArr . AsSpan ( 0 , indexCount * indexStructSize ) ;
510482
511- for ( var i = 0 ; i < batchSize ; i ++ )
483+ fixed ( void * vertexPointer2 = vSpan , indexPointer2 = iSpan )
512484 {
513- var spriteIndex = offset + i ;
514- ref var spriteElementInfo = ref sprites [ spriteIndex ] ;
485+ nint vertexPointer = ( nint ) vertexPointer2 ;
486+ nint indexPointer = ( nint ) indexPointer2 ;
487+ for ( var i = 0 ; i < batchSize ; i ++ )
488+ {
489+ var spriteIndex = offset + i ;
490+ ref var spriteElementInfo = ref sprites [ spriteIndex ] ;
515491
516- UpdateBufferValuesFromElementInfo ( ref spriteElementInfo , vertexPointer , indexPointer , ResourceContext . VertexBufferPosition ) ;
492+ UpdateBufferValuesFromElementInfo ( ref spriteElementInfo , vertexPointer , indexPointer , ResourceContext . VertexBufferPosition ) ;
517493
518- ResourceContext . VertexBufferPosition += spriteElementInfo . VertexCount ;
519- vertexPointer += vertexStructSize * spriteElementInfo . VertexCount ;
520- indexPointer += indexStructSize * spriteElementInfo . IndexCount ;
494+ ResourceContext . VertexBufferPosition += spriteElementInfo . VertexCount ;
495+ vertexPointer += vertexStructSize * spriteElementInfo . VertexCount ;
496+ indexPointer += indexStructSize * spriteElementInfo . IndexCount ;
497+ }
521498 }
522499
523- GraphicsContext . CommandList . UnmapSubresource ( mappedVertices ) ;
500+ // TODO: Should be faster to Map, write and Unmap instead of UpdateSubresource - tried memcopy instead of random writes as well as double-buffer but doesn't seem to matter
501+ ResourceContext . VertexBuffer . SetData < byte > ( GraphicsContext . CommandList , vSpan , offsetVertexInBytes ) ;
524502 if ( ResourceContext . IsIndexBufferDynamic )
525- GraphicsContext . CommandList . UnmapSubresource ( mappedIndices ) ;
503+ ResourceContext . IndexBuffer . SetData < byte > ( GraphicsContext . CommandList , iSpan , offsetIndexInBytes ) ;
504+ System . Buffers . ArrayPool < byte > . Shared . Return ( vArr ) ;
505+ if ( iArr is not null )
506+ System . Buffers . ArrayPool < byte > . Shared . Return ( iArr ) ;
526507 }
527508
528509 // Draw from the specified index
0 commit comments