mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
gpu,gpu/internal: move vertex buffer stride to pipeline state
Metal needs the vertex stride at pipeline creation. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+14
-8
@@ -422,9 +422,12 @@ func newCompute(ctx driver.Device) (*compute, error) {
|
|||||||
pipe, err := ctx.NewPipeline(driver.PipelineDesc{
|
pipe, err := ctx.NewPipeline(driver.PipelineDesc{
|
||||||
VertexShader: copyVert,
|
VertexShader: copyVert,
|
||||||
FragmentShader: copyFrag,
|
FragmentShader: copyFrag,
|
||||||
VertexLayout: []driver.InputDesc{
|
VertexLayout: driver.VertexLayout{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
Inputs: []driver.InputDesc{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
||||||
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
||||||
|
},
|
||||||
|
Stride: int(unsafe.Sizeof(g.output.layerVertices[0])),
|
||||||
},
|
},
|
||||||
PixelFormat: driver.TextureFormatOutput,
|
PixelFormat: driver.TextureFormatOutput,
|
||||||
BlendDesc: driver.BlendDesc{
|
BlendDesc: driver.BlendDesc{
|
||||||
@@ -457,9 +460,12 @@ func newCompute(ctx driver.Device) (*compute, error) {
|
|||||||
pipe, err = ctx.NewPipeline(driver.PipelineDesc{
|
pipe, err = ctx.NewPipeline(driver.PipelineDesc{
|
||||||
VertexShader: materialVert,
|
VertexShader: materialVert,
|
||||||
FragmentShader: materialFrag,
|
FragmentShader: materialFrag,
|
||||||
VertexLayout: []driver.InputDesc{
|
VertexLayout: driver.VertexLayout{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
Inputs: []driver.InputDesc{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
||||||
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
||||||
|
},
|
||||||
|
Stride: int(unsafe.Sizeof(g.materials.quads[0])),
|
||||||
},
|
},
|
||||||
PixelFormat: driver.TextureFormatRGBA8,
|
PixelFormat: driver.TextureFormatRGBA8,
|
||||||
})
|
})
|
||||||
@@ -817,7 +823,7 @@ func (g *compute) blitLayers(viewport image.Point) {
|
|||||||
vertexData := byteslice.Slice(g.output.layerVertices)
|
vertexData := byteslice.Slice(g.output.layerVertices)
|
||||||
g.output.buffer.ensureCapacity(false, g.ctx, driver.BufferBindingVertices, len(vertexData))
|
g.output.buffer.ensureCapacity(false, g.ctx, driver.BufferBindingVertices, len(vertexData))
|
||||||
g.output.buffer.buffer.Upload(vertexData)
|
g.output.buffer.buffer.Upload(vertexData)
|
||||||
g.ctx.BindVertexBuffer(g.output.buffer.buffer, int(unsafe.Sizeof(g.output.layerVertices[0])), 0)
|
g.ctx.BindVertexBuffer(g.output.buffer.buffer, 0)
|
||||||
g.ctx.BindTexture(0, atlas.image)
|
g.ctx.BindTexture(0, atlas.image)
|
||||||
g.ctx.DrawArrays(driver.DrawModeTriangles, 0, len(g.output.layerVertices))
|
g.ctx.DrawArrays(driver.DrawModeTriangles, 0, len(g.output.layerVertices))
|
||||||
}
|
}
|
||||||
@@ -931,7 +937,7 @@ restart:
|
|||||||
g.ctx.BindFramebuffer(m.fbo, d)
|
g.ctx.BindFramebuffer(m.fbo, d)
|
||||||
g.ctx.Viewport(0, 0, texSize, texSize)
|
g.ctx.Viewport(0, 0, texSize, texSize)
|
||||||
g.ctx.BindPipeline(m.pipeline)
|
g.ctx.BindPipeline(m.pipeline)
|
||||||
g.ctx.BindVertexBuffer(m.buffer.buffer, int(unsafe.Sizeof(m.quads[0])), 0)
|
g.ctx.BindVertexBuffer(m.buffer.buffer, 0)
|
||||||
g.ctx.DrawArrays(driver.DrawModeTriangles, 0, len(m.quads))
|
g.ctx.DrawArrays(driver.DrawModeTriangles, 0, len(m.quads))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -580,9 +580,12 @@ func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader.
|
|||||||
SrcFactor: driver.BlendFactorOne,
|
SrcFactor: driver.BlendFactorOne,
|
||||||
DstFactor: driver.BlendFactorOneMinusSrcAlpha,
|
DstFactor: driver.BlendFactorOneMinusSrcAlpha,
|
||||||
}
|
}
|
||||||
layout := []driver.InputDesc{
|
layout := driver.VertexLayout{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
Inputs: []driver.InputDesc{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
||||||
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
||||||
|
},
|
||||||
|
Stride: 4 * 4,
|
||||||
}
|
}
|
||||||
vsh, err := b.NewVertexShader(vsSrc)
|
vsh, err := b.NewVertexShader(vsSrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -702,7 +705,7 @@ func (r *renderer) intersect(ops []imageOp) {
|
|||||||
}
|
}
|
||||||
fbo := -1
|
fbo := -1
|
||||||
r.pather.stenciler.beginIntersect(r.intersections.sizes)
|
r.pather.stenciler.beginIntersect(r.intersections.sizes)
|
||||||
r.ctx.BindVertexBuffer(r.blitter.quadVerts, 4*4, 0)
|
r.ctx.BindVertexBuffer(r.blitter.quadVerts, 0)
|
||||||
for _, img := range ops {
|
for _, img := range ops {
|
||||||
if img.clipType != clipTypeIntersection {
|
if img.clipType != clipTypeIntersection {
|
||||||
continue
|
continue
|
||||||
@@ -1093,7 +1096,7 @@ func (d *drawState) materialFor(rect f32.Rectangle, off f32.Point, partTrans f32
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *renderer) drawOps(cache *resourceCache, ops []imageOp) {
|
func (r *renderer) drawOps(cache *resourceCache, ops []imageOp) {
|
||||||
r.ctx.BindVertexBuffer(r.blitter.quadVerts, 4*4, 0)
|
r.ctx.BindVertexBuffer(r.blitter.quadVerts, 0)
|
||||||
var coverTex driver.Texture
|
var coverTex driver.Texture
|
||||||
for _, img := range ops {
|
for _, img := range ops {
|
||||||
m := img.material
|
m := img.material
|
||||||
|
|||||||
@@ -77,12 +77,15 @@ func TestInputShader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer vsh.Release()
|
defer vsh.Release()
|
||||||
defer fsh.Release()
|
defer fsh.Release()
|
||||||
layout := []driver.InputDesc{
|
layout := driver.VertexLayout{
|
||||||
{
|
Inputs: []driver.InputDesc{
|
||||||
Type: shader.DataTypeFloat,
|
{
|
||||||
Size: 4,
|
Type: shader.DataTypeFloat,
|
||||||
Offset: 0,
|
Size: 4,
|
||||||
|
Offset: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
Stride: 4 * 4,
|
||||||
}
|
}
|
||||||
pipe, err := b.NewPipeline(driver.PipelineDesc{
|
pipe, err := b.NewPipeline(driver.PipelineDesc{
|
||||||
VertexShader: vsh,
|
VertexShader: vsh,
|
||||||
@@ -106,7 +109,7 @@ func TestInputShader(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer buf.Release()
|
defer buf.Release()
|
||||||
b.BindVertexBuffer(buf, 4*4, 0)
|
b.BindVertexBuffer(buf, 0)
|
||||||
b.DrawArrays(driver.DrawModeTriangles, 0, 3)
|
b.DrawArrays(driver.DrawModeTriangles, 0, 3)
|
||||||
img := screenshot(t, b, fbo, sz)
|
img := screenshot(t, b, fbo, sz)
|
||||||
if got := img.RGBAAt(0, 0); got != clearColExpect {
|
if got := img.RGBAAt(0, 0); got != clearColExpect {
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ type Backend struct {
|
|||||||
viewport d3d11.VIEWPORT
|
viewport d3d11.VIEWPORT
|
||||||
|
|
||||||
pipeline *Pipeline
|
pipeline *Pipeline
|
||||||
|
vert struct {
|
||||||
|
buffer *Buffer
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
caps driver.Caps
|
caps driver.Caps
|
||||||
|
|
||||||
@@ -40,6 +44,7 @@ type Pipeline struct {
|
|||||||
frag *d3d11.PixelShader
|
frag *d3d11.PixelShader
|
||||||
layout *d3d11.InputLayout
|
layout *d3d11.InputLayout
|
||||||
blend *d3d11.BlendState
|
blend *d3d11.BlendState
|
||||||
|
stride int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
@@ -375,9 +380,9 @@ func (b *Backend) NewPipeline(desc driver.PipelineDesc) (driver.Pipeline, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var layout *d3d11.InputLayout
|
var layout *d3d11.InputLayout
|
||||||
if l := desc.VertexLayout; l != nil {
|
if l := desc.VertexLayout; l.Stride > 0 {
|
||||||
var err error
|
var err error
|
||||||
layout, err = b.newInputLayout(vsh.src, l)
|
layout, err = b.newInputLayout(vsh.src, l.Inputs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d3d11.IUnknownRelease(unsafe.Pointer(blend), blend.Vtbl.AddRef)
|
d3d11.IUnknownRelease(unsafe.Pointer(blend), blend.Vtbl.AddRef)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -394,6 +399,7 @@ func (b *Backend) NewPipeline(desc driver.PipelineDesc) (driver.Pipeline, error)
|
|||||||
vert: vshRef,
|
vert: vshRef,
|
||||||
frag: fshRef,
|
frag: fshRef,
|
||||||
layout: layout,
|
layout: layout,
|
||||||
|
stride: desc.VertexLayout.Stride,
|
||||||
blend: blend,
|
blend: blend,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -460,6 +466,9 @@ func (b *Backend) prepareDraw(mode driver.DrawMode) {
|
|||||||
b.ctx.PSSetShader(p.frag)
|
b.ctx.PSSetShader(p.frag)
|
||||||
b.ctx.IASetInputLayout(p.layout)
|
b.ctx.IASetInputLayout(p.layout)
|
||||||
b.ctx.OMSetBlendState(p.blend, nil, 0xffffffff)
|
b.ctx.OMSetBlendState(p.blend, nil, 0xffffffff)
|
||||||
|
if b.vert.buffer != nil {
|
||||||
|
b.ctx.IASetVertexBuffers(b.vert.buffer.buf, uint32(p.stride), uint32(b.vert.offset))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var topology uint32
|
var topology uint32
|
||||||
switch mode {
|
switch mode {
|
||||||
@@ -562,8 +571,9 @@ func (b *Backend) BindFragmentUniforms(buffer driver.Buffer) {
|
|||||||
b.ctx.PSSetConstantBuffers(buf.buf)
|
b.ctx.PSSetConstantBuffers(buf.buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) BindVertexBuffer(buf driver.Buffer, stride, offset int) {
|
func (b *Backend) BindVertexBuffer(buf driver.Buffer, offset int) {
|
||||||
b.ctx.IASetVertexBuffers(buf.(*Buffer).buf, uint32(stride), uint32(offset))
|
b.vert.buffer = buf.(*Buffer)
|
||||||
|
b.vert.offset = offset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) BindIndexBuffer(buf driver.Buffer) {
|
func (b *Backend) BindIndexBuffer(buf driver.Buffer) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ type Device interface {
|
|||||||
BindPipeline(p Pipeline)
|
BindPipeline(p Pipeline)
|
||||||
BindFramebuffer(f Framebuffer, a LoadDesc)
|
BindFramebuffer(f Framebuffer, a LoadDesc)
|
||||||
BindTexture(unit int, t Texture)
|
BindTexture(unit int, t Texture)
|
||||||
BindVertexBuffer(b Buffer, stride, offset int)
|
BindVertexBuffer(b Buffer, offset int)
|
||||||
BindIndexBuffer(b Buffer)
|
BindIndexBuffer(b Buffer)
|
||||||
BindImageTexture(unit int, texture Texture, access AccessBits, format TextureFormat)
|
BindImageTexture(unit int, texture Texture, access AccessBits, format TextureFormat)
|
||||||
BindVertexUniforms(buf Buffer)
|
BindVertexUniforms(buf Buffer)
|
||||||
@@ -69,11 +69,16 @@ type Pipeline interface {
|
|||||||
type PipelineDesc struct {
|
type PipelineDesc struct {
|
||||||
VertexShader VertexShader
|
VertexShader VertexShader
|
||||||
FragmentShader FragmentShader
|
FragmentShader FragmentShader
|
||||||
VertexLayout []InputDesc
|
VertexLayout VertexLayout
|
||||||
BlendDesc BlendDesc
|
BlendDesc BlendDesc
|
||||||
PixelFormat TextureFormat
|
PixelFormat TextureFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VertexLayout struct {
|
||||||
|
Inputs []InputDesc
|
||||||
|
Stride int
|
||||||
|
}
|
||||||
|
|
||||||
// InputDesc describes a vertex attribute as laid out in a Buffer.
|
// InputDesc describes a vertex attribute as laid out in a Buffer.
|
||||||
type InputDesc struct {
|
type InputDesc struct {
|
||||||
Type shader.DataType
|
Type shader.DataType
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ type state struct {
|
|||||||
type bufferBinding struct {
|
type bufferBinding struct {
|
||||||
obj gl.Buffer
|
obj gl.Buffer
|
||||||
offset int
|
offset int
|
||||||
stride int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type timer struct {
|
type timer struct {
|
||||||
@@ -115,7 +114,7 @@ type framebuffer struct {
|
|||||||
type pipeline struct {
|
type pipeline struct {
|
||||||
prog *program
|
prog *program
|
||||||
inputs []shader.InputLocation
|
inputs []shader.InputLocation
|
||||||
layout []driver.InputDesc
|
layout driver.VertexLayout
|
||||||
blend driver.BlendDesc
|
blend driver.BlendDesc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,11 +899,11 @@ func (b *Backend) NewPipeline(desc driver.PipelineDesc) (driver.Pipeline, error)
|
|||||||
}
|
}
|
||||||
layout := desc.VertexLayout
|
layout := desc.VertexLayout
|
||||||
vsrc := desc.VertexShader.(*glshader).src
|
vsrc := desc.VertexShader.(*glshader).src
|
||||||
if len(vsrc.Inputs) != len(layout) {
|
if len(vsrc.Inputs) != len(layout.Inputs) {
|
||||||
return nil, fmt.Errorf("opengl: got %d inputs, expected %d", len(layout), len(vsrc.Inputs))
|
return nil, fmt.Errorf("opengl: got %d inputs, expected %d", len(layout.Inputs), len(vsrc.Inputs))
|
||||||
}
|
}
|
||||||
for i, inp := range vsrc.Inputs {
|
for i, inp := range vsrc.Inputs {
|
||||||
if exp, got := inp.Size, layout[i].Size; exp != got {
|
if exp, got := inp.Size, layout.Inputs[i].Size; exp != got {
|
||||||
return nil, fmt.Errorf("opengl: data size mismatch for %q: got %d expected %d", inp.Name, got, exp)
|
return nil, fmt.Errorf("opengl: data size mismatch for %q: got %d expected %d", inp.Name, got, exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1122,12 +1121,12 @@ func (b *buffer) Release() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) BindVertexBuffer(buf driver.Buffer, stride, offset int) {
|
func (b *Backend) BindVertexBuffer(buf driver.Buffer, offset int) {
|
||||||
gbuf := buf.(*buffer)
|
gbuf := buf.(*buffer)
|
||||||
if gbuf.typ&driver.BufferBindingVertices == 0 {
|
if gbuf.typ&driver.BufferBindingVertices == 0 {
|
||||||
panic("not a vertex buffer")
|
panic("not a vertex buffer")
|
||||||
}
|
}
|
||||||
b.state.buffer = bufferBinding{obj: gbuf.obj, stride: stride, offset: offset}
|
b.state.buffer = bufferBinding{obj: gbuf.obj, offset: offset}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) setupVertexArrays() {
|
func (b *Backend) setupVertexArrays() {
|
||||||
@@ -1141,7 +1140,7 @@ func (b *Backend) setupVertexArrays() {
|
|||||||
var enabled [max]bool
|
var enabled [max]bool
|
||||||
buf := b.state.buffer
|
buf := b.state.buffer
|
||||||
for i, inp := range inputs {
|
for i, inp := range inputs {
|
||||||
l := layout[i]
|
l := layout.Inputs[i]
|
||||||
var gltyp gl.Enum
|
var gltyp gl.Enum
|
||||||
switch l.Type {
|
switch l.Type {
|
||||||
case shader.DataTypeFloat:
|
case shader.DataTypeFloat:
|
||||||
@@ -1152,7 +1151,7 @@ func (b *Backend) setupVertexArrays() {
|
|||||||
panic("unsupported data type")
|
panic("unsupported data type")
|
||||||
}
|
}
|
||||||
enabled[inp.Location] = true
|
enabled[inp.Location] = true
|
||||||
b.glstate.vertexAttribPointer(b.funcs, buf.obj, inp.Location, l.Size, gltyp, false, buf.stride, buf.offset+l.Offset)
|
b.glstate.vertexAttribPointer(b.funcs, buf.obj, inp.Location, l.Size, gltyp, false, p.layout.Stride, buf.offset+l.Offset)
|
||||||
}
|
}
|
||||||
for i := 0; i < max; i++ {
|
for i := 0; i < max; i++ {
|
||||||
b.glstate.setVertexAttribArray(b.funcs, i, enabled[i])
|
b.glstate.setVertexAttribArray(b.funcs, i, enabled[i])
|
||||||
|
|||||||
+16
-10
@@ -187,16 +187,22 @@ func newStenciler(ctx driver.Device) *stenciler {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
progLayout := []driver.InputDesc{
|
progLayout := driver.VertexLayout{
|
||||||
{Type: shader.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).Corner))},
|
Inputs: []driver.InputDesc{
|
||||||
{Type: shader.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).MaxY))},
|
{Type: shader.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).Corner))},
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).FromX))},
|
{Type: shader.DataTypeFloat, Size: 1, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).MaxY))},
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).CtrlX))},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).FromX))},
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).ToX))},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).CtrlX))},
|
||||||
|
{Type: shader.DataTypeFloat, Size: 2, Offset: int(unsafe.Offsetof((*(*vertex)(nil)).ToX))},
|
||||||
|
},
|
||||||
|
Stride: vertStride,
|
||||||
}
|
}
|
||||||
iprogLayout := []driver.InputDesc{
|
iprogLayout := driver.VertexLayout{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
Inputs: []driver.InputDesc{
|
||||||
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 0},
|
||||||
|
{Type: shader.DataTypeFloat, Size: 2, Offset: 4 * 2},
|
||||||
|
},
|
||||||
|
Stride: 4 * 4,
|
||||||
}
|
}
|
||||||
st := &stenciler{
|
st := &stenciler{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
@@ -370,7 +376,7 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima
|
|||||||
batch = max
|
batch = max
|
||||||
}
|
}
|
||||||
off := vertStride * start * 4
|
off := vertStride * start * 4
|
||||||
s.ctx.BindVertexBuffer(data.data, vertStride, off)
|
s.ctx.BindVertexBuffer(data.data, off)
|
||||||
s.ctx.DrawElements(driver.DrawModeTriangles, 0, batch*6)
|
s.ctx.DrawElements(driver.DrawModeTriangles, 0, batch*6)
|
||||||
start += batch
|
start += batch
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user