-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathVKDDisplay.h
133 lines (108 loc) · 4.39 KB
/
VKDDisplay.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: Copyright (c) 2014-2023, NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
/* Contact iesser@nvidia.com (Ingo Esser) for feedback */
#pragma once
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include <include_gl.h>
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_win32.h>
#include <nvvk/extensions_vk.hpp>
#include <nvh/nvprint.hpp>
#include <vector>
class VKDirectDisplay
{
public:
VKDirectDisplay();
// initialize direct display and GL textures
// call this with the GL context current that's used for interop
bool init();
// shut down VKDirectDisplay
void shutdown();
// width and height of swapchain interop textures
// by default the highest resolution available for the direct display
uint32_t getWidth() { return m_swapchainExtent.width; }
uint32_t getHeight() { return m_swapchainExtent.height; }
// get the texture to render the next frame into
// synchronization: GL waits for the VK texture to be available
GLuint getTexture();
// submit this texture to the direct display
// synchronization:
// * GL signals to VK that rendering is done
// * VK signals to VK that texture can be used for next frame
void submitTexture();
private:
struct Display
{
vk::DisplayKHR displayKHR;
vk::DisplayPropertiesKHR displayProperties;
vk::DisplayModePropertiesKHR modeProperties;
};
struct VKGLSyncData
{
// VK texture
vk::UniqueDeviceMemory m_deviceMemory;
vk::UniqueImage m_image;
HANDLE m_handle;
GLuint m_memoryObject;
// GL texture handle of VK texture
GLuint m_textureGL;
// VK semaphores
vk::UniqueSemaphore m_available; // VK signals to GL: available
vk::UniqueSemaphore m_finished; // GL signals to VK: done rendering
HANDLE m_availableHandle;
HANDLE m_finishedHandle;
// GL semaphore hanldes of VK semaphores
GLuint m_availableGL;
GLuint m_finishedGL;
};
vk::UniqueInstance m_instance;
vk::PhysicalDevice m_gpu;
Display m_display;
vk::UniqueSurfaceKHR m_surface;
uint32_t m_presentFamily{ 0 };
vk::Queue m_presentQueue;
vk::UniqueDevice m_device;
vk::UniqueSwapchainKHR m_swapchain;
std::vector<vk::Image> m_swapchainImages;
vk::Extent2D m_swapchainExtent;
vk::Format m_swapchainFormat{ vk::Format::eUndefined };
uint32_t m_frameIndex{ 0 };
std::vector<VKGLSyncData> m_syncData;
std::vector<vk::UniqueFence> m_fences;
std::vector<vk::UniqueSemaphore> m_imageAcquiredSemaphores;
std::vector<vk::UniqueSemaphore> m_blitFinishedSemaphores;
vk::UniqueCommandPool m_commandPool;
std::vector<vk::CommandBuffer> m_blitCommandBuffers;
void createInstance();
bool checkDeviceExtensionSupport(vk::PhysicalDevice device);
void pickGPU();
void createDisplaySurface();
void createLogicalDevice();
void createCommandPool();
void createSwapchain();
uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties);
void createInteropTexture(VKGLSyncData& s);
void createInteropSemaphores(VKGLSyncData& s);
void createSyncObjects();
void createSyncs();
void createCommandBuffers();
vk::CommandBuffer createTmpCmdBuffer();
void submitTmpCmdBuffer(vk::CommandBuffer c);
void transitionImage(vk::CommandBuffer buf, vk::Image img, vk::AccessFlags srcAccess, vk::AccessFlags dstAccess, vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits srcStage, vk::PipelineStageFlags dstStage);
};