1package vulkan
2
3import (
4 "image/color"
5 "slices"
6 "testing"
7
8 "github.com/bnema/neferwl/internal/ports"
9)
10
11// A mixed resource table must select SHM pixels, RGB images, and both YUV
12// planes independently within the same draw call.
13func TestComposeIndexedMixedResources(t *testing.T) {
14 r, err := New(64, 16)
15 if err != nil {
16 t.Skipf("Vulkan unavailable: %v", err)
17 }
18 defer r.Close()
19 if !r.compose.indexing || r.compose.resources < 3 {
20 t.Skip("nonuniform indexing of three resources unavailable")
21 }
22 yuv := yuvTestBuffer(t, false, 63, 102, 240)
23 if !slices.Contains(r.DMABuf().Formats, ports.DMABufFormat{Format: yuv.Format}) {
24 t.Skip("linear NV12 not importable")
25 }
26 rgbFormat := fourcc('A', 'R', '2', '4')
27 if !slices.Contains(r.DMABuf().Formats, ports.DMABufFormat{Format: rgbFormat}) {
28 t.Skip("linear ARGB not importable")
29 }
30 rgb := &ports.DMABuf{ID: 991, Width: 64, Height: 16, Format: rgbFormat, Planes: []ports.DMABufPlane{{File: udmabuf(t, 64, 16, func(int, int) [4]byte { return [4]byte{255, 0, 0, 255} }), Stride: 256}}}
31 shm := solidContent(t, 64, 16, color.RGBA{G: 255, A: 255})
32 shm.ID, shm.Seq, shm.Version = 2, 1, 1
33 scene := ports.Scene{Layers: []ports.SceneLayer{
34 {ID: 1, Layer: ports.LayerOverlay, Rect: ports.Rect{W: 64, H: 16}},
35 {ID: 2, Layer: ports.LayerOverlay, Rect: ports.Rect{X: 16, W: 32, H: 16}},
36 {ID: 3, Layer: ports.LayerOverlay, Rect: ports.Rect{X: 32, W: 16, H: 16}},
37 }}
38 contents := map[ports.WindowID]ports.SurfaceContent{
39 1: {ID: 1, Width: 64, Height: 16, Opaque: true, DMABuf: yuv, Color: ports.SurfaceColor{Coefficients: 2, Range: 2, Chroma: 1}},
40 2: shm,
41 3: {ID: 3, Width: 64, Height: 16, Opaque: true, DMABuf: rgb},
42 }
43 for range 4 {
44 if err := render(r, scene, contents); err != nil {
45 t.Fatal(err)
46 }
47 pixels := readPixels(t, r)
48 for _, tc := range []struct {
49 x int
50 want color.RGBA
51 }{{8, color.RGBA{R: 255, A: 255}}, {24, color.RGBA{G: 255, A: 255}}, {40, color.RGBA{B: 255, A: 255}}} {
52 if got := pixels.RGBAAt(tc.x, 8); !near(got, tc.want, 8) {
53 t.Fatalf("resource at x=%d: %v, want %v", tc.x, got, tc.want)
54 }
55 }
56 }
57 for i := range r.slots {
58 if len(r.slots[i].batches) != 1 || r.slots[i].batches[0].count != 3 {
59 t.Fatalf("slot %d did not batch the three resource modes", i)
60 }
61 }
62}