mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-04 17:05:38 +00:00
gpu: fold buffer clearing into framebuffer bind
In Metal, clearing a framebuffer is most efficiently done during bind. Modify our driver accordingly. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -432,11 +432,6 @@ func (b *Backend) NewFragmentShader(src shader.Sources) (driver.FragmentShader,
|
||||
return &FragmentShader{b, fs}, nil
|
||||
}
|
||||
|
||||
func (b *Backend) Clear(colr, colg, colb, cola float32) {
|
||||
b.clearColor = [4]float32{colr, colg, colb, cola}
|
||||
b.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor)
|
||||
}
|
||||
|
||||
func (b *Backend) Viewport(x, y, width, height int) {
|
||||
b.viewport = d3d11.VIEWPORT{
|
||||
TopLeftX: float32(x),
|
||||
@@ -643,9 +638,14 @@ func (f *Framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backend) BindFramebuffer(fbo driver.Framebuffer) {
|
||||
func (b *Backend) BindFramebuffer(fbo driver.Framebuffer, d driver.LoadDesc) {
|
||||
b.fbo = fbo.(*Framebuffer)
|
||||
b.ctx.OMSetRenderTargets(b.fbo.renderTarget, nil)
|
||||
if d.Action == driver.LoadActionClear {
|
||||
c := d.ClearColor
|
||||
b.clearColor = [4]float32{c.R, c.G, c.B, c.A}
|
||||
b.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Framebuffer) Invalidate() {
|
||||
|
||||
@@ -30,14 +30,13 @@ type Device interface {
|
||||
NewFragmentShader(src shader.Sources) (FragmentShader, error)
|
||||
NewPipeline(desc PipelineDesc) (Pipeline, error)
|
||||
|
||||
Clear(r, g, b, a float32)
|
||||
Viewport(x, y, width, height int)
|
||||
DrawArrays(mode DrawMode, off, count int)
|
||||
DrawElements(mode DrawMode, off, count int)
|
||||
|
||||
BindProgram(p Program)
|
||||
BindPipeline(p Pipeline)
|
||||
BindFramebuffer(f Framebuffer)
|
||||
BindFramebuffer(f Framebuffer, a LoadDesc)
|
||||
BindTexture(unit int, t Texture)
|
||||
BindVertexBuffer(b Buffer, stride, offset int)
|
||||
BindIndexBuffer(b Buffer)
|
||||
@@ -53,6 +52,16 @@ type Device interface {
|
||||
Release()
|
||||
}
|
||||
|
||||
type LoadDesc struct {
|
||||
Action LoadAction
|
||||
ClearColor struct {
|
||||
R float32
|
||||
G float32
|
||||
B float32
|
||||
A float32
|
||||
}
|
||||
}
|
||||
|
||||
type Pipeline interface {
|
||||
Release()
|
||||
}
|
||||
@@ -89,6 +98,8 @@ type TextureFormat uint8
|
||||
|
||||
type BufferBinding uint8
|
||||
|
||||
type LoadAction uint8
|
||||
|
||||
type Features uint
|
||||
|
||||
type Caps struct {
|
||||
@@ -119,7 +130,6 @@ type Buffer interface {
|
||||
|
||||
type Framebuffer interface {
|
||||
RenderTarget
|
||||
Invalidate()
|
||||
Release()
|
||||
ReadPixels(src image.Rectangle, pixels []byte) error
|
||||
}
|
||||
@@ -182,6 +192,12 @@ const (
|
||||
BlendFactorDstColor
|
||||
)
|
||||
|
||||
const (
|
||||
LoadActionKeep LoadAction = iota
|
||||
LoadActionClear
|
||||
LoadActionInvalidate
|
||||
)
|
||||
|
||||
var ErrContentLost = errors.New("buffer content lost")
|
||||
|
||||
func (f Features) Has(feats Features) bool {
|
||||
|
||||
@@ -268,7 +268,7 @@ func (b *Backend) BeginFrame(target driver.RenderTarget, clear bool, viewport im
|
||||
}
|
||||
b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, renderFBO)
|
||||
if b.sRGBFBO != nil && !clear {
|
||||
b.Clear(0, 0, 0, 0)
|
||||
b.clearOutput(0, 0, 0, 0)
|
||||
}
|
||||
return &framebuffer{backend: b, obj: renderFBO, foreign: true}
|
||||
}
|
||||
@@ -652,7 +652,7 @@ func (b *Backend) NewFramebuffer(tex driver.Texture) (driver.Framebuffer, error)
|
||||
gltex := tex.(*texture)
|
||||
fb := b.funcs.CreateFramebuffer()
|
||||
fbo := &framebuffer{backend: b, obj: fb}
|
||||
b.BindFramebuffer(fbo)
|
||||
b.BindFramebuffer(fbo, driver.LoadDesc{})
|
||||
if err := glErr(b.funcs); err != nil {
|
||||
fbo.Release()
|
||||
return nil, err
|
||||
@@ -849,7 +849,7 @@ func (b *Backend) Viewport(x, y, width, height int) {
|
||||
b.glstate.setViewport(b.funcs, x, y, width, height)
|
||||
}
|
||||
|
||||
func (b *Backend) Clear(colR, colG, colB, colA float32) {
|
||||
func (b *Backend) clearOutput(colR, colG, colB, colA float32) {
|
||||
b.glstate.setClearColor(b.funcs, colR, colG, colB, colA)
|
||||
b.funcs.Clear(gl.COLOR_BUFFER_BIT)
|
||||
}
|
||||
@@ -1179,7 +1179,7 @@ func (b *Backend) BlitFramebuffer(dst, src driver.Framebuffer, srect, drect imag
|
||||
|
||||
func (f *framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error {
|
||||
glErr(f.backend.funcs)
|
||||
f.backend.BindFramebuffer(f)
|
||||
f.backend.BindFramebuffer(f, driver.LoadDesc{})
|
||||
if len(pixels) < src.Dx()*src.Dy()*4 {
|
||||
return errors.New("unexpected RGBA size")
|
||||
}
|
||||
@@ -1195,13 +1195,15 @@ func (b *Backend) BindPipeline(pl driver.Pipeline) {
|
||||
b.BlendFunc(p.blend.SrcFactor, p.blend.DstFactor)
|
||||
}
|
||||
|
||||
func (b *Backend) BindFramebuffer(fbo driver.Framebuffer) {
|
||||
func (b *Backend) BindFramebuffer(fbo driver.Framebuffer, desc driver.LoadDesc) {
|
||||
b.glstate.bindFramebuffer(b.funcs, gl.FRAMEBUFFER, fbo.(*framebuffer).obj)
|
||||
}
|
||||
|
||||
func (f *framebuffer) Invalidate() {
|
||||
f.backend.BindFramebuffer(f)
|
||||
f.backend.funcs.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
|
||||
switch desc.Action {
|
||||
case driver.LoadActionClear:
|
||||
c := desc.ClearColor
|
||||
b.clearOutput(c.R, c.G, c.B, c.A)
|
||||
case driver.LoadActionInvalidate:
|
||||
b.funcs.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *framebuffer) Release() {
|
||||
|
||||
Reference in New Issue
Block a user