blob: 650fdfd287ac17d89cb347985e5050aeb472b9f0 [file] [log] [blame]
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001// Copyright 2017 The NXT Authors
2//
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 Wallez0b186b12017-07-12 12:56:05 -040015#include "common/Platform.h"
Corentin Wallez1bd219d2017-06-19 12:53:38 -040016#include "utils/BackendBinding.h"
Corentin Wallez0b186b12017-07-12 12:56:05 -040017#include "wire/TerribleCommandBuffer.h"
Corentin Wallez1bd219d2017-06-19 12:53:38 -040018
Corentin Wallez83e779d2017-07-10 21:44:06 -040019// Include Windows.h before GLFW to avoid a redefinition of APIENTRY
Corentin Wallez0b186b12017-07-12 12:56:05 -040020#if defined(NXT_PLATFORM_WINDOWS)
Corentin Wallez83e779d2017-07-10 21:44:06 -040021 #include <Windows.h>
Corentin Wallez0b186b12017-07-12 12:56:05 -040022#elif defined(NXT_PLATFORM_POSIX)
23 #include <unistd.h>
Corentin Wallez83e779d2017-07-10 21:44:06 -040024#else
Corentin Wallez0b186b12017-07-12 12:56:05 -040025 #error "Unsupported platform."
Corentin Wallez83e779d2017-07-10 21:44:06 -040026#endif
27
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040028#include <nxt/nxt.h>
29#include <nxt/nxtcpp.h>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040030#include "GLFW/glfw3.h"
31
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040032#include <cstring>
33#include <iostream>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040034
Corentin Wallez4b410a32017-04-20 14:42:36 -040035void PrintDeviceError(const char* message, nxt::CallbackUserdata) {
36 std::cout << "Device error: " << 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
47#if defined(NXT_ENABLE_BACKEND_D3D12)
48 static utils::BackendType backendType = utils::BackendType::D3D12;
49#elif defined(NXT_ENABLE_BACKEND_METAL)
50 static utils::BackendType backendType = utils::BackendType::Metal;
51#elif defined(NXT_ENABLE_BACKEND_VULKAN)
52 static utils::BackendType backendType = utils::BackendType::OpenGL;
53#elif defined(NXT_ENABLE_BACKEND_OPENGL)
54 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
64static nxt::wire::CommandHandler* wireServer = nullptr;
Corentin Wallez682a8252017-05-09 15:34:13 +020065static nxt::wire::CommandHandler* wireClient = nullptr;
66static nxt::wire::TerribleCommandBuffer* c2sBuf = nullptr;
67static nxt::wire::TerribleCommandBuffer* s2cBuf = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040068
Corentin Wallez583e9a82017-05-29 11:30:29 -070069nxt::Device CreateCppNXTDevice() {
Corentin Wallez1bd219d2017-06-19 12:53:38 -040070 binding = utils::CreateBinding(backendType);
71 if (binding == nullptr) {
72 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040073 }
74
75 if (!glfwInit()) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070076 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040077 }
78
79 binding->SetupGLFWWindowHints();
80 window = glfwCreateWindow(640, 480, "NXT window", nullptr, nullptr);
81 if (!window) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070082 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040083 }
84
85 binding->SetWindow(window);
86
87 nxtDevice backendDevice;
88 nxtProcTable backendProcs;
89 binding->GetProcAndDevice(&backendProcs, &backendDevice);
90
Corentin Wallez583e9a82017-05-29 11:30:29 -070091 nxtDevice cDevice = nullptr;
92 nxtProcTable 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 Wallez682a8252017-05-09 15:34:13 +0200101 c2sBuf = new nxt::wire::TerribleCommandBuffer();
102 s2cBuf = new nxt::wire::TerribleCommandBuffer();
103
104 wireServer = nxt::wire::NewServerCommandHandler(backendDevice, backendProcs, s2cBuf);
105 c2sBuf->SetHandler(wireServer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400106
107 nxtDevice clientDevice;
108 nxtProcTable clientProcs;
Corentin Wallez682a8252017-05-09 15:34:13 +0200109 wireClient = nxt::wire::NewClientDevice(&clientProcs, &clientDevice, c2sBuf);
110 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 Wallez583e9a82017-05-29 11:30:29 -0700118 nxtSetProcs(&procs);
119 procs.deviceSetErrorCallback(cDevice, PrintDeviceError, 0);
120 return nxt::Device::Acquire(cDevice);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400121}
122
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400123bool InitSample(int argc, const char** argv) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400124 for (int i = 0; i < argc; i++) {
125 if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
126 i++;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400127 if (i < argc && std::string("d3d12") == argv[i]) {
128 backendType = utils::BackendType::D3D12;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400129 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400130 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400131 if (i < argc && std::string("metal") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400132 backendType = utils::BackendType::Metal;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400133 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400134 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400135 if (i < argc && std::string("null") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400136 backendType = utils::BackendType::Null;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400137 continue;
138 }
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400139 if (i < argc && std::string("opengl") == argv[i]) {
140 backendType = utils::BackendType::OpenGL;
141 continue;
142 }
143 if (i < argc && std::string("vulkan") == argv[i]) {
144 backendType = utils::BackendType::Vulkan;
145 continue;
146 }
147 fprintf(stderr, "--backend expects a backend name (opengl, metal, d3d12, null, vulkan)\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400148 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400149 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400150 if (std::string("-c") == argv[i] || std::string("--comand-buffer") == argv[i]) {
151 i++;
152 if (i < argc && std::string("none") == argv[i]) {
153 cmdBufType = CmdBufType::None;
154 continue;
155 }
156 if (i < argc && std::string("terrible") == argv[i]) {
157 cmdBufType = CmdBufType::Terrible;
158 continue;
159 }
160 fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
161 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400162 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400163 if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
164 printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400165 printf(" BACKEND is one of: d3d12, metal, null, opengl, vulkan\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400166 printf(" COMMAND_BUFFER is one of: none, terrible\n");
167 return false;
168 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400169 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400170 return true;
171}
172
173void DoSwapBuffers() {
174 if (cmdBufType == CmdBufType::Terrible) {
175 c2sBuf->Flush();
176 s2cBuf->Flush();
177 }
178 glfwPollEvents();
179 binding->SwapBuffers();
180}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400181
Corentin Wallez0b186b12017-07-12 12:56:05 -0400182#if defined(NXT_PLATFORM_WINDOWS)
183 void USleep(uint64_t usecs) {
184 Sleep(static_cast<DWORD>(usecs / 1000));
185 }
186#elif defined(NXT_PLATFORM_POSIX)
187 void USleep(uint64_t usecs) {
188 usleep(usecs);
189 }
Corentin Wallez583e9a82017-05-29 11:30:29 -0700190#else
Corentin Wallez0b186b12017-07-12 12:56:05 -0400191 #error "Implement USleep for your platform."
Corentin Wallez583e9a82017-05-29 11:30:29 -0700192#endif
193
Corentin Wallez931e6e82017-06-16 18:51:14 -0400194bool ShouldQuit() {
195 return glfwWindowShouldClose(window);
196}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400197
Corentin Wallez931e6e82017-06-16 18:51:14 -0400198GLFWwindow* GetGLFWWindow() {
199 return window;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400200}