blob: b2edd4d18c1907eb2a41f221eef8b0ca73942dbd [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Corentin Wallezf07e3bd2017-04-20 14:38:20 -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
Corentin Wallezb91022d2018-01-19 12:52:25 -050015#include "SampleUtils.h"
16
Kai Ninomiya21006bb2018-06-20 18:54:18 -070017#include "common/Assert.h"
Corentin Wallez0b186b12017-07-12 12:56:05 -040018#include "common/Platform.h"
Corentin Wallez1bd219d2017-06-19 12:53:38 -040019#include "utils/BackendBinding.h"
Corentin Wallezbdc86772018-07-26 15:07:57 +020020#include "utils/TerribleCommandBuffer.h"
Corentin Wallez1bd219d2017-06-19 12:53:38 -040021
Corentin Wallez046cb462018-07-18 14:28:38 +020022#include <dawn/dawn.h>
23#include <dawn/dawncpp.h>
Corentin Wallez3e371b12018-07-18 14:32:45 +020024#include <dawn/dawn_wsi.h>
Corentin Wallezdcb71a12018-08-02 22:27:57 +020025#include <dawn_native/DawnNative.h>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040026#include "GLFW/glfw3.h"
27
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040028#include <cstring>
29#include <iostream>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040030
Corentin Wallez4828d922018-07-18 13:45:46 +020031void PrintDeviceError(const char* message, dawn::CallbackUserdata) {
Corentin Wallez4b410a32017-04-20 14:42:36 -040032 std::cout << "Device error: " << message << std::endl;
33}
34
Corentin Wallez52cbcb42018-01-19 12:52:03 -050035void PrintGLFWError(int code, const char* message) {
36 std::cout << "GLFW error: " << code << " - " << message << std::endl;
37}
38
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040039enum class CmdBufType {
40 None,
41 Terrible,
Corentin Wallez682a8252017-05-09 15:34:13 +020042 //TODO(cwallez@chromium.org) double terrible cmdbuf
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040043};
44
Corentin Wallez275817a2017-07-12 12:43:24 -040045// Default to D3D12, Metal, Vulkan, OpenGL in that order as D3D12 and Metal are the preferred on
46// their respective platforms, and Vulkan is preferred to OpenGL
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020047#if defined(DAWN_ENABLE_BACKEND_D3D12)
Corentin Wallez275817a2017-07-12 12:43:24 -040048 static utils::BackendType backendType = utils::BackendType::D3D12;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020049#elif defined(DAWN_ENABLE_BACKEND_METAL)
Corentin Wallez275817a2017-07-12 12:43:24 -040050 static utils::BackendType backendType = utils::BackendType::Metal;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020051#elif defined(DAWN_ENABLE_BACKEND_OPENGL)
Kai Ninomiyac16a67a2017-07-27 18:30:57 -070052 static utils::BackendType backendType = utils::BackendType::OpenGL;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020053#elif defined(DAWN_ENABLE_BACKEND_VULKAN)
Corentin Wallez275817a2017-07-12 12:43:24 -040054 static utils::BackendType backendType = utils::BackendType::Vulkan;
Austin Engfc2bac72017-06-05 17:08:55 -040055#else
Corentin Wallez275817a2017-07-12 12:43:24 -040056 #error
Austin Engfc2bac72017-06-05 17:08:55 -040057#endif
58
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040059static CmdBufType cmdBufType = CmdBufType::Terrible;
Corentin Wallez1bd219d2017-06-19 12:53:38 -040060static utils::BackendBinding* binding = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040061
62static GLFWwindow* window = nullptr;
63
Corentin Wallezbdc86772018-07-26 15:07:57 +020064static dawn_wire::CommandHandler* wireServer = nullptr;
65static dawn_wire::CommandHandler* wireClient = nullptr;
66static utils::TerribleCommandBuffer* c2sBuf = nullptr;
67static utils::TerribleCommandBuffer* s2cBuf = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040068
Corentin Wallez39039fa2018-07-18 14:06:10 +020069dawn::Device CreateCppDawnDevice() {
Corentin Wallez1bd219d2017-06-19 12:53:38 -040070 binding = utils::CreateBinding(backendType);
71 if (binding == nullptr) {
Corentin Wallez4828d922018-07-18 13:45:46 +020072 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040073 }
74
Corentin Wallez52cbcb42018-01-19 12:52:03 -050075 glfwSetErrorCallback(PrintGLFWError);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040076 if (!glfwInit()) {
Corentin Wallez4828d922018-07-18 13:45:46 +020077 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040078 }
79
80 binding->SetupGLFWWindowHints();
Corentin Wallez6ed9cbf2018-07-18 15:32:04 +020081 window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040082 if (!window) {
Corentin Wallez4828d922018-07-18 13:45:46 +020083 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040084 }
85
86 binding->SetWindow(window);
87
Corentin Wallezdcb71a12018-08-02 22:27:57 +020088 dawnDevice backendDevice = binding->CreateDevice();
89 dawnProcTable backendProcs = dawn_native::GetProcs();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040090
Corentin Wallezb1669e32018-07-18 15:12:52 +020091 dawnDevice cDevice = nullptr;
Corentin Wallezbe5ca382018-07-18 15:15:07 +020092 dawnProcTable procs;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040093 switch (cmdBufType) {
94 case CmdBufType::None:
Corentin Wallez583e9a82017-05-29 11:30:29 -070095 procs = backendProcs;
96 cDevice = backendDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040097 break;
98
99 case CmdBufType::Terrible:
100 {
Corentin Wallezbdc86772018-07-26 15:07:57 +0200101 c2sBuf = new utils::TerribleCommandBuffer();
102 s2cBuf = new utils::TerribleCommandBuffer();
Corentin Wallez682a8252017-05-09 15:34:13 +0200103
Corentin Wallezbdc86772018-07-26 15:07:57 +0200104 wireServer = dawn_wire::NewServerCommandHandler(backendDevice, backendProcs, s2cBuf);
Corentin Wallez682a8252017-05-09 15:34:13 +0200105 c2sBuf->SetHandler(wireServer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400106
Corentin Wallezb1669e32018-07-18 15:12:52 +0200107 dawnDevice clientDevice;
Corentin Wallezbe5ca382018-07-18 15:15:07 +0200108 dawnProcTable clientProcs;
Corentin Wallezbdc86772018-07-26 15:07:57 +0200109 wireClient = dawn_wire::NewClientDevice(&clientProcs, &clientDevice, c2sBuf);
Corentin Wallez682a8252017-05-09 15:34:13 +0200110 s2cBuf->SetHandler(wireClient);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400111
Corentin Wallez583e9a82017-05-29 11:30:29 -0700112 procs = clientProcs;
113 cDevice = clientDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400114 }
115 break;
116 }
117
Corentin Wallezbe5ca382018-07-18 15:15:07 +0200118 dawnSetProcs(&procs);
Corentin Wallez583e9a82017-05-29 11:30:29 -0700119 procs.deviceSetErrorCallback(cDevice, PrintDeviceError, 0);
Corentin Wallez4828d922018-07-18 13:45:46 +0200120 return dawn::Device::Acquire(cDevice);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400121}
122
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700123uint64_t GetSwapChainImplementation() {
124 return binding->GetSwapChainImplementation();
125}
126
Corentin Wallez4828d922018-07-18 13:45:46 +0200127dawn::TextureFormat GetPreferredSwapChainTextureFormat() {
Corentin Wallezb91022d2018-01-19 12:52:25 -0500128 DoFlush();
Corentin Wallez4828d922018-07-18 13:45:46 +0200129 return static_cast<dawn::TextureFormat>(binding->GetPreferredSwapChainTextureFormat());
Corentin Wallez2e31e8f2017-09-21 12:54:53 -0400130}
131
Corentin Wallez4828d922018-07-18 13:45:46 +0200132dawn::SwapChain GetSwapChain(const dawn::Device &device) {
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700133 return device.CreateSwapChainBuilder()
134 .SetImplementation(GetSwapChainImplementation())
135 .GetResult();
136}
137
Corentin Wallez4828d922018-07-18 13:45:46 +0200138dawn::TextureView CreateDefaultDepthStencilView(const dawn::Device& device) {
Jiawei Shao425428f2018-08-27 08:44:48 +0800139 dawn::TextureDescriptor descriptor;
140 descriptor.dimension = dawn::TextureDimension::e2D;
Corentin Wallez29353d62018-09-18 12:49:22 +0000141 descriptor.size.width = 640;
142 descriptor.size.height = 480;
143 descriptor.size.depth = 1;
Jiawei Shao425428f2018-08-27 08:44:48 +0800144 descriptor.arrayLayer = 1;
145 descriptor.format = dawn::TextureFormat::D32FloatS8Uint;
146 descriptor.mipLevel = 1;
147 descriptor.usage = dawn::TextureUsageBit::OutputAttachment;
148 auto depthStencilTexture = device.CreateTexture(&descriptor);
Jiawei Shao3d670502018-09-18 00:31:57 +0000149 return depthStencilTexture.CreateDefaultTextureView();
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700150}
151
Corentin Wallez4828d922018-07-18 13:45:46 +0200152void GetNextRenderPassDescriptor(const dawn::Device& device,
153 const dawn::SwapChain& swapchain,
154 const dawn::TextureView& depthStencilView,
155 dawn::Texture* backbuffer,
156 dawn::RenderPassDescriptor* info) {
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700157 *backbuffer = swapchain.GetNextTexture();
Jiawei Shao3d670502018-09-18 00:31:57 +0000158 auto backbufferView = backbuffer->CreateDefaultTextureView();
Corentin Wallez8d6b5d22018-05-11 13:04:44 -0400159 *info = device.CreateRenderPassDescriptorBuilder()
Corentin Wallez4828d922018-07-18 13:45:46 +0200160 .SetColorAttachment(0, backbufferView, dawn::LoadOp::Clear)
161 .SetDepthStencilAttachment(depthStencilView, dawn::LoadOp::Clear, dawn::LoadOp::Clear)
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700162 .GetResult();
163}
164
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400165bool InitSample(int argc, const char** argv) {
Corentin Wallez862f8842018-06-07 13:03:29 +0200166 for (int i = 1; i < argc; i++) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400167 if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
168 i++;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400169 if (i < argc && std::string("d3d12") == argv[i]) {
170 backendType = utils::BackendType::D3D12;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400171 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400172 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400173 if (i < argc && std::string("metal") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400174 backendType = utils::BackendType::Metal;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400175 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400176 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400177 if (i < argc && std::string("null") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400178 backendType = utils::BackendType::Null;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400179 continue;
180 }
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400181 if (i < argc && std::string("opengl") == argv[i]) {
182 backendType = utils::BackendType::OpenGL;
183 continue;
184 }
185 if (i < argc && std::string("vulkan") == argv[i]) {
186 backendType = utils::BackendType::Vulkan;
187 continue;
188 }
189 fprintf(stderr, "--backend expects a backend name (opengl, metal, d3d12, null, vulkan)\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400190 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400191 }
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700192 if (std::string("-c") == argv[i] || std::string("--command-buffer") == argv[i]) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400193 i++;
194 if (i < argc && std::string("none") == argv[i]) {
195 cmdBufType = CmdBufType::None;
196 continue;
197 }
198 if (i < argc && std::string("terrible") == argv[i]) {
199 cmdBufType = CmdBufType::Terrible;
200 continue;
201 }
202 fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
203 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400204 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400205 if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
206 printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400207 printf(" BACKEND is one of: d3d12, metal, null, opengl, vulkan\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400208 printf(" COMMAND_BUFFER is one of: none, terrible\n");
209 return false;
210 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400211 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400212 return true;
213}
214
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700215void DoFlush() {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400216 if (cmdBufType == CmdBufType::Terrible) {
Corentin Walleza5696c72018-08-13 08:24:01 +0200217 bool c2sSuccess = c2sBuf->Flush();
218 bool s2cSuccess = s2cBuf->Flush();
219
220 ASSERT(c2sSuccess && s2cSuccess);
Corentin Wallez931e6e82017-06-16 18:51:14 -0400221 }
222 glfwPollEvents();
Corentin Wallez931e6e82017-06-16 18:51:14 -0400223}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400224
Corentin Wallez931e6e82017-06-16 18:51:14 -0400225bool ShouldQuit() {
226 return glfwWindowShouldClose(window);
227}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400228
Corentin Wallez931e6e82017-06-16 18:51:14 -0400229GLFWwindow* GetGLFWWindow() {
230 return window;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400231}