Skip to content

Commit

Permalink
Rebuild programs with shader source from their link state.
Browse files Browse the repository at this point in the history
Use the shaders and their source as they were when the program was
linked, not using the program state on serialization. Shaders can be
detached, have their source change, and even deleted, while the program
that they were used to link stays unaffected.
  • Loading branch information
pmuetschard committed Jun 29, 2018
1 parent 0a64725 commit fe2042f
Showing 1 changed file with 36 additions and 7 deletions.
43 changes: 36 additions & 7 deletions gapis/api/gles/state_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,14 @@ func (sb *stateBuilder) contextObject(ctx context.Context, handle EGLContext, c
}
}
if objs := c.Objects().Programs(); sb.once(objs) {
// Get the largest used shader ID.
maxID := uint32(0)
if l := c.Objects().Shaders().Len(); l > 0 {
maxID = uint32(c.Objects().Shaders().Keys()[l-1])
}
for _, id := range objs.Keys() {
if o := c.Objects().Programs().Get(id); !o.IsNil() {
sb.programObject(ctx, o)
sb.programObject(ctx, o, maxID+1)
}
}
}
Expand Down Expand Up @@ -625,15 +630,10 @@ func (sb *stateBuilder) shaderObject(ctx context.Context, s Shaderʳ) {
write(cb.GlShaderSource(id, 1, sb.readsData(ctx, sb.readsData(ctx, s.Source())), memory.Nullptr))
}

func (sb *stateBuilder) programObject(ctx context.Context, p Programʳ) {
func (sb *stateBuilder) programObject(ctx context.Context, p Programʳ, firstShaderID uint32) {
write, cb, id := sb.write, sb.cb, p.GetID()

write(cb.GlCreateProgram(id))
for _, s := range p.Shaders().All() {
if s := s.GetID(); s != 0 {
write(cb.GlAttachShader(id, s))
}
}
for name, location := range p.AttributeBindings().All() {
write(cb.GlBindAttribLocation(id, location, sb.readsData(ctx, name)))
}
Expand All @@ -658,6 +658,23 @@ func (sb *stateBuilder) programObject(ctx context.Context, p Programʳ) {
if !p.LinkExtra().Binary().IsNil() {
sb.E(ctx, "Precompiled programs not suppored yet") // TODO
}

// Create the shaders from the extra.
attachedShaders := []ShaderId{}
for t, s := range p.LinkExtra().Shaders().All() {
if !s.Binary().IsNil() {
sb.E(ctx, "Precompiled programs not suppored yet") // TODO
continue
}
shaderID := ShaderId(firstShaderID)
firstShaderID++
write(cb.GlCreateShader(t, shaderID))
write(cb.GlShaderSource(shaderID, 1, sb.readsData(ctx, sb.readsData(ctx, s.Source())), memory.Nullptr))
write(api.WithExtras(cb.GlCompileShader(shaderID), s.Get().Clone(cb.Arena, sb.cloneCtx)))
write(cb.GlAttachShader(id, shaderID))
attachedShaders = append(attachedShaders, shaderID)
}

write(api.WithExtras(cb.GlLinkProgram(id), p.LinkExtra().Get().Clone(cb.Arena, sb.cloneCtx)))
write(cb.GlUseProgram(id))
for _, u := range p.ActiveResources().DefaultUniformBlock().All() {
Expand All @@ -666,10 +683,22 @@ func (sb *stateBuilder) programObject(ctx context.Context, p Programʳ) {
}
}
write(cb.GlUseProgram(0))

// Detach and delete the linked shaders (we'll attach the shaders from the state below).
for _, shaderID := range attachedShaders {
write(cb.GlDetachShader(id, shaderID))
write(cb.GlDeleteShader(shaderID))
}
}
if !p.ValidateExtra().IsNil() {
write(api.WithExtras(cb.GlValidateProgram(id), p.ValidateExtra().Get().Clone(cb.Arena, sb.cloneCtx)))
}

for _, s := range p.Shaders().All() {
if s := s.GetID(); s != 0 {
write(cb.GlAttachShader(id, s))
}
}
}

func (sb *stateBuilder) uniform(ctx context.Context, ty GLenum, loc UniformLocation, n GLsizei, v memory.Pointer) {
Expand Down

0 comments on commit fe2042f

Please sign in to comment.