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:
Elias Naur
2020-12-30 16:48:22 +01:00
parent 7d24b790a2
commit bfe2d04c60
11 changed files with 400 additions and 89 deletions
+39 -16
View File
@@ -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() {
+2 -2
View File
@@ -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
View File
@@ -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())
}
+6 -2
View File
@@ -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