mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Directx 12 mrt working - 1st iteration
This commit is contained in:
parent
2faf8a551d
commit
7dd4aa9150
@ -127,7 +127,7 @@ func main() {
|
||||
ebiten.SetVsyncEnabled(false)
|
||||
ebiten.SetWindowTitle("MRT (Ebitengine Demo)")
|
||||
if err := ebiten.RunGameWithOptions(&Game{}, &ebiten.RunGameOptions{
|
||||
GraphicsLibrary: ebiten.GraphicsLibraryOpenGL,
|
||||
GraphicsLibrary: ebiten.GraphicsLibraryDirectX,
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -625,6 +625,7 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
if targetCount > 1 || firstTarget > 0 {
|
||||
targetCount = graphics.ShaderDstImageCount
|
||||
}
|
||||
|
||||
g.deviceContext.RSSetViewports(viewports[:targetCount])
|
||||
|
||||
if err := g.setAsRenderTargets(dsts[:targetCount], fillRule != graphicsdriver.FillAll); err != nil {
|
||||
|
@ -1082,7 +1082,78 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
func (g *graphics12) setAsRenderTargets(dsts []*image12, useStencil bool) error {
|
||||
var rtvs []_D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
var dsvPtr *_D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
|
||||
for i, img := range dsts {
|
||||
// Ignore a nil image in case of MRT
|
||||
if img == nil {
|
||||
_ = i
|
||||
rtvBase, err := g.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtv := rtvBase
|
||||
rtv.Offset(int32(g.frameIndex), g.rtvDescriptorSize)
|
||||
rtvs = append(rtvs, rtv)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := img.ensureRenderTargetView(g.device); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if img.screen {
|
||||
if useStencil {
|
||||
return fmt.Errorf("directx: stencils are not available on the screen framebuffer")
|
||||
}
|
||||
|
||||
rtvBase, err := g.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtv := rtvBase
|
||||
rtv.Offset(int32(g.frameIndex), g.rtvDescriptorSize)
|
||||
rtvs = append(rtvs, rtv)
|
||||
continue
|
||||
}
|
||||
|
||||
rtvBase, err := img.rtvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rtv := rtvBase
|
||||
rtvs = append(rtvs, rtv)
|
||||
|
||||
if !useStencil || dsvPtr != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := img.ensureDepthStencilView(g.device); err != nil {
|
||||
return err
|
||||
}
|
||||
dsv, err := img.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dsvPtr = &dsv
|
||||
}
|
||||
|
||||
if !useStencil {
|
||||
g.drawCommandList.OMSetRenderTargets(rtvs, false, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
g.drawCommandList.OMSetStencilRef(0)
|
||||
g.drawCommandList.OMSetRenderTargets(rtvs, false, dsvPtr)
|
||||
g.drawCommandList.ClearDepthStencilView(*dsvPtr, _D3D12_CLEAR_FLAG_STENCIL, 0, 0, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
if shaderID == graphicsdriver.InvalidShaderID {
|
||||
return fmt.Errorf("directx: shader ID is invalid")
|
||||
}
|
||||
@ -1103,20 +1174,46 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
g.pipelineStates.releaseConstantBuffers(g.frameIndex)
|
||||
}
|
||||
|
||||
dst := g.images[dstIDs[0]] // TODO: handle array
|
||||
var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition
|
||||
if rb, ok := dst.transiteState(_D3D12_RESOURCE_STATE_RENDER_TARGET); ok {
|
||||
resourceBarriers = append(resourceBarriers, rb)
|
||||
}
|
||||
|
||||
var srcImages [graphics.ShaderSrcImageCount]*image12
|
||||
for i, srcID := range srcs {
|
||||
src := g.images[srcID]
|
||||
if src == nil {
|
||||
var dsts [graphics.ShaderDstImageCount]*image12
|
||||
var viewports [graphics.ShaderDstImageCount]_D3D12_VIEWPORT
|
||||
var targetCount int
|
||||
firstTarget := -1
|
||||
for i, id := range dstIDs {
|
||||
img := g.images[id]
|
||||
if img == nil {
|
||||
continue
|
||||
}
|
||||
srcImages[i] = src
|
||||
if rb, ok := src.transiteState(_D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); ok {
|
||||
if firstTarget == -1 {
|
||||
firstTarget = i
|
||||
}
|
||||
dsts[i] = img
|
||||
w, h := img.internalSize()
|
||||
viewports[i] = _D3D12_VIEWPORT{
|
||||
TopLeftX: 0,
|
||||
TopLeftY: 0,
|
||||
Width: float32(w),
|
||||
Height: float32(h),
|
||||
MinDepth: _D3D12_MIN_DEPTH,
|
||||
MaxDepth: _D3D12_MAX_DEPTH,
|
||||
}
|
||||
|
||||
if rb, ok := img.transiteState(_D3D12_RESOURCE_STATE_RENDER_TARGET); ok {
|
||||
resourceBarriers = append(resourceBarriers, rb)
|
||||
}
|
||||
|
||||
targetCount++
|
||||
}
|
||||
|
||||
var srcs [graphics.ShaderSrcImageCount]*image12
|
||||
for i, srcID := range srcIDs {
|
||||
img := g.images[srcID]
|
||||
if img == nil {
|
||||
continue
|
||||
}
|
||||
srcs[i] = img
|
||||
if rb, ok := img.transiteState(_D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); ok {
|
||||
resourceBarriers = append(resourceBarriers, rb)
|
||||
}
|
||||
}
|
||||
@ -1125,25 +1222,26 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
g.drawCommandList.ResourceBarrier(resourceBarriers)
|
||||
}
|
||||
|
||||
if err := dst.setAsRenderTarget(g.drawCommandList, g.device, fillRule != graphicsdriver.FillAll); err != nil {
|
||||
// If the number of targets is more than one, or if the only target is the first one, then
|
||||
// it is safe to assume that MRT is used.
|
||||
// Also, it only matters in order to specify empty targets/viewports when not all slots are
|
||||
// being filled.
|
||||
usesMRT := targetCount > 1 || firstTarget > 0
|
||||
if usesMRT {
|
||||
targetCount = graphics.ShaderDstImageCount
|
||||
}
|
||||
|
||||
g.drawCommandList.RSSetViewports(viewports[:targetCount])
|
||||
|
||||
if err := g.setAsRenderTargets(dsts[:targetCount], fillRule != graphicsdriver.FillAll); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
shader := g.shaders[shaderID]
|
||||
adjustedUniforms := adjustUniforms(shader.uniformTypes, shader.uniformOffsets, uniforms)
|
||||
|
||||
w, h := dst.internalSize()
|
||||
g.needFlushDrawCommandList = true
|
||||
g.drawCommandList.RSSetViewports([]_D3D12_VIEWPORT{
|
||||
{
|
||||
TopLeftX: 0,
|
||||
TopLeftY: 0,
|
||||
Width: float32(w),
|
||||
Height: float32(h),
|
||||
MinDepth: _D3D12_MIN_DEPTH,
|
||||
MaxDepth: _D3D12_MAX_DEPTH,
|
||||
},
|
||||
})
|
||||
|
||||
g.drawCommandList.IASetPrimitiveTopology(_D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
||||
g.drawCommandList.IASetVertexBuffers(0, []_D3D12_VERTEX_BUFFER_VIEW{
|
||||
{
|
||||
@ -1158,7 +1256,7 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
Format: _DXGI_FORMAT_R32_UINT,
|
||||
})
|
||||
|
||||
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, dst.screen, srcImages, shader, dstRegions, adjustedUniforms, blend, indexOffset, fillRule); err != nil {
|
||||
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, !usesMRT && dsts[firstTarget].screen, srcs, shader, dstRegions, adjustedUniforms, blend, indexOffset, fillRule); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -510,6 +510,90 @@ func (p *pipelineStates) newPipelineState(device *_ID3D12Device, vsh, psh *_ID3D
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
},
|
||||
},
|
||||
SampleMask: math.MaxUint32,
|
||||
@ -532,9 +616,10 @@ func (p *pipelineStates) newPipelineState(device *_ID3D12Device, vsh, psh *_ID3D
|
||||
NumElements: uint32(len(inputElementDescsForDX12)),
|
||||
},
|
||||
PrimitiveTopologyType: _D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
|
||||
NumRenderTargets: 1,
|
||||
NumRenderTargets: graphics.ShaderDstImageCount,
|
||||
RTVFormats: [8]_DXGI_FORMAT{
|
||||
rtvFormat,
|
||||
rtvFormat, rtvFormat, rtvFormat, rtvFormat,
|
||||
rtvFormat, rtvFormat, rtvFormat, rtvFormat,
|
||||
},
|
||||
DSVFormat: dsvFormat,
|
||||
SampleDesc: _DXGI_SAMPLE_DESC{
|
||||
|
Loading…
Reference in New Issue
Block a user