From 646a7676657258926246457541233b4deac11a5f Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 19 Feb 2020 21:06:30 +0100 Subject: [PATCH] gpu,gpu/gl: implement shader uniform buffers Emulate them for the OpenGL ES backend because 2.0 doesn't support uniform buffers. The future d3d backend only supports uniform (constant) buffers. Signed-off-by: Elias Naur --- gpu/backend.go | 15 +-- gpu/build.go | 33 +++--- gpu/gl/backend.go | 161 ++++++++++++++++++++++++----- gpu/gl/gl.go | 1 + gpu/gpu.go | 202 +++++++++++++++++++++++++++---------- gpu/path.go | 200 ++++++++++++++++++++---------------- gpu/shaders.go | 100 +++++++++--------- gpu/shaders/blit.vert | 10 +- gpu/shaders/common.inc | 4 + gpu/shaders/cover.vert | 12 +-- gpu/shaders/intersect.vert | 4 +- gpu/shaders/stencil.vert | 14 +-- 12 files changed, 504 insertions(+), 252 deletions(-) create mode 100644 gpu/shaders/common.inc diff --git a/gpu/backend.go b/gpu/backend.go index f75c5ee4..2c411090 100644 --- a/gpu/backend.go +++ b/gpu/backend.go @@ -41,10 +41,11 @@ type Backend interface { } type ShaderSources struct { - GLES2 string - HLSL []byte - Uniforms []UniformLocation - Inputs []InputLocation + GLES2 string + HLSL []byte + Uniforms []UniformLocation + UniformSize int + Inputs []InputLocation } type UniformLocation struct { @@ -106,11 +107,10 @@ type Caps struct { type Program interface { Bind() Release() + SetVertexUniforms(buf Buffer) + SetFragmentUniforms(buf Buffer) UniformFor(uniform string) Uniform Uniform1i(u Uniform, v int) - Uniform1f(u Uniform, v float32) - Uniform2f(u Uniform, v0, v1 float32) - Uniform4f(u Uniform, v0, v1, v2, v3 float32) } type Uniform interface{} @@ -161,6 +161,7 @@ const ( const ( BufferTypeIndices BufferType = iota BufferTypeVertices + BufferTypeUniforms ) const ( diff --git a/gpu/build.go b/gpu/build.go index 59d7fef7..347e4360 100644 --- a/gpu/build.go +++ b/gpu/build.go @@ -85,16 +85,17 @@ func generate() error { for _, shader := range shaders { const nvariants = 2 var variants [nvariants]struct { - gles2 string - hlslSrc string - hlsl []byte - inputs []InputLocation - uniforms []UniformLocation + gles2 string + hlslSrc string + hlsl []byte + inputs []InputLocation + uniforms []UniformLocation + uniformSize int } args := [nvariants]shaderArgs{ { - FetchColorExpr: `color.color`, - Header: `layout(binding=0) uniform Color { vec4 color; } color;`, + FetchColorExpr: `_color`, + Header: `layout(binding=0) uniform Color { vec4 _color; };`, }, { FetchColorExpr: `texture(tex, vUV)`, @@ -108,7 +109,7 @@ func generate() error { } // Make the GL ES 2 source compatible with desktop GL 3. gles2 = "#version 100\n" + gles2 - inputs, uniforms, err := parseReflection(reflect) + inputs, uniforms, uniformSize, err := parseReflection(reflect) if err != nil { return err } @@ -137,6 +138,7 @@ func generate() error { variants[i].hlsl = hlslc variants[i].inputs = inputs variants[i].uniforms = uniforms + variants[i].uniformSize = uniformSize } name := filepath.Base(shader) name = strings.ReplaceAll(name, ".", "_") @@ -163,6 +165,7 @@ func generate() error { fmt.Fprintf(&out, "{Name: %q, Type: %d, Size: %d, Offset: %d},\n", u.Name, u.Type, u.Size, u.Offset) } fmt.Fprintf(&out, "},\n") + fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize) } fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2) fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc) @@ -188,7 +191,7 @@ func generate() error { return ioutil.WriteFile("shaders.go", gosrc, 0644) } -func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error) { +func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int, error) { type InputReflection struct { ID int `json:"id"` Name string `json:"name"` @@ -221,14 +224,14 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error } var reflect shaderMetadata if err := json.Unmarshal(jsonData, &reflect); err != nil { - return nil, nil, fmt.Errorf("parseReflection: %v", err) + return nil, nil, 0, fmt.Errorf("parseReflection: %v", err) } var inputs []InputLocation inputRef := reflect.VS.Inputs for _, input := range inputRef { dataType, dataSize, err := parseDataType(input.Type) if err != nil { - return nil, nil, err + return nil, nil, 0, fmt.Errorf("parseReflection: %v", err) } inputs = append(inputs, InputLocation{ Name: input.Name, @@ -247,22 +250,24 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error if len(shaderBlocks) == 0 { shaderBlocks = reflect.FS.UniformBuffers } + blockOffset := 0 for _, block := range shaderBlocks { for _, member := range block.Members { dataType, size, err := parseDataType(member.Type) if err != nil { - return nil, nil, err + return nil, nil, 0, fmt.Errorf("parseReflection: %v", err) } ublocks = append(ublocks, UniformLocation{ // Synthetic name generated by glslcc. Name: fmt.Sprintf("_%d.%s", block.ID, member.Name), Type: dataType, Size: size, - Offset: member.Offset, + Offset: blockOffset + member.Offset, }) } + blockOffset += block.Size } - return inputs, ublocks, nil + return inputs, ublocks, blockOffset, nil } func parseDataType(t string) (DataType, int, error) { diff --git a/gpu/gl/backend.go b/gpu/gl/backend.go index d4542536..e5b7fa9a 100644 --- a/gpu/gl/backend.go +++ b/gpu/gl/backend.go @@ -8,6 +8,7 @@ import ( "image" "strings" "time" + "unsafe" "gioui.org/gpu" ) @@ -65,12 +66,31 @@ type gpuBuffer struct { typ Enum size int immutable bool + version int + // For emulation of uniform buffers. + data []byte } type gpuProgram struct { - backend *Backend - obj Program - nattr int + backend *Backend + obj Program + nattr int + vertUniforms uniformsTracker + fragUniforms uniformsTracker +} + +type uniformsTracker struct { + locs []uniformLocation + size int + buf *gpuBuffer + version int +} + +type uniformLocation struct { + uniform Uniform + offset int + typ gpu.DataType + size int } type gpuInputLayout struct { @@ -165,9 +185,16 @@ func (b *Backend) NewTexture(minFilter, magFilter gpu.TextureFilter) gpu.Texture } func (b *Backend) NewBuffer(typ gpu.BufferType, size int) gpu.Buffer { - obj := b.funcs.CreateBuffer() gltyp := toBufferType(typ) - return &gpuBuffer{backend: b, obj: obj, typ: gltyp, size: size} + buf := &gpuBuffer{backend: b, typ: gltyp, size: size} + switch typ { + case gpu.BufferTypeUniforms: + // GLES 2 doesn't support uniform buffers. + buf.data = make([]byte, size) + default: + buf.obj = b.funcs.CreateBuffer() + } + return buf } func (b *Backend) NewImmutableBuffer(typ gpu.BufferType, data []byte) gpu.Buffer { @@ -246,15 +273,22 @@ func (b *Backend) SetBlend(enable bool) { } func (b *Backend) DrawElements(mode gpu.DrawMode, off, count int) { - b.setupVertexArrays() + b.prepareDraw() b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, off) } func (b *Backend) DrawArrays(mode gpu.DrawMode, off, count int) { - b.setupVertexArrays() + b.prepareDraw() b.funcs.DrawArrays(toGLDrawMode(mode), off, count) } +func (b *Backend) prepareDraw() { + b.setupVertexArrays() + if p := b.state.prog; p != nil { + p.updateUniforms() + } +} + func toGLDrawMode(mode gpu.DrawMode) Enum { switch mode { case gpu.DrawModeTriangleStrip: @@ -325,7 +359,32 @@ func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error if err != nil { return nil, err } - return &gpuProgram{backend: b, obj: p, nattr: len(attr)}, nil + gpuProg := &gpuProgram{ + backend: b, + obj: p, + nattr: len(attr), + } + gpuProg.vertUniforms.setup(b.funcs, p, vssrc.UniformSize, vssrc.Uniforms) + gpuProg.fragUniforms.setup(b.funcs, p, fssrc.UniformSize, fssrc.Uniforms) + return gpuProg, nil +} + +func lookupUniform(funcs Functions, p Program, loc gpu.UniformLocation) uniformLocation { + u := GetUniformLocation(funcs, p, loc.Name) + return uniformLocation{uniform: u, offset: loc.Offset, typ: loc.Type, size: loc.Size} +} + +func (p *gpuProgram) SetVertexUniforms(buffer gpu.Buffer) { + p.vertUniforms.setBuffer(buffer) +} + +func (p *gpuProgram) SetFragmentUniforms(buffer gpu.Buffer) { + p.fragUniforms.setBuffer(buffer) +} + +func (p *gpuProgram) updateUniforms() { + p.vertUniforms.update(p.backend.funcs) + p.fragUniforms.update(p.backend.funcs) } func (p *gpuProgram) Uniform1i(u gpu.Uniform, v int) { @@ -333,21 +392,6 @@ func (p *gpuProgram) Uniform1i(u gpu.Uniform, v int) { p.backend.funcs.Uniform1i(u.(Uniform), v) } -func (p *gpuProgram) Uniform1f(u gpu.Uniform, v0 float32) { - p.Bind() - p.backend.funcs.Uniform1f(u.(Uniform), v0) -} - -func (p *gpuProgram) Uniform2f(u gpu.Uniform, v0, v1 float32) { - p.Bind() - p.backend.funcs.Uniform2f(u.(Uniform), v0, v1) -} - -func (p *gpuProgram) Uniform4f(u gpu.Uniform, v0, v1, v2, v3 float32) { - p.Bind() - p.backend.funcs.Uniform4f(u.(Uniform), v0, v1, v2, v3) -} - func (p *gpuProgram) Bind() { p.backend.useProgram(p) p.backend.enableVertexArrays(p.nattr) @@ -362,6 +406,59 @@ func (p *gpuProgram) Release() { p.backend.funcs.DeleteProgram(p.obj) } +func (u *uniformsTracker) setup(funcs Functions, p Program, uniformSize int, uniforms []gpu.UniformLocation) { + u.locs = make([]uniformLocation, len(uniforms)) + for i, uniform := range uniforms { + u.locs[i] = lookupUniform(funcs, p, uniform) + } + u.size = uniformSize +} + +func (u *uniformsTracker) setBuffer(buffer gpu.Buffer) { + buf := buffer.(*gpuBuffer) + if buf.typ != UNIFORM_BUFFER { + panic("not a uniform buffer") + } + if buf.size < u.size { + panic(fmt.Errorf("uniform buffer too small, got %d need %d", buf.size, u.size)) + } + u.buf = buf + // Force update. + u.version = buf.version - 1 +} + +func (p *uniformsTracker) update(funcs Functions) { + b := p.buf + if b == nil || b.version == p.version { + return + } + p.version = b.version + data := b.data + for _, u := range p.locs { + data := data[u.offset:] + switch { + case u.typ == gpu.DataTypeFloat && u.size == 1: + data := data[:4] + v := *(*[1]float32)(unsafe.Pointer(&data[0])) + funcs.Uniform1f(u.uniform, v[0]) + case u.typ == gpu.DataTypeFloat && u.size == 2: + data := data[:8] + v := *(*[2]float32)(unsafe.Pointer(&data[0])) + funcs.Uniform2f(u.uniform, v[0], v[1]) + case u.typ == gpu.DataTypeFloat && u.size == 3: + data := data[:12] + v := *(*[3]float32)(unsafe.Pointer(&data[0])) + funcs.Uniform3f(u.uniform, v[0], v[1], v[2]) + case u.typ == gpu.DataTypeFloat && u.size == 4: + data := data[:16] + v := *(*[4]float32)(unsafe.Pointer(&data[0])) + funcs.Uniform4f(u.uniform, v[0], v[1], v[2], v[3]) + default: + panic("unsupported uniform data type or size") + } + } +} + func (b *gpuBuffer) Upload(data []byte) { if b.immutable { panic("immutable buffer") @@ -369,12 +466,22 @@ func (b *gpuBuffer) Upload(data []byte) { if len(data) > b.size { panic("buffer size overflow") } - b.backend.funcs.BindBuffer(b.typ, b.obj) - b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW) + b.version++ + switch b.typ { + case UNIFORM_BUFFER: + copy(b.data, data) + default: + b.backend.funcs.BindBuffer(b.typ, b.obj) + b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW) + } } func (b *gpuBuffer) Release() { - b.backend.funcs.DeleteBuffer(b.obj) + switch b.typ { + case UNIFORM_BUFFER: + default: + b.backend.funcs.DeleteBuffer(b.obj) + } } func (b *gpuBuffer) BindVertex(stride, offset int) { @@ -585,6 +692,8 @@ func toBufferType(typ gpu.BufferType) Enum { return ARRAY_BUFFER case gpu.BufferTypeIndices: return ELEMENT_ARRAY_BUFFER + case gpu.BufferTypeUniforms: + return UNIFORM_BUFFER default: panic("unsupported buffer type") } diff --git a/gpu/gl/gl.go b/gpu/gl/gl.go index 4b887fa9..51b34e82 100644 --- a/gpu/gl/gl.go +++ b/gpu/gl/gl.go @@ -71,6 +71,7 @@ const ( TRIANGLE_STRIP = 0x5 TRIANGLES = 0x4 TRUE = 1 + UNIFORM_BUFFER = 0x8A11 UNPACK_ALIGNMENT = 0xcf5 UNSIGNED_BYTE = 0x1401 UNSIGNED_SHORT = 0x1403 diff --git a/gpu/gpu.go b/gpu/gpu.go index 65281568..ee188a64 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -13,6 +13,7 @@ import ( "image" "image/color" "math" + "reflect" "time" "unsafe" @@ -209,19 +210,52 @@ type texture struct { } type blitter struct { - ctx Backend - viewport image.Point - prog [2]Program - layout InputLayout - vars [2]struct { - z Uniform - uScale, uOffset Uniform - uUVScale, uUVOffset Uniform - uColor Uniform + ctx Backend + viewport image.Point + prog [2]*program + layout InputLayout + colUniforms struct { + vert struct { + blitUniforms + _ [8]byte // Padding to a multiple of 16. + } + frag struct { + colorUniforms + } + } + texUniforms struct { + vert struct { + blitUniforms + _ [8]byte // Padding to a multiple of 16. + } } quadVerts Buffer } +type uniformBuffer struct { + buf Buffer + ptr []byte +} + +type program struct { + prog Program + vertUniforms *uniformBuffer + fragUniforms *uniformBuffer +} + +type blitUniforms struct { + z float32 + _ float32 // Padding. + scale [2]float32 + offset [2]float32 + uvScale [2]float32 + uvOffset [2]float32 +} + +type colorUniforms struct { + color [4]float32 +} + type materialType uint8 const ( @@ -372,10 +406,6 @@ func (r *renderer) release() { } func newBlitter(ctx Backend) *blitter { - prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag) - if err != nil { - panic(err) - } quadVerts := ctx.NewImmutableBuffer(BufferTypeVertices, gunsafe.BytesView([]float32{ -1, +1, 0, 0, @@ -386,24 +416,17 @@ func newBlitter(ctx Backend) *blitter { ) b := &blitter{ ctx: ctx, - prog: prog, - layout: layout, quadVerts: quadVerts, } - for i, prog := range prog { - switch materialType(i) { - case materialTexture: - uTex := prog.UniformFor("tex") - prog.Uniform1i(uTex, 0) - b.vars[i].uUVScale = prog.UniformFor("uniforms.uvScale") - b.vars[i].uUVOffset = prog.UniformFor("uniforms.uvOffset") - case materialColor: - b.vars[i].uColor = prog.UniformFor("color.color") - } - b.vars[i].z = prog.UniformFor("uniforms.z") - b.vars[i].uScale = prog.UniformFor("uniforms.scale") - b.vars[i].uOffset = prog.UniformFor("uniforms.offset") + prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag, + [2]interface{}{&b.colUniforms.vert, &b.texUniforms.vert}, [2]interface{}{&b.colUniforms.frag, nil}) + if err != nil { + panic(err) } + b.prog = prog + b.layout = layout + texProg := b.prog[materialTexture].prog + texProg.Uniform1i(texProg.UniformFor("tex"), 0) return b } @@ -415,28 +438,47 @@ func (b *blitter) release() { b.layout.Release() } -func createColorPrograms(ctx Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources) ([2]Program, InputLayout, error) { - var prog [2]Program - var err error - prog[materialTexture], err = ctx.NewProgram(vsSrc, fsSrc[materialTexture]) +func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources, vertUniforms, fragUniforms [2]interface{}) ([2]*program, InputLayout, error) { + var progs [2]*program + prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture]) if err != nil { - return prog, nil, err + return progs, nil, err } - prog[materialColor], err = ctx.NewProgram(vsSrc, fsSrc[materialColor]) + var vertBuffer *uniformBuffer + if u := vertUniforms[materialTexture]; u != nil { + vertBuffer = newUniformBuffer(b, u) + prog.SetVertexUniforms(vertBuffer.buf) + } + var fragBuffer *uniformBuffer + if u := fragUniforms[materialTexture]; u != nil { + fragBuffer = newUniformBuffer(b, u) + prog.SetFragmentUniforms(fragBuffer.buf) + } + progs[materialTexture] = newProgram(prog, vertBuffer, fragBuffer) + prog, err = b.NewProgram(vsSrc, fsSrc[materialColor]) if err != nil { - prog[materialTexture].Release() - return prog, nil, err + progs[materialTexture].Release() + return progs, nil, err } - layout, err := ctx.NewInputLayout(vsSrc, []InputDesc{ + if u := vertUniforms[materialColor]; u != nil { + vertBuffer = newUniformBuffer(b, u) + prog.SetVertexUniforms(vertBuffer.buf) + } + if u := fragUniforms[materialColor]; u != nil { + fragBuffer = newUniformBuffer(b, u) + prog.SetFragmentUniforms(fragBuffer.buf) + } + progs[materialColor] = newProgram(prog, vertBuffer, fragBuffer) + layout, err := b.NewInputLayout(vsSrc, []InputDesc{ {Type: DataTypeFloat, Size: 2, Offset: 0}, {Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, }) if err != nil { - prog[materialTexture].Release() - prog[materialColor].Release() - return prog, nil, err + progs[materialTexture].Release() + progs[materialColor].Release() + return progs, nil, err } - return prog, layout, nil + return progs, layout, nil } func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) { @@ -465,7 +507,7 @@ func (r *renderer) intersect(ops []imageOp) { fbo := -1 r.pather.stenciler.beginIntersect(r.intersections.sizes) r.blitter.quadVerts.BindVertex(4*4, 0) - r.pather.stenciler.iprogLayout.Bind() + r.pather.stenciler.iprog.layout.Bind() for _, img := range ops { if img.clipType != clipTypeIntersection { continue @@ -497,8 +539,9 @@ func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) { fbo := r.pather.stenciler.cover(p.place.Idx) fbo.tex.Bind(0) coverScale, coverOff := texSpaceTransform(toRectF(uv), fbo.size) - r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVScale, coverScale.X, coverScale.Y) - r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVOffset, coverOff.X, coverOff.Y) + r.pather.stenciler.iprog.uniforms.vert.uvScale = [2]float32{coverScale.X, coverScale.Y} + r.pather.stenciler.iprog.uniforms.vert.uvOffset = [2]float32{coverOff.X, coverOff.Y} + r.pather.stenciler.iprog.prog.UploadUniforms() r.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) } @@ -846,20 +889,77 @@ func gamma(r, g, b, a uint32) [4]float32 { func (b *blitter) blit(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff f32.Point) { p := b.prog[mat] - p.Bind() + p.prog.Bind() + var uniforms *blitUniforms switch mat { case materialColor: - p.Uniform4f(b.vars[mat].uColor, col[0], col[1], col[2], col[3]) + b.colUniforms.frag.color = col + uniforms = &b.colUniforms.vert.blitUniforms case materialTexture: - p.Uniform2f(b.vars[mat].uUVScale, uvScale.X, uvScale.Y) - p.Uniform2f(b.vars[mat].uUVOffset, uvOff.X, uvOff.Y) + b.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y} + b.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y} + uniforms = &b.texUniforms.vert.blitUniforms } - p.Uniform1f(b.vars[mat].z, z) - p.Uniform2f(b.vars[mat].uScale, scale.X, scale.Y) - p.Uniform2f(b.vars[mat].uOffset, off.X, off.Y) + uniforms.z = z + uniforms.scale = [2]float32{scale.X, scale.Y} + uniforms.offset = [2]float32{off.X, off.Y} + p.UploadUniforms() b.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) } +// newUniformBuffer creates a new GPU uniform buffer backed by the +// structure uniformBlock points to. +func newUniformBuffer(b Backend, uniformBlock interface{}) *uniformBuffer { + ref := reflect.ValueOf(uniformBlock) + // Determine the size of the uniforms structure, *uniforms. + size := ref.Elem().Type().Size() + // Map the uniforms structure as a byte slice. + ptr := (*[1 << 30]byte)(unsafe.Pointer(ref.Pointer()))[:size:size] + ubuf := b.NewBuffer(BufferTypeUniforms, len(ptr)) + return &uniformBuffer{buf: ubuf, ptr: ptr} +} + +func (u *uniformBuffer) Upload() { + u.buf.Upload(u.ptr) +} + +func (u *uniformBuffer) Release() { + u.buf.Release() + u.buf = nil +} + +func newProgram(prog Program, vertUniforms, fragUniforms *uniformBuffer) *program { + if vertUniforms != nil { + prog.SetVertexUniforms(vertUniforms.buf) + } + if fragUniforms != nil { + prog.SetFragmentUniforms(fragUniforms.buf) + } + return &program{prog: prog, vertUniforms: vertUniforms, fragUniforms: fragUniforms} +} + +func (p *program) UploadUniforms() { + if p.vertUniforms != nil { + p.vertUniforms.Upload() + } + if p.fragUniforms != nil { + p.fragUniforms.Upload() + } +} + +func (p *program) Release() { + p.prog.Release() + p.prog = nil + if p.vertUniforms != nil { + p.vertUniforms.Release() + p.vertUniforms = nil + } + if p.fragUniforms != nil { + p.fragUniforms.Release() + p.fragUniforms = nil + } +} + // texSpaceTransform return the scale and offset that transforms the given subimage // into quad texture coordinates. func texSpaceTransform(r f32.Rectangle, bounds image.Point) (f32.Point, f32.Point) { diff --git a/gpu/path.go b/gpu/path.go index 3f5b6c02..3fd7f25a 100644 --- a/gpu/path.go +++ b/gpu/path.go @@ -24,32 +24,65 @@ type pather struct { } type coverer struct { - ctx Backend - prog [2]Program - layout InputLayout - vars [2]struct { - z Uniform - uScale, uOffset Uniform - uUVScale, uUVOffset Uniform - uCoverUVScale, uCoverUVOffset Uniform - uColor Uniform + ctx Backend + prog [2]*program + texUniforms struct { + vert struct { + coverUniforms + _ [8]byte // Padding to multiple of 16. + } } + colUniforms struct { + vert struct { + coverUniforms + _ [8]byte // Padding to multiple of 16. + } + frag struct { + colorUniforms + } + } + layout InputLayout +} + +type coverUniforms struct { + z float32 + _ float32 // Padding. + scale [2]float32 + offset [2]float32 + uvCoverScale [2]float32 + uvCoverOffset [2]float32 + uvScale [2]float32 + uvOffset [2]float32 } type stenciler struct { - ctx Backend - defFBO Framebuffer - prog Program - progLayout InputLayout - iprog Program - iprogLayout InputLayout - fbos fboSet - intersections fboSet - uScale, uOffset Uniform - uPathOffset Uniform - uIntersectUVOffset Uniform - uIntersectUVScale Uniform - indexBuf Buffer + ctx Backend + defFBO Framebuffer + prog struct { + prog *program + uniforms struct { + vert struct { + scale [2]float32 + offset [2]float32 + pathOffset [2]float32 + _ [8]byte // Padding to multiple of 16. + } + } + layout InputLayout + } + iprog struct { + prog *program + uniforms struct { + vert struct { + uvScale [2]float32 + uvOffset [2]float32 + } + } + layout InputLayout + } + fbos fboSet + intersections fboSet + indexBuf Buffer } type fboSet struct { @@ -89,48 +122,28 @@ func newPather(ctx Backend) *pather { } func newCoverer(ctx Backend) *coverer { - prog, layout, err := createColorPrograms(ctx, shader_cover_vert, shader_cover_frag) + c := &coverer{ + ctx: ctx, + } + prog, layout, err := createColorPrograms(ctx, shader_cover_vert, shader_cover_frag, + [2]interface{}{&c.colUniforms.vert, &c.texUniforms.vert}, + [2]interface{}{&c.colUniforms.frag, nil}, + ) if err != nil { panic(err) } - c := &coverer{ - ctx: ctx, - prog: prog, - layout: layout, - } - for i, prog := range prog { - switch materialType(i) { - case materialTexture: - uTex := prog.UniformFor("tex") - prog.Uniform1i(uTex, 0) - c.vars[i].uUVScale = prog.UniformFor("uniforms.uvScale") - c.vars[i].uUVOffset = prog.UniformFor("uniforms.uvOffset") - case materialColor: - c.vars[i].uColor = prog.UniformFor("color.color") - } - uCover := prog.UniformFor("cover") - prog.Uniform1i(uCover, 1) - c.vars[i].z = prog.UniformFor("uniforms.z") - c.vars[i].uScale = prog.UniformFor("uniforms.scale") - c.vars[i].uOffset = prog.UniformFor("uniforms.offset") - c.vars[i].uCoverUVScale = prog.UniformFor("uniforms.uvCoverScale") - c.vars[i].uCoverUVOffset = prog.UniformFor("uniforms.uvCoverOffset") + c.prog = prog + c.layout = layout + texProg := prog[materialTexture].prog + texProg.Uniform1i(texProg.UniformFor("tex"), 0) + for _, p := range prog { + p.prog.Uniform1i(p.prog.UniformFor("cover"), 1) } return c } func newStenciler(ctx Backend) *stenciler { defFBO := ctx.DefaultFramebuffer() - prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag) - if err != nil { - panic(err) - } - iprog, err := ctx.NewProgram(shader_intersect_vert, shader_intersect_frag) - if err != nil { - panic(err) - } - coverLoc := iprog.UniformFor("cover") - iprog.Uniform1i(coverLoc, 0) // Allocate a suitably large index buffer for drawing paths. indices := make([]uint16, pathBatchSize*6) for i := 0; i < pathBatchSize; i++ { @@ -160,20 +173,28 @@ func newStenciler(ctx Backend) *stenciler { if err != nil { panic(err) } - return &stenciler{ - ctx: ctx, - defFBO: defFBO, - prog: prog, - progLayout: progLayout, - iprog: iprog, - iprogLayout: iprogLayout, - uScale: prog.UniformFor("uniforms.scale"), - uOffset: prog.UniformFor("uniforms.offset"), - uPathOffset: prog.UniformFor("uniforms.pathOffset"), - uIntersectUVScale: iprog.UniformFor("uvparams.scale"), - uIntersectUVOffset: iprog.UniformFor("uvparams.offset"), - indexBuf: indexBuf, + st := &stenciler{ + ctx: ctx, + defFBO: defFBO, + indexBuf: indexBuf, } + prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag) + if err != nil { + panic(err) + } + vertUniforms := newUniformBuffer(ctx, &st.prog.uniforms.vert) + st.prog.prog = newProgram(prog, vertUniforms, nil) + st.prog.layout = progLayout + iprog, err := ctx.NewProgram(shader_intersect_vert, shader_intersect_frag) + if err != nil { + panic(err) + } + vertUniforms = newUniformBuffer(ctx, &st.iprog.uniforms.vert) + coverLoc := iprog.UniformFor("cover") + iprog.Uniform1i(coverLoc, 0) + st.iprog.prog = newProgram(iprog, vertUniforms, nil) + st.iprog.layout = iprogLayout + return st } func (s *fboSet) resize(ctx Backend, sizes []image.Point) { @@ -219,10 +240,10 @@ func (s *fboSet) delete(ctx Backend, idx int) { func (s *stenciler) release() { s.fbos.delete(s.ctx, 0) - s.progLayout.Release() - s.prog.Release() - s.iprogLayout.Release() - s.iprog.Release() + s.prog.layout.Release() + s.prog.prog.Release() + s.iprog.layout.Release() + s.iprog.prog.Release() s.indexBuf.Release() } @@ -270,7 +291,7 @@ func (s *stenciler) beginIntersect(sizes []image.Point) { // no floating point support is available. s.intersections.resize(s.ctx, sizes) s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0) - s.iprog.Bind() + s.iprog.prog.prog.Bind() } func (s *stenciler) endIntersect() { @@ -292,8 +313,8 @@ func (s *stenciler) begin(sizes []image.Point) { s.ctx.BlendFunc(BlendFactorOne, BlendFactorOne) s.fbos.resize(s.ctx, sizes) s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0) - s.prog.Bind() - s.progLayout.Bind() + s.prog.prog.prog.Bind() + s.prog.layout.Bind() s.indexBuf.BindIndex() } @@ -303,9 +324,10 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima texSize := f32.Point{X: float32(bounds.Dx()), Y: float32(bounds.Dy())} scale := f32.Point{X: 2 / texSize.X, Y: 2 / texSize.Y} orig := f32.Point{X: -1 - float32(bounds.Min.X)*2/texSize.X, Y: -1 - float32(bounds.Min.Y)*2/texSize.Y} - s.prog.Uniform2f(s.uScale, scale.X, scale.Y) - s.prog.Uniform2f(s.uOffset, orig.X, orig.Y) - s.prog.Uniform2f(s.uPathOffset, offset.X, offset.Y) + s.prog.uniforms.vert.scale = [2]float32{scale.X, scale.Y} + s.prog.uniforms.vert.offset = [2]float32{orig.X, orig.Y} + s.prog.uniforms.vert.pathOffset = [2]float32{offset.X, offset.Y} + s.prog.prog.UploadUniforms() // Draw in batches that fit in uint16 indices. start := 0 nquads := data.ncurves / 4 @@ -331,18 +353,22 @@ func (p *pather) cover(z float32, mat materialType, col [4]float32, scale, off, func (c *coverer) cover(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff, coverScale, coverOff f32.Point) { p := c.prog[mat] - p.Bind() + p.prog.Bind() + var uniforms *coverUniforms switch mat { case materialColor: - p.Uniform4f(c.vars[mat].uColor, col[0], col[1], col[2], col[3]) + c.colUniforms.frag.color = col + uniforms = &c.colUniforms.vert.coverUniforms case materialTexture: - p.Uniform2f(c.vars[mat].uUVScale, uvScale.X, uvScale.Y) - p.Uniform2f(c.vars[mat].uUVOffset, uvOff.X, uvOff.Y) + c.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y} + c.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y} + uniforms = &c.texUniforms.vert.coverUniforms } - p.Uniform1f(c.vars[mat].z, z) - p.Uniform2f(c.vars[mat].uScale, scale.X, scale.Y) - p.Uniform2f(c.vars[mat].uOffset, off.X, off.Y) - p.Uniform2f(c.vars[mat].uCoverUVScale, coverScale.X, coverScale.Y) - p.Uniform2f(c.vars[mat].uCoverUVOffset, coverOff.X, coverOff.Y) + uniforms.z = z + uniforms.scale = [2]float32{scale.X, scale.Y} + uniforms.offset = [2]float32{off.X, off.Y} + uniforms.uvCoverScale = [2]float32{coverScale.X, coverScale.Y} + uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y} + p.UploadUniforms() c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) } diff --git a/gpu/shaders.go b/gpu/shaders.go index 0d104d1b..306e6e64 100644 --- a/gpu/shaders.go +++ b/gpu/shaders.go @@ -6,13 +6,14 @@ var ( shader_blit_frag = [...]ShaderSources{ ShaderSources{ Uniforms: []UniformLocation{ - {Name: "_12.color", Type: 0, Size: 4, Offset: 0}, + {Name: "_12._color", Type: 0, Size: 4, Offset: 0}, }, - GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 color;\n};\n\nuniform Color color;\n\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = color.color;\n}\n\n", + UniformSize: 16, + GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 _color;\n};\n\nuniform Color _12;\n\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = _12._color;\n}\n\n", /* cbuffer Color : register(b0) { - float4 color_color : packoffset(c0); + float4 _12_color : packoffset(c0); }; @@ -31,7 +32,7 @@ var ( void frag_main() { - fragColor = color_color; + fragColor = _12_color; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) @@ -95,15 +96,16 @@ var ( {Name: "_15.uvScale", Type: 0, Size: 2, Offset: 24}, {Name: "_15.uvOffset", Type: 0, Size: 2, Offset: 32}, }, - GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p *= uniforms.scale;\n p += uniforms.offset;\n gl_Position = vec4(p, uniforms.z, 1.0);\n vUV = (uv * uniforms.uvScale) + uniforms.uvOffset;\n}\n\n", + UniformSize: 40, + GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block _15;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p *= _15.scale;\n p += _15.offset;\n gl_Position = vec4(p, _15.z, 1.0);\n vUV = (uv * _15.uvScale) + _15.uvOffset;\n}\n\n", /* cbuffer Block : register(b0) { - float uniforms_z : packoffset(c0); - float2 uniforms_scale : packoffset(c0.z); - float2 uniforms_offset : packoffset(c1); - float2 uniforms_uvScale : packoffset(c1.z); - float2 uniforms_uvOffset : packoffset(c2); + float _15_z : packoffset(c0); + float2 _15_scale : packoffset(c0.z); + float2 _15_offset : packoffset(c1); + float2 _15_uvScale : packoffset(c1.z); + float2 _15_uvOffset : packoffset(c2); }; @@ -127,10 +129,10 @@ var ( void vert_main() { float2 p = pos; - p *= uniforms_scale; - p += uniforms_offset; - gl_Position = float4(p, uniforms_z, 1.0f); - vUV = (uv * uniforms_uvScale) + uniforms_uvOffset; + p *= _15_scale; + p += _15_offset; + gl_Position = float4(p, _15_z, 1.0f); + vUV = (uv * _15_uvScale) + _15_uvOffset; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) @@ -150,13 +152,14 @@ var ( shader_cover_frag = [...]ShaderSources{ ShaderSources{ Uniforms: []UniformLocation{ - {Name: "_12.color", Type: 0, Size: 4, Offset: 0}, + {Name: "_12._color", Type: 0, Size: 4, Offset: 0}, }, - GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 color;\n};\n\nuniform Color color;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vCoverUV;\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = color.color;\n float cover_1 = abs(texture2D(cover, vCoverUV).x);\n gl_FragData[0] *= cover_1;\n}\n\n", + UniformSize: 16, + GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 _color;\n};\n\nuniform Color _12;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vCoverUV;\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = _12._color;\n float cover_1 = abs(texture2D(cover, vCoverUV).x);\n gl_FragData[0] *= cover_1;\n}\n\n", /* cbuffer Color : register(b0) { - float4 color_color : packoffset(c0); + float4 _12_color : packoffset(c0); }; Texture2D cover : register(t1); @@ -179,7 +182,7 @@ var ( void frag_main() { - fragColor = color_color; + fragColor = _12_color; float cover_1 = abs(cover.Sample(_cover_sampler, vCoverUV).x); fragColor *= cover_1; } @@ -250,22 +253,23 @@ var ( {Name: "_19.z", Type: 0, Size: 1, Offset: 0}, {Name: "_19.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_19.offset", Type: 0, Size: 2, Offset: 16}, - {Name: "_19.uvScale", Type: 0, Size: 2, Offset: 24}, - {Name: "_19.uvOffset", Type: 0, Size: 2, Offset: 32}, - {Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 40}, - {Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 48}, + {Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 24}, + {Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 32}, + {Name: "_19.uvScale", Type: 0, Size: 2, Offset: 40}, + {Name: "_19.uvOffset", Type: 0, Size: 2, Offset: 48}, }, - GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n vec2 uvCoverScale;\n vec2 uvCoverOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\nvarying vec2 vCoverUV;\n\nvoid main()\n{\n gl_Position = vec4((pos * uniforms.scale) + uniforms.offset, uniforms.z, 1.0);\n vUV = (uv * uniforms.uvScale) + uniforms.uvOffset;\n vCoverUV = (uv * uniforms.uvCoverScale) + uniforms.uvCoverOffset;\n}\n\n", + UniformSize: 56, + GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvCoverScale;\n vec2 uvCoverOffset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block _19;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\nvarying vec2 vCoverUV;\n\nvoid main()\n{\n gl_Position = vec4((pos * _19.scale) + _19.offset, _19.z, 1.0);\n vUV = (uv * _19.uvScale) + _19.uvOffset;\n vCoverUV = (uv * _19.uvCoverScale) + _19.uvCoverOffset;\n}\n\n", /* cbuffer Block : register(b0) { - float uniforms_z : packoffset(c0); - float2 uniforms_scale : packoffset(c0.z); - float2 uniforms_offset : packoffset(c1); - float2 uniforms_uvScale : packoffset(c1.z); - float2 uniforms_uvOffset : packoffset(c2); - float2 uniforms_uvCoverScale : packoffset(c2.z); - float2 uniforms_uvCoverOffset : packoffset(c3); + float _19_z : packoffset(c0); + float2 _19_scale : packoffset(c0.z); + float2 _19_offset : packoffset(c1); + float2 _19_uvCoverScale : packoffset(c1.z); + float2 _19_uvCoverOffset : packoffset(c2); + float2 _19_uvScale : packoffset(c2.z); + float2 _19_uvOffset : packoffset(c3); }; @@ -290,9 +294,9 @@ var ( void vert_main() { - gl_Position = float4((pos * uniforms_scale) + uniforms_offset, uniforms_z, 1.0f); - vUV = (uv * uniforms_uvScale) + uniforms_uvOffset; - vCoverUV = (uv * uniforms_uvCoverScale) + uniforms_uvCoverOffset; + gl_Position = float4((pos * _19_scale) + _19_offset, _19_z, 1.0f); + vUV = (uv * _19_uvScale) + _19_uvOffset; + vCoverUV = (uv * _19_uvCoverScale) + _19_uvCoverOffset; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) @@ -356,12 +360,13 @@ var ( {Name: "_40.scale", Type: 0, Size: 2, Offset: 0}, {Name: "_40.offset", Type: 0, Size: 2, Offset: 8}, }, - GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n};\n\nuniform Block uvparams;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p.y = -p.y;\n gl_Position = vec4(p, 0.0, 1.0);\n vUV = (uv * uvparams.scale) + uvparams.offset;\n}\n\n", + UniformSize: 16, + GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n};\n\nuniform Block _40;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p.y = -p.y;\n gl_Position = vec4(p, 0.0, 1.0);\n vUV = (uv * _40.scale) + _40.offset;\n}\n\n", /* cbuffer Block : register(b0) { - float2 uvparams_scale : packoffset(c0); - float2 uvparams_offset : packoffset(c0.z); + float2 _40_scale : packoffset(c0); + float2 _40_offset : packoffset(c0.z); }; @@ -387,7 +392,7 @@ var ( float2 p = pos; p.y = -p.y; gl_Position = float4(p, 0.0f, 1.0f); - vUV = (uv * uvparams_scale) + uvparams_offset; + vUV = (uv * _40_scale) + _40_offset; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) @@ -484,13 +489,14 @@ var ( {Name: "_15.offset", Type: 0, Size: 2, Offset: 8}, {Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16}, }, - GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n vec2 pathOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 from;\nattribute vec2 ctrl;\nattribute vec2 to;\nattribute float maxy;\nattribute vec2 corner;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\nvarying vec2 vTo;\n\nvoid main()\n{\n vec2 from_1 = from + uniforms.pathOffset;\n vec2 ctrl_1 = ctrl + uniforms.pathOffset;\n vec2 to_1 = to + uniforms.pathOffset;\n float maxy_1 = maxy + uniforms.pathOffset.y;\n vec2 pos;\n if (corner.x > 0.0)\n {\n pos.x = max(max(from_1.x, ctrl_1.x), to_1.x) + 1.0;\n }\n else\n {\n pos.x = min(min(from_1.x, ctrl_1.x), to_1.x) - 1.0;\n }\n if (corner.y > 0.0)\n {\n pos.y = maxy_1 + 1.0;\n }\n else\n {\n pos.y = min(min(from_1.y, ctrl_1.y), to_1.y) - 1.0;\n }\n vFrom = from_1 - pos;\n vCtrl = ctrl_1 - pos;\n vTo = to_1 - pos;\n pos *= uniforms.scale;\n pos += uniforms.offset;\n gl_Position = vec4(pos, 1.0, 1.0);\n}\n\n", + UniformSize: 24, + GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n vec2 pathOffset;\n};\n\nuniform Block _15;\n\nattribute vec2 from;\nattribute vec2 ctrl;\nattribute vec2 to;\nattribute float maxy;\nattribute vec2 corner;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\nvarying vec2 vTo;\n\nvoid main()\n{\n vec2 from_1 = from + _15.pathOffset;\n vec2 ctrl_1 = ctrl + _15.pathOffset;\n vec2 to_1 = to + _15.pathOffset;\n float maxy_1 = maxy + _15.pathOffset.y;\n vec2 pos;\n if (corner.x > 0.0)\n {\n pos.x = max(max(from_1.x, ctrl_1.x), to_1.x) + 1.0;\n }\n else\n {\n pos.x = min(min(from_1.x, ctrl_1.x), to_1.x) - 1.0;\n }\n if (corner.y > 0.0)\n {\n pos.y = maxy_1 + 1.0;\n }\n else\n {\n pos.y = min(min(from_1.y, ctrl_1.y), to_1.y) - 1.0;\n }\n vFrom = from_1 - pos;\n vCtrl = ctrl_1 - pos;\n vTo = to_1 - pos;\n pos *= _15.scale;\n pos += _15.offset;\n gl_Position = vec4(pos, 1.0, 1.0);\n}\n\n", /* cbuffer Block : register(b0) { - float2 uniforms_scale : packoffset(c0); - float2 uniforms_offset : packoffset(c0.z); - float2 uniforms_pathOffset : packoffset(c1); + float2 _15_scale : packoffset(c0); + float2 _15_offset : packoffset(c0.z); + float2 _15_pathOffset : packoffset(c1); }; @@ -523,10 +529,10 @@ var ( void vert_main() { - float2 from_1 = from + uniforms_pathOffset; - float2 ctrl_1 = ctrl + uniforms_pathOffset; - float2 to_1 = to + uniforms_pathOffset; - float maxy_1 = maxy + uniforms_pathOffset.y; + float2 from_1 = from + _15_pathOffset; + float2 ctrl_1 = ctrl + _15_pathOffset; + float2 to_1 = to + _15_pathOffset; + float maxy_1 = maxy + _15_pathOffset.y; float2 pos; if (corner.x > 0.0f) { @@ -547,8 +553,8 @@ var ( vFrom = from_1 - pos; vCtrl = ctrl_1 - pos; vTo = to_1 - pos; - pos *= uniforms_scale; - pos += uniforms_offset; + pos *= _15_scale; + pos += _15_offset; gl_Position = float4(pos, 1.0f, 1.0f); } diff --git a/gpu/shaders/blit.vert b/gpu/shaders/blit.vert index 58d2325b..b064dcac 100644 --- a/gpu/shaders/blit.vert +++ b/gpu/shaders/blit.vert @@ -10,7 +10,7 @@ layout(binding = 0) uniform Block { vec2 offset; vec2 uvScale; vec2 uvOffset; -} uniforms; +}; layout(location = 0) in vec2 pos; @@ -20,8 +20,8 @@ layout(location = 0) out vec2 vUV; void main() { vec2 p = pos; - p *= uniforms.scale; - p += uniforms.offset; - gl_Position = vec4(p, uniforms.z, 1); - vUV = uv*uniforms.uvScale + uniforms.uvOffset; + p *= scale; + p += offset; + gl_Position = vec4(p, z, 1); + vUV = uv*uvScale + uvOffset; } diff --git a/gpu/shaders/common.inc b/gpu/shaders/common.inc new file mode 100644 index 00000000..89c9baf7 --- /dev/null +++ b/gpu/shaders/common.inc @@ -0,0 +1,4 @@ +#version 310 es + +void blah() { +} diff --git a/gpu/shaders/cover.vert b/gpu/shaders/cover.vert index 369443d2..66d58bd4 100644 --- a/gpu/shaders/cover.vert +++ b/gpu/shaders/cover.vert @@ -8,11 +8,11 @@ layout(binding = 0) uniform Block { float z; vec2 scale; vec2 offset; - vec2 uvScale; - vec2 uvOffset; vec2 uvCoverScale; vec2 uvCoverOffset; -} uniforms; + vec2 uvScale; + vec2 uvOffset; +}; layout(location = 0) in vec2 pos; @@ -22,7 +22,7 @@ layout(location = 1) in vec2 uv; layout(location = 1) out vec2 vUV; void main() { - gl_Position = vec4(pos*uniforms.scale + uniforms.offset, uniforms.z, 1); - vUV = uv*uniforms.uvScale + uniforms.uvOffset; - vCoverUV = uv*uniforms.uvCoverScale+uniforms.uvCoverOffset; + gl_Position = vec4(pos*scale + offset, z, 1); + vUV = uv*uvScale + uvOffset; + vCoverUV = uv*uvCoverScale+uvCoverOffset; } diff --git a/gpu/shaders/intersect.vert b/gpu/shaders/intersect.vert index 3ce6eb23..2a353c40 100644 --- a/gpu/shaders/intersect.vert +++ b/gpu/shaders/intersect.vert @@ -10,7 +10,7 @@ layout(location = 1) in vec2 uv; layout(binding = 0) uniform Block { vec2 scale; vec2 offset; -} uvparams; +}; layout(location = 0) out vec2 vUV; @@ -18,5 +18,5 @@ void main() { vec2 p = pos; p.y = -p.y; gl_Position = vec4(p, 0, 1); - vUV = uv*uvparams.scale + uvparams.offset; + vUV = uv*scale + offset; } diff --git a/gpu/shaders/stencil.vert b/gpu/shaders/stencil.vert index 2b5cdf5a..8942ecba 100644 --- a/gpu/shaders/stencil.vert +++ b/gpu/shaders/stencil.vert @@ -8,7 +8,7 @@ layout(binding = 0) uniform Block { vec2 scale; vec2 offset; vec2 pathOffset; -} uniforms; +}; layout(location=0) in vec2 corner; layout(location=1) in float maxy; @@ -24,10 +24,10 @@ void main() { // Add a one pixel overlap so curve quads cover their // entire curves. Could use conservative rasterization // if available. - vec2 from = from + uniforms.pathOffset; - vec2 ctrl = ctrl + uniforms.pathOffset; - vec2 to = to + uniforms.pathOffset; - float maxy = maxy + uniforms.pathOffset.y; + vec2 from = from + pathOffset; + vec2 ctrl = ctrl + pathOffset; + vec2 to = to + pathOffset; + float maxy = maxy + pathOffset.y; vec2 pos; if (corner.x > 0.0) { // East. @@ -46,8 +46,8 @@ void main() { vFrom = from-pos; vCtrl = ctrl-pos; vTo = to-pos; - pos *= uniforms.scale; - pos += uniforms.offset; + pos *= scale; + pos += offset; gl_Position = vec4(pos, 1, 1); }