Skip to content

Commit 0f5f541

Browse files
committed
Create SwapChain based on display/cvars, clean-up
Also get SwapChain images.
1 parent b0d0ee8 commit 0f5f541

File tree

7 files changed

+165
-27
lines changed

7 files changed

+165
-27
lines changed

src/engine/renderer-vulkan/GraphicsCore/CapabilityPack.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ constexpr Array instanceExtensions {
8181

8282
constexpr Array extensionsMinimal {
8383
"VK_EXT_descriptor_indexing",
84-
"VK_KHR_swapchain"
84+
"VK_KHR_swapchain",
85+
#ifdef _MSC_VER
86+
"VK_EXT_full_screen_exclusive"
87+
#endif
8588
};
8689

8790
constexpr Array featuresMinimal {

src/engine/renderer-vulkan/GraphicsCore/GraphicsCoreCVars.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3939

4040
#include "SwapChain.h"
4141

42+
#include "Memory/EngineAllocator.h"
43+
4244
#include "GraphicsCoreCVars.h"
4345

44-
Cvar::Cvar<int> r_rendererApi( "r_rendererAPI", "Renderer API: 0: OpenGL, 1: Vulkan", Cvar::ROM, 1 );
46+
Cvar::Cvar<int> r_rendererApi( "r_rendererAPI", "Renderer API: 0: OpenGL, 1: Vulkan", Cvar::ROM, 1 );
4547

46-
Cvar::Cvar<std::string> r_vkVersion( "r_vkVersion", "Daemon-vulkan version", Cvar::ROM, DAEMON_VULKAN_VERSION.FormatVersion() );
48+
Cvar::Cvar<std::string> r_vkVersion( "r_vkVersion", "Daemon-vulkan version", Cvar::ROM, DAEMON_VULKAN_VERSION.FormatVersion() );
4749

4850
Cvar::Range<Cvar::Cvar<int>> r_vkCapabilityPack( "r_vkCapabilityPack", "CapabilityPack override",
4951
Cvar::NONE, CapabilityPackType::MINIMAL, CapabilityPackType::MINIMAL, CapabilityPackType::EXPERIMENTAL );
5052

51-
Cvar::Cvar<int> r_vkDevice( "r_vkDevice", "Use specific GPU (-1: auto)", Cvar::NONE, -1 );
53+
Cvar::Cvar<int> r_vkDevice( "r_vkDevice", "Use specific GPU (-1: auto)", Cvar::NONE, -1 );
54+
55+
Cvar::Cvar<int> r_displayIndex( "r_displayIndex", "Display index to create the window in", Cvar::NONE, 0 );
5256

5357
Cvar::Range<Cvar::Cvar<int>> r_vkPresentMode( "r_vkPresentMode",
5458
"Presentation mode: 0 - immediate, 1 - vsync on last frame, 2 - vsync on first new frame, "
5559
"3 - relaxed vsync on first new frame, 4 - vsync on the closest frame to scanout",
56-
Cvar::NONE, PresentMode::IMMEDIATE, PresentMode::IMMEDIATE, PresentMode::SCANOUT_SYNC_LATEST );
60+
Cvar::NONE, PresentMode::IMMEDIATE, PresentMode::IMMEDIATE, PresentMode::SCANOUT_SYNC_LATEST );
61+
62+
Cvar::Range<Cvar::Cvar<int>> r_mode( "r_mode",
63+
"Window mode: -2: use display size, -1: use r_customWidth / r_customHeight",
64+
Cvar::NONE, -2, -2, -1 );
65+
66+
Cvar::Cvar<int> r_customWidth( "r_customWidth", "Window width when using r_mode -1", Cvar::NONE, 1920 );
67+
Cvar::Cvar<int> r_customHeight( "r_customHeight", "Window height when using r_mode -1", Cvar::NONE, 1080 );
68+
69+
// Cvar::Cvar<bool> r_fullscreen( "r_fullscreen", "Fullscreen", Cvar::ARCHIVE, true );
70+
Cvar::Cvar<bool> r_noBorder( "r_noBorder", "Borderless window", Cvar::ARCHIVE, false );
71+
// Cvar::Cvar<bool> r_allowResize( "r_allowResize", "Resizable window", Cvar::ARCHIVE, false );
72+
73+
Cvar::Range<Cvar::Cvar<int>> r_vkGraphicsMaxMemory( "r_vkGraphicsMaxMemory",
74+
"Select memory allocation size for graphics engine; requires r_vkGraphicsMaxMemoryAuto",
75+
Cvar::NONE, EngineAllocator::minGraphicsMemorySize, EngineAllocator::minGraphicsMemorySize, EngineAllocator::maxGraphicsMemorySize );
76+
77+
Cvar::Cvar<bool> r_vkGraphicsMaxMemoryAuto( "r_vkGraphicsMaxMemoryAuto",
78+
"Automatically select memory allocation size based on available memory; use r_vkResourceSystemMaxMemory to set size manually",
79+
Cvar::NONE, true );

src/engine/renderer-vulkan/GraphicsCore/GraphicsCoreCVars.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3838

3939
#include "common/Common.h"
4040

41-
extern Cvar::Cvar<int> r_rendererAPI;
41+
#include "../Math/NumberTypes.h"
4242

43-
extern Cvar::Cvar<std::string> r_vkVersion;
43+
extern Cvar::Cvar<int> r_rendererAPI;
44+
45+
extern Cvar::Cvar<std::string> r_vkVersion;
4446

4547
extern Cvar::Range<Cvar::Cvar<int>> r_vkCapabilityPack;
4648

47-
extern Cvar::Cvar<int> r_vkDevice;
49+
extern Cvar::Cvar<int> r_vkDevice;
50+
51+
extern Cvar::Cvar<int> r_displayIndex;
4852

4953
extern Cvar::Range<Cvar::Cvar<int>> r_vkPresentMode;
54+
extern Cvar::Range<Cvar::Cvar<int>> r_mode;
55+
extern Cvar::Cvar<int> r_customWidth;
56+
extern Cvar::Cvar<int> r_customHeight;
57+
extern Cvar::Modified<Cvar::Cvar<bool>> r_fullscreen;
58+
extern Cvar::Cvar<bool> r_noBorder;
59+
// extern cvar_t* r_allowResize;
60+
61+
extern Cvar::Range<Cvar::Cvar<int>> r_vkGraphicsMaxMemory;
62+
extern Cvar::Cvar<bool> r_vkGraphicsMaxMemoryAuto;
5063

5164
#endif // GRAPHICS_CORE_CVARS_H

src/engine/renderer-vulkan/GraphicsCore/SwapChain.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static std::unordered_map<VkFormat, int, VkFormatHasher> surfaceFormatPriorities
6363
};
6464

6565
static VkSurfaceFormat2KHR SelectSurfaceFormat( DynamicArray<VkSurfaceFormat2KHR>& formats ) {
66-
VkFormat bestFormat = VK_FORMAT_UNDEFINED;
66+
VkFormat bestFormat = VK_FORMAT_UNDEFINED;
6767
VkSurfaceFormat2KHR* bestFmt = &formats[0];
6868

6969
for ( VkSurfaceFormat2KHR& format : formats ) {
@@ -79,7 +79,7 @@ static VkSurfaceFormat2KHR SelectSurfaceFormat( DynamicArray<VkSurfaceFormat2KHR
7979

8080
if ( surfaceFormatPriorities[surfaceFormat] > surfaceFormatPriorities[bestFormat] ) {
8181
bestFormat = surfaceFormat;
82-
bestFmt = &format;
82+
bestFmt = &format;
8383
}
8484
}
8585

@@ -106,6 +106,7 @@ static std::unordered_map<VkPresentModeKHR, uint32, VkPresentModeKHRHasher> pres
106106

107107
static VkPresentModeKHR SelectPresentMode( DynamicArray<VkPresentModeKHR>& presentModes ) {
108108
VkPresentModeKHR bestMode = presentModes[0];
109+
109110
for ( VkPresentModeKHR mode : presentModes ) {
110111
if ( mode == r_vkPresentMode.Get() ) {
111112
return mode;
@@ -127,7 +128,7 @@ void SwapChain::Init( const VkInstance instance ) {
127128

128129
#ifdef _MSC_VER
129130
VkSurfaceFullScreenExclusiveInfoEXT fullscreenInfo {
130-
.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT
131+
.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT
131132
};
132133

133134
surfaceInfo.pNext = &fullscreenInfo;
@@ -164,24 +165,36 @@ void SwapChain::Init( const VkInstance instance ) {
164165
}
165166

166167
VkSurfaceCapabilitiesKHR& capabilities = capabilities2.surfaceCapabilities;
167-
imageCount =
168+
const uint32 minImageCount =
168169
capabilities.minImageCount > 2
169-
? capabilities.minImageCount
170+
? capabilities.minImageCount
170171
: ( 2 <= capabilities.maxImageCount ? 2 : capabilities.maxImageCount );
171172

172173
minImages = capabilities.minImageCount;
173174
maxImages = capabilities.maxImageCount;
174175

176+
VkExtent2D swapChainSize;
177+
178+
switch ( r_mode.Get() ) {
179+
case -2:
180+
default:
181+
swapChainSize = capabilities.minImageExtent;
182+
break;
183+
case -1:
184+
swapChainSize = { ( uint32 ) r_customWidth.Get(), ( uint32 ) r_customHeight.Get() };
185+
break;
186+
}
187+
175188
VkSwapchainCreateInfoKHR swapChainInfo {
176-
.flags = 0,
189+
.flags = 0,
177190

178-
.surface = surface,
191+
.surface = surface,
179192

180-
.minImageCount = imageCount,
193+
.minImageCount = minImageCount,
181194
.imageFormat = format.surfaceFormat.format,
182195
.imageColorSpace = format.surfaceFormat.colorSpace,
183196

184-
.imageExtent = capabilities.minImageExtent,
197+
.imageExtent = swapChainSize,
185198
.imageArrayLayers = 1,
186199
.imageUsage = capabilities.supportedUsageFlags,
187200
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
@@ -193,10 +206,24 @@ void SwapChain::Init( const VkInstance instance ) {
193206

194207
.clipped = VK_TRUE,
195208

196-
.oldSwapchain = nullptr
209+
.oldSwapchain = nullptr
197210
};
198211

199212
vkCreateSwapchainKHR( device, &swapChainInfo, nullptr, &swapChain );
213+
214+
#ifdef _MSC_VER
215+
/* VkResult res = vkAcquireFullScreenExclusiveModeEXT( device, swapChain );
216+
217+
if ( res == VK_SUCCESS ) {
218+
Log::Notice( "SwapChain: acquired exclusive fullscreen" );
219+
} */
220+
#endif
221+
222+
vkGetSwapchainImagesKHR( device, swapChain, &imageCount, nullptr );
223+
224+
images.Resize( mainSwapChain.imageCount );
225+
226+
vkGetSwapchainImagesKHR( device, swapChain, &imageCount, images.memory );
200227
}
201228

202229
void SwapChain::Free() {

src/engine/renderer-vulkan/GraphicsCore/SwapChain.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4040

4141
#include "../Math/NumberTypes.h"
4242

43+
#include "../Memory/DynamicArray.h"
44+
4345
#include "GraphicsResource.h"
4446

4547
namespace PresentMode {
@@ -53,12 +55,14 @@ namespace PresentMode {
5355
}
5456

5557
struct SwapChain : public GraphicsResource {
56-
VkSurfaceKHR surface;
58+
VkSurfaceKHR surface;
5759
VkSwapchainKHR swapChain;
5860

59-
uint32 minImages;
60-
uint32 maxImages;
61-
uint32 imageCount;
61+
uint32 minImages;
62+
uint32 maxImages;
63+
uint32 imageCount;
64+
65+
DynamicArray<VkImage> images;
6266

6367
void Init( const VkInstance instance );
6468
void Free() override;

src/engine/renderer-vulkan/RefAPI.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4444
#include "Thread/ThreadMemory.h"
4545
#include "Thread/ThreadUplink.h"
4646

47-
Cvar::Modified<Cvar::Cvar<bool>> r_fullscreen( "r_fullscreen", "use full-screen window", CVAR_ARCHIVE, true );
48-
49-
cvar_t* r_allowResize;
50-
5147
// struct SDL_Window* window;
5248

5349
#include "Surface/Surface.h"
@@ -56,8 +52,13 @@ cvar_t* r_allowResize;
5652
#include "engine/framework/System.h"
5753
#include "Thread/SyncTask.h"
5854

55+
#include "GraphicsCore/GraphicsCoreCVars.h"
56+
5957
SDL_Window* window;
6058

59+
Cvar::Modified<Cvar::Cvar<bool>> r_fullscreen( "r_fullscreen", "Fullscreen", Cvar::ARCHIVE, true );
60+
cvar_t* r_allowResize;
61+
6162
static Cvar::Cvar<int> r_width( "r_width", "width", Cvar::NONE, 0 );
6263
static Cvar::Cvar<int> r_height( "r_height", "height", Cvar::NONE, 0 );
6364

src/engine/renderer-vulkan/Surface/Surface.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,78 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3535

3636
#include "engine/qcommon/q_shared.h"
3737

38+
#include "../GraphicsCore/GraphicsCoreCVars.h"
39+
3840
#include "Surface.h"
3941

4042
Surface::Surface() {
41-
window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, 1920, 1080, SDL_WINDOW_VULKAN );
4243
SDL_InitSubSystem( SDL_INIT_VIDEO );
44+
45+
// See the SDL wiki page for details: https://wiki.libsdl.org/SDL3/SDL_SetAppMetadataProperty
46+
SDL_SetAppMetadataProperty( SDL_PROP_APP_METADATA_NAME_STRING, PRODUCT_NAME );
47+
SDL_SetAppMetadataProperty( SDL_PROP_APP_METADATA_VERSION_STRING, PRODUCT_VERSION );
48+
SDL_SetAppMetadataProperty( SDL_PROP_APP_METADATA_TYPE_STRING, "game" );
49+
50+
/* Let X11 and Wayland desktops (Linux, FreeBSD…) associate the game
51+
window with the XDG .desktop file, with the proper name and icon.
52+
The .desktop file should have PRODUCT_APPID as base name or set the
53+
StartupWMClass variable to PRODUCT_APPID. */
54+
SDL_SetAppMetadataProperty( SDL_PROP_APP_METADATA_IDENTIFIER_STRING, PRODUCT_APPID );
55+
56+
/* Disable DPI scaling.
57+
See the SDL wiki page for details: https://wiki.libsdl.org/SDL3/SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY */
58+
SDL_SetHint( SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY, "1" );
59+
60+
int displayCount;
61+
SDL_DisplayID* displayIDs = SDL_GetDisplays( &displayCount );
62+
63+
if ( !displayIDs ) {
64+
Sys::Error( "SDL_GetDisplays failed: %s", SDL_GetError() );
65+
}
66+
67+
if ( displayCount <= 0 ) {
68+
Sys::Error( "SDL_GetDisplays returned 0 displays" );
69+
}
70+
71+
const int displayID = r_displayIndex.Get() >= 0 && r_displayIndex.Get() < displayCount ? displayIDs[r_displayIndex.Get()] : 0;
72+
73+
SDL_free( displayIDs );
74+
75+
int width;
76+
int height;
77+
const SDL_DisplayMode* displayMode = SDL_GetDesktopDisplayMode( displayID );
78+
79+
switch ( r_mode.Get() ) {
80+
case -2:
81+
default:
82+
width = displayMode->w;
83+
height = displayMode->h;
84+
85+
break;
86+
87+
case -1:
88+
width = r_customWidth.Get();
89+
height = r_customHeight.Get();
90+
break;
91+
}
92+
93+
SDL_WindowFlags flags = SDL_WINDOW_VULKAN;
94+
95+
if ( r_fullscreen.Get() ) {
96+
flags |= SDL_WINDOW_FULLSCREEN;
97+
} else if ( r_noBorder.Get() ) {
98+
flags |= SDL_WINDOW_BORDERLESS;
99+
}
100+
101+
/* if ( r_allowResize.Get() ) {
102+
flags |= SDL_WINDOW_RESIZABLE;
103+
} */
104+
105+
window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, width, height, flags );
106+
107+
if ( !window ) {
108+
Sys::Drop( "SDL: failed to create window" );
109+
}
43110
}
44111

45112
Surface::~Surface() {

0 commit comments

Comments
 (0)