@@ -302,10 +302,10 @@ class CompiledShader {
302302
303303class BaseHeap {
304304 public var stride (default ,null ) : Int ;
305- var size : Int ;
305+ public var size (default ,null ) : Int ;
306+ public var address (default ,null ) : Address ;
306307 var type : DescriptorHeapType ;
307308 var heap : DescriptorHeap ;
308- var address : Address ;
309309 var cpuToGpu : Int64 ;
310310 var shaderVisible : Bool ;
311311
@@ -328,6 +328,10 @@ class BaseHeap {
328328 cpuToGpu = desc .flags == SHADER_VISIBLE ? ( heap .getHandle (true ).value - address .value ) : 0 ;
329329 }
330330
331+ public dynamic function onFree ( prev : DescriptorHeap , prevSize : Int ) {
332+ throw " Too many buffers" ;
333+ }
334+
331335 public inline function toGPU ( address : Address ) : Address {
332336 return new Address (address .value + cpuToGpu );
333337 }
@@ -354,10 +358,6 @@ class ScratchHeap extends BaseHeap {
354358 super .allocHeap (size );
355359 }
356360
357- public dynamic function onFree ( prev : DescriptorHeap , prevSize : Int ) {
358- throw " Too many buffers" ;
359- }
360-
361361 public function alloc ( count : Int ) {
362362 if ( cursor + count > size ) {
363363 var prevCursor = cursor ;
@@ -382,6 +382,7 @@ class ScratchHeap extends BaseHeap {
382382
383383class BlockHeap extends BaseHeap {
384384 var freeList : Array <Int >;
385+ public var available (get ,never ) : Int ;
385386
386387 override public function new (type ,size ,shaderVisible ) {
387388 if ( shaderVisible )
@@ -390,25 +391,35 @@ class BlockHeap extends BaseHeap {
390391 freeList = [for (i in 0 ... size ) i ];
391392 }
392393
394+ function resize () {
395+ var prevSize = size ;
396+ var prev = heap ;
397+ allocHeap (getNextHeapSize ());
398+ for ( i in prevSize + 1 ... size )
399+ freeList .push (i );
400+ onFree (prev , prevSize );
401+ }
402+
393403 public function allocIndex () : Int {
394404 var idx = freeList .pop ();
395405 if ( idx == null ) {
396- var prevAddress = address .value ;
397- var prevSize = size ;
398- var prev = heap ;
399- allocHeap (getNextHeapSize ());
400- Driver .copyDescriptorsSimple (prevSize , address .value , prevAddress , type );
401- idx = prevSize ;
402- for ( i in prevSize + 1 ... size )
403- freeList .push (i );
404- (prev : Resource ).release ();
406+ idx = size ;
407+ resize ();
405408 }
406409 return idx ;
407410 }
408411
409412 public function disposeIndex ( index : Int ) {
410413 freeList .push (index );
411414 }
415+
416+ inline function get_available () {
417+ return freeList .length ;
418+ }
419+
420+ public inline function isEmpty () {
421+ return available == size ;
422+ }
412423}
413424
414425class ResourceData {
@@ -441,6 +452,7 @@ class TextureData extends ResourceData {
441452 public var uploadBuffer : TextureUploadBuffer ;
442453 var clearColorChanges : Int ;
443454 public var cpuViewsIndex : Array <Int > = [for (i in 0 ... 16 ) - 1 ];
455+ public var handles : Map <Int , h3d.mat. TextureHandle >;
444456
445457 public function setClearColor ( c : h3d. Vector4 ) {
446458 var color = color ;
@@ -478,6 +490,8 @@ class DX12Driver extends h3d.impl.Driver {
478490 var cpuSrvHeap : BlockHeap ;
479491 var cpuSamplerHeap : ScratchHeap ;
480492 var cpuSamplersIndex : Map <Int , Int >;
493+ var bindlessSrvHeap : BlockHeap ;
494+ var bindlessSamplerHeap : BlockHeap ;
481495 var indirectCommand : CommandSignature ;
482496
483497 var currentFrame : Int ;
@@ -546,8 +560,8 @@ class DX12Driver extends h3d.impl.Driver {
546560 f .allocator = new CommandAllocator (DIRECT );
547561 f .commandList = new CommandList (DIRECT , f .allocator , null );
548562 f .commandList .close ();
549- f .srvHeapCache = new ScratchHeapArray (CBV_SRV_UAV , INITIAL_SRV_COUNT );
550- f .samplerHeapCache = new ScratchHeapArray (SAMPLER , INITIAL_SAMPLER_COUNT );
563+ f .srvHeapCache = new ScratchHeapArray (CBV_SRV_UAV , INITIAL_SRV_COUNT * 2 );
564+ f .samplerHeapCache = new ScratchHeapArray (SAMPLER , INITIAL_SAMPLER_COUNT * 2 );
551565 if ( f .bufferAllocator != null )
552566 f .bufferAllocator .dispose ();
553567 f .bufferAllocator = new BufferAllocator (INITIAL_BUFFER_ALLOCATOR_SIZE );
@@ -563,14 +577,32 @@ class DX12Driver extends h3d.impl.Driver {
563577 depthStenciViews .onFree = function (prev , prevSize ) frame .toRelease .push (prev );
564578
565579 cpuSrvHeap = new BlockHeap (CBV_SRV_UAV , INITIAL_SRV_COUNT , false );
580+ cpuSrvHeap .onFree = function (prev , prevSize ) @:privateAccess {
581+ Driver .copyDescriptorsSimple (prevSize , cpuSrvHeap .address .value , prev .getHandle (false ).value , CBV_SRV_UAV );
582+ (prev : Resource ).release ();
583+ }
584+
566585 cpuSamplerHeap = new ScratchHeap (SAMPLER , INITIAL_SAMPLER_COUNT , false );
567586 cpuSamplerHeap .onFree = function (prev , prevSize ) @:privateAccess {
568587 Driver .copyDescriptorsSimple (prevSize , cpuSamplerHeap .address .value , prev .getHandle (false ).value , SAMPLER );
569- cpuSamplerHeap .alloc ( prevSize ) ;
588+ cpuSamplerHeap .cursor = prevSize ;
570589 (prev : Resource ).release ();
571590 }
572591 cpuSamplersIndex = [];
573592
593+ bindlessSrvHeap = new BlockHeap (CBV_SRV_UAV , INITIAL_SRV_COUNT , false );
594+ bindlessSrvHeap .onFree = function (prev , prevSize ) @:privateAccess {
595+ Driver .copyDescriptorsSimple (prevSize , bindlessSrvHeap .address .value , prev .getHandle (false ).value , CBV_SRV_UAV );
596+ (prev : Resource ).release ();
597+ flushHeaps ();
598+ }
599+ bindlessSamplerHeap = new BlockHeap (SAMPLER , INITIAL_SAMPLER_COUNT , false );
600+ bindlessSamplerHeap .onFree = function (prev , prevSize ) @:privateAccess {
601+ Driver .copyDescriptorsSimple (prevSize , bindlessSamplerHeap .address .value , prev .getHandle (false ).value , SAMPLER );
602+ (prev : Resource ).release ();
603+ flushHeaps ();
604+ }
605+
574606 if ( h3d. Engine .getCurrent () != null ) {
575607 defaultDepth = new h3d.mat. Texture (0 ,0 , Depth24Stencil8 );
576608 defaultDepth .t = new TextureData ();
@@ -595,7 +627,6 @@ class DX12Driver extends h3d.impl.Driver {
595627
596628 function beginFrame () {
597629 frameCount = hxd. Timer .frameCount ;
598- heapCount ++ ;
599630 currentFrame = Driver .getCurrentBackBufferIndex ();
600631 var prevFrame = frame ;
601632 frame = frames [currentFrame ];
@@ -648,13 +679,7 @@ class DX12Driver extends h3d.impl.Driver {
648679
649680 frame .srvHeapCache .reset ();
650681 frame .samplerHeapCache .reset ();
651- frame .srvHeap = frame .srvHeapCache .next ();
652- frame .samplerHeap = frame .samplerHeapCache .next ();
653-
654- var arr = tmp .descriptors2 ;
655- arr [0 ] = @:privateAccess frame .srvHeap .heap ;
656- arr [1 ] = @:privateAccess frame .samplerHeap .heap ;
657- frame .commandList .setDescriptorHeaps (arr );
682+ flushHeaps ();
658683 }
659684
660685 override function clear (? color : Vector4 , ? depth : Float , ? stencil : Int ) {
@@ -1511,6 +1536,10 @@ class DX12Driver extends h3d.impl.Driver {
15111536 sign .flags .set (DENY_VERTEX_SHADER_ROOT_ACCESS );
15121537 } else
15131538 sign .flags .set (ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT );
1539+ if ( shader .hasBindless () ) {
1540+ sign .flags .set (CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED );
1541+ sign .flags .set (SAMPLER_HEAP_DIRECTLY_INDEXED );
1542+ }
15141543 sign .flags .set (DENY_HULL_SHADER_ROOT_ACCESS );
15151544 sign .flags .set (DENY_DOMAIN_SHADER_ROOT_ACCESS );
15161545 sign .flags .set (DENY_GEOMETRY_SHADER_ROOT_ACCESS );
@@ -1531,9 +1560,9 @@ class DX12Driver extends h3d.impl.Driver {
15311560 var c = new CompiledShader ();
15321561
15331562 var rootStr = stringifyRootSignature (res .sign , " ROOT_SIGNATURE" , res .params , res .paramsCount );
1534- var vs = shader .mode == Compute ? null : compileSource (shader .vertex , " vs_6_0 " , rootStr );
1535- var ps = shader .mode == Compute ? null : compileSource (shader .fragment , " ps_6_0 " , rootStr );
1536- var cs = shader .mode == Compute ? compileSource (shader .compute , " cs_6_0 " , rootStr ) : null ;
1563+ var vs = shader .mode == Compute ? null : compileSource (shader .vertex , " vs_6_6 " , rootStr );
1564+ var ps = shader .mode == Compute ? null : compileSource (shader .fragment , " ps_6_6 " , rootStr );
1565+ var cs = shader .mode == Compute ? compileSource (shader .compute , " cs_6_6 " , rootStr ) : null ;
15371566
15381567 var signSize = 0 ;
15391568 var signBytes = Driver .serializeRootSignature (res .sign , 1 , signSize );
@@ -2187,6 +2216,10 @@ class DX12Driver extends h3d.impl.Driver {
21872216 frame .commandList .setComputeRoot32BitConstants (regs .params , dataSize >> 2 , data , 0 );
21882217 else
21892218 frame .commandList .setGraphicsRoot32BitConstants (regs .params , dataSize >> 2 , data , 0 );
2219+ for ( i in 0 ... shader .paramsHandleCount ) {
2220+ var handle = buf .handles [i ];
2221+ transition (handle .texture .t , shader .kind == Fragment ? PIXEL_SHADER_RESOURCE : NON_PIXEL_SHADER_RESOURCE );
2222+ }
21902223 }
21912224 case Globals :
21922225 var isFragment = shader .kind == Fragment ;
@@ -2211,6 +2244,12 @@ class DX12Driver extends h3d.impl.Driver {
22112244 frame .commandList .setComputeRoot32BitConstants (regs .globals , dataSize >> 2 , data , 0 );
22122245 else
22132246 frame .commandList .setGraphicsRoot32BitConstants (regs .globals , dataSize >> 2 , data , 0 );
2247+ var startIdx = shader .paramsHandleCount ;
2248+ var lastIdx = startIdx + shader .globalsHandleCount ;
2249+ for ( i in startIdx ... lastIdx ) {
2250+ var handle = buf .handles [i ];
2251+ transition (handle .texture .t , isFragment ? PIXEL_SHADER_RESOURCE : NON_PIXEL_SHADER_RESOURCE );
2252+ }
22142253 }
22152254 if ( isFragment )
22162255 lastFragmentGlobalBind = bind ;
@@ -2438,6 +2477,13 @@ class DX12Driver extends h3d.impl.Driver {
24382477 }
24392478 }
24402479
2480+ override function selectTextureHandles ( handles : Array <h3d.mat. TextureHandle > ) {
2481+ for ( i in 0 ... handles .length ) {
2482+ var th = handles [i ];
2483+ transition (th .texture .t , PIXEL_SHADER_RESOURCE );
2484+ }
2485+ }
2486+
24412487 override function selectBuffer (buffer : Buffer ) {
24422488 var views = tmp .vertexViews ;
24432489 var bview = buffer .vbuf .view ;
@@ -2700,15 +2746,24 @@ class DX12Driver extends h3d.impl.Driver {
27002746 }
27012747 }
27022748
2703- override function flushShaderBuffers () {
2704- if ( frame .srvHeap .available < 128 || frame .samplerHeap .available < 64 ) {
2705- frame .srvHeap = frame .srvHeapCache .next ();
2706- frame .samplerHeap = frame .samplerHeapCache .next ();
2707- heapCount ++ ;
2708- var arr = tmp .descriptors2 ;
2709- arr [0 ] = @:privateAccess frame .srvHeap .heap ;
2710- arr [1 ] = @:privateAccess frame .samplerHeap .heap ;
2711- frame .commandList .setDescriptorHeaps (arr );
2749+ function flushHeaps (rebind : Bool = false ) {
2750+ frame .srvHeap = frame .srvHeapCache .next ();
2751+ frame .samplerHeap = frame .samplerHeapCache .next ();
2752+ heapCount ++ ;
2753+ var arr = tmp .descriptors2 ;
2754+ arr [0 ] = @:privateAccess frame .srvHeap .heap ;
2755+ arr [1 ] = @:privateAccess frame .samplerHeap .heap ;
2756+ frame .commandList .setDescriptorHeaps (arr );
2757+
2758+ if ( ! bindlessSrvHeap .isEmpty () )
2759+ Driver .copyDescriptorsSimple ( bindlessSrvHeap .size , frame .srvHeap .address .value , bindlessSrvHeap .address .value , CBV_SRV_UAV );
2760+ if ( ! bindlessSamplerHeap .isEmpty () )
2761+ Driver .copyDescriptorsSimple ( bindlessSamplerHeap .size , frame .samplerHeap .address .value , bindlessSamplerHeap .address .value , SAMPLER );
2762+
2763+ @:privateAccess frame .srvHeap .cursor = bindlessSrvHeap .size ;
2764+ @:privateAccess frame .samplerHeap .cursor = bindlessSamplerHeap .size ;
2765+
2766+ if ( rebind ) {
27122767 inline function rebindGlobal (bindSlot , desc ) {
27132768 if ( bindSlot >= 0 ) {
27142769 var srv = frame .srvHeap .alloc (1 );
@@ -2722,9 +2777,22 @@ class DX12Driver extends h3d.impl.Driver {
27222777
27232778 rebindGlobal (lastVertexGlobalBind , tmp .vertexGlobalDesc );
27242779 rebindGlobal (lastFragmentGlobalBind , tmp .fragmentGlobalDesc );
2780+
2781+ if ( currentShader .shader .hasBindless () ) {
2782+ if ( currentShader .isCompute )
2783+ frame .commandList .setComputeRootSignature (currentShader .rootSignature );
2784+ else
2785+ frame .commandList .setGraphicsRootSignature (currentShader .rootSignature );
2786+ frame .commandList .setPipelineState (currentPipelineState );
2787+ }
27252788 }
27262789 }
27272790
2791+ override function flushShaderBuffers () {
2792+ if ( frame .srvHeap .available < 128 || frame .samplerHeap .available < 64 )
2793+ flushHeaps (true );
2794+ }
2795+
27282796 function flushFrame ( onResize : Bool = false ) {
27292797 flushQueries ();
27302798 frame .commandList .close ();
@@ -2775,6 +2843,27 @@ class DX12Driver extends h3d.impl.Driver {
27752843 needUAVBarrier = true ;
27762844 }
27772845
2846+ override function getTextureHandle ( t : h3d.mat. Texture ) : h3d.mat. TextureHandle {
2847+ var handle : h3d.mat. TextureHandle = null ;
2848+ if ( t .t .handles == null )
2849+ t .t .handles = []
2850+ else
2851+ handle = t .t .handles .get (t .bits );
2852+ if ( handle == null ) {
2853+ var sampler = getCpuSampler (t );
2854+ var srv = getCpuTexView (t );
2855+ var srvIndex = bindlessSrvHeap .allocIndex ();
2856+ var samplerIndex = bindlessSamplerHeap .allocIndex ();
2857+ Driver .copyDescriptorsSimple (1 , bindlessSrvHeap .getCpuAddressAt (srvIndex ), srv , CBV_SRV_UAV );
2858+ Driver .copyDescriptorsSimple (1 , frame .srvHeap .getCpuAddressAt (srvIndex ), srv , CBV_SRV_UAV );
2859+ Driver .copyDescriptorsSimple (1 , bindlessSamplerHeap .getCpuAddressAt (samplerIndex ), sampler , SAMPLER );
2860+ Driver .copyDescriptorsSimple (1 , frame .samplerHeap .getCpuAddressAt (samplerIndex ), sampler , SAMPLER );
2861+ handle = new h3d.mat. TextureHandle (t , haxe. Int64 .make (samplerIndex , srvIndex ));
2862+ t .t .handles .set (t .bits , handle );
2863+ }
2864+ return handle ;
2865+ }
2866+
27782867}
27792868
27802869#end
0 commit comments