gpu: [compute] use array type for scene elements

All scene elements have a fixed size in uint32s. Model them accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-02-15 19:26:36 +01:00
parent c9a8265126
commit b5d21b209c
+68 -72
View File
@@ -101,7 +101,7 @@ type materialVertex struct {
} }
type encoder struct { type encoder struct {
scene []byte scene []sceneElem
npath int npath int
npathseg int npathseg int
} }
@@ -129,6 +129,8 @@ type config struct {
anno_alloc memAlloc anno_alloc memAlloc
} }
type sceneElem [sceneElemSize / 4]uint32
// memAlloc matches Alloc in mem.h // memAlloc matches Alloc in mem.h
type memAlloc struct { type memAlloc struct {
offset uint32 offset uint32
@@ -684,18 +686,18 @@ func (g *compute) render(tileDims image.Point) error {
} }
// Pad scene with zeroes to avoid reading garbage in elements.comp. // Pad scene with zeroes to avoid reading garbage in elements.comp.
scenePadding := partitionSize*sceneElemSize - len(g.enc.scene)%(partitionSize*sceneElemSize) scenePadding := partitionSize - len(g.enc.scene)%partitionSize
g.enc.scene = append(g.enc.scene, make([]byte, scenePadding)...) g.enc.scene = append(g.enc.scene, make([]sceneElem, scenePadding)...)
realloced := false realloced := false
if s := len(g.enc.scene); s > g.buffers.scene.size { if s := len(g.enc.scene) * sceneElemSize; s > g.buffers.scene.size {
realloced = true realloced = true
paddedCap := s * 11 / 10 paddedCap := s * 11 / 10
if err := g.buffers.scene.ensureCapacity(g.ctx, paddedCap); err != nil { if err := g.buffers.scene.ensureCapacity(g.ctx, paddedCap); err != nil {
return err return err
} }
} }
g.buffers.scene.buffer.Upload(g.enc.scene) g.buffers.scene.buffer.Upload(gunsafe.BytesView(g.enc.scene))
w, h := tileDims.X*tileWidthPx, tileDims.Y*tileHeightPx w, h := tileDims.X*tileWidthPx, tileDims.Y*tileHeightPx
if g.output.size.X < w || g.output.size.Y < h { if g.output.size.X < w || g.output.size.Y < h {
@@ -954,7 +956,7 @@ func (e *encoder) reset() {
} }
func (e *encoder) numElements() int { func (e *encoder) numElements() int {
return len(e.scene) / sceneElemSize return len(e.scene)
} }
func (e *encoder) append(e2 encoder) { func (e *encoder) append(e2 encoder) {
@@ -965,52 +967,51 @@ func (e *encoder) append(e2 encoder) {
func (e *encoder) transform(m f32.Affine2D) { func (e *encoder) transform(m f32.Affine2D) {
sx, hx, ox, hy, sy, oy := m.Elems() sx, hx, ox, hy, sy, oy := m.Elems()
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd[0:4], elemTransform) 0: elemTransform,
bo.PutUint32(cmd[4:8], math.Float32bits(sx)) 1: math.Float32bits(sx),
bo.PutUint32(cmd[8:12], math.Float32bits(hy)) 2: math.Float32bits(hy),
bo.PutUint32(cmd[12:16], math.Float32bits(hx)) 3: math.Float32bits(hx),
bo.PutUint32(cmd[16:20], math.Float32bits(sy)) 4: math.Float32bits(sy),
bo.PutUint32(cmd[20:24], math.Float32bits(ox)) 5: math.Float32bits(ox),
bo.PutUint32(cmd[24:28], math.Float32bits(oy)) 6: math.Float32bits(oy),
e.cmd(cmd) })
} }
func (e *encoder) lineWidth(width float32) { func (e *encoder) lineWidth(width float32) {
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd, elemLineWidth) 0: elemLineWidth,
bo.PutUint32(cmd[4:8], math.Float32bits(width)) 1: math.Float32bits(width),
e.cmd(cmd) })
} }
func (e *encoder) stroke(col color.RGBA) { func (e *encoder) stroke(col color.RGBA) {
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd, elemStroke) 0: elemStroke,
c := uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A) 1: uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A),
bo.PutUint32(cmd[4:8], c) })
e.cmd(cmd)
e.npath++ e.npath++
} }
func (e *encoder) beginClip(bbox f32.Rectangle) { func (e *encoder) beginClip(bbox f32.Rectangle) {
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd, elemBeginClip) 0: elemBeginClip,
bo.PutUint32(cmd[4:8], math.Float32bits(bbox.Min.X)) 1: math.Float32bits(bbox.Min.X),
bo.PutUint32(cmd[8:12], math.Float32bits(bbox.Min.Y)) 2: math.Float32bits(bbox.Min.Y),
bo.PutUint32(cmd[12:16], math.Float32bits(bbox.Max.X)) 3: math.Float32bits(bbox.Max.X),
bo.PutUint32(cmd[16:20], math.Float32bits(bbox.Max.Y)) 4: math.Float32bits(bbox.Max.Y),
e.cmd(cmd) })
e.npath++ e.npath++
} }
func (e *encoder) endClip(bbox f32.Rectangle) { func (e *encoder) endClip(bbox f32.Rectangle) {
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd, elemEndClip) 0: elemEndClip,
bo.PutUint32(cmd[4:8], math.Float32bits(bbox.Min.X)) 1: math.Float32bits(bbox.Min.X),
bo.PutUint32(cmd[8:12], math.Float32bits(bbox.Min.Y)) 2: math.Float32bits(bbox.Min.Y),
bo.PutUint32(cmd[12:16], math.Float32bits(bbox.Max.X)) 3: math.Float32bits(bbox.Max.X),
bo.PutUint32(cmd[16:20], math.Float32bits(bbox.Max.Y)) 4: math.Float32bits(bbox.Max.Y),
e.cmd(cmd) })
e.npath++ e.npath++
} }
@@ -1024,57 +1025,52 @@ func (e *encoder) rect(r f32.Rectangle, stroke bool) {
} }
func (e *encoder) fill(col color.RGBA) { func (e *encoder) fill(col color.RGBA) {
cmd := make([]byte, sceneElemSize) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd, elemFill) 0: elemFill,
c := uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A) 1: uint32(col.R)<<24 | uint32(col.G)<<16 | uint32(col.B)<<8 | uint32(col.A),
bo.PutUint32(cmd[4:8], c) })
e.cmd(cmd)
e.npath++ e.npath++
} }
func (e *encoder) fillImage(index int, offset image.Point) { func (e *encoder) fillImage(index int, offset image.Point) {
cmd := make([]byte, sceneElemSize)
bo.PutUint32(cmd, elemFillImage)
x := int16(offset.X) x := int16(offset.X)
y := int16(offset.Y) y := int16(offset.Y)
bo.PutUint32(cmd[4:8], uint32(index)) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd[8:12], uint32(uint16(x))|uint32(uint16(y))<<16) 0: elemFillImage,
e.cmd(cmd) 1: uint32(index),
2: uint32(uint16(x)) | uint32(uint16(y))<<16,
})
e.npath++ e.npath++
} }
func (e *encoder) line(start, end f32.Point, stroke bool) { func (e *encoder) line(start, end f32.Point, stroke bool) {
cmd := make([]byte, sceneElemSize) tag := uint32(elemFillLine)
if stroke { if stroke {
bo.PutUint32(cmd, elemStrokeLine) tag = elemStrokeLine
} else {
bo.PutUint32(cmd, elemFillLine)
} }
bo.PutUint32(cmd[4:8], math.Float32bits(start.X)) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd[8:12], math.Float32bits(start.Y)) 0: tag,
bo.PutUint32(cmd[12:16], math.Float32bits(end.X)) 1: math.Float32bits(start.X),
bo.PutUint32(cmd[16:20], math.Float32bits(end.Y)) 2: math.Float32bits(start.Y),
e.cmd(cmd) 3: math.Float32bits(end.X),
4: math.Float32bits(end.Y),
})
e.npathseg++ e.npathseg++
} }
func (e *encoder) quad(start, ctrl, end f32.Point, stroke bool) { func (e *encoder) quad(start, ctrl, end f32.Point, stroke bool) {
cmd := make([]byte, sceneElemSize) tag := uint32(elemFillQuad)
if stroke { if stroke {
bo.PutUint32(cmd, elemStrokeQuad) tag = elemStrokeQuad
} else {
bo.PutUint32(cmd, elemFillQuad)
} }
bo.PutUint32(cmd[4:8], math.Float32bits(start.X)) e.scene = append(e.scene, sceneElem{
bo.PutUint32(cmd[8:12], math.Float32bits(start.Y)) 0: tag,
bo.PutUint32(cmd[12:16], math.Float32bits(ctrl.X)) 1: math.Float32bits(start.X),
bo.PutUint32(cmd[16:20], math.Float32bits(ctrl.Y)) 2: math.Float32bits(start.Y),
bo.PutUint32(cmd[20:24], math.Float32bits(end.X)) 3: math.Float32bits(ctrl.X),
bo.PutUint32(cmd[24:28], math.Float32bits(end.Y)) 4: math.Float32bits(ctrl.Y),
e.cmd(cmd) 5: math.Float32bits(end.X),
6: math.Float32bits(end.Y),
})
e.npathseg++ e.npathseg++
} }
func (e *encoder) cmd(cmd []byte) {
e.scene = append(e.scene, cmd...)
}