blob: cf6624e09b353eeebabab4935e9943c45172d239 [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2018 The Dawn Authors
Stephen White1c24abc2018-04-03 11:41:05 -04002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Stephen White1c24abc2018-04-03 11:41:05 -040015#include <cmath>
16
Corentin Walleza4da0322018-07-18 15:18:25 +020017#include "tests/DawnTest.h"
Stephen White1c24abc2018-04-03 11:41:05 -040018
19#include "common/Assert.h"
20#include "common/Constants.h"
Yan, Shaoboa4924272018-12-10 19:47:22 +000021#include "utils/ComboRenderPipelineDescriptor.h"
Corentin Wallez04863c42019-10-25 11:36:47 +000022#include "utils/WGPUHelpers.h"
Stephen White1c24abc2018-04-03 11:41:05 -040023
24constexpr static unsigned int kRTSize = 64;
25
26namespace {
27 struct AddressModeTestCase {
Corentin Wallezcab352c2019-10-28 13:27:36 +000028 wgpu::AddressMode mMode;
Stephen White1c24abc2018-04-03 11:41:05 -040029 uint8_t mExpected2;
30 uint8_t mExpected3;
31 };
32 AddressModeTestCase addressModes[] = {
Corentin Wallezcab352c2019-10-28 13:27:36 +000033 {
34 wgpu::AddressMode::Repeat,
35 0,
36 255,
37 },
38 {
39 wgpu::AddressMode::MirrorRepeat,
40 255,
41 0,
42 },
43 {
44 wgpu::AddressMode::ClampToEdge,
45 255,
46 255,
47 },
Stephen White1c24abc2018-04-03 11:41:05 -040048 };
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000049} // namespace
Stephen White1c24abc2018-04-03 11:41:05 -040050
Corentin Walleza4da0322018-07-18 15:18:25 +020051class SamplerTest : public DawnTest {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000052 protected:
Austin Eng40dc5d32020-05-15 22:06:35 +000053 void SetUp() override {
54 DawnTest::SetUp();
Corentin Wallez6f7749c2018-05-02 18:10:13 -040055 mRenderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
Stephen White1c24abc2018-04-03 11:41:05 -040056
Corentin Wallez7aec4ae2021-03-24 15:55:32 +000057 auto vsModule = utils::CreateShaderModule(device, R"(
Brandon Jonese87ea2b2021-04-14 17:05:07 +000058 [[stage(vertex)]]
59 fn main([[builtin(vertex_index)]] VertexIndex : u32) -> [[builtin(position)]] vec4<f32> {
Corentin Wallezb86e45f2021-06-17 21:36:11 +000060 var pos = array<vec2<f32>, 6>(
Austin Eng69afcb42020-11-26 13:41:55 +000061 vec2<f32>(-2.0, -2.0),
62 vec2<f32>(-2.0, 2.0),
63 vec2<f32>( 2.0, -2.0),
64 vec2<f32>(-2.0, 2.0),
65 vec2<f32>( 2.0, -2.0),
66 vec2<f32>( 2.0, 2.0));
Brandon Jonese87ea2b2021-04-14 17:05:07 +000067 return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
Stephen White1c24abc2018-04-03 11:41:05 -040068 }
69 )");
Corentin Wallez7aec4ae2021-03-24 15:55:32 +000070 auto fsModule = utils::CreateShaderModule(device, R"(
James Price7e80cce2021-02-10 20:17:14 +000071 [[group(0), binding(0)]] var sampler0 : sampler;
72 [[group(0), binding(1)]] var texture0 : texture_2d<f32>;
Austin Eng69afcb42020-11-26 13:41:55 +000073
Brandon Jonese87ea2b2021-04-14 17:05:07 +000074 [[stage(fragment)]]
James Priceeae70b72021-04-19 15:29:49 +000075 fn main([[builtin(position)]] FragCoord : vec4<f32>) -> [[location(0)]] vec4<f32> {
Brandon Jonese87ea2b2021-04-14 17:05:07 +000076 return textureSample(texture0, sampler0, FragCoord.xy / vec2<f32>(2.0, 2.0));
Austin Eng69afcb42020-11-26 13:41:55 +000077 })");
Stephen White1c24abc2018-04-03 11:41:05 -040078
Brandon Jones41c87d92021-05-21 05:01:38 +000079 utils::ComboRenderPipelineDescriptor pipelineDescriptor;
Brandon Jonesbff9d3a2021-03-18 02:54:27 +000080 pipelineDescriptor.vertex.module = vsModule;
81 pipelineDescriptor.cFragment.module = fsModule;
82 pipelineDescriptor.cTargets[0].format = mRenderPass.colorFormat;
Yan, Shaoboa4924272018-12-10 19:47:22 +000083
Brandon Jones41c87d92021-05-21 05:01:38 +000084 mPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
Austin Eng1fe99792019-12-03 21:32:55 +000085 mBindGroupLayout = mPipeline.GetBindGroupLayout(0);
Stephen White1c24abc2018-04-03 11:41:05 -040086
Corentin Wallezcab352c2019-10-28 13:27:36 +000087 wgpu::TextureDescriptor descriptor;
88 descriptor.dimension = wgpu::TextureDimension::e2D;
Corentin Wallez29353d62018-09-18 12:49:22 +000089 descriptor.size.width = 2;
90 descriptor.size.height = 2;
shrekshaob00de7f2021-03-22 21:12:36 +000091 descriptor.size.depthOrArrayLayers = 1;
Jiawei Shao8bff3b22018-12-12 09:27:16 +000092 descriptor.sampleCount = 1;
Corentin Wallezcab352c2019-10-28 13:27:36 +000093 descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
Jiawei Shao20301662019-02-21 00:45:19 +000094 descriptor.mipLevelCount = 1;
Corentin Wallezcab352c2019-10-28 13:27:36 +000095 descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
96 wgpu::Texture texture = device.CreateTexture(&descriptor);
Stephen White1c24abc2018-04-03 11:41:05 -040097
98 // Create a 2x2 checkerboard texture, with black in the top left and bottom right corners.
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +000099 const uint32_t rowPixels = kTextureBytesPerRowAlignment / sizeof(RGBA8);
Stephen White1c24abc2018-04-03 11:41:05 -0400100 RGBA8 data[rowPixels * 2];
Yunchao He0c02f542019-11-19 17:57:30 +0000101 data[0] = data[rowPixels + 1] = RGBA8::kBlack;
102 data[1] = data[rowPixels] = RGBA8::kWhite;
Stephen White1c24abc2018-04-03 11:41:05 -0400103
Corentin Wallezcab352c2019-10-28 13:27:36 +0000104 wgpu::Buffer stagingBuffer =
105 utils::CreateBufferFromData(device, data, sizeof(data), wgpu::BufferUsage::CopySrc);
Corentin Wallez80915842021-03-04 18:13:45 +0000106 wgpu::ImageCopyBuffer imageCopyBuffer = utils::CreateImageCopyBuffer(stagingBuffer, 0, 256);
107 wgpu::ImageCopyTexture imageCopyTexture =
108 utils::CreateImageCopyTexture(texture, 0, {0, 0, 0});
Corentin Wallezcab352c2019-10-28 13:27:36 +0000109 wgpu::Extent3D copySize = {2, 2, 1};
Stephen White1c24abc2018-04-03 11:41:05 -0400110
Corentin Wallezcab352c2019-10-28 13:27:36 +0000111 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
Corentin Wallez80915842021-03-04 18:13:45 +0000112 encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &copySize);
Corentin Walleze1f0d4e2019-02-15 12:54:08 +0000113
Corentin Wallezcab352c2019-10-28 13:27:36 +0000114 wgpu::CommandBuffer copy = encoder.Finish();
Stephen White1c24abc2018-04-03 11:41:05 -0400115 queue.Submit(1, &copy);
Corentin Walleze1f0d4e2019-02-15 12:54:08 +0000116
Kai Ninomiya4078ed82019-08-27 17:56:23 +0000117 mTextureView = texture.CreateView();
Stephen White1c24abc2018-04-03 11:41:05 -0400118 }
119
120 void TestAddressModes(AddressModeTestCase u, AddressModeTestCase v, AddressModeTestCase w) {
Corentin Wallezcab352c2019-10-28 13:27:36 +0000121 wgpu::Sampler sampler;
Corentin Wallez1ae19e82018-05-17 17:09:07 -0400122 {
Austin Eng7817a9a2020-04-20 23:43:20 +0000123 wgpu::SamplerDescriptor descriptor = {};
Corentin Wallezcab352c2019-10-28 13:27:36 +0000124 descriptor.minFilter = wgpu::FilterMode::Nearest;
125 descriptor.magFilter = wgpu::FilterMode::Nearest;
126 descriptor.mipmapFilter = wgpu::FilterMode::Nearest;
Corentin Wallez1ae19e82018-05-17 17:09:07 -0400127 descriptor.addressModeU = u.mMode;
128 descriptor.addressModeV = v.mMode;
129 descriptor.addressModeW = w.mMode;
130 sampler = device.CreateSampler(&descriptor);
131 }
Stephen White1c24abc2018-04-03 11:41:05 -0400132
Corentin Wallezcab352c2019-10-28 13:27:36 +0000133 wgpu::BindGroup bindGroup =
134 utils::MakeBindGroup(device, mBindGroupLayout, {{0, sampler}, {1, mTextureView}});
Stephen White1c24abc2018-04-03 11:41:05 -0400135
Corentin Wallezcab352c2019-10-28 13:27:36 +0000136 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
Corentin Wallez82fbccb2018-09-21 00:24:37 +0000137 {
Corentin Wallezcab352c2019-10-28 13:27:36 +0000138 wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&mRenderPass.renderPassInfo);
Yan, Shaobo300eec02018-12-21 10:40:26 +0000139 pass.SetPipeline(mPipeline);
Corentin Wallez70c8c102019-10-09 16:08:42 +0000140 pass.SetBindGroup(0, bindGroup);
Corentin Wallez67b1ad72020-03-31 16:21:35 +0000141 pass.Draw(6);
Corentin Wallez82fbccb2018-09-21 00:24:37 +0000142 pass.EndPass();
143 }
Stephen White1c24abc2018-04-03 11:41:05 -0400144
Corentin Wallezcab352c2019-10-28 13:27:36 +0000145 wgpu::CommandBuffer commands = encoder.Finish();
Stephen White1c24abc2018-04-03 11:41:05 -0400146 queue.Submit(1, &commands);
147
148 RGBA8 expectedU2(u.mExpected2, u.mExpected2, u.mExpected2, 255);
149 RGBA8 expectedU3(u.mExpected3, u.mExpected3, u.mExpected3, 255);
150 RGBA8 expectedV2(v.mExpected2, v.mExpected2, v.mExpected2, 255);
151 RGBA8 expectedV3(v.mExpected3, v.mExpected3, v.mExpected3, 255);
Yunchao He0c02f542019-11-19 17:57:30 +0000152 EXPECT_PIXEL_RGBA8_EQ(RGBA8::kBlack, mRenderPass.color, 0, 0);
153 EXPECT_PIXEL_RGBA8_EQ(RGBA8::kWhite, mRenderPass.color, 0, 1);
154 EXPECT_PIXEL_RGBA8_EQ(RGBA8::kWhite, mRenderPass.color, 1, 0);
155 EXPECT_PIXEL_RGBA8_EQ(RGBA8::kBlack, mRenderPass.color, 1, 1);
Corentin Wallez6f7749c2018-05-02 18:10:13 -0400156 EXPECT_PIXEL_RGBA8_EQ(expectedU2, mRenderPass.color, 2, 0);
157 EXPECT_PIXEL_RGBA8_EQ(expectedU3, mRenderPass.color, 3, 0);
158 EXPECT_PIXEL_RGBA8_EQ(expectedV2, mRenderPass.color, 0, 2);
159 EXPECT_PIXEL_RGBA8_EQ(expectedV3, mRenderPass.color, 0, 3);
Corentin Wallez9fc65342018-07-18 15:28:38 +0200160 // TODO: add tests for W address mode, once Dawn supports 3D textures
Stephen White1c24abc2018-04-03 11:41:05 -0400161 }
162
Corentin Wallez6f7749c2018-05-02 18:10:13 -0400163 utils::BasicRenderPass mRenderPass;
Corentin Wallezcab352c2019-10-28 13:27:36 +0000164 wgpu::BindGroupLayout mBindGroupLayout;
165 wgpu::RenderPipeline mPipeline;
166 wgpu::TextureView mTextureView;
Stephen White1c24abc2018-04-03 11:41:05 -0400167};
168
169// Test drawing a rect with a checkerboard texture with different address modes.
170TEST_P(SamplerTest, AddressMode) {
171 for (auto u : addressModes) {
172 for (auto v : addressModes) {
173 for (auto w : addressModes) {
174 TestAddressModes(u, v, w);
175 }
176 }
177 }
178}
179
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000180DAWN_INSTANTIATE_TEST(SamplerTest,
181 D3D12Backend(),
182 MetalBackend(),
183 OpenGLBackend(),
Stephen Whitef31b78e2020-12-04 15:59:29 +0000184 OpenGLESBackend(),
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000185 VulkanBackend());