mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
driver: Add AddressUnsafe
This skips the source-region check and reduces 'if' branches from shader programs. AddressUnsafe is internal only so far. We might expose this value later. Updates #1210
This commit is contained in:
parent
bfc2fffba6
commit
2a63512c6e
2
image.go
2
image.go
@ -471,7 +471,7 @@ func (i *Image) DrawTrianglesWithShader(vertices []Vertex, indices []uint16, sha
|
||||
is := make([]uint16, len(indices))
|
||||
copy(is, indices)
|
||||
|
||||
i.buffered.DrawTriangles(nil, vs, is, nil, mode, driver.FilterNearest, driver.AddressClampToZero, shader.shader, us)
|
||||
i.buffered.DrawTriangles(nil, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, shader.shader, us)
|
||||
}
|
||||
|
||||
// SubImage returns an image representing the portion of the image p visible through r.
|
||||
|
@ -27,4 +27,5 @@ type Address int
|
||||
const (
|
||||
AddressClampToZero Address = iota
|
||||
AddressRepeat
|
||||
AddressUnsafe
|
||||
)
|
||||
|
@ -386,6 +386,8 @@ func (c *drawTrianglesCommand) String() string {
|
||||
address = "clamp_to_zero"
|
||||
case driver.AddressRepeat:
|
||||
address = "repeat"
|
||||
case driver.AddressUnsafe:
|
||||
address = "unsafe"
|
||||
default:
|
||||
panic(fmt.Sprintf("graphicscommand: invalid address: %d", c.address))
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func TestClear(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w/2, h/2)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels()
|
||||
if err != nil {
|
||||
@ -74,8 +74,8 @@ func TestReplacePixelsPartAfterDrawTriangles(t *testing.T) {
|
||||
dst := NewImage(w, h)
|
||||
vs := quadVertices(w/2, h/2)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(clr, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(clr, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ func TestShader(t *testing.T) {
|
||||
dst := NewImage(w, h)
|
||||
vs := quadVertices(w, h)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(clr, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(clr, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
|
@ -53,6 +53,7 @@ const source = `#include <metal_stdlib>
|
||||
|
||||
#define ADDRESS_CLAMP_TO_ZERO {{.AddressClampToZero}}
|
||||
#define ADDRESS_REPEAT {{.AddressRepeat}}
|
||||
#define ADDRESS_UNSAFE {{.AddressUnsafe}}
|
||||
|
||||
using namespace metal;
|
||||
|
||||
@ -72,7 +73,7 @@ struct VertexOut {
|
||||
|
||||
vertex VertexOut VertexShader(
|
||||
uint vid [[vertex_id]],
|
||||
device VertexIn* vertices [[buffer(0)]],
|
||||
const device VertexIn* vertices [[buffer(0)]],
|
||||
constant float2& viewport_size [[buffer(1)]]
|
||||
) {
|
||||
float4x4 projectionMatrix = float4x4(
|
||||
@ -118,6 +119,15 @@ inline float2 AdjustTexelByAddress<ADDRESS_REPEAT>(float2 p, float4 tex_region)
|
||||
template<uint8_t filter, uint8_t address>
|
||||
struct ColorFromTexel;
|
||||
|
||||
template<>
|
||||
struct ColorFromTexel<FILTER_NEAREST, ADDRESS_UNSAFE> {
|
||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||
float2 p = v.tex;
|
||||
constexpr sampler texture_sampler(filter::nearest);
|
||||
return texture.sample(texture_sampler, p);
|
||||
}
|
||||
};
|
||||
|
||||
template<uint8_t address>
|
||||
struct ColorFromTexel<FILTER_NEAREST, address> {
|
||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||
@ -133,6 +143,27 @@ struct ColorFromTexel<FILTER_NEAREST, address> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorFromTexel<FILTER_LINEAR, ADDRESS_UNSAFE> {
|
||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||
constexpr sampler texture_sampler(filter::nearest);
|
||||
const float2 texel_size = 1 / source_size;
|
||||
|
||||
// Shift 1/512 [texel] to avoid the tie-breaking issue.
|
||||
// As all the vertex positions are aligned to 1/16 [pixel], this shiting should work in most cases.
|
||||
float2 p0 = v.tex - texel_size / 2.0 + (texel_size / 512.0);
|
||||
float2 p1 = v.tex + texel_size / 2.0 + (texel_size / 512.0);
|
||||
|
||||
float4 c0 = texture.sample(texture_sampler, p0);
|
||||
float4 c1 = texture.sample(texture_sampler, float2(p1.x, p0.y));
|
||||
float4 c2 = texture.sample(texture_sampler, float2(p0.x, p1.y));
|
||||
float4 c3 = texture.sample(texture_sampler, p1);
|
||||
|
||||
float2 rate = fract(p0 * source_size);
|
||||
return mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
|
||||
}
|
||||
};
|
||||
|
||||
template<uint8_t address>
|
||||
struct ColorFromTexel<FILTER_LINEAR, address> {
|
||||
inline float4 Do(VertexOut v, texture2d<float> texture, constant float2& source_size, float scale) {
|
||||
@ -252,12 +283,16 @@ FragmentShaderFunc(0, FILTER_NEAREST, ADDRESS_CLAMP_TO_ZERO)
|
||||
FragmentShaderFunc(0, FILTER_LINEAR, ADDRESS_CLAMP_TO_ZERO)
|
||||
FragmentShaderFunc(0, FILTER_NEAREST, ADDRESS_REPEAT)
|
||||
FragmentShaderFunc(0, FILTER_LINEAR, ADDRESS_REPEAT)
|
||||
FragmentShaderFunc(0, FILTER_NEAREST, ADDRESS_UNSAFE)
|
||||
FragmentShaderFunc(0, FILTER_LINEAR, ADDRESS_UNSAFE)
|
||||
FragmentShaderFunc(1, FILTER_NEAREST, ADDRESS_CLAMP_TO_ZERO)
|
||||
FragmentShaderFunc(1, FILTER_LINEAR, ADDRESS_CLAMP_TO_ZERO)
|
||||
FragmentShaderFunc(1, FILTER_NEAREST, ADDRESS_REPEAT)
|
||||
FragmentShaderFunc(1, FILTER_LINEAR, ADDRESS_REPEAT)
|
||||
FragmentShaderFunc(1, FILTER_NEAREST, ADDRESS_UNSAFE)
|
||||
FragmentShaderFunc(1, FILTER_LINEAR, ADDRESS_UNSAFE)
|
||||
|
||||
FragmentShaderFunc(0, FILTER_SCREEN, ADDRESS_CLAMP_TO_ZERO)
|
||||
FragmentShaderFunc(0, FILTER_SCREEN, ADDRESS_UNSAFE)
|
||||
|
||||
#undef FragmentShaderFuncName
|
||||
`
|
||||
@ -481,6 +516,7 @@ func (g *Graphics) Reset() error {
|
||||
"{{.FilterScreen}}": fmt.Sprintf("%d", driver.FilterScreen),
|
||||
"{{.AddressClampToZero}}": fmt.Sprintf("%d", driver.AddressClampToZero),
|
||||
"{{.AddressRepeat}}": fmt.Sprintf("%d", driver.AddressRepeat),
|
||||
"{{.AddressUnsafe}}": fmt.Sprintf("%d", driver.AddressUnsafe),
|
||||
}
|
||||
src := source
|
||||
for k, v := range replaces {
|
||||
@ -496,7 +532,7 @@ func (g *Graphics) Reset() error {
|
||||
return err
|
||||
}
|
||||
fs, err := lib.MakeFunction(
|
||||
fmt.Sprintf("FragmentShader_%d_%d_%d", 0, driver.FilterScreen, driver.AddressClampToZero))
|
||||
fmt.Sprintf("FragmentShader_%d_%d_%d", 0, driver.FilterScreen, driver.AddressUnsafe))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -540,6 +576,7 @@ func (g *Graphics) Reset() error {
|
||||
for _, a := range []driver.Address{
|
||||
driver.AddressClampToZero,
|
||||
driver.AddressRepeat,
|
||||
driver.AddressUnsafe,
|
||||
} {
|
||||
for _, f := range []driver.Filter{
|
||||
driver.FilterNearest,
|
||||
|
@ -65,6 +65,7 @@ func fragmentShaderStr(useColorM bool, filter driver.Filter, address driver.Addr
|
||||
replaces := map[string]string{
|
||||
"{{.AddressClampToZero}}": fmt.Sprintf("%d", driver.AddressClampToZero),
|
||||
"{{.AddressRepeat}}": fmt.Sprintf("%d", driver.AddressRepeat),
|
||||
"{{.AddressUnsafe}}": fmt.Sprintf("%d", driver.AddressUnsafe),
|
||||
}
|
||||
src := shaderStrFragment
|
||||
for k, v := range replaces {
|
||||
@ -93,6 +94,8 @@ func fragmentShaderStr(useColorM bool, filter driver.Filter, address driver.Addr
|
||||
defs = append(defs, "#define ADDRESS_CLAMP_TO_ZERO")
|
||||
case driver.AddressRepeat:
|
||||
defs = append(defs, "#define ADDRESS_REPEAT")
|
||||
case driver.AddressUnsafe:
|
||||
defs = append(defs, "#define ADDRESS_UNSAFE")
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid address: %d", address))
|
||||
}
|
||||
@ -173,6 +176,10 @@ highp vec2 adjustTexelByAddress(highp vec2 p, highp vec4 tex_region) {
|
||||
highp vec2 size = vec2(tex_region[2] - tex_region[0], tex_region[3] - tex_region[1]);
|
||||
return vec2(floorMod((p.x - o.x), size.x) + o.x, floorMod((p.y - o.y), size.y) + o.y);
|
||||
#endif
|
||||
|
||||
#if defined(ADDRESS_UNSAFE)
|
||||
return p;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
@ -180,6 +187,9 @@ void main(void) {
|
||||
|
||||
#if defined(FILTER_NEAREST)
|
||||
vec4 color;
|
||||
# if defined(ADDRESS_UNSAFE)
|
||||
color = texture2D(texture, pos);
|
||||
# else
|
||||
pos = adjustTexelByAddress(pos, varying_tex_region);
|
||||
if (varying_tex_region[0] <= pos.x &&
|
||||
varying_tex_region[1] <= pos.y &&
|
||||
@ -189,6 +199,7 @@ void main(void) {
|
||||
} else {
|
||||
color = vec4(0, 0, 0, 0);
|
||||
}
|
||||
# endif // defined(ADDRESS_UNSAFE)
|
||||
#endif
|
||||
|
||||
#if defined(FILTER_LINEAR)
|
||||
@ -200,13 +211,16 @@ void main(void) {
|
||||
highp vec2 p0 = pos - (texel_size) / 2.0 + (texel_size / 512.0);
|
||||
highp vec2 p1 = pos + (texel_size) / 2.0 + (texel_size / 512.0);
|
||||
|
||||
# if !defined(ADDRESS_UNSAFE)
|
||||
p0 = adjustTexelByAddress(p0, varying_tex_region);
|
||||
p1 = adjustTexelByAddress(p1, varying_tex_region);
|
||||
# endif // defined(ADDRESS_UNSAFE)
|
||||
|
||||
vec4 c0 = texture2D(texture, p0);
|
||||
vec4 c1 = texture2D(texture, vec2(p1.x, p0.y));
|
||||
vec4 c2 = texture2D(texture, vec2(p0.x, p1.y));
|
||||
vec4 c3 = texture2D(texture, p1);
|
||||
# if !defined(ADDRESS_UNSAFE)
|
||||
if (p0.x < varying_tex_region[0]) {
|
||||
c0 = vec4(0, 0, 0, 0);
|
||||
c2 = vec4(0, 0, 0, 0);
|
||||
@ -223,6 +237,7 @@ void main(void) {
|
||||
c2 = vec4(0, 0, 0, 0);
|
||||
c3 = vec4(0, 0, 0, 0);
|
||||
}
|
||||
# endif // defined(ADDRESS_UNSAFE)
|
||||
|
||||
vec2 rate = fract(p0 * source_size);
|
||||
color = mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y);
|
||||
|
@ -184,6 +184,7 @@ func (s *openGLState) reset(context *context) error {
|
||||
for _, a := range []driver.Address{
|
||||
driver.AddressClampToZero,
|
||||
driver.AddressRepeat,
|
||||
driver.AddressUnsafe,
|
||||
} {
|
||||
for _, f := range []driver.Filter{
|
||||
driver.FilterNearest,
|
||||
|
@ -151,7 +151,7 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color
|
||||
if level == 0 {
|
||||
vs := quadVertices(bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y, a, b, c, d, tx, ty, cr, cg, cb, ca, screen)
|
||||
is := graphics.QuadIndices()
|
||||
m.orig.DrawTriangles(src.orig, vs, is, colorm, mode, filter, driver.AddressClampToZero, nil, nil)
|
||||
m.orig.DrawTriangles(src.orig, vs, is, colorm, mode, filter, driver.AddressUnsafe, nil, nil)
|
||||
} else if buf := src.level(bounds, level); buf != nil {
|
||||
w, h := sizeForLevel(bounds.Dx(), bounds.Dy(), level)
|
||||
s := pow2(level)
|
||||
@ -161,7 +161,7 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color
|
||||
d *= s
|
||||
vs := quadVertices(0, 0, w, h, a, b, c, d, tx, ty, cr, cg, cb, ca, false)
|
||||
is := graphics.QuadIndices()
|
||||
m.orig.DrawTriangles(buf, vs, is, colorm, mode, filter, driver.AddressClampToZero, nil, nil)
|
||||
m.orig.DrawTriangles(buf, vs, is, colorm, mode, filter, driver.AddressUnsafe, nil, nil)
|
||||
}
|
||||
m.disposeMipmaps()
|
||||
}
|
||||
@ -268,7 +268,7 @@ func (m *Mipmap) level(r image.Rectangle, level int) *shareable.Image {
|
||||
return nil
|
||||
}
|
||||
s := shareable.NewImage(w2, h2, m.volatile)
|
||||
s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressClampToZero, nil, nil)
|
||||
s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressUnsafe, nil, nil)
|
||||
imgs[level] = s
|
||||
|
||||
return imgs[level]
|
||||
|
@ -258,7 +258,7 @@ func fillImage(i *graphicscommand.Image, clr color.RGBA) {
|
||||
vs := quadVertices(0, 0, float32(dw), float32(dh), 0, 0, float32(sw), float32(sh), rf, gf, bf, af)
|
||||
is := graphics.QuadIndices()
|
||||
|
||||
i.DrawTriangles(emptyImage.image, vs, is, nil, compositemode, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
i.DrawTriangles(emptyImage.image, vs, is, nil, compositemode, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
}
|
||||
|
||||
// BasePixelsForTesting returns the image's basePixels for testing.
|
||||
|
@ -131,7 +131,7 @@ func TestRestoreChain(t *testing.T) {
|
||||
for i := 0; i < num-1; i++ {
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
imgs[i+1].DrawTriangles(imgs[i], vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
imgs[i+1].DrawTriangles(imgs[i], vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
}
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -173,10 +173,10 @@ func TestRestoreChain2(t *testing.T) {
|
||||
imgs[8].ReplacePixels([]byte{clr8.R, clr8.G, clr8.B, clr8.A}, 0, 0, w, h)
|
||||
|
||||
is := graphics.QuadIndices()
|
||||
imgs[8].DrawTriangles(imgs[7], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
imgs[9].DrawTriangles(imgs[8], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
imgs[8].DrawTriangles(imgs[7], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
imgs[9].DrawTriangles(imgs[8], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
for i := 0; i < 7; i++ {
|
||||
imgs[i+1].DrawTriangles(imgs[i], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
imgs[i+1].DrawTriangles(imgs[i], quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
}
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -216,10 +216,10 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
||||
img1.ReplacePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, w, h)
|
||||
is := graphics.QuadIndices()
|
||||
img2.DrawTriangles(img1, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img3.DrawTriangles(img2, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img2.DrawTriangles(img1, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img3.DrawTriangles(img2, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img0.ReplacePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
|
||||
img1.DrawTriangles(img0, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img0, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -298,23 +298,23 @@ func TestRestoreComplexGraph(t *testing.T) {
|
||||
}()
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img3.DrawTriangles(img0, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img3.DrawTriangles(img0, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img3.DrawTriangles(img1, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img3.DrawTriangles(img1, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img4.DrawTriangles(img1, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img4.DrawTriangles(img1, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 2, 0)
|
||||
img4.DrawTriangles(img2, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img4.DrawTriangles(img2, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img5.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img5.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img6.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img6.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img6.DrawTriangles(img4, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img6.DrawTriangles(img4, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img7.DrawTriangles(img2, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img7.DrawTriangles(img2, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
vs = quadVertices(w, h, 2, 0)
|
||||
img7.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img7.DrawTriangles(img3, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -406,8 +406,8 @@ func TestRestoreRecursive(t *testing.T) {
|
||||
img0.Dispose()
|
||||
}()
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img0, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img0.DrawTriangles(img1, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img0, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img0.DrawTriangles(img1, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -501,7 +501,7 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
||||
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img0, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img0, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -538,8 +538,8 @@ func TestDispose(t *testing.T) {
|
||||
defer img2.Dispose()
|
||||
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img2, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img0.DrawTriangles(img1, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img2, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img0.DrawTriangles(img1, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img1.Dispose()
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -647,7 +647,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
||||
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img0, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img0, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
||||
|
||||
// BasePixelsForTesting is available without GPU accessing.
|
||||
@ -700,7 +700,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
||||
src.ReplacePixels(pix, 0, 0, w, h)
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
||||
// stale.
|
||||
@ -721,7 +721,7 @@ func TestAllowReplacePixelsAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4*w*h), 0, 0, w, h)
|
||||
// ReplacePixels for a whole image doesn't panic.
|
||||
}
|
||||
@ -739,7 +739,7 @@ func TestDisallowReplacePixelsForPartAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||
}
|
||||
|
||||
@ -828,7 +828,7 @@ func TestFill2(t *testing.T) {
|
||||
dst := NewImage(w, h, false)
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
// Fill src with a different color. This should not affect dst.
|
||||
src.Fill(color.RGBA{0, 0xff, 0, 0xff})
|
||||
@ -867,7 +867,7 @@ func TestMutateSlices(t *testing.T) {
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := make([]uint16, len(graphics.QuadIndices()))
|
||||
copy(is, graphics.QuadIndices())
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
for i := range vs {
|
||||
vs[i] = 0
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func TestShader(t *testing.T) {
|
||||
us := []interface{}{
|
||||
[]float32{0, 0},
|
||||
}
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, s, us)
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -76,7 +76,7 @@ func TestShaderChain(t *testing.T) {
|
||||
[]float32{0, 0},
|
||||
imgs[i],
|
||||
}
|
||||
imgs[i+1].DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
imgs[i+1].DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, s, us)
|
||||
}
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -120,7 +120,7 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
srcs[2],
|
||||
[]float32{0, 0, 1, 1},
|
||||
}
|
||||
dst.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
dst.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, s, us)
|
||||
|
||||
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
||||
srcs[0].Fill(color.RGBA{})
|
||||
@ -152,7 +152,7 @@ func TestShaderDispose(t *testing.T) {
|
||||
us := []interface{}{
|
||||
[]float32{0, 0},
|
||||
}
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, s, us)
|
||||
|
||||
// Dispose the shader. This should invalidates all the images using this shader i.e., all the images become
|
||||
// stale.
|
||||
|
@ -220,7 +220,7 @@ func (i *Image) ensureNotShared() {
|
||||
dx1, dy1, sx1, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1,
|
||||
}
|
||||
is := graphics.QuadIndices()
|
||||
newImg.DrawTriangles(i.backend.restorable, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
newImg.DrawTriangles(i.backend.restorable, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
i.dispose(false)
|
||||
i.backend = &backend{
|
||||
|
@ -89,7 +89,7 @@ func TestEnsureNotShared(t *testing.T) {
|
||||
// img4.ensureNotShared() should be called.
|
||||
vs := quadVertices(size/2, size/2, size/4, size/4, 1)
|
||||
is := graphics.QuadIndices()
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
want := false
|
||||
if got := img4.IsSharedForTesting(); got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
@ -119,7 +119,7 @@ func TestEnsureNotShared(t *testing.T) {
|
||||
|
||||
// Check further drawing doesn't cause panic.
|
||||
// This bug was fixed by 03dcd948.
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img4.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
}
|
||||
|
||||
func TestReshared(t *testing.T) {
|
||||
@ -159,7 +159,7 @@ func TestReshared(t *testing.T) {
|
||||
// Use img1 as a render target.
|
||||
vs := quadVertices(size, size, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles(img2, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img1.DrawTriangles(img2, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -169,7 +169,7 @@ func TestReshared(t *testing.T) {
|
||||
if err := MakeImagesSharedForTesting(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -196,7 +196,7 @@ func TestReshared(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img0.DrawTriangles(img1, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if got, want := img1.IsSharedForTesting(), true; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -224,7 +224,7 @@ func TestReshared(t *testing.T) {
|
||||
if err := MakeImagesSharedForTesting(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
img0.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
img0.DrawTriangles(img3, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
if got, want := img3.IsSharedForTesting(), false; got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -319,7 +319,7 @@ func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
dst.ReplacePixels(pix)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, w, h)
|
||||
@ -361,7 +361,7 @@ func TestSmallImages(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, w, h)
|
||||
if err != nil {
|
||||
@ -403,7 +403,7 @@ func TestLongImages(t *testing.T) {
|
||||
const scale = 120
|
||||
vs := quadVertices(w, h, 0, 0, scale)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressClampToZero, nil, nil)
|
||||
dst.DrawTriangles(src, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels(0, 0, dstW, dstH)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user