blob: caa10d4afe5b0bbee5f351a4af8461a9b3422f80 [file] [edit]
// Copyright 2026 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <initializer_list>
#include <string>
#include <vector>
#include "dawn/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/WGPUHelpers.h"
namespace dawn {
namespace {
class BufferViewTest : public DawnTest {
protected:
void SetUp() override { DawnTest::SetUp(); }
void BaseLengthTest(const std::string& wgsl,
uint32_t len,
const std::initializer_list<uint32_t>& uniforms,
const std::vector<uint32_t>& expected) {
wgpu::ShaderModule module = utils::CreateShaderModule(device, wgsl);
std::vector<wgpu::ConstantEntry> constants{{nullptr, "len", static_cast<double>(len)}};
wgpu::ComputePipelineDescriptor desc;
desc.compute.module = module;
desc.compute.constants = constants.data();
desc.compute.constantCount = constants.size();
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&desc);
wgpu::BufferDescriptor srcDesc;
srcDesc.size = len;
srcDesc.usage =
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
wgpu::Buffer src = device.CreateBuffer(&srcDesc);
wgpu::BufferDescriptor outDesc;
outDesc.size = sizeof(uint32_t) * expected.size();
outDesc.usage =
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
wgpu::Buffer out = device.CreateBuffer(&outDesc);
wgpu::Buffer uni = utils::CreateBufferFromData<uint32_t>(
device, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopySrc, uniforms);
wgpu::BindGroup bg =
utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
{
{0, src, 0, srcDesc.size},
{1, out, 0, outDesc.size},
{2, uni, 0, uniforms.size() * sizeof(uint32_t)},
});
wgpu::CommandBuffer commands;
{
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
pass.SetPipeline(pipeline);
pass.SetBindGroup(0, bg);
pass.DispatchWorkgroups(1, 1, 1);
pass.End();
commands = encoder.Finish();
}
queue.Submit(1, &commands);
EXPECT_BUFFER_U32_RANGE_EQ(&expected[0], out, 0, expected.size())
<< "Buffer length = " << len << "\n";
}
void TestBufferViewArrayLength(uint32_t len) {
const std::string src = R"(
override len : u32;
struct Offsets {
a : u32,
b : u32,
c : u32,
}
@group(0) @binding(0) var<storage> in : buffer;
@group(0) @binding(1) var<storage, read_write> out : array<u32>;
@group(0) @binding(2) var<uniform> offsets : Offsets;
struct S1 {
a : vec4f,
b : array<u32>,
}
struct S2 {
a : vec4f,
b : array<vec2u>,
}
struct S3 {
a : vec4f,
b : array<vec4u>,
}
@compute @workgroup_size(1)
fn main() {
out[0] = bufferLength(&in);
out[1] = arrayLength(bufferView<array<u32>>(&in, offsets.a));
out[2] = arrayLength(bufferView<array<u32>>(&in, offsets.b));
out[3] = arrayLength(bufferView<array<u32>>(&in, offsets.c));
out[4] = arrayLength(bufferView<array<vec2u>>(&in, offsets.a));
out[5] = arrayLength(bufferView<array<vec2u>>(&in, offsets.b));
out[6] = arrayLength(bufferView<array<vec2u>>(&in, offsets.c));
out[7] = arrayLength(bufferView<array<vec3u>>(&in, offsets.a));
out[8] = arrayLength(bufferView<array<vec3u>>(&in, offsets.b));
out[9] = arrayLength(bufferView<array<vec3u>>(&in, offsets.c));
out[10] = arrayLength(bufferView<array<vec4u>>(&in, offsets.a));
out[11] = arrayLength(bufferView<array<vec4u>>(&in, offsets.b));
out[12] = arrayLength(bufferView<array<vec4u>>(&in, offsets.c));
out[13] = arrayLength(&bufferView<S1>(&in, offsets.a).b);
out[14] = arrayLength(&bufferView<S1>(&in, offsets.b).b);
out[15] = arrayLength(&bufferView<S1>(&in, offsets.c).b);
out[16] = arrayLength(&bufferView<S2>(&in, offsets.a).b);
out[17] = arrayLength(&bufferView<S2>(&in, offsets.b).b);
out[18] = arrayLength(&bufferView<S2>(&in, offsets.c).b);
out[19] = arrayLength(&bufferView<S3>(&in, offsets.a).b);
out[20] = arrayLength(&bufferView<S3>(&in, offsets.b).b);
out[21] = arrayLength(&bufferView<S3>(&in, offsets.c).b);
}
)";
std::initializer_list<uint32_t> uniforms = {0u, 16u, 32u};
std::vector<uint32_t> expected = {
len, //
len / 4, //
(len - 16) / 4, //
(len - 32) / 4, //
len / 8, //
(len - 16) / 8, //
(len - 32) / 8, //
len / 16, //
(len - 16) / 16, //
(len - 32) / 16, //
len / 16, //
(len - 16) / 16, //
(len - 32) / 16, //
(len - 16) / 4, //
(len - 16 - 16) / 4, //
(len - 16 - 32) / 4, //
(len - 16) / 8, //
(len - 16 - 16) / 8, //
(len - 16 - 32) / 8, //
(len - 16) / 16, //
(len - 16 - 16) / 16, //
(len - 16 - 32) / 16, //
};
BaseLengthTest(src, len, uniforms, expected);
}
void TestBufferArrayViewArrayLength(uint32_t len) {
const std::string src = R"(
override len : u32;
@group(0) @binding(0) var<storage> in : buffer;
@group(0) @binding(1) var<storage, read_write> out : array<u32>;
@group(0) @binding(2) var<uniform> uniforms : array<vec4u, 2>;
struct S1 {
a : u32,
b : array<u32>,
}
struct S2 {
a : u32,
b : array<vec2u>,
}
struct S3 {
a : u32,
b : array<vec4u>,
}
@compute @workgroup_size(1)
fn main() {
var i = 0u;
out[i] = bufferLength(&in); i++;
out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][0], uniforms[1][0])); i++;
out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][1], uniforms[1][1])); i++;
out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][2], uniforms[1][2])); i++;
out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][3], uniforms[1][3])); i++;
out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][2], uniforms[1][2])); i++;
out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][2], uniforms[1][3])); i++;
out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][2], uniforms[1][2])); i++;
out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][1], uniforms[1][3])); i++;
out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][2], uniforms[1][2])); i++;
out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][0], uniforms[1][3])); i++;
out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][1], uniforms[1][1]).b); i++;
out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][2], uniforms[1][2]).b); i++;
out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][1], uniforms[1][3]).b); i++;
out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][1], uniforms[1][1]).b); i++;
out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][2], uniforms[1][2]).b); i++;
out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][1], uniforms[1][3]).b); i++;
out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][1], uniforms[1][1]).b); i++;
out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][2], uniforms[1][2]).b); i++;
out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][0], uniforms[1][3]).b); i++;
}
)";
std::initializer_list<uint32_t> uniforms = {0u, 16u, 32u, 48u, 20u, 36u, 52u, len - 20u};
std::vector<uint32_t> uniformData{uniforms};
auto InBounds = [&](uint32_t offset_idx, uint32_t size_idx, uint32_t size,
uint32_t str_offset = 0) {
auto req_size = uniformData[size_idx];
auto used_size = std::max(((req_size - str_offset) / size) * size, size);
if (len < str_offset + uniformData[offset_idx] + used_size) {
return 1u;
}
return used_size / size;
};
std::vector<uint32_t> expected = {
len, //
InBounds(0, 4 + 0, 4), //
InBounds(1, 4 + 1, 4), //
InBounds(2, 4 + 2, 4), //
InBounds(3, 4 + 3, 4), //
InBounds(0, 4 + 0, 8), //
InBounds(1, 4 + 1, 8), //
InBounds(2, 4 + 2, 8), //
InBounds(2, 4 + 3, 8), //
InBounds(0, 4 + 0, 16), //
InBounds(1, 4 + 1, 16), //
InBounds(2, 4 + 2, 16), //
InBounds(1, 4 + 3, 16), //
InBounds(0, 4 + 0, 16), //
InBounds(1, 4 + 1, 16), //
InBounds(2, 4 + 2, 16), //
InBounds(0, 4 + 3, 16), //
InBounds(0, 4 + 0, 4, 4), //
InBounds(1, 4 + 1, 4, 4), //
InBounds(2, 4 + 2, 4, 4), //
InBounds(1, 4 + 3, 4, 4), //
InBounds(0, 4 + 0, 8, 8), //
InBounds(1, 4 + 1, 8, 8), //
InBounds(2, 4 + 2, 8, 8), //
InBounds(1, 4 + 3, 8, 8), //
InBounds(0, 4 + 0, 16, 16), //
InBounds(1, 4 + 1, 16, 16), //
InBounds(2, 4 + 2, 16, 16), //
InBounds(0, 4 + 3, 16, 16), //
};
BaseLengthTest(src, len, uniforms, expected);
}
void TestArrayLengthFunctions(uint32_t len) {
const std::string wgsl = R"(
override len : u32;
@group(0) @binding(0) var<storage> in : buffer<)" +
std::to_string(len) + R"(>;
@group(0) @binding(1) var<storage, read_write> out : array<u32>;
@group(0) @binding(2) var<uniform> uniforms : buffer<20>;
var<workgroup> wg1 : buffer<64>;
var<workgroup> wg2 : buffer<128>;
var<workgroup> wg3 : buffer<len>;
struct S {
a : vec2u,
b : array<u32>,
}
fn uniformLengthUnsized(p : ptr<uniform, buffer>, offset : u32) -> u32 {
return arrayLength(bufferView<array<u32>>(p, offset));
}
fn uniformLengthSized(p : ptr<uniform, buffer<16>>, offset : u32) -> u32 {
return uniformLengthUnsized(p, offset);
}
fn workgroupLengthUnsized(p : ptr<workgroup, buffer>, offset : u32, size : u32) -> u32 {
return arrayLength(bufferArrayView<array<u32>>(p, offset, size));
}
fn workgroupLengthSmall(p : ptr<workgroup, buffer<64>>, offset : u32) -> u32 {
return workgroupLengthUnsized(p, offset, 32);
}
fn workgroupLengthOverride(p : ptr<workgroup, buffer<len>>, offset : u32) -> u32 {
return workgroupLengthUnsized(p, offset, 32);
}
fn storageLengthUnsized(p : ptr<storage, buffer>, offset : u32, size : u32) -> u32 {
return arrayLength(&bufferArrayView<S>(p, offset, size).b);
}
fn storageLengthLarge(p : ptr<storage, buffer>, offset : u32) -> u32 {
return arrayLength(&bufferView<S>(p, offset).b);
}
fn storageLengthSmall(p : ptr<storage, buffer<48>>, offset : u32) -> u32 {
return storageLengthLarge(p, offset);
}
@compute @workgroup_size(1)
fn main() {
let offsets = bufferView<array<u32>>(&uniforms, 0u);
var i = 0u;
out[i] = uniformLengthUnsized(&uniforms, offsets[0]); i++;
out[i] = uniformLengthUnsized(&uniforms, offsets[1]); i++;
out[i] = uniformLengthUnsized(&uniforms, offsets[2]); i++;
out[i] = uniformLengthSized(&uniforms, offsets[0]); i++;
out[i] = uniformLengthSized(&uniforms, offsets[1]); i++;
out[i] = workgroupLengthUnsized(&wg1, offsets[0], bufferLength(&wg1)); i++;
out[i] = workgroupLengthUnsized(&wg1, offsets[1], offsets[2]); i++;
out[i] = workgroupLengthUnsized(&wg1, offsets[3], offsets[3]); i++;
out[i] = workgroupLengthUnsized(&wg2, offsets[0], bufferLength(&wg2)); i++;
out[i] = workgroupLengthSmall(&wg2, offsets[1]); i++;
out[i] = workgroupLengthSmall(&wg2, offsets[2]); i++;
out[i] = workgroupLengthUnsized(&wg3, offsets[0], bufferLength(&wg3)); i++;
out[i] = workgroupLengthOverride(&wg3, offsets[1]); i++;
out[i] = workgroupLengthOverride(&wg3, offsets[2]); i++;
out[i] = storageLengthUnsized(&in, offsets[0], bufferLength(&in)); i++;
out[i] = storageLengthUnsized(&in, offsets[0], offsets[4]); i++;
out[i] = storageLengthUnsized(&in, offsets[1], bufferLength(&in) - 8); i++;
out[i] = storageLengthSmall(&in, 0); i++;
}
)";
std::initializer_list<uint32_t> uniforms = {0, 8, 16, 32, 64};
std::vector<uint32_t> uniformData{uniforms};
uint32_t uniformSize = static_cast<uint32_t>(uniforms.size());
std::vector<uint32_t> expected = {
// Uniform sizes
uniformSize,
uniformSize - uniformData[1] / 4,
uniformSize - uniformData[2] / 4,
uniformSize - 1,
uniformSize - 1 - uniformData[1] / 4,
// Workgroup sizes
64 / 4,
uniformData[2] / 4,
uniformData[3] / 4,
128 / 4,
32 / 4,
32 / 4,
len / 4,
32 / 4,
32 / 4,
// Storage sizes
(len - 8) / 4,
(uniformData[4] - 8) / 4,
(len - 8 - uniformData[1]) / 4,
(48 - 8) / 4,
};
BaseLengthTest(wgsl, len, uniforms, expected);
}
void BaseViewTest(const std::string& wgsl) {
wgpu::ShaderModule module = utils::CreateShaderModule(device, wgsl);
std::initializer_list<uint32_t> uniforms = {0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15};
std::initializer_list<uint32_t> inputs = {
1, 2, 3, 4, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 7, 8, 9, 10, 11, 12, 13, 14,
};
const std::vector<uint32_t> expected = {
1, 2, 3, 4, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 7, 8, 9, 10, 11, 12, 13, 14,
};
wgpu::ComputePipelineDescriptor desc;
desc.compute.module = module;
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&desc);
wgpu::Buffer src = utils::CreateBufferFromData<uint32_t>(
device, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc, inputs);
wgpu::BufferDescriptor outDesc;
outDesc.size = sizeof(uint32_t) * expected.size();
outDesc.usage =
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
wgpu::Buffer out = device.CreateBuffer(&outDesc);
wgpu::Buffer uni = utils::CreateBufferFromData<uint32_t>(
device, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopySrc, uniforms);
wgpu::BindGroup bg =
utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
{
{0, src, 0, inputs.size() * sizeof(uint32_t)},
{1, out, 0, outDesc.size},
{2, uni, 0, uniforms.size() * sizeof(uint32_t)},
});
wgpu::CommandBuffer commands;
{
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
pass.SetPipeline(pipeline);
pass.SetBindGroup(0, bg);
pass.DispatchWorkgroups(1, 1, 1);
pass.End();
commands = encoder.Finish();
}
queue.Submit(1, &commands);
EXPECT_BUFFER_U32_RANGE_EQ(&expected[0], out, 0, expected.size());
}
void TestBufferViewBasics() {
const std::string wgsl = R"(
@group(0) @binding(0) var<storage> in : buffer;
@group(0) @binding(1) var<storage, read_write> out : buffer;
@group(0) @binding(2) var<uniform> uniforms : buffer<64>;
struct S {
a : u32,
b : vec4u,
}
@compute @workgroup_size(1)
fn main() {
let uniform_v1 = bufferView<array<u32>>(&uniforms, 0);
let in1 = bufferView<array<u32, 4>>(&in, uniform_v1[0]);
let out1 = bufferView<vec4u>(&out, uniform_v1[0]);
out1.x = in1[0];
out1.y = in1[1];
out1.z = in1[2];
out1.w = in1[3];
let in2x = bufferView<f32>(&in, uniform_v1[4] * 4);
let in2y = bufferView<f32>(&in, uniform_v1[5] * 4);
let in2z = bufferView<f32>(&in, uniform_v1[6] * 4);
let in2w = bufferView<f32>(&in, uniform_v1[7] * 4);
let out2 = bufferView<array<f32, 4>>(&out, 16u);
out2[0] = *in2x;
out2[1] = *in2y;
out2[2] = *in2z;
out2[3] = *in2w;
let in3 = bufferView<S>(&in, uniform_v1[8] * 4);
let in3_sub = bufferView<array<u32, 3>>(&in, uniform_v1[9] * 4);
let out3 = bufferView<S>(&out, uniform_v1[8] * 4);
let out3_sub = bufferView<array<u32, 3>>(&out, uniform_v1[9] * 4);
let in3_ld = *in3;
*out3_sub = *in3_sub;
*out3 = in3_ld;
}
)";
BaseViewTest(wgsl);
}
void TestBufferArrayViewBasics() {
const std::string wgsl = R"(
@group(0) @binding(0) var<storage> in : buffer;
@group(0) @binding(1) var<storage, read_write> out : buffer;
@group(0) @binding(2) var<uniform> uniforms : buffer<64>;
struct S {
a : u32,
b : vec4u,
}
@compute @workgroup_size(1)
fn main() {
let uniform_v1 = bufferArrayView<array<u32>>(&uniforms, 0, 16 * 4);
let in1 = bufferArrayView<array<u32>>(&in, uniform_v1[0], uniform_v1[5] * 4);
let out1 = bufferArrayView<array<vec4u>>(&out, uniform_v1[0], 16);
out1[0].x = in1[0];
out1[0].y = in1[1];
out1[0].z = in1[2];
out1[0].w = in1[3];
let in2x = bufferArrayView<array<f32>>(&in, uniform_v1[4] * 4, 8);
let in2y = bufferArrayView<array<f32>>(&in, uniform_v1[5] * 4, 8);
let in2z = bufferArrayView<array<f32>>(&in, uniform_v1[6] * 4, 8);
let in2w = bufferArrayView<array<f32>>(&in, uniform_v1[7] * 4, 8);
let out2 = bufferArrayView<array<f32>>(&out, 16u, 16u);
out2[0] = in2x[0];
out2[1] = in2y[0];
out2[2] = in2z[0];
out2[3] = in2w[0];
let in3 = bufferArrayView<array<S>>(&in, uniform_v1[8] * 4, 32);
let in3_sub = bufferArrayView<array<array<u32, 3>>>(&in, uniform_v1[9] * 4, 12);
let out3 = bufferArrayView<array<S>>(&out, uniform_v1[8] * 4, 32);
let out3_sub = bufferArrayView<array<array<u32, 3>>>(&out, uniform_v1[9] * 4, 12);
let in3_ld = in3[0];
out3_sub[0] = in3_sub[0];
out3[0] = in3_ld;
}
)";
BaseViewTest(wgsl);
}
};
TEST_P(BufferViewTest, BufferViewArrayLength) {
DAWN_SUPPRESS_TEST_IF(IsD3D11());
DAWN_SUPPRESS_TEST_IF(IsD3D12());
TestBufferViewArrayLength(128);
TestBufferViewArrayLength(256);
TestBufferViewArrayLength(512);
TestBufferViewArrayLength(1024);
TestBufferViewArrayLength(64);
}
TEST_P(BufferViewTest, BufferArrayViewArrayLength) {
DAWN_SUPPRESS_TEST_IF(IsD3D11());
DAWN_SUPPRESS_TEST_IF(IsD3D12());
TestBufferArrayViewArrayLength(128);
TestBufferArrayViewArrayLength(256);
TestBufferArrayViewArrayLength(512);
TestBufferArrayViewArrayLength(1024);
TestBufferArrayViewArrayLength(64);
}
TEST_P(BufferViewTest, ArrayLengthFunctions) {
DAWN_SUPPRESS_TEST_IF(IsD3D11());
DAWN_SUPPRESS_TEST_IF(IsD3D12());
TestArrayLengthFunctions(128);
TestArrayLengthFunctions(256);
TestArrayLengthFunctions(512);
TestArrayLengthFunctions(1024);
TestArrayLengthFunctions(64);
}
TEST_P(BufferViewTest, BufferViewBasics) {
DAWN_SUPPRESS_TEST_IF(IsD3D11());
DAWN_SUPPRESS_TEST_IF(IsD3D12());
TestBufferViewBasics();
}
TEST_P(BufferViewTest, BufferArrayViewBasics) {
DAWN_SUPPRESS_TEST_IF(IsD3D11());
DAWN_SUPPRESS_TEST_IF(IsD3D12());
TestBufferArrayViewBasics();
}
DAWN_INSTANTIATE_TEST(BufferViewTest,
D3D11Backend(),
D3D12Backend(),
MetalBackend(),
OpenGLBackend(),
OpenGLESBackend(),
VulkanBackend(),
WebGPUBackend());
} // namespace
} // namespace dawn