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 <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-19 21:06:30 +01:00
parent ef3e94e7a7
commit 646a767665
12 changed files with 504 additions and 252 deletions
+4 -3
View File
@@ -44,6 +44,7 @@ type ShaderSources struct {
GLES2 string GLES2 string
HLSL []byte HLSL []byte
Uniforms []UniformLocation Uniforms []UniformLocation
UniformSize int
Inputs []InputLocation Inputs []InputLocation
} }
@@ -106,11 +107,10 @@ type Caps struct {
type Program interface { type Program interface {
Bind() Bind()
Release() Release()
SetVertexUniforms(buf Buffer)
SetFragmentUniforms(buf Buffer)
UniformFor(uniform string) Uniform UniformFor(uniform string) Uniform
Uniform1i(u Uniform, v int) 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{} type Uniform interface{}
@@ -161,6 +161,7 @@ const (
const ( const (
BufferTypeIndices BufferType = iota BufferTypeIndices BufferType = iota
BufferTypeVertices BufferTypeVertices
BufferTypeUniforms
) )
const ( const (
+14 -9
View File
@@ -90,11 +90,12 @@ func generate() error {
hlsl []byte hlsl []byte
inputs []InputLocation inputs []InputLocation
uniforms []UniformLocation uniforms []UniformLocation
uniformSize int
} }
args := [nvariants]shaderArgs{ args := [nvariants]shaderArgs{
{ {
FetchColorExpr: `color.color`, FetchColorExpr: `_color`,
Header: `layout(binding=0) uniform Color { vec4 color; } color;`, Header: `layout(binding=0) uniform Color { vec4 _color; };`,
}, },
{ {
FetchColorExpr: `texture(tex, vUV)`, FetchColorExpr: `texture(tex, vUV)`,
@@ -108,7 +109,7 @@ func generate() error {
} }
// Make the GL ES 2 source compatible with desktop GL 3. // Make the GL ES 2 source compatible with desktop GL 3.
gles2 = "#version 100\n" + gles2 gles2 = "#version 100\n" + gles2
inputs, uniforms, err := parseReflection(reflect) inputs, uniforms, uniformSize, err := parseReflection(reflect)
if err != nil { if err != nil {
return err return err
} }
@@ -137,6 +138,7 @@ func generate() error {
variants[i].hlsl = hlslc variants[i].hlsl = hlslc
variants[i].inputs = inputs variants[i].inputs = inputs
variants[i].uniforms = uniforms variants[i].uniforms = uniforms
variants[i].uniformSize = uniformSize
} }
name := filepath.Base(shader) name := filepath.Base(shader)
name = strings.ReplaceAll(name, ".", "_") 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, "{Name: %q, Type: %d, Size: %d, Offset: %d},\n", u.Name, u.Type, u.Size, u.Offset)
} }
fmt.Fprintf(&out, "},\n") fmt.Fprintf(&out, "},\n")
fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize)
} }
fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2) fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2)
fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc) fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc)
@@ -188,7 +191,7 @@ func generate() error {
return ioutil.WriteFile("shaders.go", gosrc, 0644) 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 { type InputReflection struct {
ID int `json:"id"` ID int `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@@ -221,14 +224,14 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
} }
var reflect shaderMetadata var reflect shaderMetadata
if err := json.Unmarshal(jsonData, &reflect); err != nil { 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 var inputs []InputLocation
inputRef := reflect.VS.Inputs inputRef := reflect.VS.Inputs
for _, input := range inputRef { for _, input := range inputRef {
dataType, dataSize, err := parseDataType(input.Type) dataType, dataSize, err := parseDataType(input.Type)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
} }
inputs = append(inputs, InputLocation{ inputs = append(inputs, InputLocation{
Name: input.Name, Name: input.Name,
@@ -247,22 +250,24 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
if len(shaderBlocks) == 0 { if len(shaderBlocks) == 0 {
shaderBlocks = reflect.FS.UniformBuffers shaderBlocks = reflect.FS.UniformBuffers
} }
blockOffset := 0
for _, block := range shaderBlocks { for _, block := range shaderBlocks {
for _, member := range block.Members { for _, member := range block.Members {
dataType, size, err := parseDataType(member.Type) dataType, size, err := parseDataType(member.Type)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
} }
ublocks = append(ublocks, UniformLocation{ ublocks = append(ublocks, UniformLocation{
// Synthetic name generated by glslcc. // Synthetic name generated by glslcc.
Name: fmt.Sprintf("_%d.%s", block.ID, member.Name), Name: fmt.Sprintf("_%d.%s", block.ID, member.Name),
Type: dataType, Type: dataType,
Size: size, 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) { func parseDataType(t string) (DataType, int, error) {
+129 -20
View File
@@ -8,6 +8,7 @@ import (
"image" "image"
"strings" "strings"
"time" "time"
"unsafe"
"gioui.org/gpu" "gioui.org/gpu"
) )
@@ -65,12 +66,31 @@ type gpuBuffer struct {
typ Enum typ Enum
size int size int
immutable bool immutable bool
version int
// For emulation of uniform buffers.
data []byte
} }
type gpuProgram struct { type gpuProgram struct {
backend *Backend backend *Backend
obj Program obj Program
nattr int 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 { 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 { func (b *Backend) NewBuffer(typ gpu.BufferType, size int) gpu.Buffer {
obj := b.funcs.CreateBuffer()
gltyp := toBufferType(typ) 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 { 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) { func (b *Backend) DrawElements(mode gpu.DrawMode, off, count int) {
b.setupVertexArrays() b.prepareDraw()
b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, off) b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, off)
} }
func (b *Backend) DrawArrays(mode gpu.DrawMode, off, count int) { func (b *Backend) DrawArrays(mode gpu.DrawMode, off, count int) {
b.setupVertexArrays() b.prepareDraw()
b.funcs.DrawArrays(toGLDrawMode(mode), off, count) 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 { func toGLDrawMode(mode gpu.DrawMode) Enum {
switch mode { switch mode {
case gpu.DrawModeTriangleStrip: case gpu.DrawModeTriangleStrip:
@@ -325,7 +359,32 @@ func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error
if err != nil { if err != nil {
return nil, err 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) { 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) 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() { func (p *gpuProgram) Bind() {
p.backend.useProgram(p) p.backend.useProgram(p)
p.backend.enableVertexArrays(p.nattr) p.backend.enableVertexArrays(p.nattr)
@@ -362,6 +406,59 @@ func (p *gpuProgram) Release() {
p.backend.funcs.DeleteProgram(p.obj) 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) { func (b *gpuBuffer) Upload(data []byte) {
if b.immutable { if b.immutable {
panic("immutable buffer") panic("immutable buffer")
@@ -369,13 +466,23 @@ func (b *gpuBuffer) Upload(data []byte) {
if len(data) > b.size { if len(data) > b.size {
panic("buffer size overflow") panic("buffer size overflow")
} }
b.version++
switch b.typ {
case UNIFORM_BUFFER:
copy(b.data, data)
default:
b.backend.funcs.BindBuffer(b.typ, b.obj) b.backend.funcs.BindBuffer(b.typ, b.obj)
b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW) b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW)
} }
}
func (b *gpuBuffer) Release() { func (b *gpuBuffer) Release() {
switch b.typ {
case UNIFORM_BUFFER:
default:
b.backend.funcs.DeleteBuffer(b.obj) b.backend.funcs.DeleteBuffer(b.obj)
} }
}
func (b *gpuBuffer) BindVertex(stride, offset int) { func (b *gpuBuffer) BindVertex(stride, offset int) {
if b.typ != ARRAY_BUFFER { if b.typ != ARRAY_BUFFER {
@@ -585,6 +692,8 @@ func toBufferType(typ gpu.BufferType) Enum {
return ARRAY_BUFFER return ARRAY_BUFFER
case gpu.BufferTypeIndices: case gpu.BufferTypeIndices:
return ELEMENT_ARRAY_BUFFER return ELEMENT_ARRAY_BUFFER
case gpu.BufferTypeUniforms:
return UNIFORM_BUFFER
default: default:
panic("unsupported buffer type") panic("unsupported buffer type")
} }
+1
View File
@@ -71,6 +71,7 @@ const (
TRIANGLE_STRIP = 0x5 TRIANGLE_STRIP = 0x5
TRIANGLES = 0x4 TRIANGLES = 0x4
TRUE = 1 TRUE = 1
UNIFORM_BUFFER = 0x8A11
UNPACK_ALIGNMENT = 0xcf5 UNPACK_ALIGNMENT = 0xcf5
UNSIGNED_BYTE = 0x1401 UNSIGNED_BYTE = 0x1401
UNSIGNED_SHORT = 0x1403 UNSIGNED_SHORT = 0x1403
+148 -48
View File
@@ -13,6 +13,7 @@ import (
"image" "image"
"image/color" "image/color"
"math" "math"
"reflect"
"time" "time"
"unsafe" "unsafe"
@@ -211,17 +212,50 @@ type texture struct {
type blitter struct { type blitter struct {
ctx Backend ctx Backend
viewport image.Point viewport image.Point
prog [2]Program prog [2]*program
layout InputLayout layout InputLayout
vars [2]struct { colUniforms struct {
z Uniform vert struct {
uScale, uOffset Uniform blitUniforms
uUVScale, uUVOffset Uniform _ [8]byte // Padding to a multiple of 16.
uColor Uniform }
frag struct {
colorUniforms
}
}
texUniforms struct {
vert struct {
blitUniforms
_ [8]byte // Padding to a multiple of 16.
}
} }
quadVerts Buffer 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 type materialType uint8
const ( const (
@@ -372,10 +406,6 @@ func (r *renderer) release() {
} }
func newBlitter(ctx Backend) *blitter { 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, quadVerts := ctx.NewImmutableBuffer(BufferTypeVertices,
gunsafe.BytesView([]float32{ gunsafe.BytesView([]float32{
-1, +1, 0, 0, -1, +1, 0, 0,
@@ -386,24 +416,17 @@ func newBlitter(ctx Backend) *blitter {
) )
b := &blitter{ b := &blitter{
ctx: ctx, ctx: ctx,
prog: prog,
layout: layout,
quadVerts: quadVerts, quadVerts: quadVerts,
} }
for i, prog := range prog { prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag,
switch materialType(i) { [2]interface{}{&b.colUniforms.vert, &b.texUniforms.vert}, [2]interface{}{&b.colUniforms.frag, nil})
case materialTexture: if err != nil {
uTex := prog.UniformFor("tex") panic(err)
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")
} }
b.prog = prog
b.layout = layout
texProg := b.prog[materialTexture].prog
texProg.Uniform1i(texProg.UniformFor("tex"), 0)
return b return b
} }
@@ -415,28 +438,47 @@ func (b *blitter) release() {
b.layout.Release() b.layout.Release()
} }
func createColorPrograms(ctx Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources) ([2]Program, InputLayout, error) { func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources, vertUniforms, fragUniforms [2]interface{}) ([2]*program, InputLayout, error) {
var prog [2]Program var progs [2]*program
var err error prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture])
prog[materialTexture], err = ctx.NewProgram(vsSrc, fsSrc[materialTexture])
if err != nil { 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 { if err != nil {
prog[materialTexture].Release() progs[materialTexture].Release()
return prog, nil, err 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: 0},
{Type: DataTypeFloat, Size: 2, Offset: 4 * 2}, {Type: DataTypeFloat, Size: 2, Offset: 4 * 2},
}) })
if err != nil { if err != nil {
prog[materialTexture].Release() progs[materialTexture].Release()
prog[materialColor].Release() progs[materialColor].Release()
return prog, nil, err return progs, nil, err
} }
return prog, layout, nil return progs, layout, nil
} }
func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) { func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) {
@@ -465,7 +507,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.blitter.quadVerts.BindVertex(4*4, 0) r.blitter.quadVerts.BindVertex(4*4, 0)
r.pather.stenciler.iprogLayout.Bind() r.pather.stenciler.iprog.layout.Bind()
for _, img := range ops { for _, img := range ops {
if img.clipType != clipTypeIntersection { if img.clipType != clipTypeIntersection {
continue continue
@@ -497,8 +539,9 @@ func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) {
fbo := r.pather.stenciler.cover(p.place.Idx) fbo := r.pather.stenciler.cover(p.place.Idx)
fbo.tex.Bind(0) fbo.tex.Bind(0)
coverScale, coverOff := texSpaceTransform(toRectF(uv), fbo.size) coverScale, coverOff := texSpaceTransform(toRectF(uv), fbo.size)
r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVScale, coverScale.X, coverScale.Y) r.pather.stenciler.iprog.uniforms.vert.uvScale = [2]float32{coverScale.X, coverScale.Y}
r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVOffset, coverOff.X, coverOff.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) 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) { func (b *blitter) blit(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff f32.Point) {
p := b.prog[mat] p := b.prog[mat]
p.Bind() p.prog.Bind()
var uniforms *blitUniforms
switch mat { switch mat {
case materialColor: 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: case materialTexture:
p.Uniform2f(b.vars[mat].uUVScale, uvScale.X, uvScale.Y) b.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y}
p.Uniform2f(b.vars[mat].uUVOffset, uvOff.X, uvOff.Y) b.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y}
uniforms = &b.texUniforms.vert.blitUniforms
} }
p.Uniform1f(b.vars[mat].z, z) uniforms.z = z
p.Uniform2f(b.vars[mat].uScale, scale.X, scale.Y) uniforms.scale = [2]float32{scale.X, scale.Y}
p.Uniform2f(b.vars[mat].uOffset, off.X, off.Y) uniforms.offset = [2]float32{off.X, off.Y}
p.UploadUniforms()
b.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) 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 // texSpaceTransform return the scale and offset that transforms the given subimage
// into quad texture coordinates. // into quad texture coordinates.
func texSpaceTransform(r f32.Rectangle, bounds image.Point) (f32.Point, f32.Point) { func texSpaceTransform(r f32.Rectangle, bounds image.Point) (f32.Point, f32.Point) {
+104 -78
View File
@@ -25,30 +25,63 @@ type pather struct {
type coverer struct { type coverer struct {
ctx Backend ctx Backend
prog [2]Program prog [2]*program
layout InputLayout texUniforms struct {
vars [2]struct { vert struct {
z Uniform coverUniforms
uScale, uOffset Uniform _ [8]byte // Padding to multiple of 16.
uUVScale, uUVOffset Uniform
uCoverUVScale, uCoverUVOffset Uniform
uColor Uniform
} }
} }
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 { type stenciler struct {
ctx Backend ctx Backend
defFBO Framebuffer defFBO Framebuffer
prog Program prog struct {
progLayout InputLayout prog *program
iprog Program uniforms struct {
iprogLayout InputLayout 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 fbos fboSet
intersections fboSet intersections fboSet
uScale, uOffset Uniform
uPathOffset Uniform
uIntersectUVOffset Uniform
uIntersectUVScale Uniform
indexBuf Buffer indexBuf Buffer
} }
@@ -89,48 +122,28 @@ func newPather(ctx Backend) *pather {
} }
func newCoverer(ctx Backend) *coverer { 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 { if err != nil {
panic(err) panic(err)
} }
c := &coverer{ c.prog = prog
ctx: ctx, c.layout = layout
prog: prog, texProg := prog[materialTexture].prog
layout: layout, texProg.Uniform1i(texProg.UniformFor("tex"), 0)
} for _, p := range prog {
for i, prog := range prog { p.prog.Uniform1i(p.prog.UniformFor("cover"), 1)
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")
} }
return c return c
} }
func newStenciler(ctx Backend) *stenciler { func newStenciler(ctx Backend) *stenciler {
defFBO := ctx.DefaultFramebuffer() 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. // Allocate a suitably large index buffer for drawing paths.
indices := make([]uint16, pathBatchSize*6) indices := make([]uint16, pathBatchSize*6)
for i := 0; i < pathBatchSize; i++ { for i := 0; i < pathBatchSize; i++ {
@@ -160,20 +173,28 @@ func newStenciler(ctx Backend) *stenciler {
if err != nil { if err != nil {
panic(err) panic(err)
} }
return &stenciler{ st := &stenciler{
ctx: ctx, ctx: ctx,
defFBO: defFBO, 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, 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) { 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() { func (s *stenciler) release() {
s.fbos.delete(s.ctx, 0) s.fbos.delete(s.ctx, 0)
s.progLayout.Release() s.prog.layout.Release()
s.prog.Release() s.prog.prog.Release()
s.iprogLayout.Release() s.iprog.layout.Release()
s.iprog.Release() s.iprog.prog.Release()
s.indexBuf.Release() s.indexBuf.Release()
} }
@@ -270,7 +291,7 @@ func (s *stenciler) beginIntersect(sizes []image.Point) {
// no floating point support is available. // no floating point support is available.
s.intersections.resize(s.ctx, sizes) s.intersections.resize(s.ctx, sizes)
s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0) s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0)
s.iprog.Bind() s.iprog.prog.prog.Bind()
} }
func (s *stenciler) endIntersect() { func (s *stenciler) endIntersect() {
@@ -292,8 +313,8 @@ func (s *stenciler) begin(sizes []image.Point) {
s.ctx.BlendFunc(BlendFactorOne, BlendFactorOne) s.ctx.BlendFunc(BlendFactorOne, BlendFactorOne)
s.fbos.resize(s.ctx, sizes) s.fbos.resize(s.ctx, sizes)
s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0) s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0)
s.prog.Bind() s.prog.prog.prog.Bind()
s.progLayout.Bind() s.prog.layout.Bind()
s.indexBuf.BindIndex() 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())} texSize := f32.Point{X: float32(bounds.Dx()), Y: float32(bounds.Dy())}
scale := f32.Point{X: 2 / texSize.X, Y: 2 / texSize.Y} 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} 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.uniforms.vert.scale = [2]float32{scale.X, scale.Y}
s.prog.Uniform2f(s.uOffset, orig.X, orig.Y) s.prog.uniforms.vert.offset = [2]float32{orig.X, orig.Y}
s.prog.Uniform2f(s.uPathOffset, offset.X, offset.Y) s.prog.uniforms.vert.pathOffset = [2]float32{offset.X, offset.Y}
s.prog.prog.UploadUniforms()
// Draw in batches that fit in uint16 indices. // Draw in batches that fit in uint16 indices.
start := 0 start := 0
nquads := data.ncurves / 4 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) { func (c *coverer) cover(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff, coverScale, coverOff f32.Point) {
p := c.prog[mat] p := c.prog[mat]
p.Bind() p.prog.Bind()
var uniforms *coverUniforms
switch mat { switch mat {
case materialColor: 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: case materialTexture:
p.Uniform2f(c.vars[mat].uUVScale, uvScale.X, uvScale.Y) c.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y}
p.Uniform2f(c.vars[mat].uUVOffset, uvOff.X, uvOff.Y) c.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y}
uniforms = &c.texUniforms.vert.coverUniforms
} }
p.Uniform1f(c.vars[mat].z, z) uniforms.z = z
p.Uniform2f(c.vars[mat].uScale, scale.X, scale.Y) uniforms.scale = [2]float32{scale.X, scale.Y}
p.Uniform2f(c.vars[mat].uOffset, off.X, off.Y) uniforms.offset = [2]float32{off.X, off.Y}
p.Uniform2f(c.vars[mat].uCoverUVScale, coverScale.X, coverScale.Y) uniforms.uvCoverScale = [2]float32{coverScale.X, coverScale.Y}
p.Uniform2f(c.vars[mat].uCoverUVOffset, coverOff.X, coverOff.Y) uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y}
p.UploadUniforms()
c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4) c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4)
} }
+53 -47
View File
@@ -6,13 +6,14 @@ var (
shader_blit_frag = [...]ShaderSources{ shader_blit_frag = [...]ShaderSources{
ShaderSources{ ShaderSources{
Uniforms: []UniformLocation{ 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) cbuffer Color : register(b0)
{ {
float4 color_color : packoffset(c0); float4 _12_color : packoffset(c0);
}; };
@@ -31,7 +32,7 @@ var (
void frag_main() void frag_main()
{ {
fragColor = color_color; fragColor = _12_color;
} }
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) 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.uvScale", Type: 0, Size: 2, Offset: 24},
{Name: "_15.uvOffset", Type: 0, Size: 2, Offset: 32}, {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) cbuffer Block : register(b0)
{ {
float uniforms_z : packoffset(c0); float _15_z : packoffset(c0);
float2 uniforms_scale : packoffset(c0.z); float2 _15_scale : packoffset(c0.z);
float2 uniforms_offset : packoffset(c1); float2 _15_offset : packoffset(c1);
float2 uniforms_uvScale : packoffset(c1.z); float2 _15_uvScale : packoffset(c1.z);
float2 uniforms_uvOffset : packoffset(c2); float2 _15_uvOffset : packoffset(c2);
}; };
@@ -127,10 +129,10 @@ var (
void vert_main() void vert_main()
{ {
float2 p = pos; float2 p = pos;
p *= uniforms_scale; p *= _15_scale;
p += uniforms_offset; p += _15_offset;
gl_Position = float4(p, uniforms_z, 1.0f); gl_Position = float4(p, _15_z, 1.0f);
vUV = (uv * uniforms_uvScale) + uniforms_uvOffset; vUV = (uv * _15_uvScale) + _15_uvOffset;
} }
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
@@ -150,13 +152,14 @@ var (
shader_cover_frag = [...]ShaderSources{ shader_cover_frag = [...]ShaderSources{
ShaderSources{ ShaderSources{
Uniforms: []UniformLocation{ 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) cbuffer Color : register(b0)
{ {
float4 color_color : packoffset(c0); float4 _12_color : packoffset(c0);
}; };
Texture2D<float4> cover : register(t1); Texture2D<float4> cover : register(t1);
@@ -179,7 +182,7 @@ var (
void frag_main() void frag_main()
{ {
fragColor = color_color; fragColor = _12_color;
float cover_1 = abs(cover.Sample(_cover_sampler, vCoverUV).x); float cover_1 = abs(cover.Sample(_cover_sampler, vCoverUV).x);
fragColor *= cover_1; fragColor *= cover_1;
} }
@@ -250,22 +253,23 @@ var (
{Name: "_19.z", Type: 0, Size: 1, Offset: 0}, {Name: "_19.z", Type: 0, Size: 1, Offset: 0},
{Name: "_19.scale", Type: 0, Size: 2, Offset: 8}, {Name: "_19.scale", Type: 0, Size: 2, Offset: 8},
{Name: "_19.offset", Type: 0, Size: 2, Offset: 16}, {Name: "_19.offset", Type: 0, Size: 2, Offset: 16},
{Name: "_19.uvScale", Type: 0, Size: 2, Offset: 24}, {Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 24},
{Name: "_19.uvOffset", Type: 0, Size: 2, Offset: 32}, {Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 32},
{Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 40}, {Name: "_19.uvScale", Type: 0, Size: 2, Offset: 40},
{Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 48}, {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) cbuffer Block : register(b0)
{ {
float uniforms_z : packoffset(c0); float _19_z : packoffset(c0);
float2 uniforms_scale : packoffset(c0.z); float2 _19_scale : packoffset(c0.z);
float2 uniforms_offset : packoffset(c1); float2 _19_offset : packoffset(c1);
float2 uniforms_uvScale : packoffset(c1.z); float2 _19_uvCoverScale : packoffset(c1.z);
float2 uniforms_uvOffset : packoffset(c2); float2 _19_uvCoverOffset : packoffset(c2);
float2 uniforms_uvCoverScale : packoffset(c2.z); float2 _19_uvScale : packoffset(c2.z);
float2 uniforms_uvCoverOffset : packoffset(c3); float2 _19_uvOffset : packoffset(c3);
}; };
@@ -290,9 +294,9 @@ var (
void vert_main() void vert_main()
{ {
gl_Position = float4((pos * uniforms_scale) + uniforms_offset, uniforms_z, 1.0f); gl_Position = float4((pos * _19_scale) + _19_offset, _19_z, 1.0f);
vUV = (uv * uniforms_uvScale) + uniforms_uvOffset; vUV = (uv * _19_uvScale) + _19_uvOffset;
vCoverUV = (uv * uniforms_uvCoverScale) + uniforms_uvCoverOffset; vCoverUV = (uv * _19_uvCoverScale) + _19_uvCoverOffset;
} }
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) 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.scale", Type: 0, Size: 2, Offset: 0},
{Name: "_40.offset", Type: 0, Size: 2, Offset: 8}, {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) cbuffer Block : register(b0)
{ {
float2 uvparams_scale : packoffset(c0); float2 _40_scale : packoffset(c0);
float2 uvparams_offset : packoffset(c0.z); float2 _40_offset : packoffset(c0.z);
}; };
@@ -387,7 +392,7 @@ var (
float2 p = pos; float2 p = pos;
p.y = -p.y; p.y = -p.y;
gl_Position = float4(p, 0.0f, 1.0f); 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) 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.offset", Type: 0, Size: 2, Offset: 8},
{Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16}, {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) cbuffer Block : register(b0)
{ {
float2 uniforms_scale : packoffset(c0); float2 _15_scale : packoffset(c0);
float2 uniforms_offset : packoffset(c0.z); float2 _15_offset : packoffset(c0.z);
float2 uniforms_pathOffset : packoffset(c1); float2 _15_pathOffset : packoffset(c1);
}; };
@@ -523,10 +529,10 @@ var (
void vert_main() void vert_main()
{ {
float2 from_1 = from + uniforms_pathOffset; float2 from_1 = from + _15_pathOffset;
float2 ctrl_1 = ctrl + uniforms_pathOffset; float2 ctrl_1 = ctrl + _15_pathOffset;
float2 to_1 = to + uniforms_pathOffset; float2 to_1 = to + _15_pathOffset;
float maxy_1 = maxy + uniforms_pathOffset.y; float maxy_1 = maxy + _15_pathOffset.y;
float2 pos; float2 pos;
if (corner.x > 0.0f) if (corner.x > 0.0f)
{ {
@@ -547,8 +553,8 @@ var (
vFrom = from_1 - pos; vFrom = from_1 - pos;
vCtrl = ctrl_1 - pos; vCtrl = ctrl_1 - pos;
vTo = to_1 - pos; vTo = to_1 - pos;
pos *= uniforms_scale; pos *= _15_scale;
pos += uniforms_offset; pos += _15_offset;
gl_Position = float4(pos, 1.0f, 1.0f); gl_Position = float4(pos, 1.0f, 1.0f);
} }
+5 -5
View File
@@ -10,7 +10,7 @@ layout(binding = 0) uniform Block {
vec2 offset; vec2 offset;
vec2 uvScale; vec2 uvScale;
vec2 uvOffset; vec2 uvOffset;
} uniforms; };
layout(location = 0) in vec2 pos; layout(location = 0) in vec2 pos;
@@ -20,8 +20,8 @@ layout(location = 0) out vec2 vUV;
void main() { void main() {
vec2 p = pos; vec2 p = pos;
p *= uniforms.scale; p *= scale;
p += uniforms.offset; p += offset;
gl_Position = vec4(p, uniforms.z, 1); gl_Position = vec4(p, z, 1);
vUV = uv*uniforms.uvScale + uniforms.uvOffset; vUV = uv*uvScale + uvOffset;
} }
+4
View File
@@ -0,0 +1,4 @@
#version 310 es
void blah() {
}
+6 -6
View File
@@ -8,11 +8,11 @@ layout(binding = 0) uniform Block {
float z; float z;
vec2 scale; vec2 scale;
vec2 offset; vec2 offset;
vec2 uvScale;
vec2 uvOffset;
vec2 uvCoverScale; vec2 uvCoverScale;
vec2 uvCoverOffset; vec2 uvCoverOffset;
} uniforms; vec2 uvScale;
vec2 uvOffset;
};
layout(location = 0) in vec2 pos; layout(location = 0) in vec2 pos;
@@ -22,7 +22,7 @@ layout(location = 1) in vec2 uv;
layout(location = 1) out vec2 vUV; layout(location = 1) out vec2 vUV;
void main() { void main() {
gl_Position = vec4(pos*uniforms.scale + uniforms.offset, uniforms.z, 1); gl_Position = vec4(pos*scale + offset, z, 1);
vUV = uv*uniforms.uvScale + uniforms.uvOffset; vUV = uv*uvScale + uvOffset;
vCoverUV = uv*uniforms.uvCoverScale+uniforms.uvCoverOffset; vCoverUV = uv*uvCoverScale+uvCoverOffset;
} }
+2 -2
View File
@@ -10,7 +10,7 @@ layout(location = 1) in vec2 uv;
layout(binding = 0) uniform Block { layout(binding = 0) uniform Block {
vec2 scale; vec2 scale;
vec2 offset; vec2 offset;
} uvparams; };
layout(location = 0) out vec2 vUV; layout(location = 0) out vec2 vUV;
@@ -18,5 +18,5 @@ void main() {
vec2 p = pos; vec2 p = pos;
p.y = -p.y; p.y = -p.y;
gl_Position = vec4(p, 0, 1); gl_Position = vec4(p, 0, 1);
vUV = uv*uvparams.scale + uvparams.offset; vUV = uv*scale + offset;
} }
+7 -7
View File
@@ -8,7 +8,7 @@ layout(binding = 0) uniform Block {
vec2 scale; vec2 scale;
vec2 offset; vec2 offset;
vec2 pathOffset; vec2 pathOffset;
} uniforms; };
layout(location=0) in vec2 corner; layout(location=0) in vec2 corner;
layout(location=1) in float maxy; layout(location=1) in float maxy;
@@ -24,10 +24,10 @@ void main() {
// Add a one pixel overlap so curve quads cover their // Add a one pixel overlap so curve quads cover their
// entire curves. Could use conservative rasterization // entire curves. Could use conservative rasterization
// if available. // if available.
vec2 from = from + uniforms.pathOffset; vec2 from = from + pathOffset;
vec2 ctrl = ctrl + uniforms.pathOffset; vec2 ctrl = ctrl + pathOffset;
vec2 to = to + uniforms.pathOffset; vec2 to = to + pathOffset;
float maxy = maxy + uniforms.pathOffset.y; float maxy = maxy + pathOffset.y;
vec2 pos; vec2 pos;
if (corner.x > 0.0) { if (corner.x > 0.0) {
// East. // East.
@@ -46,8 +46,8 @@ void main() {
vFrom = from-pos; vFrom = from-pos;
vCtrl = ctrl-pos; vCtrl = ctrl-pos;
vTo = to-pos; vTo = to-pos;
pos *= uniforms.scale; pos *= scale;
pos += uniforms.offset; pos += offset;
gl_Position = vec4(pos, 1, 1); gl_Position = vec4(pos, 1, 1);
} }