blob: 1a91958b18664cceaa2ca929bf108062a777d7f1 [file] [log] [blame]
// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "tests/unittests/validation/ValidationTest.h"
#include "common/Constants.h"
#include "common/Log.h"
#include "utils/GLFWUtils.h"
#include "utils/WGPUHelpers.h"
#include "GLFW/glfw3.h"
class SwapChainValidationTests : public ValidationTest {
public:
void SetUp() override {
glfwSetErrorCallback([](int code, const char* message) {
dawn::ErrorLog() << "GLFW error " << code << " " << message;
});
glfwInit();
// The SwapChainValidationTests tests don't create devices so we don't need to call
// SetupGLFWWindowHintsForBackend. Set GLFW_NO_API anyway to avoid GLFW bringing up a GL
// context that we won't use.
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(400, 400, "SwapChainValidationTests window", nullptr, nullptr);
surface = utils::CreateSurfaceForWindow(instance->Get(), window);
ASSERT_NE(surface, nullptr);
goodDescriptor.width = 1;
goodDescriptor.height = 1;
goodDescriptor.usage = wgpu::TextureUsage::OutputAttachment;
goodDescriptor.format = wgpu::TextureFormat::BGRA8Unorm;
goodDescriptor.presentMode = wgpu::PresentMode::VSync;
badDescriptor = goodDescriptor;
badDescriptor.width = 0;
}
void TearDown() override {
// Destroy the surface before the window as required by webgpu-native.
surface = wgpu::Surface();
glfwDestroyWindow(window);
}
protected:
GLFWwindow* window = nullptr;
wgpu::Surface surface;
wgpu::SwapChainDescriptor goodDescriptor;
wgpu::SwapChainDescriptor badDescriptor;
// Checks that an OutputAttachment view is an error by trying to create a render pass on it.
void CheckTextureViewIsError(wgpu::TextureView view) {
utils::ComboRenderPassDescriptor renderPassDesc({view});
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc);
pass.EndPass();
ASSERT_DEVICE_ERROR(encoder.Finish());
}
};
// Control case for a successful swapchain creation.
TEST_F(SwapChainValidationTests, CreationSuccess) {
device.CreateSwapChain(surface, &goodDescriptor);
}
// Checks that the creation size must be a valid 2D texture size.
TEST_F(SwapChainValidationTests, InvalidCreationSize) {
// A width of 0 is invalid.
{
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.width = 0;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// A height of 0 is invalid.
{
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.height = 0;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// A width of kMaxTextureSize is valid but kMaxTextureSize + 1 isn't.
{
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.width = kMaxTextureSize;
device.CreateSwapChain(surface, &desc);
desc.width = kMaxTextureSize + 1;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// A height of kMaxTextureSize is valid but kMaxTextureSize + 1 isn't.
{
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.height = kMaxTextureSize;
device.CreateSwapChain(surface, &desc);
desc.height = kMaxTextureSize + 1;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
}
// Checks that the creation usage must be OutputAttachment
TEST_F(SwapChainValidationTests, InvalidCreationUsage) {
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.usage = wgpu::TextureUsage::Sampled;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// Checks that the creation format must (currently) be BGRA8Unorm
TEST_F(SwapChainValidationTests, InvalidCreationFormat) {
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.format = wgpu::TextureFormat::RGBA8Unorm;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// Checks that the implementation must be zero.
TEST_F(SwapChainValidationTests, InvalidWithImplementation) {
wgpu::SwapChainDescriptor desc = goodDescriptor;
desc.implementation = 1;
ASSERT_DEVICE_ERROR(device.CreateSwapChain(surface, &desc));
}
// Check swapchain operations with an error swapchain are errors
TEST_F(SwapChainValidationTests, OperationsOnErrorSwapChain) {
wgpu::SwapChain swapchain;
ASSERT_DEVICE_ERROR(swapchain = device.CreateSwapChain(surface, &badDescriptor));
wgpu::TextureView view;
ASSERT_DEVICE_ERROR(view = swapchain.GetCurrentTextureView());
CheckTextureViewIsError(view);
ASSERT_DEVICE_ERROR(swapchain.Present());
}