Skip to content

Commit afd897a

Browse files
committed
* Reapply "Bindless (#1323)" + Force init that write varying in vertex shader.
1 parent f27ef42 commit afd897a

32 files changed

+620
-138
lines changed

h3d/impl/DX12Driver.hx

Lines changed: 127 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ class CompiledShader {
302302

303303
class 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

383383
class 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

414425
class 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

h3d/impl/DirectXDriver.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ class DirectXDriver extends h3d.impl.Driver {
915915

916916
override function hasFeature(f:Feature) {
917917
return switch(f) {
918-
case Queries, BottomLeftCoords:
918+
case Queries, BottomLeftCoords, Bindless:
919919
false;
920920
default:
921921
true;

h3d/impl/Driver.hx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ enum Feature {
8181
Supports instanced rendering
8282
*/
8383
InstancedRendering;
84+
/*
85+
Supports bindless
86+
*/
87+
Bindless;
8488
}
8589

8690
enum QueryKind {
@@ -183,6 +187,9 @@ class Driver {
183187
public function selectMaterial( pass : h3d.mat.Pass ) {
184188
}
185189

190+
public function selectTextureHandles( handles : Array<h3d.mat.TextureHandle> ) {
191+
}
192+
186193
public function uploadShaderBuffers( buffers : h3d.shader.Buffers, which : h3d.shader.Buffers.BufferKind ) {
187194
}
188195

@@ -320,4 +327,9 @@ class Driver {
320327
throw "Compute shaders are not implemented on this platform";
321328
}
322329

330+
// --- Bindless
331+
332+
public function getTextureHandle( t : h3d.mat.Texture ) : h3d.mat.TextureHandle {
333+
throw "Bindless is not implemented on this platform";
334+
}
323335
}

h3d/impl/GlDriver.hx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,11 +1958,16 @@ class GlDriver extends Driver {
19581958
}
19591959

19601960
override function hasFeature( f : Feature ) : Bool {
1961-
#if js
1962-
return features.get(f);
1963-
#else
1964-
return true;
1965-
#end
1961+
return switch(f) {
1962+
case Bindless:
1963+
false;
1964+
default:
1965+
#if js
1966+
features.get(f);
1967+
#else
1968+
true;
1969+
#end
1970+
};
19661971
}
19671972

19681973
#if js

0 commit comments

Comments
 (0)