|
@@ -7,6 +7,7 @@ private class ShaderContext {
|
|
|
public var shader : Shader;
|
|
|
public var globalsSize : Int;
|
|
|
public var paramsSize : Int;
|
|
|
+ public var texturesCount : Int;
|
|
|
public var globals : dx.Resource;
|
|
|
public var params : dx.Resource;
|
|
|
public function new(shader) {
|
|
@@ -22,12 +23,26 @@ private class CompiledShader {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+enum PipelineKind {
|
|
|
+ Vertex;
|
|
|
+ Pixel;
|
|
|
+}
|
|
|
+
|
|
|
+class PipelineState {
|
|
|
+ public var kind : PipelineKind;
|
|
|
+ public var samplers = new hl.NativeArray<SamplerState>(64);
|
|
|
+ public var resources = new hl.NativeArray<ShaderResourceView>(64);
|
|
|
+ public var buffers = new hl.NativeArray<dx.Resource>(16);
|
|
|
+ public function new(kind) {
|
|
|
+ this.kind = kind;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
class DirectXDriver extends h3d.impl.Driver {
|
|
|
|
|
|
var driver : DriverInstance;
|
|
|
var shaders : Map<Int,CompiledShader>;
|
|
|
var box = new dx.Resource.ResourceBox();
|
|
|
- var buffers = new hl.NativeArray<dx.Resource>(16);
|
|
|
var strides : Array<Int> = [];
|
|
|
var zeroes : Array<Int> = [for( i in 0...16 ) 0];
|
|
|
var currentShader : CompiledShader;
|
|
@@ -37,6 +52,10 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
var currentTargets = new hl.NativeArray<RenderTargetView>(16);
|
|
|
var viewport : hl.BytesAccess<hl.F32> = new hl.Bytes(6 * 4);
|
|
|
var depthView : DepthStencilView;
|
|
|
+ var vertexShader = new PipelineState(Vertex);
|
|
|
+ var pixelShader = new PipelineState(Pixel);
|
|
|
+ var buffers = new hl.NativeArray<dx.Resource>(16);
|
|
|
+ var frame : Int;
|
|
|
|
|
|
public function new() {
|
|
|
shaders = new Map();
|
|
@@ -82,12 +101,10 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
desc.depthClipEnable = true;
|
|
|
var rs = Driver.createRasterizerState(desc);
|
|
|
Driver.rsSetState(rs);
|
|
|
+ }
|
|
|
|
|
|
- var desc = new SamplerStateDesc();
|
|
|
- var ss = Driver.createSamplerState(desc);
|
|
|
- var sarr = new hl.NativeArray(1);
|
|
|
- sarr[0] = ss;
|
|
|
- Driver.psSetSamplers(0, 1, sarr);
|
|
|
+ override function begin(frame:Int) {
|
|
|
+ this.frame = frame;
|
|
|
}
|
|
|
|
|
|
override function isDisposed() {
|
|
@@ -131,14 +148,22 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
desc.usage = Default;
|
|
|
desc.bind = ShaderResource;
|
|
|
var tex = Driver.createTexture2d(desc);
|
|
|
- return tex;
|
|
|
+
|
|
|
+ var vdesc = new ShaderResourceViewDesc();
|
|
|
+ vdesc.format = desc.format;
|
|
|
+ vdesc.dimension = Texture2D;
|
|
|
+ vdesc.start = 0; // top mip level
|
|
|
+ vdesc.count = -1; // all mip levels
|
|
|
+ var view = Driver.createShaderResourceView(tex, vdesc);
|
|
|
+ return { res : tex, view : view };
|
|
|
}
|
|
|
|
|
|
override function disposeTexture( t : h3d.mat.Texture ) {
|
|
|
var tt = t.t;
|
|
|
if( tt == null ) return;
|
|
|
t.t = null;
|
|
|
- tt.release();
|
|
|
+ tt.view.release();
|
|
|
+ tt.res.release();
|
|
|
}
|
|
|
|
|
|
override function disposeVertexes(v:VertexBuffer) {
|
|
@@ -167,6 +192,18 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
throw "TODO";
|
|
|
}
|
|
|
|
|
|
+ override function uploadTextureBitmap(t:h3d.mat.Texture, bmp:hxd.BitmapData, mipLevel:Int, side:Int) {
|
|
|
+ var pixels = bmp.getPixels();
|
|
|
+ uploadTexturePixels(t, pixels, mipLevel, side);
|
|
|
+ pixels.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ override function uploadTexturePixels(t:h3d.mat.Texture, pixels:hxd.Pixels, mipLevel:Int, side:Int) {
|
|
|
+ if( mipLevel != 0 || side != 0 ) throw "TODO";
|
|
|
+ pixels.convert(RGBA);
|
|
|
+ t.t.res.updateSubresource(0, null, pixels.bytes, pixels.width << 2, 0);
|
|
|
+ }
|
|
|
+
|
|
|
function compileShader( shader : hxsl.RuntimeShader.RuntimeShaderData, compileOnly = false ) {
|
|
|
var h = new hxsl.HlslOut();
|
|
|
var source = h.run(shader.data);
|
|
@@ -187,6 +224,7 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
var ctx = new ShaderContext(s);
|
|
|
ctx.globalsSize = shader.globalsSize;
|
|
|
ctx.paramsSize = shader.paramsSize;
|
|
|
+ ctx.texturesCount = shader.textures2DCount + shader.texturesCubeCount;
|
|
|
ctx.globals = dx.Driver.createBuffer(shader.globalsSize * 16, Dynamic, ConstantBuffer, CpuWrite, None, 0, null);
|
|
|
ctx.params = dx.Driver.createBuffer(shader.paramsSize * 16, Dynamic, ConstantBuffer, CpuWrite, None, 0, null);
|
|
|
return { s : ctx, bytes : bytes };
|
|
@@ -266,23 +304,94 @@ class DirectXDriver extends h3d.impl.Driver {
|
|
|
}
|
|
|
|
|
|
override function uploadShaderBuffers(buffers:h3d.shader.Buffers, which:h3d.shader.Buffers.BufferKind) {
|
|
|
+ uploadBuffers(vertexShader, currentShader.vertex, buffers.vertex, which);
|
|
|
+ uploadBuffers(pixelShader, currentShader.fragment, buffers.fragment, which);
|
|
|
+ }
|
|
|
+
|
|
|
+ function uploadBuffers( state : PipelineState, shader : ShaderContext, buffers : h3d.shader.Buffers.ShaderBuffers, which : h3d.shader.Buffers.BufferKind ) {
|
|
|
switch( which ) {
|
|
|
case Globals:
|
|
|
- uploadShaderBuffer(currentShader.vertex.globals, buffers.vertex.globals, currentShader.vertex.globalsSize);
|
|
|
- uploadShaderBuffer(currentShader.fragment.globals, buffers.fragment.globals, currentShader.fragment.globalsSize);
|
|
|
- this.buffers[0] = currentShader.vertex.globals;
|
|
|
- Driver.vsSetConstantBuffers(0, 1, this.buffers);
|
|
|
- this.buffers[0] = currentShader.fragment.globals;
|
|
|
- Driver.psSetConstantBuffers(0, 1, this.buffers);
|
|
|
+ if( shader.globalsSize > 0 ) {
|
|
|
+ uploadShaderBuffer(shader.globals, buffers.globals, shader.globalsSize);
|
|
|
+ if( state.buffers[0] != shader.globals ) {
|
|
|
+ state.buffers[0] = shader.globals;
|
|
|
+ switch( state.kind ) {
|
|
|
+ case Vertex:
|
|
|
+ Driver.vsSetConstantBuffers(0, 1, state.buffers, 0);
|
|
|
+ case Pixel:
|
|
|
+ Driver.psSetConstantBuffers(0, 1, state.buffers, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
case Params:
|
|
|
- uploadShaderBuffer(currentShader.vertex.params, buffers.vertex.params, currentShader.vertex.paramsSize);
|
|
|
- uploadShaderBuffer(currentShader.fragment.params, buffers.fragment.params, currentShader.fragment.paramsSize);
|
|
|
- this.buffers[0] = currentShader.vertex.params;
|
|
|
- Driver.vsSetConstantBuffers(1, 1, this.buffers);
|
|
|
- this.buffers[0] = currentShader.fragment.params;
|
|
|
- Driver.psSetConstantBuffers(1, 1, this.buffers);
|
|
|
+ if( shader.paramsSize > 0 ) {
|
|
|
+ uploadShaderBuffer(shader.params, buffers.params, shader.paramsSize);
|
|
|
+ if( state.buffers[1] != shader.params ) {
|
|
|
+ state.buffers[1] = shader.params;
|
|
|
+ switch( state.kind ) {
|
|
|
+ case Vertex:
|
|
|
+ Driver.vsSetConstantBuffers(1, 1, state.buffers, 1);
|
|
|
+ case Pixel:
|
|
|
+ Driver.psSetConstantBuffers(1, 1, state.buffers, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
case Textures:
|
|
|
+ var start = -1, max = -1;
|
|
|
+ var sstart = -1, smax = -1;
|
|
|
+ for( i in 0...shader.texturesCount ) {
|
|
|
+ var t = buffers.tex[i];
|
|
|
+ if( t == null || t.isDisposed() ) {
|
|
|
+ var color = h3d.mat.Defaults.loadingTextureColor;
|
|
|
+ t = h3d.mat.Texture.fromColor(color,(color>>>24)/255);
|
|
|
+ }
|
|
|
+ if( t != null && t.t == null && t.realloc != null ) {
|
|
|
+ t.alloc();
|
|
|
+ t.realloc();
|
|
|
+ }
|
|
|
+ t.lastFrame = frame;
|
|
|
+
|
|
|
+ var view = t.t.view;
|
|
|
+ if( view == state.resources[i] ) continue;
|
|
|
+
|
|
|
+ state.resources[i] = view;
|
|
|
+ max = i;
|
|
|
+ if( start < 0 ) start = i;
|
|
|
+
|
|
|
+ // make sampler state
|
|
|
+ var ss = getTextureSampler(t);
|
|
|
+ if( state.samplers[i] == ss ) continue;
|
|
|
+
|
|
|
+ state.samplers[i] = ss;
|
|
|
+ smax = i;
|
|
|
+ if( sstart < 0 ) sstart = i;
|
|
|
+ }
|
|
|
+ switch( state.kind) {
|
|
|
+ case Vertex:
|
|
|
+ if( max >= 0 ) Driver.vsSetShaderResources(start, max - start + 1, state.resources, start);
|
|
|
+ if( smax >= 0 ) Driver.vsSetSamplers(sstart, smax - sstart + 1, state.samplers, sstart);
|
|
|
+ case Pixel:
|
|
|
+ if( max >= 0 ) Driver.psSetShaderResources(start, max - start + 1, state.resources, start);
|
|
|
+ if( smax >= 0 ) Driver.psSetSamplers(sstart, smax - sstart + 1, state.samplers, sstart);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ var defSampler : SamplerState;
|
|
|
+ function getTextureSampler( t : h3d.mat.Texture ) {
|
|
|
+ if( defSampler == null ) {
|
|
|
+ var desc = new SamplerDesc();
|
|
|
+ desc.filter = MinMagMipLinear;
|
|
|
+ desc.addressU = Wrap;
|
|
|
+ desc.addressV = Wrap;
|
|
|
+ desc.addressW = Wrap;
|
|
|
+ desc.maxAnisotropy = 1;
|
|
|
+ desc.comparisonFunc = Always;
|
|
|
+ desc.maxLod = 1e32;
|
|
|
+ defSampler = Driver.createSamplerState(desc);
|
|
|
}
|
|
|
+ return defSampler;
|
|
|
}
|
|
|
|
|
|
override function draw(ibuf:IndexBuffer, startIndex:Int, ntriangles:Int) {
|