blob: 7e1e7311f44b5f45eb0ee5da9d790b57ee69c7a1 [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>
Corentin Wallez3e371b12018-07-18 14:32:45 +020023#include <dawn/dawn_wsi.h>
Austin Enge2c85132019-02-11 21:50:16 +000024#include <dawn/dawncpp.h>
Corentin Wallezdcb71a12018-08-02 22:27:57 +020025#include <dawn_native/DawnNative.h>
Austin Enge2c85132019-02-11 21:50:16 +000026#include <dawn_wire/WireClient.h>
27#include <dawn_wire/WireServer.h>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040028#include "GLFW/glfw3.h"
29
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040030#include <cstring>
31#include <iostream>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040032
Corentin Wallez4828d922018-07-18 13:45:46 +020033void PrintDeviceError(const char* message, dawn::CallbackUserdata) {
Corentin Wallez4b410a32017-04-20 14:42:36 -040034 std::cout << "Device error: " << message << std::endl;
35}
36
Corentin Wallez52cbcb42018-01-19 12:52:03 -050037void PrintGLFWError(int code, const char* message) {
38 std::cout << "GLFW error: " << code << " - " << message << std::endl;
39}
40
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040041enum class CmdBufType {
42 None,
43 Terrible,
Corentin Wallez682a8252017-05-09 15:34:13 +020044 //TODO(cwallez@chromium.org) double terrible cmdbuf
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040045};
46
Corentin Wallez275817a2017-07-12 12:43:24 -040047// Default to D3D12, Metal, Vulkan, OpenGL in that order as D3D12 and Metal are the preferred on
48// their respective platforms, and Vulkan is preferred to OpenGL
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020049#if defined(DAWN_ENABLE_BACKEND_D3D12)
Corentin Wallez8c88e1d2019-02-05 12:17:20 +000050 static dawn_native::BackendType backendType = dawn_native::BackendType::D3D12;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020051#elif defined(DAWN_ENABLE_BACKEND_METAL)
Corentin Wallez8c88e1d2019-02-05 12:17:20 +000052 static dawn_native::BackendType backendType = dawn_native::BackendType::Metal;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020053#elif defined(DAWN_ENABLE_BACKEND_OPENGL)
Corentin Wallez8c88e1d2019-02-05 12:17:20 +000054 static dawn_native::BackendType backendType = dawn_native::BackendType::OpenGL;
Corentin Wallezf1ded9b2018-07-18 13:52:46 +020055#elif defined(DAWN_ENABLE_BACKEND_VULKAN)
Corentin Wallez8c88e1d2019-02-05 12:17:20 +000056 static dawn_native::BackendType backendType = dawn_native::BackendType::Vulkan;
Austin Engfc2bac72017-06-05 17:08:55 -040057#else
Corentin Wallez275817a2017-07-12 12:43:24 -040058 #error
Austin Engfc2bac72017-06-05 17:08:55 -040059#endif
60
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040061static CmdBufType cmdBufType = CmdBufType::Terrible;
Corentin Wallez1bd219d2017-06-19 12:53:38 -040062static utils::BackendBinding* binding = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040063
64static GLFWwindow* window = nullptr;
65
Austin Enge2c85132019-02-11 21:50:16 +000066static dawn_wire::WireServer* wireServer = nullptr;
67static dawn_wire::WireClient* wireClient = nullptr;
Corentin Wallezbdc86772018-07-26 15:07:57 +020068static utils::TerribleCommandBuffer* c2sBuf = nullptr;
69static utils::TerribleCommandBuffer* s2cBuf = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040070
Corentin Wallez39039fa2018-07-18 14:06:10 +020071dawn::Device CreateCppDawnDevice() {
Corentin Wallez1bd219d2017-06-19 12:53:38 -040072 binding = utils::CreateBinding(backendType);
73 if (binding == nullptr) {
Corentin Wallez4828d922018-07-18 13:45:46 +020074 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040075 }
76
Corentin Wallez52cbcb42018-01-19 12:52:03 -050077 glfwSetErrorCallback(PrintGLFWError);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040078 if (!glfwInit()) {
Corentin Wallez4828d922018-07-18 13:45:46 +020079 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040080 }
81
82 binding->SetupGLFWWindowHints();
Corentin Wallez6ed9cbf2018-07-18 15:32:04 +020083 window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040084 if (!window) {
Corentin Wallez4828d922018-07-18 13:45:46 +020085 return dawn::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040086 }
87
88 binding->SetWindow(window);
89
Corentin Wallezdcb71a12018-08-02 22:27:57 +020090 dawnDevice backendDevice = binding->CreateDevice();
91 dawnProcTable backendProcs = dawn_native::GetProcs();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040092
Corentin Wallezb1669e32018-07-18 15:12:52 +020093 dawnDevice cDevice = nullptr;
Corentin Wallezbe5ca382018-07-18 15:15:07 +020094 dawnProcTable procs;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040095 switch (cmdBufType) {
96 case CmdBufType::None:
Corentin Wallez583e9a82017-05-29 11:30:29 -070097 procs = backendProcs;
98 cDevice = backendDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040099 break;
100
101 case CmdBufType::Terrible:
102 {
Corentin Wallezbdc86772018-07-26 15:07:57 +0200103 c2sBuf = new utils::TerribleCommandBuffer();
104 s2cBuf = new utils::TerribleCommandBuffer();
Corentin Wallez682a8252017-05-09 15:34:13 +0200105
Austin Enge2c85132019-02-11 21:50:16 +0000106 wireServer = new dawn_wire::WireServer(backendDevice, backendProcs, s2cBuf);
Corentin Wallez682a8252017-05-09 15:34:13 +0200107 c2sBuf->SetHandler(wireServer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400108
Austin Enge2c85132019-02-11 21:50:16 +0000109 wireClient = new dawn_wire::WireClient(c2sBuf);
110 dawnDevice clientDevice = wireClient->GetDevice();
111 dawnProcTable clientProcs = wireClient->GetProcs();
Corentin Wallez682a8252017-05-09 15:34:13 +0200112 s2cBuf->SetHandler(wireClient);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400113
Corentin Wallez583e9a82017-05-29 11:30:29 -0700114 procs = clientProcs;
115 cDevice = clientDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400116 }
117 break;
118 }
119
Corentin Wallezbe5ca382018-07-18 15:15:07 +0200120 dawnSetProcs(&procs);
Corentin Wallez583e9a82017-05-29 11:30:29 -0700121 procs.deviceSetErrorCallback(cDevice, PrintDeviceError, 0);
Corentin Wallez4828d922018-07-18 13:45:46 +0200122 return dawn::Device::Acquire(cDevice);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400123}
124
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700125uint64_t GetSwapChainImplementation() {
126 return binding->GetSwapChainImplementation();
127}
128
Corentin Wallez4828d922018-07-18 13:45:46 +0200129dawn::TextureFormat GetPreferredSwapChainTextureFormat() {
Corentin Wallezb91022d2018-01-19 12:52:25 -0500130 DoFlush();
Corentin Wallez4828d922018-07-18 13:45:46 +0200131 return static_cast<dawn::TextureFormat>(binding->GetPreferredSwapChainTextureFormat());
Corentin Wallez2e31e8f2017-09-21 12:54:53 -0400132}
133
Corentin Wallez4828d922018-07-18 13:45:46 +0200134dawn::SwapChain GetSwapChain(const dawn::Device &device) {
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700135 return device.CreateSwapChainBuilder()
136 .SetImplementation(GetSwapChainImplementation())
137 .GetResult();
138}
139
Corentin Wallez4828d922018-07-18 13:45:46 +0200140dawn::TextureView CreateDefaultDepthStencilView(const dawn::Device& device) {
Jiawei Shao425428f2018-08-27 08:44:48 +0800141 dawn::TextureDescriptor descriptor;
142 descriptor.dimension = dawn::TextureDimension::e2D;
Corentin Wallez29353d62018-09-18 12:49:22 +0000143 descriptor.size.width = 640;
144 descriptor.size.height = 480;
145 descriptor.size.depth = 1;
Jiawei Shao8bff3b22018-12-12 09:27:16 +0000146 descriptor.arraySize = 1;
147 descriptor.sampleCount = 1;
Jiawei Shao425428f2018-08-27 08:44:48 +0800148 descriptor.format = dawn::TextureFormat::D32FloatS8Uint;
Jiawei Shao84cde512018-10-31 10:51:11 +0000149 descriptor.levelCount = 1;
Jiawei Shao425428f2018-08-27 08:44:48 +0800150 descriptor.usage = dawn::TextureUsageBit::OutputAttachment;
151 auto depthStencilTexture = device.CreateTexture(&descriptor);
Jiawei Shao3d670502018-09-18 00:31:57 +0000152 return depthStencilTexture.CreateDefaultTextureView();
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700153}
154
Corentin Wallez4828d922018-07-18 13:45:46 +0200155void GetNextRenderPassDescriptor(const dawn::Device& device,
156 const dawn::SwapChain& swapchain,
157 const dawn::TextureView& depthStencilView,
158 dawn::Texture* backbuffer,
159 dawn::RenderPassDescriptor* info) {
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700160 *backbuffer = swapchain.GetNextTexture();
Jiawei Shao3d670502018-09-18 00:31:57 +0000161 auto backbufferView = backbuffer->CreateDefaultTextureView();
Jiawei Shao5e811ae2018-12-19 08:21:13 +0000162 dawn::RenderPassColorAttachmentDescriptor colorAttachment;
163 colorAttachment.attachment = backbufferView;
164 colorAttachment.resolveTarget = nullptr;
165 colorAttachment.clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
166 colorAttachment.loadOp = dawn::LoadOp::Clear;
167 colorAttachment.storeOp = dawn::StoreOp::Store;
168
169 dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
170 depthStencilAttachment.attachment = depthStencilView;
171 depthStencilAttachment.depthLoadOp = dawn::LoadOp::Clear;
172 depthStencilAttachment.stencilLoadOp = dawn::LoadOp::Clear;
173 depthStencilAttachment.clearDepth = 1.0f;
174 depthStencilAttachment.clearStencil = 0;
175 depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
176 depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
177
Corentin Wallez8d6b5d22018-05-11 13:04:44 -0400178 *info = device.CreateRenderPassDescriptorBuilder()
Jiawei Shao5e811ae2018-12-19 08:21:13 +0000179 .SetColorAttachments(1, &colorAttachment)
180 .SetDepthStencilAttachment(&depthStencilAttachment)
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700181 .GetResult();
182}
183
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400184bool InitSample(int argc, const char** argv) {
Corentin Wallez862f8842018-06-07 13:03:29 +0200185 for (int i = 1; i < argc; i++) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400186 if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
187 i++;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400188 if (i < argc && std::string("d3d12") == argv[i]) {
Corentin Wallez8c88e1d2019-02-05 12:17:20 +0000189 backendType = dawn_native::BackendType::D3D12;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400190 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400191 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400192 if (i < argc && std::string("metal") == argv[i]) {
Corentin Wallez8c88e1d2019-02-05 12:17:20 +0000193 backendType = dawn_native::BackendType::Metal;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400194 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400195 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400196 if (i < argc && std::string("null") == argv[i]) {
Corentin Wallez8c88e1d2019-02-05 12:17:20 +0000197 backendType = dawn_native::BackendType::Null;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400198 continue;
199 }
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400200 if (i < argc && std::string("opengl") == argv[i]) {
Corentin Wallez8c88e1d2019-02-05 12:17:20 +0000201 backendType = dawn_native::BackendType::OpenGL;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400202 continue;
203 }
204 if (i < argc && std::string("vulkan") == argv[i]) {
Corentin Wallez8c88e1d2019-02-05 12:17:20 +0000205 backendType = dawn_native::BackendType::Vulkan;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400206 continue;
207 }
208 fprintf(stderr, "--backend expects a backend name (opengl, metal, d3d12, null, vulkan)\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400209 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400210 }
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700211 if (std::string("-c") == argv[i] || std::string("--command-buffer") == argv[i]) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400212 i++;
213 if (i < argc && std::string("none") == argv[i]) {
214 cmdBufType = CmdBufType::None;
215 continue;
216 }
217 if (i < argc && std::string("terrible") == argv[i]) {
218 cmdBufType = CmdBufType::Terrible;
219 continue;
220 }
221 fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
222 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400223 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400224 if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
225 printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400226 printf(" BACKEND is one of: d3d12, metal, null, opengl, vulkan\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400227 printf(" COMMAND_BUFFER is one of: none, terrible\n");
228 return false;
229 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400230 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400231 return true;
232}
233
Kai Ninomiyac16a67a2017-07-27 18:30:57 -0700234void DoFlush() {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400235 if (cmdBufType == CmdBufType::Terrible) {
Corentin Walleza5696c72018-08-13 08:24:01 +0200236 bool c2sSuccess = c2sBuf->Flush();
237 bool s2cSuccess = s2cBuf->Flush();
238
239 ASSERT(c2sSuccess && s2cSuccess);
Corentin Wallez931e6e82017-06-16 18:51:14 -0400240 }
241 glfwPollEvents();
Corentin Wallez931e6e82017-06-16 18:51:14 -0400242}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400243
Corentin Wallez931e6e82017-06-16 18:51:14 -0400244bool ShouldQuit() {
245 return glfwWindowShouldClose(window);
246}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400247
Corentin Wallez931e6e82017-06-16 18:51:14 -0400248GLFWwindow* GetGLFWWindow() {
249 return window;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400250}