mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
gpu: fix depth buffer on direct3d and headless opengl
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user