mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-03 08:25:34 +00:00
gpu,app,internal/glimpl: update GL backend for the compute renderer
Modern graphics APIs have immutable objects, with mutable data. For example, a texture's dimensions are immutable, while the texture contents is not. Change the GPU API abstraction to match. Clearing a Texture is convenient to do with a plain []byte. Generalize Texture.Upload to take a plain byte slice and introduce a helper function for uploading *image.RGBA data. Add TextureFormatRGBA8 a format for the linear RGB colorspace. Add OpenGL ES 3.1 functions for compute programs. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -121,12 +121,7 @@ func NewDevice() (*Device, error) {
|
||||
_IUnknownRelease(unsafe.Pointer(d3dctx), d3dctx.vtbl.Release)
|
||||
return nil, fmt.Errorf("d3d11: feature level too low: %d", featLvl)
|
||||
}
|
||||
floatFormat, ok := detectFloatFormat(d3ddev)
|
||||
if !ok {
|
||||
_IUnknownRelease(unsafe.Pointer(d3ddev), d3ddev.vtbl.Release)
|
||||
_IUnknownRelease(unsafe.Pointer(d3dctx), d3dctx.vtbl.Release)
|
||||
return nil, fmt.Errorf("d3d11: no available floating point formats")
|
||||
}
|
||||
floatFormat, _ := detectFloatFormat(d3ddev)
|
||||
dev.floatFormat = floatFormat
|
||||
dev.depthStates = make(map[depthState]*_ID3D11DepthStencilState)
|
||||
dev.blendStates = make(map[blendState]*_ID3D11BlendState)
|
||||
@@ -253,6 +248,9 @@ func NewBackend(d *Device) (*Backend, error) {
|
||||
caps := backend.Caps{
|
||||
MaxTextureSize: 2048, // 9.1 maximum
|
||||
}
|
||||
if d.floatFormat != 0 {
|
||||
caps.Features |= backend.FeatureFloatRenderTargets
|
||||
}
|
||||
switch {
|
||||
case d.featLvl >= _D3D_FEATURE_LEVEL_11_0:
|
||||
caps.MaxTextureSize = 16384
|
||||
@@ -524,6 +522,10 @@ func (b *Backend) NewImmutableBuffer(typ backend.BufferBinding, data []byte) (ba
|
||||
return &Buffer{backend: b, buf: buf, bind: bind, immutable: true}, nil
|
||||
}
|
||||
|
||||
func (b *Backend) NewComputeProgram(shader backend.ShaderSources) (backend.Program, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *Backend) NewProgram(vertexShader, fragmentShader backend.ShaderSources) (backend.Program, error) {
|
||||
vs, err := b.dev.dev.CreateVertexShader(vertexShader.HLSL)
|
||||
if err != nil {
|
||||
@@ -667,17 +669,30 @@ func (b *Backend) BlendFunc(sfactor, dfactor backend.BlendFactor) {
|
||||
b.blendState.dfactor = dfactor
|
||||
}
|
||||
|
||||
func (t *Texture) Upload(img *image.RGBA) {
|
||||
b := img.Bounds()
|
||||
w := b.Dx()
|
||||
if img.Stride != w*4 {
|
||||
panic("unsupported stride")
|
||||
func (b *Backend) BindImageTexture(unit int, tex backend.Texture, access backend.AccessBits, f backend.TextureFormat) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *Backend) MemoryBarrier() {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *Backend) DispatchCompute(x, y, z int) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (t *Texture) Upload(offset, size image.Point, pixels []byte) {
|
||||
stride := size.X * 4
|
||||
dst := &_D3D11_BOX{
|
||||
left: uint32(offset.X),
|
||||
top: uint32(offset.Y),
|
||||
right: uint32(offset.X + size.X),
|
||||
bottom: uint32(offset.Y + size.Y),
|
||||
front: 0,
|
||||
back: 1,
|
||||
}
|
||||
start := (b.Min.X + b.Min.Y*w) * 4
|
||||
end := (b.Max.X + (b.Max.Y-1)*w) * 4
|
||||
pixels := img.Pix[start:end]
|
||||
res := (*_ID3D11Resource)(unsafe.Pointer(t.tex))
|
||||
t.backend.dev.ctx.UpdateSubresource(res, uint32(img.Stride), uint32(len(pixels)), pixels)
|
||||
t.backend.dev.ctx.UpdateSubresource(res, dst, uint32(stride), uint32(len(pixels)), pixels)
|
||||
}
|
||||
|
||||
func (t *Texture) Release() {
|
||||
@@ -710,6 +725,10 @@ func (p *Program) Release() {
|
||||
p.frag.shader = nil
|
||||
}
|
||||
|
||||
func (p *Program) SetStorageBuffer(binding int, buffer backend.Buffer) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (p *Program) SetVertexUniforms(buf backend.Buffer) {
|
||||
p.vert.uniforms = buf.(*Buffer)
|
||||
}
|
||||
@@ -726,8 +745,12 @@ func (b *Backend) BindIndexBuffer(buf backend.Buffer) {
|
||||
b.dev.ctx.IASetIndexBuffer(buf.(*Buffer).buf, _DXGI_FORMAT_R16_UINT, 0)
|
||||
}
|
||||
|
||||
func (b *Buffer) Download(data []byte) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *Buffer) Upload(data []byte) {
|
||||
b.backend.dev.ctx.UpdateSubresource((*_ID3D11Resource)(unsafe.Pointer(b.buf)), 0, 0, data)
|
||||
b.backend.dev.ctx.UpdateSubresource((*_ID3D11Resource)(unsafe.Pointer(b.buf)), nil, 0, 0, data)
|
||||
}
|
||||
|
||||
func (b *Buffer) Release() {
|
||||
|
||||
@@ -1127,14 +1127,14 @@ func (c *_ID3D11DeviceContext) PSSetShader(s *_ID3D11PixelShader) {
|
||||
)
|
||||
}
|
||||
|
||||
func (c *_ID3D11DeviceContext) UpdateSubresource(res *_ID3D11Resource, rowPitch, depthPitch uint32, data []byte) {
|
||||
func (c *_ID3D11DeviceContext) UpdateSubresource(res *_ID3D11Resource, dstBox *_D3D11_BOX, rowPitch, depthPitch uint32, data []byte) {
|
||||
syscall.Syscall9(
|
||||
c.vtbl.UpdateSubresource,
|
||||
7,
|
||||
uintptr(unsafe.Pointer(c)),
|
||||
uintptr(unsafe.Pointer(res)),
|
||||
0, // DstSubresource
|
||||
0, // pDstBox
|
||||
uintptr(unsafe.Pointer(dstBox)),
|
||||
uintptr(unsafe.Pointer(&data[0])),
|
||||
uintptr(rowPitch),
|
||||
uintptr(depthPitch),
|
||||
|
||||
+11
-11
@@ -71,14 +71,14 @@ func (s *FBO) Blit() {
|
||||
s.c.Uniform1i(s.c.GetUniformLocation(prog, "tex"), 0)
|
||||
s.quad = s.c.CreateBuffer()
|
||||
s.c.BindBuffer(glimpl.ARRAY_BUFFER, s.quad)
|
||||
s.c.BufferData(glimpl.ARRAY_BUFFER,
|
||||
unsafe.BytesView([]float32{
|
||||
-1, +1, 0, 1,
|
||||
+1, +1, 1, 1,
|
||||
-1, -1, 0, 0,
|
||||
+1, -1, 1, 0,
|
||||
}),
|
||||
glimpl.STATIC_DRAW)
|
||||
coords := unsafe.BytesView([]float32{
|
||||
-1, +1, 0, 1,
|
||||
+1, +1, 1, 1,
|
||||
-1, -1, 0, 0,
|
||||
+1, -1, 1, 0,
|
||||
})
|
||||
s.c.BufferData(glimpl.ARRAY_BUFFER, len(coords), glimpl.STATIC_DRAW)
|
||||
s.c.BufferSubData(glimpl.ARRAY_BUFFER, 0, coords)
|
||||
s.blitted = true
|
||||
}
|
||||
s.c.BindFramebuffer(glimpl.FRAMEBUFFER, glimpl.Framebuffer{})
|
||||
@@ -112,9 +112,9 @@ func (s *FBO) Refresh(w, h int) error {
|
||||
}
|
||||
s.c.BindTexture(glimpl.TEXTURE_2D, s.colorTex)
|
||||
if s.gl3 {
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.SRGB8_ALPHA8, w, h, glimpl.RGBA, glimpl.UNSIGNED_BYTE, nil)
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.SRGB8_ALPHA8, w, h, glimpl.RGBA, glimpl.UNSIGNED_BYTE)
|
||||
} else /* EXT_sRGB */ {
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.SRGB_ALPHA_EXT, w, h, glimpl.SRGB_ALPHA_EXT, glimpl.UNSIGNED_BYTE, nil)
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.SRGB_ALPHA_EXT, w, h, glimpl.SRGB_ALPHA_EXT, glimpl.UNSIGNED_BYTE)
|
||||
}
|
||||
currentRB := glimpl.Renderbuffer(s.c.GetBinding(glimpl.RENDERBUFFER_BINDING))
|
||||
s.c.BindRenderbuffer(glimpl.RENDERBUFFER, s.depthBuffer)
|
||||
@@ -136,7 +136,7 @@ func (s *FBO) Refresh(w, h int) error {
|
||||
var pixel [4]byte
|
||||
s.c.ReadPixels(0, 0, 1, 1, glimpl.RGBA, glimpl.UNSIGNED_BYTE, pixel[:])
|
||||
if pixel[0] == 128 { // Correct sRGB color value is ~188
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.RGBA, w, h, glimpl.RGBA, glimpl.UNSIGNED_BYTE, nil)
|
||||
s.c.TexImage2D(glimpl.TEXTURE_2D, 0, glimpl.RGBA, w, h, glimpl.RGBA, glimpl.UNSIGNED_BYTE)
|
||||
if st := s.c.CheckFramebufferStatus(glimpl.FRAMEBUFFER); st != glimpl.FRAMEBUFFER_COMPLETE {
|
||||
return fmt.Errorf("fallback RGBA framebuffer incomplete (%dx%d), status: %#x error: %x", s.width, s.height, st, s.c.GetError())
|
||||
}
|
||||
|
||||
@@ -94,8 +94,12 @@ func (c *d3d11Context) Release() {
|
||||
if c.fbo != nil {
|
||||
c.fbo.Release()
|
||||
}
|
||||
c.swchain.Release()
|
||||
c.Device.Release()
|
||||
if c.swchain != nil {
|
||||
c.swchain.Release()
|
||||
}
|
||||
if c.Device != nil {
|
||||
c.Device.Release()
|
||||
}
|
||||
c.fbo = nil
|
||||
c.swchain = nil
|
||||
c.Device = nil
|
||||
|
||||
Reference in New Issue
Block a user