Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Graphics/Vulkan/VulkanRenderDevice.cpp
1162 views
1
#ifdef VK_INTELLISENSE
2
#include "RetroEngine.hpp"
3
#include "VulkanRenderDevice.hpp"
4
#endif
5
6
#include <set>
7
#include <cfloat> // FLT_MAX
8
9
// :sob: :sob: :sob:
10
#include "BackupShaders.hpp"
11
12
#ifdef VK_DEBUG
13
#define VK_DEBUG_THRESHOLD VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
14
15
const char *validationLayers[] = { "VK_LAYER_KHRONOS_validation" };
16
17
VKAPI_ATTR VkBool32 VKAPI_CALL RenderDevice::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
18
VkDebugUtilsMessageTypeFlagsEXT messageType,
19
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
20
{
21
if (messageSeverity >= VK_DEBUG_THRESHOLD) {
22
PrintLog(PRINT_NORMAL, "[VK DEBUG] %s", pCallbackData->pMessage);
23
}
24
25
return VK_FALSE;
26
}
27
28
VkDebugUtilsMessengerEXT RenderDevice::debugMessenger;
29
#endif
30
31
const char *requiredExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
32
33
bool RenderDevice::CheckExtensionSupport(VkPhysicalDevice device)
34
{
35
uint32_t extensionCount;
36
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
37
38
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
39
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
40
41
std::set<std::string> extensionList(std::begin(requiredExtensions), std::end(requiredExtensions));
42
43
for (const auto &extension : availableExtensions) {
44
extensionList.erase(extension.extensionName);
45
}
46
47
return extensionList.empty();
48
}
49
50
RenderDevice::SwapChainDetails RenderDevice::QuerySwapChainDetails(VkPhysicalDevice device)
51
{
52
SwapChainDetails details;
53
54
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
55
56
uint32_t formatCount;
57
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
58
59
if (formatCount != 0) {
60
details.formats.resize(formatCount);
61
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
62
}
63
64
uint32_t presentModeCount;
65
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
66
67
if (presentModeCount != 0) {
68
details.presentModes.resize(presentModeCount);
69
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
70
}
71
72
currentSwapDetails = details;
73
return details;
74
}
75
76
bool RenderDevice::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer,
77
VkDeviceMemory &bufferMemory)
78
{
79
VkBufferCreateInfo bufferInfo{};
80
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
81
bufferInfo.size = size;
82
bufferInfo.usage = usage;
83
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
84
85
if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
86
return false;
87
}
88
89
VkMemoryRequirements memRequirements;
90
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
91
VkPhysicalDeviceMemoryProperties memProperties;
92
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
93
94
VkMemoryAllocateInfo allocInfo{};
95
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
96
allocInfo.allocationSize = memRequirements.size;
97
98
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, properties);
99
100
if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
101
return false;
102
}
103
104
vkBindBufferMemory(device, buffer, bufferMemory, 0);
105
return true;
106
}
107
108
struct RenderDevice::ShaderConstants {
109
float2 pixelSize;
110
float2 textureSize;
111
float2 viewSize;
112
#if RETRO_REV02
113
float screenDim;
114
#endif
115
};
116
117
GLFWwindow *RenderDevice::window;
118
119
VkInstance RenderDevice::instance;
120
VkPhysicalDevice RenderDevice::physicalDevice;
121
VkDevice RenderDevice::device;
122
VkSurfaceKHR RenderDevice::surface;
123
124
RenderDevice::SwapChainDetails RenderDevice::currentSwapDetails;
125
VkSwapchainKHR RenderDevice::swapChain;
126
VkFormat RenderDevice::swapChainImageFormat;
127
VkExtent2D RenderDevice::swapChainExtent;
128
129
std::vector<VkImage> RenderDevice::swapChainImages;
130
std::vector<VkImageView> RenderDevice::swapChainImageViews;
131
std::vector<VkFramebuffer> RenderDevice::swapChainFramebuffers;
132
133
VkBuffer RenderDevice::uniformBuffer;
134
VkDeviceMemory RenderDevice::uniformBufferMemory;
135
RenderDevice::ShaderConstants *RenderDevice::uniformMap;
136
137
VkDescriptorPool RenderDevice::descriptorPool;
138
VkDescriptorSet RenderDevice::descriptorSet[SCREEN_COUNT];
139
140
VkRenderPass RenderDevice::renderPass;
141
VkDescriptorSetLayout RenderDevice::setLayout;
142
VkPipelineLayout RenderDevice::pipelineLayout;
143
VkGraphicsPipelineCreateInfo RenderDevice::basePipeline;
144
145
VkBuffer RenderDevice::vertexBuffer;
146
VkDeviceMemory RenderDevice::vertexBufferMemory;
147
148
VkCommandPool RenderDevice::commandPool;
149
VkCommandBuffer RenderDevice::commandBuffer;
150
151
VkQueue RenderDevice::graphicsQueue;
152
VkQueue RenderDevice::presentQueue;
153
uint32 RenderDevice::graphicsIndex;
154
uint32 RenderDevice::presentIndex;
155
156
VkViewport RenderDevice::viewport;
157
158
VkSemaphore RenderDevice::imageAvailableSemaphore;
159
VkSemaphore RenderDevice::renderFinishedSemaphore;
160
VkFence RenderDevice::inFlightFence;
161
162
int32 RenderDevice::monitorIndex;
163
164
VkSampler RenderDevice::samplerPoint;
165
VkSampler RenderDevice::samplerLinear;
166
167
VkDescriptorImageInfo RenderDevice::imageInfo;
168
169
RenderDevice::Texture RenderDevice::imageTexture;
170
RenderDevice::Texture RenderDevice::screenTextures[SCREEN_COUNT];
171
172
double RenderDevice::lastFrame;
173
double RenderDevice::targetFreq;
174
175
//! PIPELINE INFOS
176
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
177
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
178
VkPipelineViewportStateCreateInfo viewportState;
179
VkPipelineRasterizationStateCreateInfo rasterizer;
180
VkPipelineDynamicStateCreateInfo dynamicState;
181
VkDynamicState dynamicStates[1];
182
VkPipelineColorBlendAttachmentState colorBlendAttachment;
183
VkPipelineColorBlendStateCreateInfo colorBlending;
184
VkPipelineMultisampleStateCreateInfo multisampleInfo;
185
186
// Creates a window using the video settings
187
GLFWwindow *RenderDevice::CreateGLFWWindow(void)
188
{
189
GLFWwindow *win;
190
GLFWmonitor *monitor = NULL;
191
int32 w, h;
192
193
glfwWindowHint(GLFW_DECORATED, videoSettings.bordered);
194
195
if (videoSettings.windowed) {
196
w = videoSettings.windowWidth;
197
h = videoSettings.windowHeight;
198
}
199
else if (videoSettings.fsWidth <= 0 || videoSettings.fsHeight <= 0) {
200
monitor = glfwGetPrimaryMonitor();
201
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
202
w = mode->width;
203
h = mode->height;
204
}
205
else {
206
monitor = glfwGetPrimaryMonitor();
207
w = videoSettings.fsWidth;
208
h = videoSettings.fsHeight;
209
}
210
211
win = glfwCreateWindow(w, h, gameVerInfo.gameTitle, monitor, NULL);
212
if (!win) {
213
PrintLog(PRINT_NORMAL, "ERROR: [GLFW] window creation failed");
214
return NULL;
215
}
216
if (videoSettings.windowed) {
217
// Center the window
218
monitor = glfwGetPrimaryMonitor();
219
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
220
int x, y;
221
glfwGetMonitorPos(monitor, &x, &y);
222
// Get scaling for HiDPI screens
223
float xscale, yscale;
224
glfwGetMonitorContentScale(monitor, &xscale, &yscale);
225
int xpos = x + (mode->width - (int)((float)videoSettings.windowWidth * xscale)) / 2;
226
int ypos = y + (mode->height - (int)((float)videoSettings.windowHeight * yscale)) / 2;
227
glfwSetWindowPos(win, xpos, ypos);
228
}
229
glfwShowWindow(win);
230
PrintLog(PRINT_NORMAL, "w: %d h: %d windowed: %d", w, h, videoSettings.windowed);
231
232
glfwSetKeyCallback(win, ProcessKeyEvent);
233
glfwSetMouseButtonCallback(win, ProcessMouseEvent);
234
glfwSetWindowFocusCallback(win, ProcessFocusEvent);
235
glfwSetWindowMaximizeCallback(win, ProcessMaximizeEvent);
236
237
return win;
238
}
239
240
bool RenderDevice::Init()
241
{
242
glfwInit();
243
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
244
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
245
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
246
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // HiDPI scaling support
247
#if GLFW_VERSION_MAJOR >= 3 && GLFW_VERSION_MINOR >= 4
248
// Disable framebuffer scaling which (surprisingly) makes the framebuffer scale correctly on Wayland
249
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
250
#endif
251
252
if ((window = CreateGLFWWindow()) == NULL)
253
return false;
254
255
glfwSetJoystickCallback(ProcessJoystickEvent);
256
257
if (!SetupRendering() || !AudioDevice::Init())
258
return false;
259
260
InitInputDevices();
261
return true;
262
}
263
264
bool RenderDevice::SetupRendering()
265
{
266
uint32_t extensionCount = 0;
267
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
268
PrintLog(PRINT_NORMAL, "[VK] %d extension supported", extensionCount);
269
270
//! DEFINE APP
271
VkApplicationInfo appInfo{};
272
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
273
appInfo.pApplicationName = "RSDK" ENGINE_V_NAME;
274
appInfo.pEngineName = "RSDK" ENGINE_V_NAME;
275
// i aint trying to populate these vers
276
appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
277
appInfo.engineVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
278
appInfo.apiVersion = VK_API_VERSION_1_1;
279
280
VkInstanceCreateInfo instanceInfo{};
281
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
282
instanceInfo.pApplicationInfo = &appInfo;
283
284
#if VULKAN_USE_GLFW
285
//! GET REQUIRED GLFW EXTENSIONS
286
uint32_t glfwExtensionCount = 0;
287
const char **glfwExtensions;
288
289
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
290
291
std::vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
292
#endif
293
294
// some macOS code here might be needed:
295
// https://vulkan-tutorial.com/en/Drawing_a_triangle/Setup/Instance#page_Encountered-VK_ERROR_INCOMPATIBLE_DRIVER
296
297
#ifndef VK_DEBUG
298
instanceInfo.enabledLayerCount = 0;
299
#else
300
//! VALIDATION LAYERS
301
uint32_t layerCount;
302
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
303
304
std::vector<VkLayerProperties> availableLayers(layerCount);
305
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
306
307
for (const char *layerName : validationLayers) {
308
for (const auto &layerProperties : availableLayers) {
309
if (strcmp(layerName, layerProperties.layerName) == 0) {
310
break;
311
}
312
}
313
314
PrintLog(PRINT_NORMAL, "[VK] Requested validation layer %s not found, we won't have it!!!!", layerName);
315
}
316
317
instanceInfo.enabledLayerCount = sizeof(validationLayers) / sizeof(const char *);
318
instanceInfo.ppEnabledLayerNames = validationLayers;
319
320
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
321
#endif
322
323
//! CHECK FOR OTHER EXTENSIONS (none required probably)
324
325
instanceInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
326
instanceInfo.ppEnabledExtensionNames = extensions.data();
327
328
if (vkCreateInstance(&instanceInfo, nullptr, &instance) != VK_SUCCESS) {
329
PrintLog(PRINT_NORMAL, "[VK] Could not create instance");
330
return false;
331
}
332
333
#if VK_DEBUG
334
//! SETUP CALLBACK
335
336
VkDebugUtilsMessengerCreateInfoEXT callbackInfo{};
337
callbackInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
338
callbackInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
339
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
340
callbackInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
341
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
342
callbackInfo.pfnUserCallback = DebugCallback;
343
callbackInfo.pUserData = nullptr;
344
345
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
346
if (func != nullptr) {
347
if (func(instance, &callbackInfo, nullptr, &debugMessenger) != VK_SUCCESS) {
348
PrintLog(PRINT_NORMAL, "[VK] Failed to create debug callback messenger");
349
return false;
350
}
351
}
352
else {
353
PrintLog(PRINT_NORMAL, "[VK] Requested debug callback extension not found");
354
return false;
355
}
356
#endif
357
358
//! SURFACE SETUP
359
#ifdef VULKAN_USE_GLFW
360
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
361
PrintLog(PRINT_NORMAL, "[VK] Vulkan surface could not be created");
362
return false;
363
}
364
#endif
365
366
//! PICK PHYSICAL DEVICE (we'll settle for any with VK_QUEUE_GRAPHICS_BIT)
367
physicalDevice = VK_NULL_HANDLE;
368
uint32_t deviceCount = 0;
369
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
370
371
if (!deviceCount) {
372
PrintLog(PRINT_NORMAL, "[VK] No GPU with Vulkan support found");
373
return false;
374
}
375
376
std::vector<VkPhysicalDevice> devices(deviceCount);
377
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
378
379
// https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Physical_devices_and_queue_families#page_Base-device-suitability-checks
380
381
for (const auto &device : devices) {
382
if (IsDeviceSuitable(device)) {
383
physicalDevice = device;
384
break;
385
}
386
}
387
388
if (physicalDevice == VK_NULL_HANDLE) {
389
PrintLog(PRINT_NORMAL, "[VK] No suitable GPU found (but %d GPUs support Vulkan)", deviceCount);
390
return false;
391
}
392
393
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
394
std::set<uint32> uniqueQueueFamilies = { graphicsIndex, presentIndex };
395
396
float queuePriority = 1.0f;
397
for (uint32_t queueFamily : uniqueQueueFamilies) {
398
VkDeviceQueueCreateInfo queueCreateInfo{};
399
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
400
queueCreateInfo.queueFamilyIndex = queueFamily;
401
queueCreateInfo.queueCount = 1;
402
queueCreateInfo.pQueuePriorities = &queuePriority;
403
queueCreateInfos.push_back(queueCreateInfo);
404
}
405
406
VkPhysicalDeviceFeatures deviceFeatures{};
407
408
VkDeviceCreateInfo deviceInfo{};
409
deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
410
deviceInfo.pQueueCreateInfos = queueCreateInfos.data();
411
deviceInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
412
413
deviceInfo.pEnabledFeatures = &deviceFeatures;
414
415
#ifndef VK_DEBUG
416
deviceInfo.enabledLayerCount = 0;
417
#else
418
deviceInfo.enabledLayerCount = sizeof(validationLayers) / sizeof(const char *);
419
deviceInfo.ppEnabledLayerNames = validationLayers;
420
#endif
421
422
deviceInfo.enabledExtensionCount = sizeof(requiredExtensions) / sizeof(const char *);
423
deviceInfo.ppEnabledExtensionNames = requiredExtensions;
424
425
if (vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &device) != VK_SUCCESS) {
426
PrintLog(PRINT_NORMAL, "[VK] Failed to create device");
427
return false;
428
}
429
430
vkGetDeviceQueue(device, graphicsIndex, 0, &graphicsQueue);
431
vkGetDeviceQueue(device, presentIndex, 0, &presentQueue);
432
433
swapChain = VK_NULL_HANDLE;
434
435
GetDisplays();
436
437
descriptorSet[0] = VK_NULL_HANDLE;
438
439
if (!InitGraphicsAPI() || !InitShaders())
440
return false;
441
442
int32 size = videoSettings.pixWidth >= SCREEN_YSIZE ? videoSettings.pixWidth : SCREEN_YSIZE;
443
scanlines = (ScanlineInfo *)malloc(size * sizeof(ScanlineInfo));
444
memset(scanlines, 0, size * sizeof(ScanlineInfo));
445
446
videoSettings.windowState = WINDOWSTATE_ACTIVE;
447
videoSettings.dimMax = 1.0;
448
videoSettings.dimPercent = 1.0;
449
450
return true;
451
}
452
453
void RenderDevice::GetDisplays()
454
{
455
GLFWmonitor *monitor = glfwGetWindowMonitor(window);
456
if (!monitor)
457
monitor = glfwGetPrimaryMonitor();
458
const GLFWvidmode *displayMode = glfwGetVideoMode(monitor);
459
int32 monitorCount;
460
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
461
462
for (int32 m = 0; m < monitorCount; ++m) {
463
const GLFWvidmode *vidMode = glfwGetVideoMode(monitors[m]);
464
displayWidth[m] = vidMode->width;
465
displayHeight[m] = vidMode->height;
466
if (!memcmp(vidMode, displayMode, sizeof(GLFWvidmode))) {
467
monitorIndex = m;
468
}
469
}
470
471
const GLFWvidmode *displayModes = glfwGetVideoModes(monitor, &displayCount);
472
if (displayInfo.displays)
473
free(displayInfo.displays);
474
475
displayInfo.displays = (decltype(displayInfo.displays))malloc(sizeof(GLFWvidmode) * displayCount);
476
int32 newDisplayCount = 0;
477
bool32 foundFullScreenDisplay = false;
478
479
for (int32 d = 0; d < displayCount; ++d) {
480
memcpy(&displayInfo.displays[newDisplayCount].internal, &displayModes[d], sizeof(GLFWvidmode));
481
482
int32 refreshRate = displayInfo.displays[newDisplayCount].refresh_rate;
483
if (refreshRate >= 59 && (refreshRate <= 60 || refreshRate >= 120) && displayInfo.displays[newDisplayCount].height >= (SCREEN_YSIZE * 2)) {
484
if (d && refreshRate == 60 && displayInfo.displays[newDisplayCount - 1].refresh_rate == 59)
485
--newDisplayCount;
486
487
if (videoSettings.fsWidth == displayInfo.displays[newDisplayCount].width
488
&& videoSettings.fsHeight == displayInfo.displays[newDisplayCount].height)
489
foundFullScreenDisplay = true;
490
491
++newDisplayCount;
492
}
493
}
494
495
displayCount = newDisplayCount;
496
if (!foundFullScreenDisplay) {
497
videoSettings.fsWidth = 0;
498
videoSettings.fsHeight = 0;
499
videoSettings.refreshRate = 60; // 0;
500
}
501
}
502
503
bool RenderDevice::InitGraphicsAPI()
504
{
505
if (videoSettings.windowed || !videoSettings.exclusiveFS) {
506
if (videoSettings.windowed) {
507
viewSize.x = videoSettings.windowWidth;
508
viewSize.y = videoSettings.windowHeight;
509
}
510
else {
511
viewSize.x = displayWidth[monitorIndex];
512
viewSize.y = displayHeight[monitorIndex];
513
}
514
}
515
else {
516
int32 bufferWidth = videoSettings.fsWidth;
517
int32 bufferHeight = videoSettings.fsHeight;
518
if (videoSettings.fsWidth <= 0 || videoSettings.fsHeight <= 0) {
519
bufferWidth = displayWidth[monitorIndex];
520
bufferHeight = displayHeight[monitorIndex];
521
}
522
viewSize.x = bufferWidth;
523
viewSize.y = bufferHeight;
524
}
525
526
int32 maxPixHeight = 0;
527
#if !RETRO_USE_ORIGINAL_CODE
528
int32 screenWidth = 0;
529
#endif
530
for (int32 s = 0; s < SCREEN_COUNT; ++s) {
531
if (videoSettings.pixHeight > maxPixHeight)
532
maxPixHeight = videoSettings.pixHeight;
533
534
screens[s].size.y = videoSettings.pixHeight;
535
536
float viewAspect = viewSize.x / viewSize.y;
537
#if !RETRO_USE_ORIGINAL_CODE
538
screenWidth = (int32)((viewAspect * videoSettings.pixHeight) + 3) & 0xFFFFFFFC;
539
#else
540
int32 screenWidth = (int32)((viewAspect * videoSettings.pixHeight) + 3) & 0xFFFFFFFC;
541
#endif
542
if (screenWidth < videoSettings.pixWidth)
543
screenWidth = videoSettings.pixWidth;
544
545
#if !RETRO_USE_ORIGINAL_CODE
546
if (customSettings.maxPixWidth && screenWidth > customSettings.maxPixWidth)
547
screenWidth = customSettings.maxPixWidth;
548
#else
549
if (screenWidth > DEFAULT_PIXWIDTH)
550
screenWidth = DEFAULT_PIXWIDTH;
551
#endif
552
553
memset(&screens[s].frameBuffer, 0, sizeof(screens[s].frameBuffer));
554
SetScreenSize(s, screenWidth, screens[s].size.y);
555
}
556
557
pixelSize.x = screens[0].size.x;
558
pixelSize.y = screens[0].size.y;
559
float pixAspect = pixelSize.x / pixelSize.y;
560
561
Vector2 viewportPos{};
562
Vector2 lastViewSize;
563
564
glfwGetWindowSize(window, &lastViewSize.x, &lastViewSize.y);
565
Vector2 viewportSize = lastViewSize;
566
567
if ((viewSize.x / viewSize.y) <= ((pixelSize.x / pixelSize.y) + 0.1)) {
568
if ((pixAspect - 0.1) > (viewSize.x / viewSize.y)) {
569
viewSize.y = (pixelSize.y / pixelSize.x) * viewSize.x;
570
viewportPos.y = (lastViewSize.y >> 1) - (viewSize.y * 0.5);
571
viewportSize.y = viewSize.y;
572
}
573
}
574
else {
575
viewSize.x = pixAspect * viewSize.y;
576
viewportPos.x = (lastViewSize.x >> 1) - ((pixAspect * viewSize.y) * 0.5);
577
viewportSize.x = (pixAspect * viewSize.y);
578
}
579
580
#if !RETRO_USE_ORIGINAL_CODE
581
if (screenWidth <= 512 && maxPixHeight <= 256) {
582
#else
583
if (maxPixHeight <= 256) {
584
#endif
585
textureSize.x = 512.0;
586
textureSize.y = 256.0;
587
}
588
else {
589
textureSize.x = 1024.0;
590
textureSize.y = 512.0;
591
}
592
593
//! PICK SWAPCHAIN DETAILS
594
VkSurfaceFormatKHR pickedFormat = currentSwapDetails.formats[0];
595
VkPresentModeKHR pickedMode = VK_PRESENT_MODE_FIFO_KHR;
596
VkExtent2D pickedExtent = currentSwapDetails.capabilities.currentExtent;
597
598
for (const auto &availableFormat : currentSwapDetails.formats) {
599
if ((availableFormat.format == VK_FORMAT_R8G8B8_UNORM || availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM)
600
&& availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
601
pickedFormat = availableFormat;
602
break;
603
}
604
}
605
606
if (!videoSettings.vsync) {
607
for (const auto &availablePresentMode : currentSwapDetails.presentModes) {
608
if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
609
pickedMode = availablePresentMode;
610
}
611
}
612
}
613
614
pickedExtent = { static_cast<uint32_t>(viewSize.x), static_cast<uint32_t>(viewSize.y) };
615
616
pickedExtent.width =
617
CLAMP(pickedExtent.width, currentSwapDetails.capabilities.minImageExtent.width, currentSwapDetails.capabilities.maxImageExtent.width);
618
pickedExtent.height =
619
CLAMP(pickedExtent.height, currentSwapDetails.capabilities.minImageExtent.height, currentSwapDetails.capabilities.maxImageExtent.height);
620
621
//! CREATE SWAPCHAIN
622
uint32_t imageCount = currentSwapDetails.capabilities.minImageCount + 1;
623
if (currentSwapDetails.capabilities.maxImageCount > 0 && imageCount > currentSwapDetails.capabilities.maxImageCount) {
624
imageCount = currentSwapDetails.capabilities.maxImageCount;
625
}
626
627
VkSwapchainCreateInfoKHR swapCreateInfo{};
628
swapCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
629
swapCreateInfo.surface = surface;
630
swapCreateInfo.minImageCount = imageCount;
631
swapCreateInfo.imageFormat = pickedFormat.format;
632
swapCreateInfo.imageColorSpace = pickedFormat.colorSpace;
633
swapCreateInfo.imageExtent = pickedExtent;
634
swapCreateInfo.imageArrayLayers = 1;
635
swapCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
636
637
if (graphicsIndex != presentIndex) {
638
swapCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
639
uint32_t queueFamilyIndices[] = { graphicsIndex, presentIndex };
640
swapCreateInfo.queueFamilyIndexCount = 2;
641
swapCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
642
}
643
else {
644
swapCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
645
}
646
647
swapCreateInfo.preTransform = currentSwapDetails.capabilities.currentTransform;
648
swapCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
649
swapCreateInfo.presentMode = pickedMode;
650
swapCreateInfo.clipped = VK_TRUE;
651
652
// swapCreateInfo.oldSwapchain = swapChain;
653
654
if (vkCreateSwapchainKHR(device, &swapCreateInfo, nullptr, &swapChain) != VK_SUCCESS) {
655
PrintLog(PRINT_NORMAL, "[VK] Failed to create swapchain");
656
return false;
657
}
658
659
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
660
swapChainImages.resize(imageCount);
661
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
662
663
swapChainImageFormat = pickedFormat.format;
664
swapChainExtent = pickedExtent;
665
666
//! CREATE IMAGE VIEWS
667
swapChainImageViews.resize(swapChainImages.size());
668
for (int i = 0; i < swapChainImages.size(); i++) {
669
VkImageViewCreateInfo createInfo{};
670
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
671
createInfo.image = swapChainImages[i];
672
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
673
createInfo.format = swapChainImageFormat;
674
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
675
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
676
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
677
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
678
679
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
680
createInfo.subresourceRange.baseMipLevel = 0;
681
createInfo.subresourceRange.levelCount = 1;
682
createInfo.subresourceRange.baseArrayLayer = 0;
683
createInfo.subresourceRange.layerCount = 1;
684
685
if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
686
PrintLog(PRINT_NORMAL, "[VK] Failed to create image chain #%d", i);
687
return false;
688
}
689
}
690
691
//! CREATE RENDERPASS
692
VkAttachmentDescription colorAttachment{};
693
colorAttachment.format = swapChainImageFormat;
694
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
695
696
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
697
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
698
699
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
700
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
701
702
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
703
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
704
705
VkAttachmentReference colorAttachmentRef{};
706
colorAttachmentRef.attachment = 0;
707
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
708
709
VkSubpassDescription subpass{};
710
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
711
712
subpass.colorAttachmentCount = 1;
713
subpass.pColorAttachments = &colorAttachmentRef;
714
715
VkRenderPassCreateInfo renderPassInfo{};
716
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
717
renderPassInfo.attachmentCount = 1;
718
renderPassInfo.pAttachments = &colorAttachment;
719
renderPassInfo.subpassCount = 1;
720
renderPassInfo.pSubpasses = &subpass;
721
722
if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
723
PrintLog(PRINT_NORMAL, "[VK] Failed to create render pass");
724
}
725
726
//! SET DYNAMIC STATE
727
dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT;
728
729
dynamicState = {};
730
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
731
dynamicState.dynamicStateCount = sizeof(dynamicStates) / sizeof(VkDynamicState);
732
dynamicState.pDynamicStates = dynamicStates;
733
734
//! SET FIXED FUNCTION CONTROLLERS
735
inputAssembly = {};
736
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
737
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
738
inputAssembly.primitiveRestartEnable = VK_FALSE;
739
740
viewport.x = (float)viewportPos.x;
741
viewport.y = (float)viewportPos.y;
742
viewport.width = (float)viewportSize.x;
743
viewport.height = (float)viewportSize.y;
744
viewport.minDepth = 0.0f;
745
viewport.maxDepth = 1.0f;
746
747
viewportState = {};
748
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
749
viewportState.viewportCount = 1;
750
viewportState.pViewports = &viewport;
751
viewportState.scissorCount = 1;
752
viewportState.pScissors = (VkRect2D *)&viewport;
753
754
rasterizer = {};
755
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
756
rasterizer.depthClampEnable = VK_FALSE;
757
rasterizer.rasterizerDiscardEnable = VK_FALSE;
758
rasterizer.lineWidth = 1.0f;
759
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
760
rasterizer.cullMode = VK_CULL_MODE_NONE;
761
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
762
rasterizer.depthBiasEnable = VK_FALSE;
763
764
colorBlendAttachment = {};
765
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
766
colorBlendAttachment.blendEnable = VK_FALSE;
767
768
colorBlending = {};
769
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
770
colorBlending.logicOpEnable = VK_FALSE;
771
colorBlending.attachmentCount = 1;
772
colorBlending.pAttachments = &colorBlendAttachment;
773
774
multisampleInfo = {};
775
multisampleInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
776
multisampleInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
777
778
//! CREATE UNIFORM AND SAMPLER LAYOUT
779
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
780
samplerLayoutBinding.binding = 0;
781
samplerLayoutBinding.descriptorCount = 1;
782
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
783
samplerLayoutBinding.pImmutableSamplers = nullptr;
784
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
785
786
VkDescriptorSetLayoutBinding uboLayoutBinding{};
787
uboLayoutBinding.binding = 1;
788
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
789
uboLayoutBinding.descriptorCount = 1;
790
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
791
792
VkDescriptorSetLayoutBinding bindings[] = { samplerLayoutBinding, uboLayoutBinding };
793
794
VkDescriptorSetLayoutCreateInfo layoutInfo{};
795
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
796
layoutInfo.bindingCount = 2;
797
layoutInfo.pBindings = bindings;
798
799
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &setLayout) != VK_SUCCESS) {
800
PrintLog(PRINT_NORMAL, "[VK] Failed to create descriptor set layout");
801
return false;
802
}
803
804
//! CREATE PIPELINE LAYOUT
805
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
806
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
807
pipelineLayoutInfo.setLayoutCount = 1;
808
pipelineLayoutInfo.pSetLayouts = &setLayout;
809
pipelineLayoutInfo.pushConstantRangeCount = 0;
810
pipelineLayoutInfo.pPushConstantRanges = nullptr;
811
812
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
813
PrintLog(PRINT_NORMAL, "[VK] Failed to create pipeline layout");
814
return false;
815
}
816
817
//! CREATE FRAMEBUFFERS
818
swapChainFramebuffers.resize(swapChainImageViews.size());
819
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
820
VkImageView attachments[] = { swapChainImageViews[i] };
821
822
VkFramebufferCreateInfo framebufferInfo{};
823
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
824
framebufferInfo.renderPass = renderPass;
825
framebufferInfo.attachmentCount = 1;
826
framebufferInfo.pAttachments = attachments;
827
framebufferInfo.width = swapChainExtent.width;
828
framebufferInfo.height = swapChainExtent.height;
829
framebufferInfo.layers = 1;
830
831
if (vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
832
PrintLog(PRINT_NORMAL, "[VK] Failed to create framebuffer %d", i);
833
return false;
834
}
835
}
836
837
//! CREATE COMMAND POOL
838
VkCommandPoolCreateInfo cmdPoolInfo{};
839
cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
840
cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
841
cmdPoolInfo.queueFamilyIndex = graphicsIndex;
842
843
if (vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &commandPool) != VK_SUCCESS) {
844
PrintLog(PRINT_NORMAL, "[VK] Failed to create command pool");
845
return false;
846
}
847
848
//! CREATE COMMAND BUFFER
849
VkCommandBufferAllocateInfo cmdAllocInfo{};
850
cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
851
cmdAllocInfo.commandPool = commandPool;
852
cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
853
cmdAllocInfo.commandBufferCount = 1;
854
855
if (vkAllocateCommandBuffers(device, &cmdAllocInfo, &commandBuffer) != VK_SUCCESS) {
856
PrintLog(PRINT_NORMAL, "[VK] Failed to create command buffer");
857
return false;
858
}
859
860
//! CREATE SYNCHRONIZATION OBJECTS
861
VkSemaphoreCreateInfo semaphoreInfo{};
862
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
863
864
VkFenceCreateInfo fenceInfo{};
865
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
866
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
867
868
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS
869
|| vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS
870
|| vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) {
871
PrintLog(PRINT_NORMAL, "[VK] Unable to create sephamores");
872
}
873
874
//! TEXTURE CREATION
875
for (int32 i = 0; i < SCREEN_COUNT; ++i) {
876
VkImageCreateInfo imageInfo{};
877
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
878
imageInfo.imageType = VK_IMAGE_TYPE_2D;
879
imageInfo.extent.width = static_cast<uint32_t>(textureSize.x);
880
imageInfo.extent.height = static_cast<uint32_t>(textureSize.y);
881
imageInfo.extent.depth = 1;
882
imageInfo.mipLevels = 1;
883
imageInfo.arrayLayers = 1;
884
imageInfo.format = VK_FORMAT_R5G6B5_UNORM_PACK16;
885
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
886
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
887
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
888
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
889
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
890
891
if (vkCreateImage(device, &imageInfo, nullptr, &screenTextures[i].image) != VK_SUCCESS) {
892
PrintLog(PRINT_NORMAL, "[VK] Failed to create image for screen texture %d", i);
893
return false;
894
}
895
896
VkMemoryRequirements memRequirements;
897
vkGetImageMemoryRequirements(device, screenTextures[i].image, &memRequirements);
898
899
VkMemoryAllocateInfo allocInfo{};
900
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
901
allocInfo.allocationSize = memRequirements.size;
902
allocInfo.memoryTypeIndex =
903
FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
904
905
if (vkAllocateMemory(device, &allocInfo, nullptr, &screenTextures[i].memory) != VK_SUCCESS) {
906
PrintLog(PRINT_NORMAL, "[VK] Failed to allocate memory for screen texture %d", i);
907
return false;
908
}
909
910
vkBindImageMemory(device, screenTextures[i].image, screenTextures[i].memory, 0);
911
vkMapMemory(device, screenTextures[i].memory, 0, memRequirements.size, 0, &screenTextures[i].map);
912
913
VkImageSubresource subresource{};
914
subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
915
916
vkGetImageSubresourceLayout(device, screenTextures[i].image, &subresource, &screenTextures[i].layout);
917
918
VkImageViewCreateInfo viewInfo{};
919
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
920
viewInfo.image = screenTextures[i].image;
921
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
922
viewInfo.format = VK_FORMAT_R5G6B5_UNORM_PACK16;
923
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
924
viewInfo.subresourceRange.baseMipLevel = 0;
925
viewInfo.subresourceRange.levelCount = 1;
926
viewInfo.subresourceRange.baseArrayLayer = 0;
927
viewInfo.subresourceRange.layerCount = 1;
928
929
if (vkCreateImageView(device, &viewInfo, nullptr, &screenTextures[i].view) != VK_SUCCESS) {
930
PrintLog(PRINT_NORMAL, "[VK] Failed to create image view for screen texture %d", i);
931
return false;
932
}
933
934
//! TRANSITION TO GENERAL
935
VkCommandBufferAllocateInfo cmdAllocInfo{};
936
cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
937
cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
938
cmdAllocInfo.commandPool = commandPool;
939
cmdAllocInfo.commandBufferCount = 1;
940
941
VkCommandBuffer commandBuffer;
942
vkAllocateCommandBuffers(device, &cmdAllocInfo, &commandBuffer);
943
944
VkCommandBufferBeginInfo beginInfo{};
945
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
946
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
947
948
vkBeginCommandBuffer(commandBuffer, &beginInfo);
949
950
VkImageMemoryBarrier barrier{};
951
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
952
barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
953
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
954
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
955
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
956
barrier.image = screenTextures[i].image;
957
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
958
barrier.subresourceRange.baseMipLevel = 0;
959
barrier.subresourceRange.levelCount = 1;
960
barrier.subresourceRange.baseArrayLayer = 0;
961
barrier.subresourceRange.layerCount = 1;
962
963
VkPipelineStageFlags sourceStage;
964
VkPipelineStageFlags destinationStage;
965
966
barrier.srcAccessMask = 0;
967
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
968
969
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
970
&barrier);
971
972
vkEndCommandBuffer(commandBuffer);
973
974
VkSubmitInfo submitInfo{};
975
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
976
submitInfo.commandBufferCount = 1;
977
submitInfo.pCommandBuffers = &commandBuffer;
978
979
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
980
vkQueueWaitIdle(graphicsQueue);
981
982
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
983
984
//! WE DON'T MAKE THE SAMPLER YET
985
}
986
987
{
988
//! IMAGE TEXTURE
989
VkImageCreateInfo imageInfo{};
990
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
991
imageInfo.imageType = VK_IMAGE_TYPE_2D;
992
imageInfo.extent.width = RETRO_VIDEO_TEXTURE_W;
993
imageInfo.extent.height = RETRO_VIDEO_TEXTURE_H;
994
imageInfo.extent.depth = 1;
995
imageInfo.mipLevels = 1;
996
imageInfo.arrayLayers = 1;
997
imageInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
998
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
999
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1000
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1001
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1002
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1003
1004
if (vkCreateImage(device, &imageInfo, nullptr, &imageTexture.image) != VK_SUCCESS) {
1005
PrintLog(PRINT_NORMAL, "[VK] Failed to create image for image texture");
1006
return false;
1007
}
1008
1009
VkMemoryRequirements memRequirements;
1010
vkGetImageMemoryRequirements(device, imageTexture.image, &memRequirements);
1011
1012
VkMemoryAllocateInfo allocInfo{};
1013
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1014
allocInfo.allocationSize = memRequirements.size;
1015
allocInfo.memoryTypeIndex =
1016
FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
1017
1018
if (vkAllocateMemory(device, &allocInfo, nullptr, &imageTexture.memory) != VK_SUCCESS) {
1019
PrintLog(PRINT_NORMAL, "[VK] Failed to allocate memory for image texturre");
1020
return false;
1021
}
1022
1023
vkBindImageMemory(device, imageTexture.image, imageTexture.memory, 0);
1024
vkMapMemory(device, imageTexture.memory, 0, memRequirements.size, 0, &imageTexture.map);
1025
1026
VkImageSubresource subresource{};
1027
subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1028
vkGetImageSubresourceLayout(device, imageTexture.image, &subresource, &imageTexture.layout);
1029
1030
VkImageViewCreateInfo viewInfo{};
1031
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1032
viewInfo.image = imageTexture.image;
1033
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1034
viewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
1035
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1036
viewInfo.subresourceRange.baseMipLevel = 0;
1037
viewInfo.subresourceRange.levelCount = 1;
1038
viewInfo.subresourceRange.baseArrayLayer = 0;
1039
viewInfo.subresourceRange.layerCount = 1;
1040
1041
if (vkCreateImageView(device, &viewInfo, nullptr, &imageTexture.view) != VK_SUCCESS) {
1042
PrintLog(PRINT_NORMAL, "[VK] Failed to create image view for image texture");
1043
return false;
1044
}
1045
1046
//! TRANSITION TO GENERAL
1047
VkCommandBufferAllocateInfo cmdAllocInfo{};
1048
cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1049
cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1050
cmdAllocInfo.commandPool = commandPool;
1051
cmdAllocInfo.commandBufferCount = 1;
1052
1053
VkCommandBuffer commandBuffer;
1054
vkAllocateCommandBuffers(device, &cmdAllocInfo, &commandBuffer);
1055
1056
VkCommandBufferBeginInfo beginInfo{};
1057
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1058
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1059
1060
vkBeginCommandBuffer(commandBuffer, &beginInfo);
1061
1062
VkImageMemoryBarrier barrier{};
1063
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1064
barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
1065
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
1066
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1067
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1068
barrier.image = imageTexture.image;
1069
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1070
barrier.subresourceRange.baseMipLevel = 0;
1071
barrier.subresourceRange.levelCount = 1;
1072
barrier.subresourceRange.baseArrayLayer = 0;
1073
barrier.subresourceRange.layerCount = 1;
1074
1075
VkPipelineStageFlags sourceStage;
1076
VkPipelineStageFlags destinationStage;
1077
1078
barrier.srcAccessMask = 0;
1079
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1080
1081
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
1082
&barrier);
1083
1084
vkEndCommandBuffer(commandBuffer);
1085
1086
VkSubmitInfo submitInfo{};
1087
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1088
submitInfo.commandBufferCount = 1;
1089
submitInfo.pCommandBuffers = &commandBuffer;
1090
1091
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
1092
vkQueueWaitIdle(graphicsQueue);
1093
1094
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
1095
}
1096
1097
lastShaderID = -1;
1098
1099
InitVertexBuffer();
1100
1101
//! CREATE UNIFORM BUFFER
1102
if (!CreateBuffer(sizeof(ShaderConstants), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
1103
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffer, uniformBufferMemory)) {
1104
PrintLog(PRINT_NORMAL, "[VK] Failed to create uniform buffer");
1105
return false;
1106
}
1107
1108
vkMapMemory(device, uniformBufferMemory, 0, sizeof(ShaderConstants), 0, (void **)&uniformMap);
1109
1110
//! CREATE FULL BASE PIPELINE
1111
basePipeline = {};
1112
basePipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1113
basePipeline.stageCount = 0;
1114
basePipeline.pStages = nullptr; //! WE FILL THESE LATER!!
1115
1116
basePipeline.pVertexInputState = &vertexInputInfo;
1117
basePipeline.pInputAssemblyState = &inputAssembly;
1118
basePipeline.pViewportState = &viewportState;
1119
basePipeline.pRasterizationState = &rasterizer;
1120
basePipeline.pDynamicState = &dynamicState;
1121
basePipeline.pColorBlendState = &colorBlending;
1122
basePipeline.pMultisampleState = &multisampleInfo;
1123
basePipeline.layout = pipelineLayout;
1124
basePipeline.renderPass = renderPass;
1125
basePipeline.subpass = 0;
1126
1127
//! CREATE DESCRIPTOR POOL
1128
VkDescriptorPoolSize poolSizes[] = { {}, {} };
1129
poolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1130
poolSizes[0].descriptorCount = SCREEN_COUNT;
1131
poolSizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1132
poolSizes[1].descriptorCount = SCREEN_COUNT;
1133
1134
VkDescriptorPoolCreateInfo poolInfo{};
1135
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1136
poolInfo.poolSizeCount = 2;
1137
poolInfo.pPoolSizes = poolSizes;
1138
poolInfo.maxSets = SCREEN_COUNT;
1139
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1140
1141
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
1142
PrintLog(PRINT_NORMAL, "[VK] Failed to create descriptor pool");
1143
}
1144
1145
engine.inFocus = 1;
1146
videoSettings.viewportX = viewportPos.x;
1147
videoSettings.viewportY = viewportPos.y;
1148
videoSettings.viewportW = 1.0 / viewSize.x;
1149
videoSettings.viewportH = 1.0 / viewSize.y;
1150
1151
return true;
1152
}
1153
1154
// CUSTOM BUFFER FOR SHENANIGAN PURPOSES
1155
// GL hates us and it's coordinate system is reverse of DX
1156
// for shader output equivalency, we havee to flip everything
1157
// X and Y are negated, some verts are specifically moved to match
1158
// U and V are 0/1s and flipped from what it was originally
1159
1160
// clang-format off
1161
#if RETRO_REV02
1162
const RenderVertex rsdkVKVertexBuffer[60] = {
1163
// 1 Screen (0)
1164
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1165
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1166
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1167
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1168
{ { -1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1169
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1170
1171
// 2 Screens - Bordered (Top Screen) (6)
1172
{ { +0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1173
{ { +0.5, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1174
{ { -0.5, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1175
{ { +0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1176
{ { -0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1177
{ { -0.5, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1178
1179
// 2 Screens - Bordered (Bottom Screen) (12)
1180
{ { +0.5, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1181
{ { +0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1182
{ { -0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1183
{ { +0.5, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1184
{ { -0.5, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1185
{ { -0.5, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1186
1187
// 2 Screens - Stretched (Top Screen) (18)
1188
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1189
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1190
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1191
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1192
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1193
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1194
1195
// 2 Screens - Stretched (Bottom Screen) (24)
1196
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1197
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1198
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1199
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1200
{ { -1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1201
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1202
1203
// 4 Screens (Top-Left) (30)
1204
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1205
{ { 0.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1206
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1207
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1208
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1209
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1210
1211
// 4 Screens (Top-Right) (36)
1212
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1213
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1214
{ { 0.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1215
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1216
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1217
{ { 0.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1218
1219
// 4 Screens (Bottom-Right) (42)
1220
{ { 0.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1221
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1222
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1223
{ { 0.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1224
{ { -1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1225
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1226
1227
// 4 Screens (Bottom-Left) (48)
1228
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1229
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1230
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1231
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1232
{ { 0.0, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1233
{ { 0.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1234
1235
// Image/Video (54)
1236
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1237
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1238
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1239
{ { +1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1240
{ { -1.0, 1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1241
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } }
1242
};
1243
#else
1244
const RenderVertex rsdkVKVertexBuffer[24] =
1245
{
1246
// 1 Screen (0)
1247
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1248
{ { +1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1249
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1250
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1251
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1252
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1253
1254
// 2 Screens - Stretched (Top Screen) (6)
1255
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1256
{ { +1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1257
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1258
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1259
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1260
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1261
1262
// 2 Screens - Stretched (Bottom Screen) (12)
1263
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1264
{ { +1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1265
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1266
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1267
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1268
{ { -1.0, 0.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1269
1270
// Image/Video (18)
1271
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1272
{ { +1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 0.0 } },
1273
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } },
1274
{ { +1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 1.0, 1.0 } },
1275
{ { -1.0, -1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 1.0 } },
1276
{ { -1.0, +1.0, 1.0 }, 0xFFFFFFFF, { 0.0, 0.0 } }
1277
};
1278
#endif
1279
// clang-format on
1280
1281
VkVertexInputBindingDescription bindingDescription;
1282
VkVertexInputAttributeDescription attributeDescriptions[3];
1283
1284
bool RenderDevice::InitVertexBuffer()
1285
{
1286
RenderVertex vertBuffer[sizeof(rsdkVKVertexBuffer) / sizeof(RenderVertex)];
1287
memcpy(vertBuffer, rsdkVKVertexBuffer, sizeof(rsdkVKVertexBuffer));
1288
1289
float x = 0.5 / (float)viewSize.x;
1290
float y = 0.5 / (float)viewSize.y;
1291
1292
// ignore the last 6 verts, they're scaled to the 1024x512 textures already!
1293
int32 vertCount = (RETRO_REV02 ? 60 : 24) - 6;
1294
for (int32 v = 0; v < vertCount; ++v) {
1295
RenderVertex *vertex = &vertBuffer[v];
1296
vertex->pos.x = vertex->pos.x + x;
1297
vertex->pos.y = vertex->pos.y + y;
1298
1299
if (vertex->tex.x)
1300
vertex->tex.x = screens[0].size.x * (1.0 / textureSize.x);
1301
1302
if (vertex->tex.y)
1303
vertex->tex.y = screens[0].size.y * (1.0 / textureSize.y);
1304
}
1305
1306
//! CONFIGURE MEMORY
1307
if (!CreateBuffer(sizeof(vertBuffer), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
1308
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory)) {
1309
PrintLog(PRINT_NORMAL, "[VK] Failed to create vertex buffer");
1310
return false;
1311
}
1312
1313
void *data;
1314
vkMapMemory(device, vertexBufferMemory, 0, sizeof(vertBuffer), 0, &data);
1315
memcpy(data, vertBuffer, sizeof(vertBuffer));
1316
vkUnmapMemory(device, vertexBufferMemory);
1317
1318
// remember to bind it later!
1319
1320
//! SET VERTEX BINDING DESCRIPTION
1321
bindingDescription = {};
1322
bindingDescription.binding = 0;
1323
bindingDescription.stride = sizeof(RenderVertex);
1324
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1325
1326
//! SET ATTRIBUTE DESCRIPTIONS
1327
// in_pos
1328
attributeDescriptions[0] = {};
1329
attributeDescriptions[0].binding = 0;
1330
attributeDescriptions[0].location = 0;
1331
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
1332
attributeDescriptions[0].offset = offsetof(RenderVertex, pos);
1333
// in_color
1334
attributeDescriptions[1] = {};
1335
attributeDescriptions[1].binding = 0;
1336
attributeDescriptions[1].location = 1;
1337
attributeDescriptions[1].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
1338
attributeDescriptions[1].offset = offsetof(RenderVertex, color);
1339
// in_UV
1340
attributeDescriptions[2] = {};
1341
attributeDescriptions[2].binding = 0;
1342
attributeDescriptions[2].location = 2;
1343
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
1344
attributeDescriptions[2].offset = offsetof(RenderVertex, tex);
1345
1346
vertexInputInfo = {};
1347
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
1348
vertexInputInfo.vertexBindingDescriptionCount = 1;
1349
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
1350
vertexInputInfo.vertexAttributeDescriptionCount = 3;
1351
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions;
1352
1353
return true;
1354
}
1355
1356
void RenderDevice::InitFPSCap()
1357
{
1358
lastFrame = glfwGetTime();
1359
targetFreq = 1.0 / videoSettings.refreshRate;
1360
}
1361
bool RenderDevice::CheckFPSCap()
1362
{
1363
if (lastFrame + targetFreq < glfwGetTime())
1364
return true;
1365
1366
return false;
1367
}
1368
void RenderDevice::UpdateFPSCap() { lastFrame = glfwGetTime(); }
1369
1370
void RenderDevice::CopyFrameBuffer()
1371
{
1372
for (int32 s = 0; s < videoSettings.screenCount; ++s) {
1373
uint16 *pixels = (uint16 *)screenTextures[s].map;
1374
uint16 *frameBuffer = screens[s].frameBuffer;
1375
1376
int32 screenPitch = screens[s].pitch;
1377
int32 pitch = (screenTextures[s].layout.rowPitch >> 1) - screenPitch;
1378
1379
for (int32 y = 0; y < SCREEN_YSIZE; ++y) {
1380
int32 pixelCount = screenPitch >> 4;
1381
for (int32 x = 0; x < pixelCount; ++x) {
1382
pixels[0] = frameBuffer[0];
1383
pixels[1] = frameBuffer[1];
1384
pixels[2] = frameBuffer[2];
1385
pixels[3] = frameBuffer[3];
1386
pixels[4] = frameBuffer[4];
1387
pixels[5] = frameBuffer[5];
1388
pixels[6] = frameBuffer[6];
1389
pixels[7] = frameBuffer[7];
1390
pixels[8] = frameBuffer[8];
1391
pixels[9] = frameBuffer[9];
1392
pixels[10] = frameBuffer[10];
1393
pixels[11] = frameBuffer[11];
1394
pixels[12] = frameBuffer[12];
1395
pixels[13] = frameBuffer[13];
1396
pixels[14] = frameBuffer[14];
1397
pixels[15] = frameBuffer[15];
1398
1399
frameBuffer += 16;
1400
pixels += 16;
1401
}
1402
1403
pixels += pitch;
1404
}
1405
}
1406
}
1407
1408
bool RenderDevice::ProcessEvents()
1409
{
1410
glfwPollEvents();
1411
if (glfwWindowShouldClose(window))
1412
isRunning = false;
1413
return false;
1414
}
1415
1416
VkWriteDescriptorSet descriptorWrites[SCREEN_COUNT][2];
1417
1418
void RenderDevice::FlipScreen()
1419
{
1420
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
1421
vkResetFences(device, 1, &inFlightFence);
1422
1423
uint32_t imageIndex;
1424
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
1425
1426
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
1427
// RefreshWindow();
1428
return;
1429
} else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
1430
PrintLog(PRINT_NORMAL, "[VK] Failed to acquire swapchain image");
1431
return;
1432
}
1433
1434
// Update descriptor textures before the render pass
1435
switch (videoSettings.screenCount) {
1436
case 0:
1437
imageInfo.imageView = imageTexture.view;
1438
vkUpdateDescriptorSets(device, 2, descriptorWrites[0], 0, nullptr);
1439
break;
1440
case 1:
1441
imageInfo.imageView = screenTextures[0].view;
1442
vkUpdateDescriptorSets(device, 2, descriptorWrites[0], 0, nullptr);
1443
break;
1444
case 2:
1445
imageInfo.imageView = screenTextures[0].view;
1446
vkUpdateDescriptorSets(device, 2, descriptorWrites[0], 0, nullptr);
1447
imageInfo.imageView = screenTextures[1].view;
1448
vkUpdateDescriptorSets(device, 2, descriptorWrites[1], 0, nullptr);
1449
break;
1450
#if RETRO_REV02
1451
case 3:
1452
imageInfo.imageView = screenTextures[0].view;
1453
vkUpdateDescriptorSets(device, 2, descriptorWrites[0], 0, nullptr);
1454
imageInfo.imageView = screenTextures[1].view;
1455
vkUpdateDescriptorSets(device, 2, descriptorWrites[1], 0, nullptr);
1456
imageInfo.imageView = screenTextures[2].view;
1457
vkUpdateDescriptorSets(device, 2, descriptorWrites[2], 0, nullptr);
1458
break;
1459
case 4:
1460
imageInfo.imageView = screenTextures[0].view;
1461
vkUpdateDescriptorSets(device, 2, descriptorWrites[0], 0, nullptr);
1462
imageInfo.imageView = screenTextures[1].view;
1463
vkUpdateDescriptorSets(device, 2, descriptorWrites[1], 0, nullptr);
1464
imageInfo.imageView = screenTextures[2].view;
1465
vkUpdateDescriptorSets(device, 2, descriptorWrites[2], 0, nullptr);
1466
imageInfo.imageView = screenTextures[3].view;
1467
vkUpdateDescriptorSets(device, 2, descriptorWrites[3], 0, nullptr);
1468
break;
1469
#endif
1470
}
1471
1472
vkResetCommandBuffer(commandBuffer, 0);
1473
1474
VkCommandBufferBeginInfo beginInfo{};
1475
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1476
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1477
1478
if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS) {
1479
PrintLog(PRINT_NORMAL, "[VK] Failed to begin recording command buffer");
1480
return;
1481
}
1482
1483
VkRenderPassBeginInfo renderPassInfo{};
1484
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
1485
renderPassInfo.renderPass = renderPass;
1486
renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
1487
renderPassInfo.renderArea.offset = { 0, 0 };
1488
renderPassInfo.renderArea.extent = swapChainExtent;
1489
1490
VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
1491
renderPassInfo.clearValueCount = 1;
1492
renderPassInfo.pClearValues = &clearColor;
1493
1494
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
1495
1496
if (lastShaderID != videoSettings.shaderID) {
1497
lastShaderID = videoSettings.shaderID;
1498
1499
imageInfo.sampler = shaderList[videoSettings.shaderID].linear ? samplerLinear : samplerPoint;
1500
}
1501
1502
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shaderList[videoSettings.shaderSupport ? videoSettings.shaderID : 0].shaderPipeline);
1503
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
1504
1505
VkBuffer vertexBuffers[] = { vertexBuffer };
1506
VkDeviceSize offsets[] = { 0 };
1507
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
1508
1509
if (windowRefreshDelay > 0) {
1510
windowRefreshDelay--;
1511
if (!windowRefreshDelay)
1512
UpdateGameWindow();
1513
return;
1514
}
1515
1516
if (videoSettings.shaderSupport) {
1517
uniformMap->textureSize = textureSize;
1518
uniformMap->pixelSize = pixelSize;
1519
uniformMap->viewSize = viewSize;
1520
#if RETRO_REV02
1521
uniformMap->screenDim = videoSettings.dimMax * videoSettings.dimPercent;
1522
#endif
1523
}
1524
1525
int32 startVert = 0;
1526
switch (videoSettings.screenCount) {
1527
default:
1528
case 0:
1529
#if RETRO_REV02
1530
startVert = 54;
1531
#else
1532
startVert = 18;
1533
#endif
1534
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[0], 0, nullptr);
1535
vkCmdDraw(commandBuffer, 6, 1, startVert, 0);
1536
1537
break;
1538
1539
case 1:
1540
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[0], 0, nullptr);
1541
vkCmdDraw(commandBuffer, 6, 1, 0, 0);
1542
break;
1543
1544
case 2:
1545
#if RETRO_REV02
1546
startVert = startVertex_2P[0];
1547
#else
1548
startVert = 6;
1549
#endif
1550
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[0], 0, nullptr);
1551
vkCmdDraw(commandBuffer, 6, 1, startVert, 0);
1552
1553
#if RETRO_REV02
1554
startVert = startVertex_2P[1];
1555
#else
1556
startVert = 12;
1557
#endif
1558
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[1], 0, nullptr);
1559
vkCmdDraw(commandBuffer, 6, 1, startVert, 0);
1560
break;
1561
1562
#if RETRO_REV02
1563
case 3:
1564
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[0], 0, nullptr);
1565
vkCmdDraw(commandBuffer, 6, 1, startVertex_3P[0], 0);
1566
1567
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[1], 0, nullptr);
1568
vkCmdDraw(commandBuffer, 6, 1, startVertex_3P[1], 0);
1569
1570
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[2], 0, nullptr);
1571
vkCmdDraw(commandBuffer, 6, 1, startVertex_3P[2], 0);
1572
break;
1573
1574
case 4:
1575
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[0], 0, nullptr);
1576
vkCmdDraw(commandBuffer, 6, 1, 30, 0);
1577
1578
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[1], 0, nullptr);
1579
vkCmdDraw(commandBuffer, 6, 1, 36, 0);
1580
1581
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[2], 0, nullptr);
1582
vkCmdDraw(commandBuffer, 6, 1, 42, 0);
1583
1584
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet[3], 0, nullptr);
1585
vkCmdDraw(commandBuffer, 6, 1, 48, 0);
1586
break;
1587
#endif
1588
}
1589
1590
vkCmdEndRenderPass(commandBuffer);
1591
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) {
1592
PrintLog(PRINT_NORMAL, "[VK] Failed to record command buffer");
1593
return;
1594
}
1595
1596
VkSubmitInfo submitInfo{};
1597
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1598
1599
VkSemaphore waitSemaphores[] = { imageAvailableSemaphore };
1600
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
1601
submitInfo.waitSemaphoreCount = 1;
1602
submitInfo.pWaitSemaphores = waitSemaphores;
1603
submitInfo.pWaitDstStageMask = waitStages;
1604
1605
submitInfo.commandBufferCount = 1;
1606
submitInfo.pCommandBuffers = &commandBuffer;
1607
1608
VkSemaphore signalSemaphores[] = { renderFinishedSemaphore };
1609
submitInfo.signalSemaphoreCount = 1;
1610
submitInfo.pSignalSemaphores = signalSemaphores;
1611
1612
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS) {
1613
PrintLog(PRINT_NORMAL, "[VK] Failed to submit to graphics queue");
1614
return;
1615
}
1616
1617
VkPresentInfoKHR presentInfo{};
1618
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
1619
1620
presentInfo.waitSemaphoreCount = 1;
1621
presentInfo.pWaitSemaphores = signalSemaphores;
1622
1623
VkSwapchainKHR swapChains[] = { swapChain };
1624
presentInfo.swapchainCount = 1;
1625
presentInfo.pSwapchains = swapChains;
1626
1627
presentInfo.pImageIndices = &imageIndex;
1628
1629
vkQueuePresentKHR(presentQueue, &presentInfo);
1630
}
1631
1632
void RenderDevice::ReleaseShaderPipelines()
1633
{
1634
vkDeviceWaitIdle(device);
1635
1636
for (int32 i = 0; i < shaderCount; ++i) {
1637
vkDestroyPipeline(device, shaderList[i].shaderPipeline, nullptr);
1638
}
1639
1640
shaderCount = 0;
1641
#if RETRO_USE_MOD_LOADER
1642
userShaderCount = 0;
1643
#endif
1644
}
1645
1646
void RenderDevice::Release(bool32 isRefresh)
1647
{
1648
vkDeviceWaitIdle(device);
1649
1650
for (auto framebuffer : swapChainFramebuffers) {
1651
vkDestroyFramebuffer(device, framebuffer, nullptr);
1652
}
1653
1654
for (auto imageView : swapChainImageViews) {
1655
vkDestroyImageView(device, imageView, nullptr);
1656
}
1657
1658
vkDestroySwapchainKHR(device, swapChain, nullptr);
1659
1660
ReleaseShaderPipelines();
1661
1662
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
1663
vkDestroyRenderPass(device, renderPass, nullptr);
1664
1665
vkDestroyBuffer(device, uniformBuffer, nullptr);
1666
vkFreeMemory(device, uniformBufferMemory, nullptr);
1667
1668
for (int32 i = 0; i < SCREEN_COUNT; ++i) {
1669
vkFreeDescriptorSets(device, descriptorPool, 1, &descriptorSet[i]);
1670
}
1671
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
1672
vkDestroyDescriptorSetLayout(device, setLayout, nullptr);
1673
1674
vkDestroySampler(device, samplerPoint, nullptr);
1675
vkDestroySampler(device, samplerLinear, nullptr);
1676
1677
for (int32 i = 0; i < SCREEN_COUNT; ++i) {
1678
vkDestroyImageView(device, screenTextures[i].view, nullptr);
1679
vkDestroyImage(device, screenTextures[i].image, nullptr);
1680
vkUnmapMemory(device, screenTextures[i].memory);
1681
vkFreeMemory(device, screenTextures[i].memory, nullptr);
1682
}
1683
vkDestroyImageView(device, imageTexture.view, nullptr);
1684
vkDestroyImage(device, imageTexture.image, nullptr);
1685
vkUnmapMemory(device, imageTexture.memory);
1686
vkFreeMemory(device, imageTexture.memory, nullptr);
1687
1688
vkDestroyBuffer(device, vertexBuffer, nullptr);
1689
vkFreeMemory(device, vertexBufferMemory, nullptr);
1690
1691
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
1692
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
1693
vkDestroyFence(device, inFlightFence, nullptr);
1694
1695
vkDestroyCommandPool(device, commandPool, nullptr);
1696
1697
vkDestroySurfaceKHR(instance, surface, nullptr);
1698
glfwDestroyWindow(window);
1699
1700
if (!isRefresh) {
1701
if (displayInfo.displays)
1702
free(displayInfo.displays);
1703
displayInfo.displays = NULL;
1704
1705
if (scanlines)
1706
free(scanlines);
1707
scanlines = NULL;
1708
1709
vkDestroyDevice(device, nullptr);
1710
1711
#ifdef VK_DEBUG
1712
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
1713
if (func != nullptr) {
1714
func(instance, debugMessenger, nullptr);
1715
}
1716
#endif
1717
1718
vkDestroyInstance(instance, nullptr);
1719
1720
glfwTerminate();
1721
}
1722
}
1723
1724
VkDescriptorBufferInfo bufferInfo{};
1725
1726
bool RenderDevice::InitShaders()
1727
{
1728
if (descriptorSet[0] == VK_NULL_HANDLE) {
1729
VkSamplerCreateInfo samplerPointInfo{};
1730
samplerPointInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
1731
samplerPointInfo.magFilter = VK_FILTER_NEAREST;
1732
samplerPointInfo.minFilter = VK_FILTER_NEAREST;
1733
samplerPointInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1734
samplerPointInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1735
samplerPointInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
1736
samplerPointInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
1737
samplerPointInfo.unnormalizedCoordinates = VK_FALSE;
1738
samplerPointInfo.anisotropyEnable = VK_FALSE;
1739
samplerPointInfo.maxAnisotropy = 1.0f;
1740
samplerPointInfo.compareEnable = VK_FALSE;
1741
samplerPointInfo.compareOp = VK_COMPARE_OP_NEVER;
1742
samplerPointInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1743
samplerPointInfo.mipLodBias = 0.0f;
1744
samplerPointInfo.minLod = -FLT_MAX;
1745
samplerPointInfo.maxLod = FLT_MAX;
1746
1747
VkSamplerCreateInfo samplerLinearInfo = samplerPointInfo;
1748
samplerLinearInfo.magFilter = VK_FILTER_LINEAR;
1749
samplerLinearInfo.minFilter = VK_FILTER_LINEAR;
1750
1751
if (vkCreateSampler(device, &samplerPointInfo, nullptr, &samplerPoint) != VK_SUCCESS) {
1752
PrintLog(PRINT_NORMAL, "[VK] Failed to create point sampler");
1753
return false;
1754
}
1755
if (vkCreateSampler(device, &samplerLinearInfo, nullptr, &samplerLinear) != VK_SUCCESS) {
1756
PrintLog(PRINT_NORMAL, "[VK] Failed to create linear sampler");
1757
return false;
1758
}
1759
1760
// Use the same descriptor set layout for all screens
1761
VkDescriptorSetLayout layouts[SCREEN_COUNT];
1762
for (int32 i = 0; i < SCREEN_COUNT; i++) {
1763
layouts[i] = setLayout;
1764
}
1765
//! CREATE DESCRIPTOR SET
1766
VkDescriptorSetAllocateInfo allocInfo{};
1767
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1768
allocInfo.descriptorPool = descriptorPool;
1769
allocInfo.descriptorSetCount = SCREEN_COUNT;
1770
allocInfo.pSetLayouts = layouts;
1771
1772
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSet) != VK_SUCCESS) {
1773
PrintLog(PRINT_NORMAL, "[VK] Failed to allocate descriptor sets");
1774
return false;
1775
}
1776
1777
//! CREATE DESCRIPTOR SET HERE BC I HAVE VULKAN
1778
bufferInfo = {};
1779
bufferInfo.buffer = uniformBuffer;
1780
bufferInfo.offset = 0;
1781
bufferInfo.range = sizeof(ShaderConstants);
1782
1783
// THIS WILL BE CHANGED REGULARLY
1784
imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1785
imageInfo.imageView = imageTexture.view;
1786
imageInfo.sampler = samplerLinear;
1787
1788
for (int32 i = 0; i < SCREEN_COUNT; ++i) {
1789
descriptorWrites[i][0] = {};
1790
descriptorWrites[i][0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1791
descriptorWrites[i][0].dstSet = descriptorSet[i];
1792
descriptorWrites[i][0].dstBinding = 0;
1793
descriptorWrites[i][0].dstArrayElement = 0;
1794
descriptorWrites[i][0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1795
descriptorWrites[i][0].descriptorCount = 1;
1796
descriptorWrites[i][0].pImageInfo = &imageInfo;
1797
1798
descriptorWrites[i][1] = {};
1799
descriptorWrites[i][1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1800
descriptorWrites[i][1].dstSet = descriptorSet[i];
1801
descriptorWrites[i][1].dstBinding = 1;
1802
descriptorWrites[i][1].dstArrayElement = 0;
1803
descriptorWrites[i][1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
1804
descriptorWrites[i][1].descriptorCount = 1;
1805
descriptorWrites[i][1].pBufferInfo = &bufferInfo;
1806
1807
vkUpdateDescriptorSets(device, 2, descriptorWrites[i], 0, nullptr);
1808
}
1809
}
1810
1811
// Release old shader pipelines
1812
if (shaderCount) {
1813
ReleaseShaderPipelines();
1814
}
1815
1816
videoSettings.shaderSupport = true;
1817
int32 maxShaders = 0;
1818
#if RETRO_USE_MOD_LOADER
1819
shaderCount = 0;
1820
#endif
1821
1822
LoadShader("None", false);
1823
LoadShader("Clean", true);
1824
LoadShader("CRT-Yeetron", true);
1825
LoadShader("CRT-Yee64", true);
1826
1827
#if RETRO_USE_MOD_LOADER
1828
// a place for mods to load custom shaders
1829
RunModCallbacks(MODCB_ONSHADERLOAD, NULL);
1830
userShaderCount = shaderCount;
1831
#endif
1832
1833
LoadShader("YUV-420", true);
1834
LoadShader("YUV-422", true);
1835
LoadShader("YUV-444", true);
1836
LoadShader("RGB-Image", true);
1837
maxShaders = shaderCount;
1838
1839
// no shaders == no support
1840
if (!maxShaders) {
1841
PrintLog(PRINT_NORMAL, "[VK] No shaders loaded correctly, attempting backup");
1842
1843
ShaderEntry *shader = &shaderList[0];
1844
sprintf_s(shader->name, sizeof(shader->name), "%s", "BACKUP");
1845
videoSettings.shaderSupport = false;
1846
1847
// let's load
1848
maxShaders = 1;
1849
shaderCount = 1;
1850
1851
VkShaderModule vertModule, fragModule;
1852
VkShaderModuleCreateInfo createInfo{};
1853
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1854
createInfo.codeSize = sizeof(backupVert);
1855
createInfo.pCode = reinterpret_cast<const uint32_t *>(backupVert);
1856
1857
if (vkCreateShaderModule(device, &createInfo, nullptr, &vertModule) != VK_SUCCESS) {
1858
PrintLog(PRINT_NORMAL, "[VK] Failed to create vertex module for backup shader");
1859
return false;
1860
}
1861
1862
createInfo.codeSize = sizeof(backupFrag);
1863
createInfo.pCode = reinterpret_cast<const uint32_t *>(backupFrag);
1864
1865
if (vkCreateShaderModule(device, &createInfo, nullptr, &fragModule) != VK_SUCCESS) {
1866
PrintLog(PRINT_NORMAL, "[VK] Failed to create fragment module for backup shader");
1867
return false;
1868
}
1869
1870
VkPipelineShaderStageCreateInfo shaderStages[] = { {}, {} };
1871
1872
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1873
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
1874
shaderStages[0].module = vertModule;
1875
shaderStages[0].pName = "main";
1876
1877
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1878
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1879
shaderStages[1].module = fragModule;
1880
shaderStages[1].pName = "main";
1881
1882
VkGraphicsPipelineCreateInfo pipelineInfo = basePipeline;
1883
pipelineInfo.stageCount = 2;
1884
pipelineInfo.pStages = shaderStages;
1885
1886
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &shader->shaderPipeline) != VK_SUCCESS) {
1887
PrintLog(PRINT_NORMAL, "[VK] Failed to create pipeline for backup shader");
1888
return false;
1889
}
1890
1891
vkDestroyShaderModule(device, fragModule, nullptr);
1892
vkDestroyShaderModule(device, vertModule, nullptr);
1893
1894
shader->linear = videoSettings.windowed ? false : shader->linear;
1895
}
1896
videoSettings.shaderID = MAX(videoSettings.shaderID >= maxShaders ? 0 : videoSettings.shaderID, 0);
1897
1898
return true;
1899
}
1900
1901
void RenderDevice::LoadShader(const char *fileName, bool32 linear)
1902
{
1903
char fullFilePath[0x100];
1904
FileInfo info;
1905
1906
for (int32 i = 0; i < shaderCount; ++i) {
1907
if (strcmp(shaderList[i].name, fileName) == 0)
1908
return;
1909
}
1910
1911
if (shaderCount == SHADER_COUNT)
1912
return;
1913
1914
ShaderEntry *shader = &shaderList[shaderCount];
1915
shader->linear = linear;
1916
sprintf_s(shader->name, sizeof(shader->name), "%s", fileName);
1917
1918
VkShaderModule vertModule, fragModule;
1919
1920
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Shaders/CSO-Vulkan/None.vert");
1921
InitFileInfo(&info);
1922
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
1923
uint8 *fileData = NULL;
1924
AllocateStorage((void **)&fileData, info.fileSize + 1, DATASET_TMP, false);
1925
ReadBytes(&info, fileData, info.fileSize);
1926
fileData[info.fileSize] = 0;
1927
CloseFile(&info);
1928
1929
VkShaderModuleCreateInfo createInfo{};
1930
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1931
createInfo.codeSize = info.fileSize;
1932
createInfo.pCode = reinterpret_cast<const uint32_t *>(fileData);
1933
1934
VkResult res = vkCreateShaderModule(device, &createInfo, nullptr, &vertModule);
1935
RemoveStorageEntry((void **)&fileData);
1936
1937
if (res != VK_SUCCESS) {
1938
PrintLog(PRINT_NORMAL, "[VK] Failed to create vertex module for %s", shader->name);
1939
return;
1940
}
1941
}
1942
else
1943
return;
1944
1945
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Shaders/CSO-Vulkan/%s.frag", fileName);
1946
InitFileInfo(&info);
1947
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
1948
uint8 *fileData = NULL;
1949
AllocateStorage((void **)&fileData, info.fileSize + 1, DATASET_TMP, false);
1950
ReadBytes(&info, fileData, info.fileSize);
1951
fileData[info.fileSize] = 0;
1952
CloseFile(&info);
1953
1954
VkShaderModuleCreateInfo createInfo{};
1955
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1956
createInfo.codeSize = info.fileSize;
1957
createInfo.pCode = reinterpret_cast<const uint32_t *>(fileData);
1958
1959
VkResult res = vkCreateShaderModule(device, &createInfo, nullptr, &fragModule);
1960
RemoveStorageEntry((void **)&fileData);
1961
1962
if (res != VK_SUCCESS) {
1963
PrintLog(PRINT_NORMAL, "[VK] Failed to create fragment module for %s", shader->name);
1964
return;
1965
}
1966
}
1967
else
1968
return;
1969
1970
VkPipelineShaderStageCreateInfo shaderStages[] = { {}, {} };
1971
1972
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1973
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
1974
shaderStages[0].module = vertModule;
1975
shaderStages[0].pName = "main";
1976
1977
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1978
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1979
shaderStages[1].module = fragModule;
1980
shaderStages[1].pName = "main";
1981
1982
VkGraphicsPipelineCreateInfo pipelineInfo = basePipeline;
1983
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1984
pipelineInfo.stageCount = 2;
1985
pipelineInfo.pStages = shaderStages;
1986
1987
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &shader->shaderPipeline) != VK_SUCCESS) {
1988
PrintLog(PRINT_NORMAL, "[VK] Failed to create pipeline for shader %s", shader->name);
1989
}
1990
else
1991
shaderCount++;
1992
1993
vkDestroyShaderModule(device, fragModule, nullptr);
1994
vkDestroyShaderModule(device, vertModule, nullptr);
1995
};
1996
1997
void RenderDevice::RefreshWindow()
1998
{
1999
videoSettings.windowState = WINDOWSTATE_UNINITIALIZED;
2000
2001
Release(true);
2002
if ((window = CreateGLFWWindow()) == NULL)
2003
return;
2004
2005
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
2006
PrintLog(PRINT_NORMAL, "[VK] Vulkan surface could not be created");
2007
return;
2008
}
2009
2010
// Update swapchain details to refresh capabilities ({min/max}ImageExtent)
2011
QuerySwapChainDetails(physicalDevice);
2012
2013
descriptorSet[0] = VK_NULL_HANDLE;
2014
2015
if (!InitGraphicsAPI() || !InitShaders())
2016
return;
2017
2018
videoSettings.windowState = WINDOWSTATE_ACTIVE;
2019
}
2020
2021
void RenderDevice::GetWindowSize(int32 *width, int32 *height)
2022
{
2023
int32 widest = 0, highest = 0, count = 0;
2024
GLFWmonitor **monitors = glfwGetMonitors(&count);
2025
for (int32 i = 0; i < count; i++) {
2026
const GLFWvidmode *mode = glfwGetVideoMode(monitors[i]);
2027
if (mode->height > highest) {
2028
highest = mode->height;
2029
widest = mode->width;
2030
}
2031
}
2032
if (width)
2033
*width = widest;
2034
if (height)
2035
*height = highest;
2036
}
2037
2038
void RenderDevice::SetupImageTexture(int32 width, int32 height, uint8 *imagePixels)
2039
{
2040
uint32 *pixels = (uint32 *)imageTexture.map;
2041
int32 pitch = (imageTexture.layout.rowPitch >> 2) - width;
2042
2043
uint32 *imagePixels32 = (uint32 *)imagePixels;
2044
for (int32 y = 0; y < height; ++y) {
2045
for (int32 x = 0; x < width; ++x) {
2046
*pixels++ = *imagePixels32++;
2047
}
2048
2049
pixels += pitch;
2050
}
2051
}
2052
2053
void RenderDevice::SetupVideoTexture_YUV420(int32 width, int32 height, uint8 *yPlane, uint8 *uPlane, uint8 *vPlane, int32 strideY, int32 strideU,
2054
int32 strideV)
2055
{
2056
uint32 *pixels = (uint32 *)imageTexture.map;
2057
int32 pitch = (imageTexture.layout.rowPitch >> 2) - width;
2058
2059
if (videoSettings.shaderSupport) {
2060
for (int32 y = 0; y < height; ++y) {
2061
for (int32 x = 0; x < width; ++x) {
2062
*pixels++ = (yPlane[x] << 16) | 0xFF000000;
2063
}
2064
2065
pixels += pitch;
2066
yPlane += strideY;
2067
}
2068
2069
pixels = (uint32 *)imageTexture.map;
2070
pitch = (imageTexture.layout.rowPitch >> 2) - (width >> 1);
2071
for (int32 y = 0; y < (height >> 1); ++y) {
2072
for (int32 x = 0; x < (width >> 1); ++x) {
2073
*pixels++ |= (vPlane[x] << 0) | (uPlane[x] << 8) | 0xFF000000;
2074
}
2075
2076
pixels += pitch;
2077
uPlane += strideU;
2078
vPlane += strideV;
2079
}
2080
}
2081
else {
2082
// No shader support means no YUV support! at least use the brightness to show it in grayscale!
2083
for (int32 y = 0; y < height; ++y) {
2084
for (int32 x = 0; x < width; ++x) {
2085
int32 brightness = yPlane[x];
2086
*pixels++ = (brightness << 0) | (brightness << 8) | (brightness << 16) | 0xFF000000;
2087
}
2088
2089
pixels += pitch;
2090
yPlane += strideY;
2091
}
2092
}
2093
}
2094
2095
void RenderDevice::SetupVideoTexture_YUV422(int32 width, int32 height, uint8 *yPlane, uint8 *uPlane, uint8 *vPlane, int32 strideY, int32 strideU,
2096
int32 strideV)
2097
{
2098
uint32 *pixels = (uint32 *)imageTexture.map;
2099
int32 pitch = (imageTexture.layout.rowPitch >> 2) - width;
2100
2101
if (videoSettings.shaderSupport) {
2102
for (int32 y = 0; y < height; ++y) {
2103
for (int32 x = 0; x < width; ++x) {
2104
*pixels++ = (yPlane[x] << 16) | 0xFF000000;
2105
}
2106
2107
pixels += pitch;
2108
yPlane += strideY;
2109
}
2110
2111
pixels = (uint32 *)imageTexture.map;
2112
pitch = (imageTexture.layout.rowPitch >> 2) - (width >> 1);
2113
for (int32 y = 0; y < height; ++y) {
2114
for (int32 x = 0; x < (width >> 1); ++x) {
2115
*pixels++ |= (vPlane[x] << 0) | (uPlane[x] << 8) | 0xFF000000;
2116
}
2117
2118
pixels += pitch;
2119
uPlane += strideU;
2120
vPlane += strideV;
2121
}
2122
}
2123
else {
2124
// No shader support means no YUV support! at least use the brightness to show it in grayscale!
2125
for (int32 y = 0; y < height; ++y) {
2126
for (int32 x = 0; x < width; ++x) {
2127
int32 brightness = yPlane[x];
2128
*pixels++ = (brightness << 0) | (brightness << 8) | (brightness << 16) | 0xFF000000;
2129
}
2130
2131
pixels += pitch;
2132
yPlane += strideY;
2133
}
2134
}
2135
}
2136
void RenderDevice::SetupVideoTexture_YUV444(int32 width, int32 height, uint8 *yPlane, uint8 *uPlane, uint8 *vPlane, int32 strideY, int32 strideU,
2137
int32 strideV)
2138
{
2139
uint32 *pixels = (uint32 *)imageTexture.map;
2140
int32 pitch = (imageTexture.layout.rowPitch >> 2) - width;
2141
2142
if (videoSettings.shaderSupport) {
2143
for (int32 y = 0; y < height; ++y) {
2144
int32 pos1 = yPlane - vPlane;
2145
int32 pos2 = uPlane - vPlane;
2146
uint8 *pixV = vPlane;
2147
for (int32 x = 0; x < width; ++x) {
2148
*pixels++ = pixV[0] | (pixV[pos2] << 8) | (pixV[pos1] << 16) | 0xFF000000;
2149
pixV++;
2150
}
2151
2152
pixels += pitch;
2153
yPlane += strideY;
2154
uPlane += strideU;
2155
vPlane += strideV;
2156
}
2157
}
2158
else {
2159
// No shader support means no YUV support! at least use the brightness to show it in grayscale!
2160
for (int32 y = 0; y < height; ++y) {
2161
for (int32 x = 0; x < width; ++x) {
2162
int32 brightness = yPlane[x];
2163
*pixels++ = (brightness << 0) | (brightness << 8) | (brightness << 16) | 0xFF000000;
2164
}
2165
2166
pixels += pitch;
2167
yPlane += strideY;
2168
}
2169
}
2170
}
2171
2172
void RenderDevice::ProcessKeyEvent(GLFWwindow *, int32 key, int32 scancode, int32 action, int32 mods)
2173
{
2174
switch (action) {
2175
case GLFW_PRESS: {
2176
#if !RETRO_REV02
2177
++RSDK::SKU::buttonDownCount;
2178
#endif
2179
switch (key) {
2180
case GLFW_KEY_ENTER:
2181
if (mods & GLFW_MOD_ALT) {
2182
videoSettings.windowed ^= 1;
2183
UpdateGameWindow();
2184
changedVideoSettings = false;
2185
break;
2186
}
2187
2188
#if !RETRO_REV02 && RETRO_INPUTDEVICE_KEYBOARD
2189
RSDK::SKU::specialKeyStates[1] = true;
2190
#endif
2191
2192
// [fallthrough]
2193
2194
default:
2195
#if RETRO_INPUTDEVICE_KEYBOARD
2196
SKU::UpdateKeyState(key);
2197
#endif
2198
break;
2199
2200
case GLFW_KEY_ESCAPE:
2201
if (engine.devMenu) {
2202
#if RETRO_REV0U
2203
if (sceneInfo.state == ENGINESTATE_DEVMENU || RSDK::Legacy::gameMode == RSDK::Legacy::ENGINE_DEVMENU)
2204
#else
2205
if (sceneInfo.state == ENGINESTATE_DEVMENU)
2206
#endif
2207
CloseDevMenu();
2208
else
2209
OpenDevMenu();
2210
}
2211
else {
2212
#if RETRO_INPUTDEVICE_KEYBOARD
2213
SKU::UpdateKeyState(key);
2214
#endif
2215
}
2216
2217
#if !RETRO_REV02 && RETRO_INPUTDEVICE_KEYBOARD
2218
RSDK::SKU::specialKeyStates[0] = true;
2219
#endif
2220
break;
2221
2222
#if !RETRO_USE_ORIGINAL_CODE
2223
case GLFW_KEY_F1:
2224
if (engine.devMenu) {
2225
sceneInfo.listPos--;
2226
while (sceneInfo.listPos < sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetStart
2227
|| sceneInfo.listPos > sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetEnd
2228
|| !sceneInfo.listCategory[sceneInfo.activeCategory].sceneCount) {
2229
sceneInfo.activeCategory--;
2230
if (sceneInfo.activeCategory >= sceneInfo.categoryCount) {
2231
sceneInfo.activeCategory = sceneInfo.categoryCount - 1;
2232
}
2233
sceneInfo.listPos = sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetEnd - 1;
2234
}
2235
2236
#if RETRO_REV0U
2237
switch (engine.version) {
2238
default: break;
2239
case 5: LoadScene(); break;
2240
case 4:
2241
case 3: RSDK::Legacy::stageMode = RSDK::Legacy::STAGEMODE_LOAD; break;
2242
}
2243
#else
2244
LoadScene();
2245
#endif
2246
}
2247
break;
2248
2249
case GLFW_KEY_F2:
2250
if (engine.devMenu) {
2251
sceneInfo.listPos++;
2252
while (sceneInfo.listPos < sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetStart
2253
|| sceneInfo.listPos > sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetEnd
2254
|| !sceneInfo.listCategory[sceneInfo.activeCategory].sceneCount) {
2255
sceneInfo.activeCategory++;
2256
if (sceneInfo.activeCategory >= sceneInfo.categoryCount) {
2257
sceneInfo.activeCategory = 0;
2258
}
2259
sceneInfo.listPos = sceneInfo.listCategory[sceneInfo.activeCategory].sceneOffsetStart;
2260
}
2261
2262
#if RETRO_REV0U
2263
switch (engine.version) {
2264
default: break;
2265
case 5: LoadScene(); break;
2266
case 4:
2267
case 3: RSDK::Legacy::stageMode = RSDK::Legacy::STAGEMODE_LOAD; break;
2268
}
2269
#else
2270
LoadScene();
2271
#endif
2272
}
2273
break;
2274
#endif
2275
2276
case GLFW_KEY_F3:
2277
if (userShaderCount)
2278
videoSettings.shaderID = (videoSettings.shaderID + 1) % userShaderCount;
2279
break;
2280
2281
#if !RETRO_USE_ORIGINAL_CODE
2282
case GLFW_KEY_F4:
2283
if (engine.devMenu)
2284
engine.showEntityInfo ^= 1;
2285
break;
2286
2287
case GLFW_KEY_F5:
2288
if (engine.devMenu) {
2289
// Quick-Reload
2290
#if RETRO_USE_MOD_LOADER
2291
if (mods & GLFW_MOD_CONTROL)
2292
RefreshModFolders();
2293
#endif
2294
2295
#if RETRO_REV0U
2296
switch (engine.version) {
2297
default: break;
2298
case 5: LoadScene(); break;
2299
case 4:
2300
case 3: RSDK::Legacy::stageMode = RSDK::Legacy::STAGEMODE_LOAD; break;
2301
}
2302
#else
2303
LoadScene();
2304
#endif
2305
}
2306
break;
2307
2308
case GLFW_KEY_F6:
2309
if (engine.devMenu && videoSettings.screenCount > 1)
2310
videoSettings.screenCount--;
2311
break;
2312
2313
case GLFW_KEY_F7:
2314
if (engine.devMenu && videoSettings.screenCount < SCREEN_COUNT)
2315
videoSettings.screenCount++;
2316
break;
2317
2318
case GLFW_KEY_F8:
2319
if (engine.devMenu)
2320
engine.showUpdateRanges ^= 1;
2321
break;
2322
2323
case GLFW_KEY_F9:
2324
if (engine.devMenu)
2325
showHitboxes ^= 1;
2326
break;
2327
2328
case GLFW_KEY_F10:
2329
if (engine.devMenu)
2330
engine.showPaletteOverlay ^= 1;
2331
break;
2332
#endif
2333
case GLFW_KEY_BACKSPACE:
2334
if (engine.devMenu)
2335
engine.gameSpeed = engine.fastForwardSpeed;
2336
break;
2337
2338
case GLFW_KEY_F11:
2339
case GLFW_KEY_INSERT:
2340
if (engine.devMenu)
2341
engine.frameStep = true;
2342
break;
2343
2344
case GLFW_KEY_F12:
2345
case GLFW_KEY_PAUSE:
2346
if (engine.devMenu) {
2347
#if RETRO_REV0U
2348
switch (engine.version) {
2349
default: break;
2350
case 5:
2351
if (sceneInfo.state != ENGINESTATE_NONE)
2352
sceneInfo.state ^= ENGINESTATE_STEPOVER;
2353
break;
2354
case 4:
2355
case 3:
2356
if (RSDK::Legacy::stageMode != ENGINESTATE_NONE)
2357
RSDK::Legacy::stageMode ^= RSDK::Legacy::STAGEMODE_STEPOVER;
2358
break;
2359
}
2360
#else
2361
if (sceneInfo.state != ENGINESTATE_NONE)
2362
sceneInfo.state ^= ENGINESTATE_STEPOVER;
2363
#endif
2364
}
2365
break;
2366
}
2367
break;
2368
}
2369
case GLFW_RELEASE: {
2370
#if !RETRO_REV02
2371
--RSDK::SKU::buttonDownCount;
2372
#endif
2373
switch (key) {
2374
default:
2375
#if RETRO_INPUTDEVICE_KEYBOARD
2376
SKU::ClearKeyState(key);
2377
#endif
2378
break;
2379
2380
#if !RETRO_REV02 && RETRO_INPUTDEVICE_KEYBOARD
2381
case GLFW_KEY_ESCAPE:
2382
RSDK::SKU::specialKeyStates[0] = false;
2383
SKU::ClearKeyState(key);
2384
break;
2385
2386
case GLFW_KEY_ENTER:
2387
RSDK::SKU::specialKeyStates[1] = false;
2388
SKU::ClearKeyState(key);
2389
break;
2390
#endif
2391
case GLFW_KEY_BACKSPACE: engine.gameSpeed = 1; break;
2392
}
2393
break;
2394
}
2395
}
2396
}
2397
void RenderDevice::ProcessFocusEvent(GLFWwindow *, int32 focused)
2398
{
2399
if (!focused) {
2400
#if RETRO_REV02
2401
SKU::userCore->focusState = 1;
2402
#endif
2403
}
2404
else {
2405
#if RETRO_REV02
2406
SKU::userCore->focusState = 0;
2407
#endif
2408
}
2409
}
2410
void RenderDevice::ProcessMouseEvent(GLFWwindow *, int32 button, int32 action, int32 mods)
2411
{
2412
switch (action) {
2413
case GLFW_PRESS: {
2414
switch (button) {
2415
case GLFW_MOUSE_BUTTON_LEFT: touchInfo.down[0] = true; touchInfo.count = 1;
2416
#if !RETRO_REV02
2417
RSDK::SKU::buttonDownCount++;
2418
#endif
2419
break;
2420
2421
case GLFW_MOUSE_BUTTON_RIGHT:
2422
#if !RETRO_REV02 && RETRO_INPUTDEVICE_KEYBOARD
2423
RSDK::SKU::specialKeyStates[3] = true;
2424
RSDK::SKU::buttonDownCount++;
2425
#endif
2426
break;
2427
}
2428
break;
2429
}
2430
2431
case GLFW_RELEASE: {
2432
switch (button) {
2433
case GLFW_MOUSE_BUTTON_LEFT: touchInfo.down[0] = false; touchInfo.count = 0;
2434
#if !RETRO_REV02
2435
RSDK::SKU::buttonDownCount--;
2436
#endif
2437
break;
2438
2439
case GLFW_MOUSE_BUTTON_RIGHT:
2440
#if !RETRO_REV02 && RETRO_INPUTDEVICE_KEYBOARD
2441
RSDK::SKU::specialKeyStates[3] = false;
2442
RSDK::SKU::buttonDownCount--;
2443
#endif
2444
break;
2445
}
2446
break;
2447
}
2448
}
2449
}
2450
void RenderDevice::ProcessJoystickEvent(int32 ID, int32 event)
2451
{
2452
#if RETRO_INPUTDEVICE_GLFW
2453
if (!glfwJoystickIsGamepad(ID))
2454
return;
2455
uint32 hash;
2456
char idBuffer[0x20];
2457
sprintf_s(idBuffer, sizeof(idBuffer), "%s%d", "GLFWDevice", ID);
2458
GenerateHashCRC(&hash, idBuffer);
2459
2460
if (event == GLFW_CONNECTED)
2461
SKU::InitGLFWInputDevice(hash, ID);
2462
else
2463
RemoveInputDevice(InputDeviceFromID(hash));
2464
#endif
2465
}
2466
void RenderDevice::ProcessMaximizeEvent(GLFWwindow *, int32 maximized)
2467
{
2468
// i don't know why this is a thing
2469
if (maximized) {
2470
// set fullscreen idk about the specifics rn
2471
}
2472
}
2473
2474