mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
gpu/internal,internal/gl: add support for strided texture uploads
The CPU fallback of the compute renderer needs to upload subtextures from a larger image. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+2
-2
@@ -557,9 +557,9 @@ restart:
|
||||
size := img.Bounds().Size()
|
||||
driver.UploadImage(a.tex, pos, img)
|
||||
rightPadding := image.Pt(padding, size.Y)
|
||||
a.tex.Upload(image.Pt(pos.X+size.X, pos.Y), rightPadding, g.zeros(rightPadding.X*rightPadding.Y*4))
|
||||
a.tex.Upload(image.Pt(pos.X+size.X, pos.Y), rightPadding, g.zeros(rightPadding.X*rightPadding.Y*4), 0)
|
||||
bottomPadding := image.Pt(size.X, padding)
|
||||
a.tex.Upload(image.Pt(pos.X, pos.Y+size.Y), bottomPadding, g.zeros(bottomPadding.X*bottomPadding.Y*4))
|
||||
a.tex.Upload(image.Pt(pos.X, pos.Y+size.Y), bottomPadding, g.zeros(bottomPadding.X*bottomPadding.Y*4), 0)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -556,8 +556,10 @@ 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
|
||||
func (t *Texture) Upload(offset, size image.Point, pixels []byte, stride int) {
|
||||
if stride == 0 {
|
||||
stride = size.X * 4
|
||||
}
|
||||
dst := &d3d11.BOX{
|
||||
Left: uint32(offset.X),
|
||||
Top: uint32(offset.Y),
|
||||
|
||||
@@ -167,7 +167,7 @@ type Timer interface {
|
||||
}
|
||||
|
||||
type Texture interface {
|
||||
Upload(offset, size image.Point, pixels []byte)
|
||||
Upload(offset, size image.Point, pixels []byte, stride int)
|
||||
Release()
|
||||
}
|
||||
|
||||
@@ -261,11 +261,8 @@ func flipImageY(stride, height int, pixels []byte) {
|
||||
func UploadImage(t Texture, offset image.Point, img *image.RGBA) {
|
||||
var pixels []byte
|
||||
size := img.Bounds().Size()
|
||||
if img.Stride != size.X*4 {
|
||||
panic("unsupported stride")
|
||||
}
|
||||
start := img.PixOffset(0, 0)
|
||||
end := img.PixOffset(size.X, size.Y-1)
|
||||
pixels = img.Pix[start:end]
|
||||
t.Upload(offset, size, pixels)
|
||||
t.Upload(offset, size, pixels, img.Stride)
|
||||
}
|
||||
|
||||
@@ -75,10 +75,11 @@ type glState struct {
|
||||
srcRGB, dstRGB gl.Enum
|
||||
srcA, dstA gl.Enum
|
||||
}
|
||||
depthTest bool
|
||||
clearColor [4]float32
|
||||
clearDepth float32
|
||||
viewport [4]int
|
||||
depthTest bool
|
||||
clearColor [4]float32
|
||||
clearDepth float32
|
||||
viewport [4]int
|
||||
unpack_row_length int
|
||||
}
|
||||
|
||||
type state struct {
|
||||
@@ -270,16 +271,17 @@ func (b *Backend) EndFrame() {
|
||||
|
||||
func (b *Backend) queryState() glState {
|
||||
s := glState{
|
||||
prog: gl.Program(b.funcs.GetBinding(gl.CURRENT_PROGRAM)),
|
||||
arrayBuf: gl.Buffer(b.funcs.GetBinding(gl.ARRAY_BUFFER_BINDING)),
|
||||
elemBuf: gl.Buffer(b.funcs.GetBinding(gl.ELEMENT_ARRAY_BUFFER_BINDING)),
|
||||
drawFBO: gl.Framebuffer(b.funcs.GetBinding(gl.FRAMEBUFFER_BINDING)),
|
||||
depthMask: b.funcs.GetInteger(gl.DEPTH_WRITEMASK) != gl.FALSE,
|
||||
depthTest: b.funcs.IsEnabled(gl.DEPTH_TEST),
|
||||
depthFunc: gl.Enum(b.funcs.GetInteger(gl.DEPTH_FUNC)),
|
||||
clearDepth: b.funcs.GetFloat(gl.DEPTH_CLEAR_VALUE),
|
||||
clearColor: b.funcs.GetFloat4(gl.COLOR_CLEAR_VALUE),
|
||||
viewport: b.funcs.GetInteger4(gl.VIEWPORT),
|
||||
prog: gl.Program(b.funcs.GetBinding(gl.CURRENT_PROGRAM)),
|
||||
arrayBuf: gl.Buffer(b.funcs.GetBinding(gl.ARRAY_BUFFER_BINDING)),
|
||||
elemBuf: gl.Buffer(b.funcs.GetBinding(gl.ELEMENT_ARRAY_BUFFER_BINDING)),
|
||||
drawFBO: gl.Framebuffer(b.funcs.GetBinding(gl.FRAMEBUFFER_BINDING)),
|
||||
depthMask: b.funcs.GetInteger(gl.DEPTH_WRITEMASK) != gl.FALSE,
|
||||
depthTest: b.funcs.IsEnabled(gl.DEPTH_TEST),
|
||||
depthFunc: gl.Enum(b.funcs.GetInteger(gl.DEPTH_FUNC)),
|
||||
clearDepth: b.funcs.GetFloat(gl.DEPTH_CLEAR_VALUE),
|
||||
clearColor: b.funcs.GetFloat4(gl.COLOR_CLEAR_VALUE),
|
||||
viewport: b.funcs.GetInteger4(gl.VIEWPORT),
|
||||
unpack_row_length: b.funcs.GetInteger(gl.UNPACK_ROW_LENGTH),
|
||||
}
|
||||
s.blend.enable = b.funcs.IsEnabled(gl.BLEND)
|
||||
s.blend.srcRGB = gl.Enum(b.funcs.GetInteger(gl.BLEND_SRC_RGB))
|
||||
@@ -358,6 +360,7 @@ func (b *Backend) restoreState(dst glState) {
|
||||
src.bindBuffer(f, gl.ARRAY_BUFFER, dst.arrayBuf)
|
||||
v := dst.viewport
|
||||
src.setViewport(f, v[0], v[1], v[2], v[3])
|
||||
src.pixelStorei(f, gl.UNPACK_ROW_LENGTH, dst.unpack_row_length)
|
||||
}
|
||||
|
||||
func (s *glState) setVertexAttribArray(f *gl.Functions, idx int, enabled bool) {
|
||||
@@ -559,6 +562,16 @@ func (s *glState) bindBuffer(f *gl.Functions, target gl.Enum, buf gl.Buffer) {
|
||||
f.BindBuffer(target, buf)
|
||||
}
|
||||
|
||||
func (s *glState) pixelStorei(f *gl.Functions, pname gl.Enum, val int) {
|
||||
if pname != gl.UNPACK_ROW_LENGTH {
|
||||
panic("unsupported PixelStorei pname")
|
||||
}
|
||||
if val != s.unpack_row_length {
|
||||
f.PixelStorei(pname, val)
|
||||
s.unpack_row_length = val
|
||||
}
|
||||
}
|
||||
|
||||
func (s *glState) setClearDepth(f *gl.Functions, d float32) {
|
||||
if d != s.clearDepth {
|
||||
f.ClearDepthf(d)
|
||||
@@ -1250,11 +1263,12 @@ func (t *gpuTexture) Release() {
|
||||
t.backend.glstate.deleteTexture(t.backend.funcs, t.obj)
|
||||
}
|
||||
|
||||
func (t *gpuTexture) Upload(offset, size image.Point, pixels []byte) {
|
||||
func (t *gpuTexture) Upload(offset, size image.Point, pixels []byte, stride int) {
|
||||
if min := size.X * size.Y * 4; min > len(pixels) {
|
||||
panic(fmt.Errorf("size %d larger than data %d", min, len(pixels)))
|
||||
}
|
||||
t.backend.BindTexture(0, t)
|
||||
t.backend.glstate.pixelStorei(t.backend.funcs, gl.UNPACK_ROW_LENGTH, stride/4)
|
||||
t.backend.funcs.TexSubImage2D(gl.TEXTURE_2D, 0, offset.X, offset.Y, size.X, size.Y, t.triple.format, t.triple.typ, pixels)
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ const (
|
||||
UNIFORM_BUFFER = 0x8A11
|
||||
UNIFORM_BUFFER_BINDING = 0x8A28
|
||||
UNPACK_ALIGNMENT = 0xcf5
|
||||
UNPACK_ROW_LENGTH = 0x0CF2
|
||||
UNSIGNED_BYTE = 0x1401
|
||||
UNSIGNED_SHORT = 0x1403
|
||||
VIEWPORT = 0x0BA2
|
||||
|
||||
@@ -343,7 +343,7 @@ func (f *Functions) IsEnabled(cap Enum) bool {
|
||||
func (f *Functions) LinkProgram(p Program) {
|
||||
f.Ctx.Call("linkProgram", js.Value(p))
|
||||
}
|
||||
func (f *Functions) PixelStorei(pname Enum, param int32) {
|
||||
func (f *Functions) PixelStorei(pname Enum, param int) {
|
||||
f.Ctx.Call("pixelStorei", int(pname), param)
|
||||
}
|
||||
func (f *Functions) MemoryBarrier(barriers Enum) {
|
||||
|
||||
@@ -1101,7 +1101,7 @@ func (f *Functions) LinkProgram(p Program) {
|
||||
C.glLinkProgram(&f.f, C.GLuint(p.V))
|
||||
}
|
||||
|
||||
func (f *Functions) PixelStorei(pname Enum, param int32) {
|
||||
func (f *Functions) PixelStorei(pname Enum, param int) {
|
||||
C.glPixelStorei(&f.f, C.GLenum(pname), C.GLint(param))
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ func (f *Functions) IsEnabled(cap Enum) bool {
|
||||
func (c *Functions) LinkProgram(p Program) {
|
||||
syscall.Syscall(_glLinkProgram.Addr(), 1, uintptr(p.V), 0, 0)
|
||||
}
|
||||
func (c *Functions) PixelStorei(pname Enum, param int32) {
|
||||
func (c *Functions) PixelStorei(pname Enum, param int) {
|
||||
syscall.Syscall(_glPixelStorei.Addr(), 2, uintptr(pname), uintptr(param), 0)
|
||||
}
|
||||
func (f *Functions) MemoryBarrier(barriers Enum) {
|
||||
|
||||
Reference in New Issue
Block a user