blob: 5af9b0da8a70731635058a0e128ad2e272baba00 [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 Wallezf07e3bd2017-04-20 14:38:20 -040018#include <nxt/nxt.h>
19#include <nxt/nxtcpp.h>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040020#include "GLFW/glfw3.h"
21
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040022#include <cstring>
23#include <iostream>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040024
Corentin Wallez583e9a82017-05-29 11:30:29 -070025#ifdef _WIN32
26 #include <Windows.h>
27#else
28 #include <unistd.h>
29#endif
30
Corentin Wallez4b410a32017-04-20 14:42:36 -040031void PrintDeviceError(const char* message, nxt::CallbackUserdata) {
32 std::cout << "Device error: " << message << std::endl;
33}
34
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040035enum class CmdBufType {
36 None,
37 Terrible,
Corentin Wallez682a8252017-05-09 15:34:13 +020038 //TODO(cwallez@chromium.org) double terrible cmdbuf
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040039};
40
Austin Engfc2bac72017-06-05 17:08:55 -040041#if defined(__APPLE__)
Corentin Wallez1bd219d2017-06-19 12:53:38 -040042static utils::BackendType backendType = utils::BackendType::Metal;
Austin Engfc2bac72017-06-05 17:08:55 -040043#elif defined(_WIN32)
Corentin Wallez1bd219d2017-06-19 12:53:38 -040044static utils::BackendType backendType = utils::BackendType::D3D12;
Austin Engfc2bac72017-06-05 17:08:55 -040045#else
Corentin Wallez1bd219d2017-06-19 12:53:38 -040046static utils::BackendType backendType = utils::BackendType::OpenGL;
Austin Engfc2bac72017-06-05 17:08:55 -040047#endif
48
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040049static CmdBufType cmdBufType = CmdBufType::Terrible;
Corentin Wallez1bd219d2017-06-19 12:53:38 -040050static utils::BackendBinding* binding = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040051
52static GLFWwindow* window = nullptr;
53
54static nxt::wire::CommandHandler* wireServer = nullptr;
Corentin Wallez682a8252017-05-09 15:34:13 +020055static nxt::wire::CommandHandler* wireClient = nullptr;
56static nxt::wire::TerribleCommandBuffer* c2sBuf = nullptr;
57static nxt::wire::TerribleCommandBuffer* s2cBuf = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040058
Corentin Wallez583e9a82017-05-29 11:30:29 -070059nxt::Device CreateCppNXTDevice() {
Corentin Wallez1bd219d2017-06-19 12:53:38 -040060 binding = utils::CreateBinding(backendType);
61 if (binding == nullptr) {
62 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040063 }
64
65 if (!glfwInit()) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070066 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040067 }
68
69 binding->SetupGLFWWindowHints();
70 window = glfwCreateWindow(640, 480, "NXT window", nullptr, nullptr);
71 if (!window) {
Corentin Wallez583e9a82017-05-29 11:30:29 -070072 return nxt::Device();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040073 }
74
75 binding->SetWindow(window);
76
77 nxtDevice backendDevice;
78 nxtProcTable backendProcs;
79 binding->GetProcAndDevice(&backendProcs, &backendDevice);
80
Corentin Wallez583e9a82017-05-29 11:30:29 -070081 nxtDevice cDevice = nullptr;
82 nxtProcTable procs;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040083 switch (cmdBufType) {
84 case CmdBufType::None:
Corentin Wallez583e9a82017-05-29 11:30:29 -070085 procs = backendProcs;
86 cDevice = backendDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040087 break;
88
89 case CmdBufType::Terrible:
90 {
Corentin Wallez682a8252017-05-09 15:34:13 +020091 c2sBuf = new nxt::wire::TerribleCommandBuffer();
92 s2cBuf = new nxt::wire::TerribleCommandBuffer();
93
94 wireServer = nxt::wire::NewServerCommandHandler(backendDevice, backendProcs, s2cBuf);
95 c2sBuf->SetHandler(wireServer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040096
97 nxtDevice clientDevice;
98 nxtProcTable clientProcs;
Corentin Wallez682a8252017-05-09 15:34:13 +020099 wireClient = nxt::wire::NewClientDevice(&clientProcs, &clientDevice, c2sBuf);
100 s2cBuf->SetHandler(wireClient);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400101
Corentin Wallez583e9a82017-05-29 11:30:29 -0700102 procs = clientProcs;
103 cDevice = clientDevice;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400104 }
105 break;
106 }
107
Corentin Wallez583e9a82017-05-29 11:30:29 -0700108 nxtSetProcs(&procs);
109 procs.deviceSetErrorCallback(cDevice, PrintDeviceError, 0);
110 return nxt::Device::Acquire(cDevice);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400111}
112
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400113bool InitSample(int argc, const char** argv) {
Corentin Wallez931e6e82017-06-16 18:51:14 -0400114 for (int i = 0; i < argc; i++) {
115 if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
116 i++;
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400117 if (i < argc && std::string("d3d12") == argv[i]) {
118 backendType = utils::BackendType::D3D12;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400119 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400120 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400121 if (i < argc && std::string("metal") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400122 backendType = utils::BackendType::Metal;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400123 continue;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400124 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400125 if (i < argc && std::string("null") == argv[i]) {
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400126 backendType = utils::BackendType::Null;
Corentin Wallez931e6e82017-06-16 18:51:14 -0400127 continue;
128 }
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400129 if (i < argc && std::string("opengl") == argv[i]) {
130 backendType = utils::BackendType::OpenGL;
131 continue;
132 }
133 if (i < argc && std::string("vulkan") == argv[i]) {
134 backendType = utils::BackendType::Vulkan;
135 continue;
136 }
137 fprintf(stderr, "--backend expects a backend name (opengl, metal, d3d12, null, vulkan)\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400138 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400139 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400140 if (std::string("-c") == argv[i] || std::string("--comand-buffer") == argv[i]) {
141 i++;
142 if (i < argc && std::string("none") == argv[i]) {
143 cmdBufType = CmdBufType::None;
144 continue;
145 }
146 if (i < argc && std::string("terrible") == argv[i]) {
147 cmdBufType = CmdBufType::Terrible;
148 continue;
149 }
150 fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
151 return false;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400152 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400153 if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
154 printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
Corentin Wallez1bd219d2017-06-19 12:53:38 -0400155 printf(" BACKEND is one of: d3d12, metal, null, opengl, vulkan\n");
Corentin Wallez931e6e82017-06-16 18:51:14 -0400156 printf(" COMMAND_BUFFER is one of: none, terrible\n");
157 return false;
158 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400159 }
Corentin Wallez931e6e82017-06-16 18:51:14 -0400160 return true;
161}
162
163void DoSwapBuffers() {
164 if (cmdBufType == CmdBufType::Terrible) {
165 c2sBuf->Flush();
166 s2cBuf->Flush();
167 }
168 glfwPollEvents();
169 binding->SwapBuffers();
170}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400171
Corentin Wallez583e9a82017-05-29 11:30:29 -0700172#ifdef _WIN32
Corentin Wallez931e6e82017-06-16 18:51:14 -0400173void USleep(uint64_t usecs) {
174 Sleep(usecs / 1000);
175}
Corentin Wallez583e9a82017-05-29 11:30:29 -0700176#else
Corentin Wallez931e6e82017-06-16 18:51:14 -0400177void USleep(uint64_t usecs) {
178 usleep(usecs);
179}
Corentin Wallez583e9a82017-05-29 11:30:29 -0700180#endif
181
Corentin Wallez931e6e82017-06-16 18:51:14 -0400182bool ShouldQuit() {
183 return glfwWindowShouldClose(window);
184}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400185
Corentin Wallez931e6e82017-06-16 18:51:14 -0400186GLFWwindow* GetGLFWWindow() {
187 return window;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400188}