|
@@ -10,7 +10,8 @@ import h3d.mat.Pass;
|
|
private typedef Driver = Dx12;
|
|
private typedef Driver = Dx12;
|
|
|
|
|
|
class DxFrame {
|
|
class DxFrame {
|
|
- public var backbuffer : Resource;
|
|
|
|
|
|
+ public var backBuffer : GpuResource;
|
|
|
|
+ public var depthBuffer : GpuResource;
|
|
public var allocator : CommandAllocator;
|
|
public var allocator : CommandAllocator;
|
|
public var commandList : CommandList;
|
|
public var commandList : CommandList;
|
|
public var fenceValue : Int64;
|
|
public var fenceValue : Int64;
|
|
@@ -34,6 +35,7 @@ class CompiledShader {
|
|
public var pipelines : Map<Int,hl.NativeArray<CachedPipeline>> = new Map();
|
|
public var pipelines : Map<Int,hl.NativeArray<CachedPipeline>> = new Map();
|
|
public var rootSignature : RootSignature;
|
|
public var rootSignature : RootSignature;
|
|
public var inputLayout : hl.CArray<InputElementDesc>;
|
|
public var inputLayout : hl.CArray<InputElementDesc>;
|
|
|
|
+ public var shader : hxsl.RuntimeShader;
|
|
public function new() {
|
|
public function new() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -46,6 +48,7 @@ class CompiledShader {
|
|
@:packed public var heap(default,null) : HeapProperties;
|
|
@:packed public var heap(default,null) : HeapProperties;
|
|
@:packed public var barrier(default,null) : ResourceBarrier;
|
|
@:packed public var barrier(default,null) : ResourceBarrier;
|
|
@:packed public var clearColor(default,null) : ClearColor;
|
|
@:packed public var clearColor(default,null) : ClearColor;
|
|
|
|
+ @:packed public var clearValue(default,null) : ClearValue;
|
|
@:packed public var viewport(default,null) : Viewport;
|
|
@:packed public var viewport(default,null) : Viewport;
|
|
@:packed public var rect(default,null) : Rect;
|
|
@:packed public var rect(default,null) : Rect;
|
|
|
|
|
|
@@ -81,9 +84,12 @@ class DX12Driver extends h3d.impl.Driver {
|
|
var frame : DxFrame;
|
|
var frame : DxFrame;
|
|
var fence : Fence;
|
|
var fence : Fence;
|
|
var fenceEvent : WaitEvent;
|
|
var fenceEvent : WaitEvent;
|
|
- var heap : DescriptorHeap;
|
|
|
|
|
|
+
|
|
var rtvDescSize : Int;
|
|
var rtvDescSize : Int;
|
|
|
|
+ var dsvDescSize : Int;
|
|
var rtvAddress : Address;
|
|
var rtvAddress : Address;
|
|
|
|
+ var dsvAddress : Address;
|
|
|
|
+
|
|
var currentFrame : Int;
|
|
var currentFrame : Int;
|
|
var fenceValue : Int64 = 0;
|
|
var fenceValue : Int64 = 0;
|
|
var needPipelineFlush = false;
|
|
var needPipelineFlush = false;
|
|
@@ -125,11 +131,17 @@ class DX12Driver extends h3d.impl.Driver {
|
|
var inf = new DescriptorHeapDesc();
|
|
var inf = new DescriptorHeapDesc();
|
|
inf.type = RTV;
|
|
inf.type = RTV;
|
|
inf.numDescriptors = BUFFER_COUNT;
|
|
inf.numDescriptors = BUFFER_COUNT;
|
|
- heap = new DescriptorHeap(inf);
|
|
|
|
|
|
+ var heap = new DescriptorHeap(inf);
|
|
rtvDescSize = Driver.getDescriptorHandleIncrementSize(RTV);
|
|
rtvDescSize = Driver.getDescriptorHandleIncrementSize(RTV);
|
|
rtvAddress = heap.getHandle(false);
|
|
rtvAddress = heap.getHandle(false);
|
|
|
|
|
|
|
|
+ inf.type = DSV;
|
|
|
|
+ var heap = new DescriptorHeap(inf);
|
|
|
|
+ dsvDescSize = Driver.getDescriptorHandleIncrementSize(DSV);
|
|
|
|
+ dsvAddress = heap.getHandle(false);
|
|
|
|
+
|
|
compiler = new ShaderCompiler();
|
|
compiler = new ShaderCompiler();
|
|
|
|
+ resize(window.width, window.height);
|
|
}
|
|
}
|
|
|
|
|
|
function beginFrame() {
|
|
function beginFrame() {
|
|
@@ -141,19 +153,12 @@ class DX12Driver extends h3d.impl.Driver {
|
|
frame.toRelease.pop().release();
|
|
frame.toRelease.pop().release();
|
|
|
|
|
|
var b = tmp.barrier;
|
|
var b = tmp.barrier;
|
|
- b.resource = frame.backbuffer;
|
|
|
|
|
|
+ b.resource = frame.backBuffer;
|
|
b.subResource = -1;
|
|
b.subResource = -1;
|
|
b.stateBefore = PRESENT;
|
|
b.stateBefore = PRESENT;
|
|
b.stateAfter = RENDER_TARGET;
|
|
b.stateAfter = RENDER_TARGET;
|
|
frame.commandList.resourceBarrier(b);
|
|
frame.commandList.resourceBarrier(b);
|
|
|
|
|
|
- var clear = tmp.clearColor;
|
|
|
|
- clear.r = 0.4;
|
|
|
|
- clear.g = 0.6;
|
|
|
|
- clear.b = 0.9;
|
|
|
|
- clear.a = 1.0;
|
|
|
|
- frame.commandList.clearRenderTargetView(rtvAddress.offset(currentFrame * rtvDescSize), clear);
|
|
|
|
-
|
|
|
|
tmp.viewport.width = currentWidth;
|
|
tmp.viewport.width = currentWidth;
|
|
tmp.viewport.height = currentHeight;
|
|
tmp.viewport.height = currentHeight;
|
|
tmp.viewport.maxDepth = 1;
|
|
tmp.viewport.maxDepth = 1;
|
|
@@ -164,7 +169,8 @@ class DX12Driver extends h3d.impl.Driver {
|
|
frame.commandList.rsSetViewports(1, tmp.viewport);
|
|
frame.commandList.rsSetViewports(1, tmp.viewport);
|
|
|
|
|
|
tmp.renderTargets[0] = rtvAddress.offset(currentFrame * rtvDescSize);
|
|
tmp.renderTargets[0] = rtvAddress.offset(currentFrame * rtvDescSize);
|
|
- frame.commandList.omSetRenderTargets(1, tmp.renderTargets, true, null);
|
|
|
|
|
|
+ tmp.depthStencils[0] = dsvAddress.offset(currentFrame * dsvDescSize);
|
|
|
|
+ frame.commandList.omSetRenderTargets(1, tmp.renderTargets, true, tmp.depthStencils);
|
|
}
|
|
}
|
|
|
|
|
|
static var VERTEX_FORMATS = [null,null,R32G32_FLOAT,R32G32B32_FLOAT,R32G32B32A32_FLOAT];
|
|
static var VERTEX_FORMATS = [null,null,R32G32_FLOAT,R32G32B32_FLOAT,R32G32B32A32_FLOAT];
|
|
@@ -178,18 +184,43 @@ class DX12Driver extends h3d.impl.Driver {
|
|
}
|
|
}
|
|
var vs = compileSource(shader.vertex, "vs_6_0");
|
|
var vs = compileSource(shader.vertex, "vs_6_0");
|
|
var ps = compileSource(shader.fragment, "ps_6_0");
|
|
var ps = compileSource(shader.fragment, "ps_6_0");
|
|
|
|
+
|
|
|
|
+ var inputs = [];
|
|
|
|
+ for( v in shader.vertex.data.vars )
|
|
|
|
+ switch( v.kind ) {
|
|
|
|
+ case Input: inputs.push(v);
|
|
|
|
+ default:
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var params = hl.CArray.alloc(RootParameterConstants,4);
|
|
|
|
+ var paramCount = 0, registerCount = 0;
|
|
|
|
+
|
|
|
|
+ function allocParam(size,vis) {
|
|
|
|
+ if( size == 0 ) return;
|
|
|
|
+ var p = params[paramCount++];
|
|
|
|
+ p.parameterType = CONSTANTS;
|
|
|
|
+ p.shaderRegister = registerCount++;
|
|
|
|
+ p.registerSpace = 0;
|
|
|
|
+ p.shaderVisibility = vis;
|
|
|
|
+ p.num32BitValues = size << 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ registerCount = 1;
|
|
|
|
+ allocParam(shader.vertex.paramsSize, VERTEX);
|
|
|
|
+ allocParam(shader.vertex.globalsSize, VERTEX);
|
|
|
|
+ registerCount = 0;
|
|
|
|
+ allocParam(shader.fragment.paramsSize, PIXEL);
|
|
|
|
+ allocParam(shader.fragment.globalsSize, PIXEL);
|
|
|
|
+
|
|
var sign = new RootSignatureDesc();
|
|
var sign = new RootSignatureDesc();
|
|
sign.flags.set(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
|
sign.flags.set(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
|
|
|
+ sign.numParameters = paramCount;
|
|
|
|
+ sign.parameters = params[0];
|
|
|
|
|
|
var signSize = 0;
|
|
var signSize = 0;
|
|
var signBytes = Driver.serializeRootSignature(sign, 1, signSize);
|
|
var signBytes = Driver.serializeRootSignature(sign, 1, signSize);
|
|
var sign = new RootSignature(signBytes,signSize);
|
|
var sign = new RootSignature(signBytes,signSize);
|
|
|
|
|
|
- var inputs = [];
|
|
|
|
- for( v in shader.vertex.data.vars )
|
|
|
|
- if( v.kind == Input )
|
|
|
|
- inputs.push(v);
|
|
|
|
-
|
|
|
|
var inputLayout = hl.CArray.alloc(InputElementDesc, inputs.length);
|
|
var inputLayout = hl.CArray.alloc(InputElementDesc, inputs.length);
|
|
for( i => v in inputs ) {
|
|
for( i => v in inputs ) {
|
|
var d = inputLayout[i];
|
|
var d = inputLayout[i];
|
|
@@ -216,7 +247,7 @@ class DX12Driver extends h3d.impl.Driver {
|
|
d.instanceDataStepRate = perInst;
|
|
d.instanceDataStepRate = perInst;
|
|
} else
|
|
} else
|
|
d.inputSlotClass = PER_VERTEX_DATA;
|
|
d.inputSlotClass = PER_VERTEX_DATA;
|
|
- d.alignedByteOffset = 1; // will trigger error if not set in makePipeline()
|
|
|
|
|
|
+ d.alignedByteOffset = -1;
|
|
}
|
|
}
|
|
|
|
|
|
var p = new GraphicsPipelineStateDesc();
|
|
var p = new GraphicsPipelineStateDesc();
|
|
@@ -230,18 +261,24 @@ class DX12Driver extends h3d.impl.Driver {
|
|
p.primitiveTopologyType = TRIANGLE;
|
|
p.primitiveTopologyType = TRIANGLE;
|
|
p.numRenderTargets = 1;
|
|
p.numRenderTargets = 1;
|
|
p.rtvFormats[0] = R8G8B8A8_UNORM;
|
|
p.rtvFormats[0] = R8G8B8A8_UNORM;
|
|
|
|
+ p.dsvFormat = D24_UNORM_S8_UINT;
|
|
p.sampleDesc.count = 1;
|
|
p.sampleDesc.count = 1;
|
|
p.sampleMask = -1;
|
|
p.sampleMask = -1;
|
|
p.inputLayout.inputElementDescs = inputLayout[0];
|
|
p.inputLayout.inputElementDescs = inputLayout[0];
|
|
p.inputLayout.numElements = inputLayout.length;
|
|
p.inputLayout.numElements = inputLayout.length;
|
|
|
|
|
|
|
|
+ //Driver.createGraphicsPipelineState(p);
|
|
|
|
+
|
|
var c = new CompiledShader();
|
|
var c = new CompiledShader();
|
|
c.inputNames = InputNames.get([for( v in inputs ) v.name]);
|
|
c.inputNames = InputNames.get([for( v in inputs ) v.name]);
|
|
c.pipeline = p;
|
|
c.pipeline = p;
|
|
c.rootSignature = sign;
|
|
c.rootSignature = sign;
|
|
c.inputLayout = inputLayout;
|
|
c.inputLayout = inputLayout;
|
|
c.inputCount = inputs.length;
|
|
c.inputCount = inputs.length;
|
|
- return c;
|
|
|
|
|
|
+ c.shader = shader;
|
|
|
|
+ for( i in 0...inputs.length )
|
|
|
|
+ inputLayout[i].alignedByteOffset = 1; // will trigger error if not set in makePipeline()
|
|
|
|
+ return c;
|
|
}
|
|
}
|
|
|
|
|
|
override function selectShader( shader : hxsl.RuntimeShader ) {
|
|
override function selectShader( shader : hxsl.RuntimeShader ) {
|
|
@@ -254,6 +291,7 @@ class DX12Driver extends h3d.impl.Driver {
|
|
return false;
|
|
return false;
|
|
currentShader = sh;
|
|
currentShader = sh;
|
|
needPipelineFlush = true;
|
|
needPipelineFlush = true;
|
|
|
|
+ frame.commandList.setGraphicsRootSignature(currentShader.rootSignature);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -264,6 +302,19 @@ class DX12Driver extends h3d.impl.Driver {
|
|
override function dispose() {
|
|
override function dispose() {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ override function clear(?color:Vector, ?depth:Float, ?stencil:Int) {
|
|
|
|
+ if( color != null ) {
|
|
|
|
+ var clear = tmp.clearColor;
|
|
|
|
+ clear.r = color.r;
|
|
|
|
+ clear.g = color.g;
|
|
|
|
+ clear.b = color.b;
|
|
|
|
+ clear.a = color.a;
|
|
|
|
+ frame.commandList.clearRenderTargetView(rtvAddress.offset(currentFrame * rtvDescSize), clear);
|
|
|
|
+ }
|
|
|
|
+ if( depth != null || stencil != null )
|
|
|
|
+ frame.commandList.clearDepthStencilView(dsvAddress.offset(currentFrame * dsvDescSize), depth != null ? (stencil != null ? BOTH : DEPTH) : STENCIL, (depth:Float), stencil);
|
|
|
|
+ }
|
|
|
|
+
|
|
override function resize(width:Int, height:Int) {
|
|
override function resize(width:Int, height:Int) {
|
|
|
|
|
|
if( currentWidth == width && currentHeight == height )
|
|
if( currentWidth == width && currentHeight == height )
|
|
@@ -280,16 +331,37 @@ class DX12Driver extends h3d.impl.Driver {
|
|
fenceEvent.wait(-1);
|
|
fenceEvent.wait(-1);
|
|
fenceValue++;
|
|
fenceValue++;
|
|
|
|
|
|
- for( f in frames )
|
|
|
|
- if( f.backbuffer != null )
|
|
|
|
- f.backbuffer.release();
|
|
|
|
|
|
+ for( f in frames ) {
|
|
|
|
+ if( f.backBuffer != null )
|
|
|
|
+ f.backBuffer.release();
|
|
|
|
+ if( f.depthBuffer != null )
|
|
|
|
+ f.depthBuffer.release();
|
|
|
|
+ }
|
|
|
|
|
|
- if( !Driver.resize(width, height, BUFFER_COUNT, R8G8B8A8_UNORM) )
|
|
|
|
- throw "Failed to resize backbuffer to " + width + "x" + height;
|
|
|
|
|
|
+ Driver.resize(width, height, BUFFER_COUNT, R8G8B8A8_UNORM);
|
|
|
|
|
|
for( i => f in frames ) {
|
|
for( i => f in frames ) {
|
|
- f.backbuffer = Driver.getBackBuffer(i);
|
|
|
|
- Driver.createRenderTargetView(f.backbuffer, null, rtvAddress.offset(i * rtvDescSize));
|
|
|
|
|
|
+ f.backBuffer = Driver.getBackBuffer(i);
|
|
|
|
+ Driver.createRenderTargetView(f.backBuffer, null, rtvAddress.offset(i * rtvDescSize));
|
|
|
|
+
|
|
|
|
+ var desc = new ResourceDesc();
|
|
|
|
+ var flags = new haxe.EnumFlags();
|
|
|
|
+ desc.dimension = TEXTURE2D;
|
|
|
|
+ desc.width = width;
|
|
|
|
+ desc.height = height;
|
|
|
|
+ desc.depthOrArraySize = 1;
|
|
|
|
+ desc.mipLevels = 1;
|
|
|
|
+ desc.sampleDesc.count = 1;
|
|
|
|
+ desc.format = D24_UNORM_S8_UINT;
|
|
|
|
+ desc.flags.set(ALLOW_DEPTH_STENCIL);
|
|
|
|
+ tmp.heap.type = DEFAULT;
|
|
|
|
+
|
|
|
|
+ tmp.clearValue.format = desc.format;
|
|
|
|
+ tmp.clearValue.depth = 1;
|
|
|
|
+ tmp.clearValue.stencil= 0;
|
|
|
|
+ f.depthBuffer = Driver.createCommittedResource(tmp.heap, flags, desc, DEPTH_WRITE, tmp.clearValue);
|
|
|
|
+
|
|
|
|
+ Driver.createDepthStencilView(f.depthBuffer, null, dsvAddress.offset(i * dsvDescSize));
|
|
}
|
|
}
|
|
|
|
|
|
beginFrame();
|
|
beginFrame();
|
|
@@ -382,6 +454,24 @@ class DX12Driver extends h3d.impl.Driver {
|
|
updateBuffer(v.res, @:privateAccess buf.b.offset(bufPos << 2), startVertex * v.stride << 2, vertexCount * v.stride << 2, VERTEX_AND_CONSTANT_BUFFER);
|
|
updateBuffer(v.res, @:privateAccess buf.b.offset(bufPos << 2), startVertex * v.stride << 2, vertexCount * v.stride << 2, VERTEX_AND_CONSTANT_BUFFER);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ override function uploadShaderBuffers(buffers:h3d.shader.Buffers, which:h3d.shader.Buffers.BufferKind) {
|
|
|
|
+ uploadBuffers(buffers.vertex, which, currentShader.shader.vertex);
|
|
|
|
+ uploadBuffers(buffers.fragment, which, currentShader.shader.fragment);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function uploadBuffers( buf : h3d.shader.Buffers.ShaderBuffers, which:h3d.shader.Buffers.BufferKind, shader : hxsl.RuntimeShader.RuntimeShaderData ) {
|
|
|
|
+ switch( which ) {
|
|
|
|
+ case Params:
|
|
|
|
+ frame.commandList.setGraphicsRoot32BitConstants(0, shader.paramsSize << 2, hl.Bytes.getArray(buf.params.toData()), 0);
|
|
|
|
+ case Globals:
|
|
|
|
+ frame.commandList.setGraphicsRoot32BitConstants(shader.paramsSize == 0 ? 0 : 1, shader.globalsSize << 2, hl.Bytes.getArray(buf.globals.toData()), 0);
|
|
|
|
+ case Textures:
|
|
|
|
+ if( buf.tex.length > 0 ) throw "TODO";
|
|
|
|
+ case Buffers:
|
|
|
|
+ if( buf.buffers != null && buf.buffers.length > 0 ) throw "TODO";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
function waitForFrame( index : Int ) {
|
|
function waitForFrame( index : Int ) {
|
|
var frame = frames[index];
|
|
var frame = frames[index];
|
|
if( fence.getValue() < frame.fenceValue ) {
|
|
if( fence.getValue() < frame.fenceValue ) {
|
|
@@ -519,7 +609,6 @@ class DX12Driver extends h3d.impl.Driver {
|
|
cp.size = signatureSize;
|
|
cp.size = signatureSize;
|
|
cp.pipeline = makePipeline(currentShader);
|
|
cp.pipeline = makePipeline(currentShader);
|
|
pipes[insert] = cp;
|
|
pipes[insert] = cp;
|
|
- frame.commandList.setGraphicsRootSignature(currentShader.rootSignature);
|
|
|
|
frame.commandList.setPipelineState(cp.pipeline);
|
|
frame.commandList.setPipelineState(cp.pipeline);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -531,7 +620,7 @@ class DX12Driver extends h3d.impl.Driver {
|
|
|
|
|
|
override function present() {
|
|
override function present() {
|
|
var barrier = tmp.barrier;
|
|
var barrier = tmp.barrier;
|
|
- barrier.resource = frame.backbuffer;
|
|
|
|
|
|
+ barrier.resource = frame.backBuffer;
|
|
barrier.subResource = -1;
|
|
barrier.subResource = -1;
|
|
barrier.stateBefore = RENDER_TARGET;
|
|
barrier.stateBefore = RENDER_TARGET;
|
|
barrier.stateAfter = PRESENT;
|
|
barrier.stateAfter = PRESENT;
|