blob: d4338fbbaae09c11c428e094f8e6c4a648750f88 [file] [log] [blame]
/*
* Copyright 2022 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/graphite/Uniform.h"
#include "src/gpu/graphite/UniformManager.h"
#include "tests/Test.h"
using namespace skgpu::graphite;
namespace {
// Used to test the exact alignment and size of an individual type. Returns the alignment and size
// as a pair.
struct AlignmentAndSize {
size_t alignment;
size_t size;
};
static AlignmentAndSize calculate_alignment_and_size(Layout layout,
SkSLType type,
size_t arrayCount = Uniform::kNonArray) {
// Set the start offset at 1 to force alignment.
constexpr uint32_t kStart = 1;
UniformOffsetCalculator calc(layout, kStart);
size_t alignment = calc.advanceOffset(type, arrayCount);
return {alignment, calc.size() - alignment};
}
#define EXPECT(type, expectedAlignment, expectedSize) \
do { \
auto [alignment, size] = calculate_alignment_and_size(kLayout, type); \
REPORTER_ASSERT(r, \
alignment == expectedAlignment, \
"incorrect alignment for type '%s': expected %d, found %zu", \
SkSLTypeString(type), \
expectedAlignment, \
alignment); \
REPORTER_ASSERT(r, \
size == expectedSize, \
"incorrect size for type '%s': expected %d, found %zu", \
SkSLTypeString(type), \
expectedSize, \
size); \
} while (0)
#define EXPECT_ARRAY(type, expectedAlignment, expectedStride, expectedSize) \
do { \
auto [alignment, size] = calculate_alignment_and_size(kLayout, type, kCount); \
size_t stride = size / kCount; \
REPORTER_ASSERT(r, \
alignment == expectedAlignment, \
"incorrect alignment for type '%s': expected %d, found %zu", \
SkSLTypeString(type), \
expectedAlignment, \
alignment); \
REPORTER_ASSERT(r, \
size == expectedSize, \
"incorrect size for type '%s': expected %d, found %zu", \
SkSLTypeString(type), \
expectedSize, \
size); \
REPORTER_ASSERT(r, \
stride == expectedStride, \
"incorrect stride for type '%s': expected %d, found %zu", \
SkSLTypeString(type), \
expectedStride, \
stride); \
} while (0)
DEF_TEST(UniformOffsetCalculatorMetalBasicTypesTest, r) {
constexpr Layout kLayout = Layout::kMetal;
// scalars: int, float, short, half (unsigned types are disallowed)
EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kShort, /*alignment=*/2, /*size=*/2);
EXPECT(SkSLType::kHalf, /*alignment=*/2, /*size=*/2);
// int2, float2, short2, half2
EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kShort2, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kHalf2, /*alignment=*/4, /*size=*/4);
// int3, float3, short3, half3
EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort3, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kHalf3, /*alignment=*/8, /*size=*/8);
// int4, float4, short4, half4
EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort4, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kHalf4, /*alignment=*/8, /*size=*/8);
// float2x2, half2x2
EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
EXPECT(SkSLType::kHalf2x2, /*alignment=*/4, /*size=*/8);
// float3x3, half3x3
EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
EXPECT(SkSLType::kHalf3x3, /*alignment=*/8, /*size=*/24);
// float4x4, half4x4
EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
EXPECT(SkSLType::kHalf4x4, /*alignment=*/8, /*size=*/32);
}
DEF_TEST(UniformOffsetCalculatorMetalArrayTest, r) {
constexpr Layout kLayout = Layout::kMetal;
constexpr size_t kCount = 3;
// int[3], float[3], short[3], half[3]
EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/2, /*stride=*/2, /*size=*/6);
EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/2, /*stride=*/2, /*size=*/6);
// int2[3], float2[3], short2[3], half2[3]
EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/4, /*stride=*/4, /*size=*/12);
// int3[3], float3[3], short3[3], half3[3]
EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/8, /*stride=*/8, /*size=*/24);
// int4[3], float4[3], short4[3], half4[3]
EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/8, /*stride=*/8, /*size=*/24);
// float2x2[3], half2x2[3]
EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/4, /*stride=*/8, /*size=*/24);
// float3x3[3], half3x3[3]
EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/8, /*stride=*/24, /*size=*/72);
// float4x4[3], half4x4[3]
EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/8, /*stride=*/32, /*size=*/96);
}
DEF_TEST(UniformOffsetCalculatorStd430BasicTypesTest, r) {
constexpr Layout kLayout = Layout::kStd430;
// scalars: int, float, short, half (unsigned types are disallowed)
EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kShort, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kHalf, /*alignment=*/4, /*size=*/4);
// int2, float2, short2, half2
EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kShort2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kHalf2, /*alignment=*/8, /*size=*/8);
// int3, float3, short3, half3
EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kHalf3, /*alignment=*/16, /*size=*/16);
// int4, float4, short4, half4
EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kHalf4, /*alignment=*/16, /*size=*/16);
// float2x2, half2x2
EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
EXPECT(SkSLType::kHalf2x2, /*alignment=*/8, /*size=*/16);
// float3x3, half3x3
EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
EXPECT(SkSLType::kHalf3x3, /*alignment=*/16, /*size=*/48);
// float4x4, half4x4
EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
EXPECT(SkSLType::kHalf4x4, /*alignment=*/16, /*size=*/64);
}
DEF_TEST(UniformOffsetCalculatorStd430ArrayTest, r) {
constexpr Layout kLayout = Layout::kStd430;
constexpr size_t kCount = 3;
// int[3], float[3], short[3], half[3]
EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/4, /*stride=*/4, /*size=*/12);
EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/4, /*stride=*/4, /*size=*/12);
// int2[3], float2[3], short2[3], half2[3]
EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
// int3[3], float3[3], short3[3], half3[3]
EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// int4[3], float4[3], short4[3], half4[3]
EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// float2x2[3], half2x2[3]
EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
// float3x3[3], half3x3[3]
EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
// float4x4[3], half4x4[3]
EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
}
DEF_TEST(UniformOffsetCalculatorStd140BasicTypesTest, r) {
constexpr Layout kLayout = Layout::kStd140;
// scalars: int, float, short, half (unsigned types are disallowed)
EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kShort, /*alignment=*/4, /*size=*/4);
EXPECT(SkSLType::kHalf, /*alignment=*/4, /*size=*/4);
// int2, float2, short2, half2
EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kShort2, /*alignment=*/8, /*size=*/8);
EXPECT(SkSLType::kHalf2, /*alignment=*/8, /*size=*/8);
// int3, float3, short3, half3
EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort3, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kHalf3, /*alignment=*/16, /*size=*/16);
// int4, float4, short4, half4
EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kShort4, /*alignment=*/16, /*size=*/16);
EXPECT(SkSLType::kHalf4, /*alignment=*/16, /*size=*/16);
// float2x2, half2x2
EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
EXPECT(SkSLType::kHalf2x2, /*alignment=*/8, /*size=*/16);
// float3x3, half3x3
EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
EXPECT(SkSLType::kHalf3x3, /*alignment=*/16, /*size=*/48);
// float4x4, half4x4
EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
EXPECT(SkSLType::kHalf4x4, /*alignment=*/16, /*size=*/64);
}
DEF_TEST(UniformOffsetCalculatorStd140ArrayTest, r) {
constexpr Layout kLayout = Layout::kStd140;
constexpr uint32_t kCount = 3;
// int[3], float[3], short[3], half[3]
EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// int2[3], float2[3], short2[3], half2[3]
EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// int3[3], float3[3], short3[3], half3[3]
EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// int4[3], float4[3], short4[3], half4[3]
EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// float2x2[3], half2x2[3]
EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
// float3x3[3], half3x3[3]
EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
// float4x4[3], half4x4[3]
EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
}
} // namespace