gpu: fix depth buffer on direct3d and headless opengl

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-03-11 16:36:08 +01:00
parent 61529c2cb6
commit 7024a0e691
5 changed files with 103 additions and 27 deletions
+41
View File
@@ -98,6 +98,47 @@ func TestClipping(t *testing.T) {
}
}
func TestDepth(t *testing.T) {
w, release := newTestWindow(t)
defer release()
var ops op.Ops
blue := color.RGBA{B: 0xFF, A: 0xFF}
paint.ColorOp{Color: blue}.Add(&ops)
paint.PaintOp{Rect: f32.Rectangle{
Max: f32.Point{X: 50, Y: 100},
}}.Add(&ops)
red := color.RGBA{R: 0xFF, A: 0xFF}
paint.ColorOp{Color: red}.Add(&ops)
paint.PaintOp{Rect: f32.Rectangle{
Max: f32.Point{X: 100, Y: 50},
}}.Add(&ops)
w.Frame(&ops)
img, err := w.Screenshot()
if err != nil {
t.Fatal(err)
}
if *dumpImages {
if err := saveImage("depth.png", img); err != nil {
t.Fatal(err)
}
}
tests := []struct {
x, y int
color color.RGBA
}{
{25, 25, red},
{75, 25, red},
{25, 75, blue},
}
for _, test := range tests {
if got := img.RGBAAt(test.x, test.y); got != test.color {
t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, test.color)
}
}
}
func newTestWindow(t *testing.T) (*Window, func()) {
t.Helper()
sz := image.Point{X: 800, Y: 600}
+45 -27
View File
@@ -193,6 +193,10 @@ func (s *SwapChain) Framebuffer(d *Device) (*Framebuffer, error) {
if s.fbo.renderTarget != nil {
return s.fbo, nil
}
desc, err := s.swchain.GetDesc()
if err != nil {
return nil, err
}
backBuffer, err := s.swchain.GetBuffer(0, &_IID_ID3D11Texture2D)
if err != nil {
return nil, err
@@ -203,7 +207,13 @@ func (s *SwapChain) Framebuffer(d *Device) (*Framebuffer, error) {
if err != nil {
return nil, err
}
depthView, err := createDepthView(d.dev, int(desc.BufferDesc.Width), int(desc.BufferDesc.Height), 24)
if err != nil {
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
return nil, err
}
s.fbo.renderTarget = renderTarget
s.fbo.depthView = depthView
s.fbo.dev = d
return s.fbo, nil
}
@@ -255,6 +265,8 @@ func NewBackend(d *Device) (*Backend, error) {
FillMode: _D3D11_FILL_SOLID,
DepthClipEnable: 1,
})
// Enable depth mask to match OpenGL.
b.depthState.mask = true
if err != nil {
return nil, err
}
@@ -359,8 +371,10 @@ func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, mi
func (b *Backend) CurrentFramebuffer() backend.Framebuffer {
renderTarget := b.dev.ctx.OMGetRenderTargets()
// Assume someone else is holding on to it.
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
if renderTarget != nil {
// Assume someone else is holding on to it.
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
}
if renderTarget == b.fbo.renderTarget {
return b.fbo
}
@@ -379,30 +393,7 @@ func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Fr
}
fbo := &Framebuffer{dev: b.dev, format: d3dtex.format, resource: resource, renderTarget: renderTarget}
if depthBits > 0 {
depthTex, err := b.dev.dev.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
Width: uint32(d3dtex.width),
Height: uint32(d3dtex.height),
MipLevels: 1,
ArraySize: 1,
Format: _DXGI_FORMAT_D24_UNORM_S8_UINT,
SampleDesc: _DXGI_SAMPLE_DESC{
Count: 1,
Quality: 0,
},
BindFlags: _D3D11_BIND_DEPTH_STENCIL,
})
if err != nil {
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
return nil, err
}
depthView, err := b.dev.dev.CreateDepthStencilViewTEX2D(
(*_ID3D11Resource)(unsafe.Pointer(depthTex)),
&_D3D11_DEPTH_STENCIL_VIEW_DESC_TEX2D{
Format: _DXGI_FORMAT_D24_UNORM_S8_UINT,
ViewDimension: _D3D11_DSV_DIMENSION_TEXTURE2D,
},
)
_IUnknownRelease(unsafe.Pointer(depthTex), depthTex.vtbl.Release)
depthView, err := createDepthView(b.dev.dev, d3dtex.width, d3dtex.height, depthBits)
if err != nil {
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
return nil, err
@@ -412,6 +403,33 @@ func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Fr
return fbo, nil
}
func createDepthView(d *_ID3D11Device, width, height, depthBits int) (*_ID3D11DepthStencilView, error) {
depthTex, err := d.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
Width: uint32(width),
Height: uint32(height),
MipLevels: 1,
ArraySize: 1,
Format: _DXGI_FORMAT_D24_UNORM_S8_UINT,
SampleDesc: _DXGI_SAMPLE_DESC{
Count: 1,
Quality: 0,
},
BindFlags: _D3D11_BIND_DEPTH_STENCIL,
})
if err != nil {
return nil, err
}
depthView, err := d.CreateDepthStencilViewTEX2D(
(*_ID3D11Resource)(unsafe.Pointer(depthTex)),
&_D3D11_DEPTH_STENCIL_VIEW_DESC_TEX2D{
Format: _DXGI_FORMAT_D24_UNORM_S8_UINT,
ViewDimension: _D3D11_DSV_DIMENSION_TEXTURE2D,
},
)
_IUnknownRelease(unsafe.Pointer(depthTex), depthTex.vtbl.Release)
return depthView, err
}
func (b *Backend) NewInputLayout(vertexShader backend.ShaderSources, layout []backend.InputDesc) (backend.InputLayout, error) {
if len(vertexShader.Inputs) != len(layout) {
return nil, fmt.Errorf("NewInputLayout: got %d inputs, expected %d", len(layout), len(vertexShader.Inputs))
@@ -583,7 +601,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
if b.depthState.enable {
desc.DepthEnable = 1
}
if !b.depthState.mask {
if b.depthState.mask {
desc.DepthWriteMask = _D3D11_DEPTH_WRITE_MASK_ALL
}
switch b.depthState.fn {
+15
View File
@@ -912,6 +912,21 @@ func (d *_ID3D11Device) CreateDepthStencilState(desc *_D3D11_DEPTH_STENCIL_DESC)
return state, nil
}
func (s *_IDXGISwapChain) GetDesc() (_DXGI_SWAP_CHAIN_DESC, error) {
var desc _DXGI_SWAP_CHAIN_DESC
r, _, _ := syscall.Syscall(
s.vtbl.GetDesc,
2,
uintptr(unsafe.Pointer(s)),
uintptr(unsafe.Pointer(&desc)),
0,
)
if r != 0 {
return _DXGI_SWAP_CHAIN_DESC{}, ErrorCode{Name: "IDXGISwapChainGetDesc", Code: uint32(r)}
}
return desc, nil
}
func (s *_IDXGISwapChain) ResizeBuffers(buffers, width, height, newFormat, flags uint32) error {
r, _, _ := syscall.Syscall6(
s.vtbl.ResizeBuffers,
+1
View File
@@ -194,6 +194,7 @@ func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Fr
depthBuf := b.funcs.CreateRenderbuffer()
b.funcs.BindRenderbuffer(RENDERBUFFER, depthBuf)
b.funcs.RenderbufferStorage(RENDERBUFFER, size, gltex.width, gltex.height)
b.funcs.FramebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER, depthBuf)
fbo.depthBuf = depthBuf
fbo.hasDepth = true
if err := glErr(b.funcs); err != nil {
+1
View File
@@ -129,6 +129,7 @@ type Functions interface {
EnableVertexAttribArray(a Attrib)
EndQuery(target Enum)
FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int)
FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer)
GetBinding(pname Enum) Object
GetError() Enum
GetInteger(pname Enum) int