Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/dawn/native/vulkan/SwapChainVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <utility>

#include "src/dawn/common/Compiler.h"
#include "src/dawn/common/Range.h"
#include "src/dawn/native/ChainUtils.h"
#include "src/dawn/native/Instance.h"
#include "src/dawn/native/Surface.h"
Expand Down Expand Up @@ -296,33 +295,34 @@ ResultOrError<SwapChain::Config> SwapChain::ChooseConfig(
"Vulkan SwapChain must support %s with sRGB colorspace.", config.wgpuFormat));
}

// Only the identity transform with opaque alpha is supported for now.
// Only the identity transform is supported for now.
DAWN_INVALID_IF(
(surfaceInfo.capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) == 0,
"Vulkan SwapChain must support the identity transform.");

config.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;

config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
#if !DAWN_PLATFORM_IS(ANDROID)
DAWN_INVALID_IF(
(surfaceInfo.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) == 0,
"Vulkan SwapChain must support opaque alpha.");
#else
// TODO(dawn:286): investigate composite alpha for WebGPU native
std::array<VkCompositeAlphaFlagBitsKHR, 4u> compositeAlphaFlags = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
};
for (uint32_t i : Range(4u)) {
if (surfaceInfo.capabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) {
config.alphaMode = compositeAlphaFlags[i];
// Choose the Vulkan alpha mode by directly converting from the WebGPU enum. PhysicalDeviceVk
// only reports the alpha modes the surface supports, Surface.cpp resolves Auto and validates
// the rest, so the mode asked for here is always available.
switch (GetAlphaMode()) {
case wgpu::CompositeAlphaMode::Opaque:
config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
break;
}
case wgpu::CompositeAlphaMode::Premultiplied:
config.alphaMode = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
break;
case wgpu::CompositeAlphaMode::Unpremultiplied:
config.alphaMode = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
break;
case wgpu::CompositeAlphaMode::Inherit:
config.alphaMode = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
break;
case wgpu::CompositeAlphaMode::Auto:
default:
DAWN_UNREACHABLE();
}
#endif // #if !DAWN_PLATFORM_IS(ANDROID)
DAWN_CHECK((surfaceInfo.capabilities.supportedCompositeAlpha & config.alphaMode) != 0);

// Choose the number of images for the swapchain= and clamp it to the min and max from the
// surface capabilities. maxImageCount = 0 means there is no limit.
Expand Down
22 changes: 18 additions & 4 deletions src/dawn/samples/ManualSurfaceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
// This is an example to manually test surface code. Controls are the following, scoped to the
// currently focused window:
// - W: creates a new window.
// - T: creates a new window with a transparent framebuffer, to test the alpha modes.
// - L: Latches the current surface, to check what happens when the window changes but not the
// surface.
// - R: switches the rendering mode, between "The Red Triangle" and color-cycling clears that's
Expand Down Expand Up @@ -64,6 +65,9 @@
// - Config change tests:
// - Check that cycling between present modes.
// - Check that cycling between alpha modes (it sometimes produce a meaningful difference).
// - Check alpha modes on a transparent window (T) in the cycling color render mode: the clear
// is premultiplied and cycles its alpha, so Premultiplied and Unpremultiplied let the
// desktop show through and Opaque does not.
// - Check that cycling between formats works and gives the same color.
//
// - Frame throttling:
Expand All @@ -75,7 +79,6 @@
// - Check sRGB vs not sRGB gradients.
// - Check wide gamut / extended color range.
// - Check OpenGL rendering with extra usages / depth buffer / MRT.
// - Check with GLFW transparency on / off.

#include <webgpu/webgpu_cpp.h>

Expand Down Expand Up @@ -125,6 +128,7 @@ struct WindowData {
uint64_t serial = 0;

float clearCycle = 1.0f;
bool transparent = false;
bool latched = false;
bool renderTriangle = true;
uint32_t divisor = 1;
Expand Down Expand Up @@ -200,8 +204,9 @@ void SyncFromWindow(WindowData* data) {
data->targetConfig.height = std::max(1u, static_cast<uint32_t>(height) / data->divisor);
}

void AddWindow() {
void AddWindow(bool transparent = false) {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, transparent ? GLFW_TRUE : GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(400, 400, "", nullptr, nullptr);
glfwSetKeyCallback(window, OnKeyPress);

Expand All @@ -221,6 +226,7 @@ void AddWindow() {
std::unique_ptr<WindowData> data = std::make_unique<WindowData>();
data->window = window;
data->serial = windowSerial++;
data->transparent = transparent;
data->surface = surface;
data->currentConfig = config;
data->targetConfig = config;
Expand Down Expand Up @@ -257,10 +263,14 @@ void DoRender(WindowData* data) {
data->clearCycle = 1.0f;
}

// On a transparent window cycle the alpha as well, so that the alpha modes have a
// visible effect. The color channels are premultiplied so that Premultiplied is valid.
const double alpha = data->transparent ? double{data->clearCycle} : 1.0;

dawn::utils::ComboRenderPassDescriptor desc({view});
desc.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
desc.cColorAttachments[0].clearValue = {double{data->clearCycle},
double{1.0f - data->clearCycle}, 0.0, 1.0};
desc.cColorAttachments[0].clearValue = {
alpha * double{data->clearCycle}, alpha * double{1.0f - data->clearCycle}, 0.0, alpha};

wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&desc);
pass.End();
Expand Down Expand Up @@ -316,6 +326,10 @@ void OnKeyPress(GLFWwindow* window, int key, int, int action, int) {
AddWindow();
break;

case GLFW_KEY_T:
AddWindow(/*transparent=*/true);
break;

case GLFW_KEY_L:
data->latched = !data->latched;
UpdateTitle(data);
Expand Down