diff --git a/internal/shaderir/hlsl/packing.go b/internal/shaderir/hlsl/packing.go index b245de2fe..246e74658 100644 --- a/internal/shaderir/hlsl/packing.go +++ b/internal/shaderir/hlsl/packing.go @@ -65,27 +65,32 @@ func calculateMemoryOffsets(uniforms []shaderir.Type) []int { // For matrices, each column is aligned to the boundary. head = align(head) offsets = append(offsets, head) - // TODO: Is this correct? - head += 1 * boundaryInBytes - head += 4 * 2 + head += 4 * 6 case shaderir.Mat3: head = align(head) offsets = append(offsets, head) - // TODO: Is this correct? - head += 2 * boundaryInBytes - head += 4 * 3 + head += 4 * 11 case shaderir.Mat4: head = align(head) offsets = append(offsets, head) - head += 4 * boundaryInBytes + head += 4 * 16 case shaderir.Array: // Each array is 16-byte aligned. // TODO: What if the array has 2 or more dimensions? head = align(head) offsets = append(offsets, head) + n := u.Sub[0].FloatNum() + switch u.Sub[0].Main { + case shaderir.Mat2: + n = 6 + case shaderir.Mat3: + n = 11 + case shaderir.Mat4: + n = 16 + } + head += (u.Length - 1) * align(4*n) // The last element is not with a padding. - head += (u.Length - 1) * align(4*u.Sub[0].FloatNum()) - head += 4 * u.Sub[0].FloatNum() + head += 4 * n case shaderir.Struct: // TODO: Implement this panic("hlsl: offset for a struct is not implemented yet") diff --git a/shader_test.go b/shader_test.go index ec4341cab..0ed7b7205 100644 --- a/shader_test.go +++ b/shader_test.go @@ -772,9 +772,10 @@ func TestShaderUniformMatrix2Array(t *testing.T) { s, err := ebiten.NewShader([]byte(`package main var Mat2 [2]mat2 +var F float func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return vec4(256 * Mat2[0] * Mat2[1] * vec2(1), 1, 1) + return vec4(F * Mat2[0] * Mat2[1] * vec2(1), 1, 1) } `)) if err != nil { @@ -789,6 +790,7 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 { 5.0 / 256.0, 6.0 / 256.0, 7.0 / 256.0, 8.0 / 256.0, }, + "F": float32(256), } dst.DrawRectShader(w, h, s, op) @@ -810,9 +812,10 @@ func TestShaderUniformMatrix3(t *testing.T) { s, err := ebiten.NewShader([]byte(`package main var Mat3 mat3 +var F float func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return vec4(Mat3 * vec3(1), 1) + return vec4(F * Mat3 * vec3(1), 1) } `)) if err != nil { @@ -826,13 +829,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 { 4.0 / 256.0, 5.0 / 256.0, 6.0 / 256.0, 7.0 / 256.0, 8.0 / 256.0, 9.0 / 256.0, }, + "F": float32(2), } dst.DrawRectShader(w, h, s, op) for j := 0; j < h; j++ { for i := 0; i < w; i++ { got := dst.At(i, j).(color.RGBA) - want := color.RGBA{12, 15, 18, 0xff} + want := color.RGBA{24, 30, 36, 0xff} if !sameColors(got, want, 2) { t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want) } @@ -847,9 +851,10 @@ func TestShaderUniformMatrix3Array(t *testing.T) { s, err := ebiten.NewShader([]byte(`package main var Mat3 [2]mat3 +var F float func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return vec4(3 * Mat3[0] * Mat3[1] * vec3(1), 1) + return vec4(F * Mat3[0] * Mat3[1] * vec3(1), 1) } `)) if err != nil { @@ -866,6 +871,7 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 { 13.0 / 256.0, 14.0 / 256.0, 15.0 / 256.0, 16.0 / 256.0, 17.0 / 256.0, 18.0 / 256.0, }, + "F": float32(3), } dst.DrawRectShader(w, h, s, op) @@ -887,9 +893,10 @@ func TestShaderUniformMatrix4(t *testing.T) { s, err := ebiten.NewShader([]byte(`package main var Mat4 mat4 +var F float func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return Mat4 * vec4(1) + return F * Mat4 * vec4(1) } `)) if err != nil { @@ -904,13 +911,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 { 9.0 / 256.0, 10.0 / 256.0, 11.0 / 256.0, 12.0 / 256.0, 13.0 / 256.0, 14.0 / 256.0, 15.0 / 256.0, 16.0 / 256.0, }, + "F": float32(4), } dst.DrawRectShader(w, h, s, op) for j := 0; j < h; j++ { for i := 0; i < w; i++ { got := dst.At(i, j).(color.RGBA) - want := color.RGBA{28, 32, 36, 40} + want := color.RGBA{112, 128, 143, 159} if !sameColors(got, want, 2) { t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want) } @@ -925,9 +933,10 @@ func TestShaderUniformMatrix4Array(t *testing.T) { s, err := ebiten.NewShader([]byte(`package main var Mat4 [2]mat4 +var F float func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return Mat4[0] * Mat4[1] * vec4(1) + return F * Mat4[0] * Mat4[1] * vec4(1) } `)) if err != nil { @@ -946,13 +955,14 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 { 25.0 / 256.0, 26.0 / 256.0, 27.0 / 256.0, 28.0 / 256.0, 29.0 / 256.0, 30.0 / 256.0, 31.0 / 256.0, 32.0 / 256.0, }, + "F": float32(4), } dst.DrawRectShader(w, h, s, op) for j := 0; j < h; j++ { for i := 0; i < w; i++ { got := dst.At(i, j).(color.RGBA) - want := color.RGBA{11, 13, 14, 16} + want := color.RGBA{44, 50, 56, 62} if !sameColors(got, want, 2) { t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want) }