blob: d89472817b353fb4d291c2555b8eb36898652513 [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 Wallez1bd219d2017-06-19 12:53:38 -040015#include "utils/BackendBinding.h"
16#include "../src/wire/TerribleCommandBuffer.h"
17
Corentin Wallez83e779d2017-07-10 21:44:06 -040018// Include Windows.h before GLFW to avoid a redefinition of APIENTRY
19#ifdef _WIN32
20 #include <Windows.h>
21#else
22 #include <unistd.h>
23#endif
24
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040025#include <nxt/nxt.h>
26#include <nxt/nxtcpp.h>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040027#include "GLFW/glfw3.h"
28
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040029#include <cstring>
30#include <iostream>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040031
Corentin Wallez4b410a32017-04-20 14:42:36 -040032void PrintDeviceError(const char* message, nxt::CallbackUserdata) {
33 std::cout << "Device error: " << message << std::endl;
34}
35
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040036enum class CmdBufType {
37 None,
38 Terrible,
Corentin Wallez682a8252017-05-09 15:34:13 +020039 //TODO(cwallez@chromium.org) double terrible cmdbuf
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040040};
41
Corentin Wallez275817a2017-07-12 12:43:24 -040042// Default to D3D12, Metal, Vulkan, OpenGL in that order as D3D12 and Metal are the preferred on
43// their respective platforms, and Vulkan is preferred to OpenGL
44#if defined(NXT_ENABLE_BACKEND_D3D12)
45 static utils::BackendType backendType = utils::BackendType::D3D12;
46#elif defined(NXT_ENABLE_BACKEND_METAL)
47 static utils::BackendType backendType = utils::BackendType::Metal;
48#elif defined(NXT_ENABLE_BACKEND_VULKAN)
49 static utils::BackendType backendType = utils::BackendType::OpenGL;
50#elif defined(NXT_ENABLE_BACKEND_OPENGL)
51 static utils::BackendType backendType = utils::BackendType::Vulkan;
Austin Engfc2bac72017-06-05 17:08:55 -040052#else
Corentin Wallez275817a2017-07-12 12:43:24 -040053 #error
Austin Engfc2bac72017-06-05 17:08:55 -040054#endif
55
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040056static CmdBufType cmdBufType = CmdBufType::Terrible;
Corentin Wallez1bd219d2017-06-19 12:53:38 -040057static utils::BackendBinding* binding = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040058
59static GLFWwindow* window = nullptr;
60
61static nxt::wire::CommandHandler* wireServer = nullptr;
Corentin Wallez682a8252017-05-09 15:34:13 +020062static nxt::wire::CommandHandler* wireClient = nullptr;
63static nxt::wire::TerribleCommandBuffer* c2sBuf = nullptr;
64static nxt::wire::TerribleCommandBuffer* s2cBuf = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040065
Corentin Wallez583e9a82017-05-29 11:30:29 -070066nxt::Device CreateCppNXTDevice() {
Corentin Wallez1bd219d2017-06-19 12:53:38 -040067 binding = utils::CreateBinding(backendType);
68 if (binding == nullptr) {
69 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040070 }
71
72 if (!glfwInit()) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070073 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040074 }
75
76 binding->SetupGLFWWindowHints();
77 window = glfwCreateWindow(640, 480, "NXT window", nullptr, nullptr);
78 if (!window) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070079 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040080 }
81
82 binding->SetWindow(window);
83
84 nxtDevice backendDevice;
85 nxtProcTable backendProcs;
86 binding->GetProcAndDevice(&backendProcs, &backendDevice);
87
Corentin Wallez583e9a82017-05-29 11:30:29 -070088 nxtDevice cDevice = nullptr;
89 nxtProcTable procs;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040090 switch (cmdBufType) {
91 case CmdBufType::None:
Corentin Wallez583e9a82017-05-29 11:30:29 -070092 procs = backendProcs;
93 cDevice = backendDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040094 break;
95
96 case CmdBufType::Terrible:
97 {
Corentin Wallez682a8252017-05-09 15:34:13 +020098 c2sBuf = new nxt::wire::TerribleCommandBuffer();
99 s2cBuf = new nxt::wire::TerribleCommandBuffer();
100
101 wireServer = nxt::wire::NewServerCommandHandler(backendDevice, backendProcs, s2cBuf);
102 c2sBuf->SetHandler(wireServer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400103
104 nxtDevice clientDevice;
105 nxtProcTable clientProcs;
Corentin Wallez682a8252017-05-09 15:34:13 +0200106 wireClient = nxt::wire::NewClientDevice(&clientProcs, &clientDevice, c2sBuf);
107 s2cBuf->SetHandler(wireClient);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400108
Corentin Wallez583e9a82017-05-29 11:30:29 -0700109 procs = clientProcs;
110 cDevice = clientDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400111 }
112 break;
113 }
114
Corentin Wallez583e9a82017-05-29 11:30:29 -0700115 nxtSetProcs(&procs);
116 procs.deviceSetErrorCallback(cDevice, PrintDeviceError, 0);
117 return nxt::Device::Acquire(cDevice);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400118}
119
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400120bool InitSample(int argc, const char** argv) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400121 for (int i = 0; i < argc; i++) {
122 if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
123 i++;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400124 if (i < argc && std::string("d3d12") == argv[i]) {
125 backendType = utils::BackendType::D3D12;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400126 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400127 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400128 if (i < argc && std::string("metal") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400129 backendType = utils::BackendType::Metal;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400130 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400131 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400132 if (i < argc && std::string("null") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400133 backendType = utils::BackendType::Null;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400134 continue;
135 }
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400136 if (i < argc && std::string("opengl") == argv[i]) {
137 backendType = utils::BackendType::OpenGL;
138 continue;
139 }
140 if (i < argc && std::string("vulkan") == argv[i]) {
141 backendType = utils::BackendType::Vulkan;
142 continue;
143 }
144 fprintf(stderr, "--backend expects a backend name (opengl, metal, d3d12, null, vulkan)\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400145 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400146 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400147 if (std::string("-c") == argv[i] || std::string("--comand-buffer") == argv[i]) {
148 i++;
149 if (i < argc && std::string("none") == argv[i]) {
150 cmdBufType = CmdBufType::None;
151 continue;
152 }
153 if (i < argc && std::string("terrible") == argv[i]) {
154 cmdBufType = CmdBufType::Terrible;
155 continue;
156 }
157 fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
158 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400159 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400160 if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
161 printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400162 printf(" BACKEND is one of: d3d12, metal, null, opengl, vulkan\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400163 printf(" COMMAND_BUFFER is one of: none, terrible\n");
164 return false;
165 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400166 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400167 return true;
168}
169
170void DoSwapBuffers() {
171 if (cmdBufType == CmdBufType::Terrible) {
172 c2sBuf->Flush();
173 s2cBuf->Flush();
174 }
175 glfwPollEvents();
176 binding->SwapBuffers();
177}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400178
Corentin Wallez583e9a82017-05-29 11:30:29 -0700179#ifdef _WIN32
Corentin Wallez931e6e82017-06-16 18:51:14 -0400180void USleep(uint64_t usecs) {
Corentin Wallez83e779d2017-07-10 21:44:06 -0400181 Sleep(static_cast<DWORD>(usecs / 1000));
Corentin Wallez931e6e82017-06-16 18:51:14 -0400182}
Corentin Wallez583e9a82017-05-29 11:30:29 -0700183#else
Corentin Wallez931e6e82017-06-16 18:51:14 -0400184void USleep(uint64_t usecs) {
185 usleep(usecs);
186}
Corentin Wallez583e9a82017-05-29 11:30:29 -0700187#endif
188
Corentin Wallez931e6e82017-06-16 18:51:14 -0400189bool ShouldQuit() {
190 return glfwWindowShouldClose(window);
191}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400192
Corentin Wallez931e6e82017-06-16 18:51:14 -0400193GLFWwindow* GetGLFWWindow() {
194 return window;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400195}