mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-04 17:05:38 +00:00
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:
+8
-7
@@ -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 (
|
||||
|
||||
+19
-14
@@ -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) {
|
||||
|
||||
+135
-26
@@ -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")
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ const (
|
||||
TRIANGLE_STRIP = 0x5
|
||||
TRIANGLES = 0x4
|
||||
TRUE = 1
|
||||
UNIFORM_BUFFER = 0x8A11
|
||||
UNPACK_ALIGNMENT = 0xcf5
|
||||
UNSIGNED_BYTE = 0x1401
|
||||
UNSIGNED_SHORT = 0x1403
|
||||
|
||||
+151
-51
@@ -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) {
|
||||
|
||||
+113
-87
@@ -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)
|
||||
}
|
||||
|
||||
+53
-47
@@ -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<float4> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#version 310 es
|
||||
|
||||
void blah() {
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user