Dirty directx11

This commit is contained in:
Zyko 2024-04-06 14:54:32 +02:00
parent c247da0f05
commit 577664c1cb
4 changed files with 92 additions and 12 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2020 The Ebiten Authors
// Copyright 2024 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -124,7 +124,7 @@ func main() {
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("MRT (Ebitengine Demo)")
if err := ebiten.RunGameWithOptions(&Game{}, &ebiten.RunGameOptions{
GraphicsLibrary: ebiten.GraphicsLibraryOpenGL,
GraphicsLibrary: ebiten.GraphicsLibraryDirectX,
}); err != nil {
log.Fatal(err)
}

View File

@ -521,7 +521,15 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
srvs := [graphics.ShaderSrcImageCount]*_ID3D11ShaderResourceView{}
g.deviceContext.PSSetShaderResources(0, srvs[:])
dst := g.images[dstIDs[0]] // TODO: handle array
var dsts []*image11
for _, id := range dstIDs {
img := g.images[id]
if img == nil {
continue
}
dsts = append(dsts, img)
}
var srcs [graphics.ShaderSrcImageCount]*image11
for i, id := range srcIDs {
img := g.images[id]
@ -531,7 +539,7 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
srcs[i] = img
}
w, h := dst.internalSize()
w, h := dsts[0].internalSize()
g.deviceContext.RSSetViewports([]_D3D11_VIEWPORT{
{
TopLeftX: 0,
@ -543,7 +551,7 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
},
})
if err := dst.setAsRenderTarget(fillRule != graphicsdriver.FillAll); err != nil {
if err := setAsRenderTargets(dsts, fillRule != graphicsdriver.FillAll); err != nil {
return err
}

View File

@ -204,6 +204,69 @@ func (i *image11) setAsRenderTarget(useStencil bool) error {
return nil
}
func setAsRenderTargets(dsts []*image11, useStencil bool) error {
for _, i := range dsts {
if i.renderTargetView == nil {
rtv, err := i.graphics.device.CreateRenderTargetView(unsafe.Pointer(i.texture), nil)
if err != nil {
return err
}
i.renderTargetView = rtv
}
if !useStencil {
continue
}
if i.screen {
return fmt.Errorf("directx: a stencil buffer is not available for a screen image")
}
if i.stencilView == nil {
sv, err := i.graphics.device.CreateDepthStencilView(unsafe.Pointer(i.stencil), nil)
if err != nil {
return err
}
i.stencilView = sv
}
if i.stencil == nil {
w, h := i.internalSize()
s, err := i.graphics.device.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
Width: uint32(w),
Height: uint32(h),
MipLevels: 0,
ArraySize: 1,
Format: _DXGI_FORMAT_D24_UNORM_S8_UINT,
SampleDesc: _DXGI_SAMPLE_DESC{
Count: 1,
Quality: 0,
},
Usage: _D3D11_USAGE_DEFAULT,
BindFlags: uint32(_D3D11_BIND_DEPTH_STENCIL),
CPUAccessFlags: 0,
MiscFlags: 0,
}, nil)
if err != nil {
return err
}
i.stencil = s
}
}
var rtvs []*_ID3D11RenderTargetView
var dsvs []*_ID3D11DepthStencilView
for _, i := range dsts {
rtvs = append(rtvs, i.renderTargetView)
dsvs = append(dsvs, i.stencilView)
}
dsts[0].graphics.deviceContext.OMSetRenderTargets(rtvs, dsts[0].stencilView)
if useStencil {
dsts[0].graphics.deviceContext.ClearDepthStencilView(dsts[0].stencilView, uint8(_D3D11_CLEAR_STENCIL), 0, 0)
}
return nil
}
func (i *image11) getShaderResourceView() (*_ID3D11ShaderResourceView, error) {
if i.shaderResourceView == nil {
srv, err := i.graphics.device.CreateShaderResourceView(unsafe.Pointer(i.texture), nil)

View File

@ -22,6 +22,7 @@ import (
"regexp"
"strings"
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
)
@ -190,7 +191,15 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader string, offsets []i
}
if p.FragmentFunc.Block != nil && len(p.FragmentFunc.Block.Stmts) > 0 {
pslines = append(pslines, "")
pslines = append(pslines, fmt.Sprintf("float4 PSMain(Varyings %s) : SV_TARGET {", vsOut))
pslines = append(pslines, "struct PS_OUTPUT")
pslines = append(pslines, "{")
for i := 0; i < graphics.ShaderDstImageCount; i++ {
pslines = append(pslines, fmt.Sprintf("\tfloat4 Color%d: SV_Target%d;", i, i))
}
pslines = append(pslines, "};")
pslines = append(pslines, "")
pslines = append(pslines, fmt.Sprintf("PS_OUTPUT PSMain(Varyings %s) {", vsOut))
pslines = append(pslines, "\tPS_OUTPUT output;")
pslines = append(pslines, c.block(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0)...)
pslines = append(pslines, "}")
}
@ -227,6 +236,8 @@ func Compile(p *shaderir.Program) (vertexShader, pixelShader string, offsets []i
vertexShader = shaders[0]
pixelShader = shaders[1]
fmt.Println("PS:", pixelShader)
return
}
@ -353,7 +364,7 @@ func (c *compileContext) localVariableName(p *shaderir.Program, topBlock *shader
case idx < nv+1:
return fmt.Sprintf("%s.M%d", vsOut, idx-1)
default:
return fmt.Sprintf("l%d", idx-(nv+1))
return fmt.Sprintf("output.Color%d", idx-(nv+1))
}
default:
return fmt.Sprintf("l%d", idx)
@ -393,9 +404,6 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
}
var lines []string
for i := range block.LocalVars {
lines = append(lines, c.initVariable(p, topBlock, block, block.LocalVarIndexOffset+i, true, level)...)
}
var expr func(e *shaderir.Expr) string
expr = func(e *shaderir.Expr) string {
@ -502,7 +510,8 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
case shaderir.Assign:
lhs := s.Exprs[0]
rhs := s.Exprs[1]
if lhs.Type == shaderir.LocalVariable {
isOutput := strings.HasPrefix(expr(&lhs), "output.Color")
if !isOutput && lhs.Type == shaderir.LocalVariable {
if t := p.LocalVariableType(topBlock, block, lhs.Index); t.Main == shaderir.Array {
for i := 0; i < t.Length; i++ {
lines = append(lines, fmt.Sprintf("%[1]s%[2]s[%[3]d] = %[4]s[%[3]d];", idt, expr(&lhs), i, expr(&rhs)))
@ -564,7 +573,7 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
case topBlock == p.VertexFunc.Block:
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vsOut))
case len(s.Exprs) == 0:
lines = append(lines, idt+"return;")
lines = append(lines, idt+"return output;")
default:
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
}