From 46cf09197bea2f4e2f33031e659a19dc8c94ad53 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 7 Sep 2024 21:58:42 +0900 Subject: [PATCH] internal/graphicscommand: enable to show shader names --- gameforui.go | 2 +- internal/atlas/shader.go | 8 +++++--- internal/atlas/shader_test.go | 6 +++--- internal/graphicscommand/command.go | 7 ++++++- internal/graphicscommand/image_test.go | 4 ++-- internal/graphicscommand/shader.go | 8 +++++--- internal/restorable/shader.go | 14 ++++++++------ internal/restorable/shader_test.go | 10 +++++----- internal/ui/shader.go | 4 ++-- shader.go | 24 ++++++++++++++++++++++-- 10 files changed, 59 insertions(+), 28 deletions(-) diff --git a/gameforui.go b/gameforui.go index d86e4fda8..6fe678341 100644 --- a/gameforui.go +++ b/gameforui.go @@ -46,7 +46,7 @@ func newGameForUI(game Game, transparent bool) *gameForUI { transparent: transparent, } - s, err := NewShader(builtinshader.ScreenShaderSource) + s, err := newShader(builtinshader.ScreenShaderSource, "screen") if err != nil { panic(fmt.Sprintf("ebiten: compiling the screen shader failed: %v", err)) } diff --git a/internal/atlas/shader.go b/internal/atlas/shader.go index f2ff046ed..86f9670f3 100644 --- a/internal/atlas/shader.go +++ b/internal/atlas/shader.go @@ -24,12 +24,14 @@ import ( type Shader struct { ir *shaderir.Program shader *restorable.Shader + name string } -func NewShader(ir *shaderir.Program) *Shader { +func NewShader(ir *shaderir.Program, name string) *Shader { // A shader is initialized lazily, and the lock is not needed. return &Shader{ - ir: ir, + ir: ir, + name: name, } } @@ -45,7 +47,7 @@ func (s *Shader) ensureShader() *restorable.Shader { if s.shader != nil { return s.shader } - s.shader = restorable.NewShader(s.ir) + s.shader = restorable.NewShader(s.ir, s.name) runtime.SetFinalizer(s, (*Shader).finalize) return s.shader } diff --git a/internal/atlas/shader_test.go b/internal/atlas/shader_test.go index 4a0a701bc..5955806b8 100644 --- a/internal/atlas/shader_test.go +++ b/internal/atlas/shader_test.go @@ -36,12 +36,12 @@ func TestShaderFillTwice(t *testing.T) { is := graphics.QuadIndices() dr := image.Rect(0, 0, w, h) g := ui.Get().GraphicsDriverForTesting() - s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff)) + s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff), "") dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s0, nil, graphicsdriver.FillRuleFillAll) // Vertices must be recreated (#1755) vs = quadVertices(w, h, 0, 0, 1) - s1 := atlas.NewShader(etesting.ShaderProgramFill(0x80, 0x80, 0x80, 0xff)) + s1 := atlas.NewShader(etesting.ShaderProgramFill(0x80, 0x80, 0x80, 0xff), "") dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s1, nil, graphicsdriver.FillRuleFillAll) pix := make([]byte, 4*w*h) @@ -89,7 +89,7 @@ func TestImageDrawTwice(t *testing.T) { } func TestGCShader(t *testing.T) { - s := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff)) + s := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff), "") // Use the shader to initialize it. const w, h = 1, 1 diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index 01ec96871..536a02c52 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -107,7 +107,12 @@ func (c *drawTrianglesCommand) String() string { } } - return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader id: %d", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, c.shader.id) + shader := fmt.Sprintf("%d", c.shader.id) + if c.shader.name != "" { + shader += " (" + c.shader.name + ")" + } + + return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader: %s", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, shader) } // Exec executes the drawTrianglesCommand. diff --git a/internal/graphicscommand/image_test.go b/internal/graphicscommand/image_test.go index 946d9c736..fb3151dea 100644 --- a/internal/graphicscommand/image_test.go +++ b/internal/graphicscommand/image_test.go @@ -35,7 +35,7 @@ func init() { if err != nil { panic(fmt.Sprintf("graphicscommand: compiling the nearest shader failed: %v", err)) } - nearestFilterShader = graphicscommand.NewShader(ir) + nearestFilterShader = graphicscommand.NewShader(ir, "") } func TestMain(m *testing.M) { @@ -109,7 +109,7 @@ func TestShader(t *testing.T) { dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillRuleFillAll) g := ui.Get().GraphicsDriverForTesting() - s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff)) + s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "") dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll) pix := make([]byte, 4*w*h) diff --git a/internal/graphicscommand/shader.go b/internal/graphicscommand/shader.go index 989cb9319..d55c82eb2 100644 --- a/internal/graphicscommand/shader.go +++ b/internal/graphicscommand/shader.go @@ -31,12 +31,14 @@ type Shader struct { shader graphicsdriver.Shader ir *shaderir.Program id int + name string } -func NewShader(ir *shaderir.Program) *Shader { +func NewShader(ir *shaderir.Program, name string) *Shader { s := &Shader{ - ir: ir, - id: genNextShaderID(), + ir: ir, + id: genNextShaderID(), + name: name, } c := &newShaderCommand{ result: s, diff --git a/internal/restorable/shader.go b/internal/restorable/shader.go index acf94504e..3a13643b9 100644 --- a/internal/restorable/shader.go +++ b/internal/restorable/shader.go @@ -28,12 +28,14 @@ import ( type Shader struct { shader *graphicscommand.Shader ir *shaderir.Program + name string } -func NewShader(ir *shaderir.Program) *Shader { +func NewShader(ir *shaderir.Program, name string) *Shader { s := &Shader{ - shader: graphicscommand.NewShader(ir), + shader: graphicscommand.NewShader(ir, name), ir: ir, + name: name, } theImages.addShader(s) return s @@ -47,7 +49,7 @@ func (s *Shader) Dispose() { } func (s *Shader) restore() { - s.shader = graphicscommand.NewShader(s.ir) + s.shader = graphicscommand.NewShader(s.ir, s.name) } func (s *Shader) Unit() shaderir.Unit { @@ -90,7 +92,7 @@ func init() { if err := wg.Wait(); err != nil { panic(err) } - NearestFilterShader = NewShader(nearestIR) - LinearFilterShader = NewShader(linearIR) - clearShader = NewShader(clearIR) + NearestFilterShader = NewShader(nearestIR, "nearest") + LinearFilterShader = NewShader(linearIR, "linear") + clearShader = NewShader(clearIR, "clear") } diff --git a/internal/restorable/shader_test.go b/internal/restorable/shader_test.go index ea78f2b78..05f6fbdb4 100644 --- a/internal/restorable/shader_test.go +++ b/internal/restorable/shader_test.go @@ -53,7 +53,7 @@ func TestShader(t *testing.T) { img := restorable.NewImage(1, 1, restorable.ImageTypeRegular) defer img.Dispose() - s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff)) + s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "") dr := image.Rect(0, 0, 1, 1) img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll) @@ -82,7 +82,7 @@ func TestShaderChain(t *testing.T) { imgs[0].WritePixels(bytesToManagedBytes([]byte{0xff, 0, 0, 0xff}), image.Rect(0, 0, 1, 1)) - s := restorable.NewShader(etesting.ShaderProgramImages(1)) + s := restorable.NewShader(etesting.ShaderProgramImages(1), "") for i := 0; i < num-1; i++ { dr := image.Rect(0, 0, 1, 1) imgs[i+1].DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll) @@ -115,7 +115,7 @@ func TestShaderMultipleSources(t *testing.T) { dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular) - s := restorable.NewShader(etesting.ShaderProgramImages(3)) + s := restorable.NewShader(etesting.ShaderProgramImages(3), "") dr := image.Rect(0, 0, 1, 1) dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll) @@ -147,7 +147,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) { dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular) - s := restorable.NewShader(etesting.ShaderProgramImages(3)) + s := restorable.NewShader(etesting.ShaderProgramImages(3), "") dr := image.Rect(0, 0, 1, 1) srcRegions := [graphics.ShaderSrcImageCount]image.Rectangle{ image.Rect(0, 0, 1, 1), @@ -177,7 +177,7 @@ func TestShaderDispose(t *testing.T) { img := restorable.NewImage(1, 1, restorable.ImageTypeRegular) defer img.Dispose() - s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff)) + s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "") dr := image.Rect(0, 0, 1, 1) img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll) diff --git a/internal/ui/shader.go b/internal/ui/shader.go index 0d9031a92..10589e72d 100644 --- a/internal/ui/shader.go +++ b/internal/ui/shader.go @@ -32,9 +32,9 @@ type Shader struct { uniformUint32Count int } -func NewShader(ir *shaderir.Program) *Shader { +func NewShader(ir *shaderir.Program, name string) *Shader { return &Shader{ - shader: atlas.NewShader(ir), + shader: atlas.NewShader(ir, name), uniformNames: ir.UniformNames[graphics.PreservedUniformVariablesCount:], uniformTypes: ir.Uniforms[graphics.PreservedUniformVariablesCount:], } diff --git a/shader.go b/shader.go index 7ae669da4..93f4fa673 100644 --- a/shader.go +++ b/shader.go @@ -38,12 +38,16 @@ type Shader struct { // // For the details about the shader, see https://ebitengine.org/en/documents/shader.html. func NewShader(src []byte) (*Shader, error) { + return newShader(src, "") +} + +func newShader(src []byte, name string) (*Shader, error) { ir, err := graphics.CompileShader(src) if err != nil { return nil, err } return &Shader{ - shader: ui.NewShader(ir), + shader: ui.NewShader(ir, name), unit: ir.Unit, }, nil } @@ -108,7 +112,23 @@ func builtinShader(filter builtinshader.Filter, address builtinshader.Address, u } } else { src := builtinshader.ShaderSource(filter, address, useColorM) - s, err := NewShader(src) + var name string + switch filter { + case builtinshader.FilterNearest: + name = "nearest" + case builtinshader.FilterLinear: + name = "linear" + } + switch address { + case builtinshader.AddressClampToZero: + name += "-clamptozero" + case builtinshader.AddressRepeat: + name += "-repeat" + } + if useColorM { + name += "-colorm" + } + s, err := newShader(src, name) if err != nil { panic(fmt.Sprintf("ebiten: NewShader for a built-in shader failed: %v", err)) }