Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GameDevWeek
Dependencies
Cpp
mirrage
Commits
20b2546f
Commit
20b2546f
authored
Dec 07, 2017
by
Florian Oetke
Browse files
added option for GPU selection
parent
a197ae55
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/mirrage/graphic/include/mirrage/graphic/settings.hpp
View file @
20b2546f
...
...
@@ -28,6 +28,7 @@ namespace mirrage::graphic {
struct
Graphics_settings
{
std
::
unordered_map
<
std
::
string
,
Window_settings
>
windows
;
std
::
string
gpu_preference
;
};
...
...
@@ -41,7 +42,9 @@ namespace mirrage::graphic {
return
settings
;
}
inline
constexpr
auto
make_version_number
(
std
::
uint32_t
major
,
std
::
uint32_t
minor
,
std
::
uint32_t
patch
)
{
inline
constexpr
auto
make_version_number
(
std
::
uint32_t
major
,
std
::
uint32_t
minor
,
std
::
uint32_t
patch
)
{
return
(((
major
)
<<
22
)
|
((
minor
)
<<
12
)
|
(
patch
));
}
...
...
@@ -49,6 +52,6 @@ namespace mirrage::graphic {
#ifdef sf2_structDef
sf2_enumDef
(
Fullscreen
,
no
,
yes
,
yes_borderless
);
sf2_structDef
(
Window_settings
,
width
,
height
,
display
,
fullscreen
);
sf2_structDef
(
Graphics_settings
,
windows
);
sf2_structDef
(
Graphics_settings
,
windows
,
gpu_preference
);
#endif
}
// namespace mirrage::graphic
src/mirrage/graphic/src/context.cpp
View file @
20b2546f
...
...
@@ -22,8 +22,8 @@ VkResult vkCreateDebugReportCallbackEXT(VkInstance
const
VkDebugReportCallbackCreateInfoEXT
*
pCreateInfo
,
const
VkAllocationCallbacks
*
pAllocator
,
VkDebugReportCallbackEXT
*
pCallback
)
{
auto
func
=
(
PFN_vkCreateDebugReportCallbackEXT
)
vkGetInstanceProcAddr
(
instance
,
"vkCreateDebugReportCallbackEXT"
);
auto
func
=
(
PFN_vkCreateDebugReportCallbackEXT
)
vkGetInstanceProcAddr
(
instance
,
"vkCreateDebugReportCallbackEXT"
);
if
(
func
!=
nullptr
)
{
return
func
(
instance
,
pCreateInfo
,
pAllocator
,
pCallback
);
}
else
{
...
...
@@ -59,7 +59,8 @@ namespace mirrage::graphic {
void
add_present_extensions
(
std
::
vector
<
const
char
*>&
extensions
)
{
auto
present_extensions
=
std
::
vector
<
const
char
*>
(
4
);
auto
present_extensions_size
=
static_cast
<
unsigned
int
>
(
present_extensions
.
size
());
if
(
!
SDL_GetVulkanInstanceExtensions
(
&
present_extensions_size
,
present_extensions
.
data
()))
{
if
(
!
SDL_GetVulkanInstanceExtensions
(
&
present_extensions_size
,
present_extensions
.
data
()))
{
MIRRAGE_FAIL
(
"Unable to determine present extensions: "
<<
SDL_GetError
());
}
...
...
@@ -71,7 +72,8 @@ namespace mirrage::graphic {
}
auto
check_extensions
(
const
std
::
vector
<
const
char
*>&
required
,
const
std
::
vector
<
const
char
*>&
optional
)
->
std
::
vector
<
const
char
*>
{
const
std
::
vector
<
const
char
*>&
optional
)
->
std
::
vector
<
const
char
*>
{
auto
extensions
=
std
::
vector
<
const
char
*>
();
extensions
.
reserve
(
required
.
size
()
+
optional
.
size
());
...
...
@@ -105,7 +107,8 @@ namespace mirrage::graphic {
}
if
(
!
all_supported
)
{
MIRRAGE_FAIL
(
"At least one required extension is not supported (see log for details)!"
);
MIRRAGE_FAIL
(
"At least one required extension is not supported (see log for details)!"
);
}
return
extensions
;
...
...
@@ -127,8 +130,9 @@ namespace mirrage::graphic {
}
if
(
!
layer_requested
)
{
MIRRAGE_DEBUG
(
"Additional validation layer is available, that hasn't been requested: "
<<
l
.
layerName
);
MIRRAGE_DEBUG
(
"Additional validation layer is available, that hasn't been requested: "
<<
l
.
layerName
);
}
}
...
...
@@ -236,7 +240,8 @@ namespace mirrage::graphic {
if
(
debug
)
{
_debug_callback
=
_instance
->
createDebugReportCallbackEXTUnique
(
{
/* vk::DebugReportFlagBitsEXT::eDebug | vk::DebugReportFlagBitsEXT::eInformation | */
vk
::
DebugReportFlagBitsEXT
::
eError
|
vk
::
DebugReportFlagBitsEXT
::
ePerformanceWarning
vk
::
DebugReportFlagBitsEXT
::
eError
|
vk
::
DebugReportFlagBitsEXT
::
ePerformanceWarning
|
vk
::
DebugReportFlagBitsEXT
::
eWarning
,
debugCallback
});
}
...
...
@@ -270,11 +275,13 @@ namespace mirrage::graphic {
settings
.
height
,
settings
.
fullscreen
);
}
auto
Context
::
_find_window_settings
(
const
std
::
string
&
name
,
int
width
,
int
height
)
->
Window_settings
{
auto
Context
::
_find_window_settings
(
const
std
::
string
&
name
,
int
width
,
int
height
)
->
Window_settings
{
auto
&
cfg
=
settings
();
auto
win_cfg
=
std
::
find_if
(
std
::
begin
(
cfg
.
windows
),
std
::
end
(
cfg
.
windows
),
[
&
](
auto
&
w
)
{
return
w
.
first
==
name
;
});
auto
win_cfg
=
std
::
find_if
(
std
::
begin
(
cfg
.
windows
),
std
::
end
(
cfg
.
windows
),
[
&
](
auto
&
w
)
{
return
w
.
first
==
name
;
});
if
(
win_cfg
==
std
::
end
(
cfg
.
windows
))
{
// no config create new
auto
new_settings
=
cfg
;
...
...
@@ -296,9 +303,10 @@ namespace mirrage::graphic {
namespace
{
bool
supports_present
(
vk
::
PhysicalDevice
&
gpu
,
const
std
::
vector
<
Window
*>&
can_present_to
)
{
auto
supported_extensions
=
gpu
.
enumerateDeviceExtensionProperties
();
auto
sc_ext
=
std
::
find_if
(
supported_extensions
.
begin
(),
supported_extensions
.
end
(),
[](
auto
&
e
)
{
return
std
::
strcmp
(
e
.
extensionName
,
VK_KHR_SWAPCHAIN_EXTENSION_NAME
)
==
0
;
});
auto
sc_ext
=
std
::
find_if
(
supported_extensions
.
begin
(),
supported_extensions
.
end
(),
[](
auto
&
e
)
{
return
std
::
strcmp
(
e
.
extensionName
,
VK_KHR_SWAPCHAIN_EXTENSION_NAME
)
==
0
;
});
if
(
sc_ext
==
supported_extensions
.
end
())
{
return
false
;
...
...
@@ -315,16 +323,18 @@ namespace mirrage::graphic {
return
true
;
}
auto
find_graphics_queue
(
vk
::
PhysicalDevice
&
gpu
,
const
std
::
vector
<
Window
*>&
can_present_to
)
auto
find_graphics_queue
(
vk
::
PhysicalDevice
&
gpu
,
const
std
::
vector
<
Window
*>&
can_present_to
)
->
util
::
maybe
<
std
::
uint32_t
>
{
auto
i
=
0
;
for
(
auto
&
queue_family
:
gpu
.
getQueueFamilyProperties
())
{
auto
can_present
=
can_present_to
.
empty
()
||
std
::
all_of
(
can_present_to
.
begin
(),
can_present_to
.
end
(),
[
&
](
auto
window
)
{
return
gpu
.
getSurfaceSupportKHR
(
i
,
window
->
surface
());
});
||
std
::
all_of
(
can_present_to
.
begin
(),
can_present_to
.
end
(),
[
&
](
auto
window
)
{
return
gpu
.
getSurfaceSupportKHR
(
i
,
window
->
surface
());
});
if
(
queue_family
.
queueCount
>
0
&&
can_present
&&
queue_family
.
timestampValidBits
...
...
@@ -346,7 +356,8 @@ namespace mirrage::graphic {
// check for transfer-only queue
for
(
auto
&
queue_family
:
families
)
{
if
(
queue_family
.
queueCount
>
0
&&
(
queue_family
.
queueFlags
&
vk
::
QueueFlagBits
::
eTransfer
)
if
(
queue_family
.
queueCount
>
0
&&
(
queue_family
.
queueFlags
&
vk
::
QueueFlagBits
::
eTransfer
)
&&
!
(
queue_family
.
queueFlags
&
vk
::
QueueFlagBits
::
eGraphics
))
{
return
i
;
}
...
...
@@ -386,15 +397,17 @@ namespace mirrage::graphic {
return
{
target_format
,
target_space
};
}
opt_found
=
std
::
find_if
(
formats
.
begin
(),
formats
.
end
(),
[
&
](
auto
&
f
)
{
return
f
.
format
==
target_format
;
});
opt_found
=
std
::
find_if
(
formats
.
begin
(),
formats
.
end
(),
[
&
](
auto
&
f
)
{
return
f
.
format
==
target_format
;
});
if
(
opt_found
!=
formats
.
end
())
{
return
*
opt_found
;
}
if
(
!
formats
.
empty
())
{
MIRRAGE_WARN
(
"Requested format is not supported by the device, fallback to first reported "
"Requested format is not supported by the device, fallback to first "
"reported "
"format"
);
return
formats
.
front
();
}
else
{
...
...
@@ -419,14 +432,16 @@ namespace mirrage::graphic {
sc_info
.
setImageUsage
(
vk
::
ImageUsageFlagBits
::
eColorAttachment
);
sc_info
.
setImageArrayLayers
(
1
);
sc_info
.
setMinImageCount
(
std
::
max
(
2u
,
capabilities
.
minImageCount
));
if
(
capabilities
.
maxImageCount
>
0
&&
capabilities
.
maxImageCount
<
sc_info
.
minImageCount
)
{
if
(
capabilities
.
maxImageCount
>
0
&&
capabilities
.
maxImageCount
<
sc_info
.
minImageCount
)
{
sc_info
.
setMinImageCount
(
capabilities
.
maxImageCount
);
}
auto
present_modes
=
gpu
.
getSurfacePresentModesKHR
(
window
->
surface
());
auto
mailbox_supported
=
std
::
find
(
present_modes
.
begin
(),
present_modes
.
end
(),
vk
::
PresentModeKHR
::
eMailbox
)
!=
present_modes
.
end
();
auto
present_modes
=
gpu
.
getSurfacePresentModesKHR
(
window
->
surface
());
auto
mailbox_supported
=
std
::
find
(
present_modes
.
begin
(),
present_modes
.
end
(),
vk
::
PresentModeKHR
::
eMailbox
)
!=
present_modes
.
end
();
if
(
mailbox_supported
)
{
sc_info
.
setPresentMode
(
vk
::
PresentModeKHR
::
eMailbox
);
}
else
{
...
...
@@ -447,11 +462,11 @@ namespace mirrage::graphic {
sc_info
.
setImageExtent
(
capabilities
.
currentExtent
);
auto
format
=
find_surface_format
(
gpu
,
*
window
,
srgb
?
vk
::
Format
::
eB8G8R8A8Srgb
:
vk
::
Format
::
eB8G8R8A8Unorm
,
vk
::
ColorSpaceKHR
::
eSrgbNonlinear
);
auto
format
=
find_surface_format
(
gpu
,
*
window
,
srgb
?
vk
::
Format
::
eB8G8R8A8Srgb
:
vk
::
Format
::
eB8G8R8A8Unorm
,
vk
::
ColorSpaceKHR
::
eSrgbNonlinear
);
sc_info
.
setImageFormat
(
format
.
format
);
sc_info
.
setImageColorSpace
(
format
.
colorSpace
);
...
...
@@ -477,6 +492,14 @@ namespace mirrage::graphic {
auto
graphics_queue
=
find_graphics_queue
(
gpu
,
can_present_to
);
auto
score
=
selector
(
gpu
,
graphics_queue
);
auto
gpu_name
=
std
::
string
(
gpu
.
getProperties
().
deviceName
);
MIRRAGE_INFO
(
"Detected GPU: "
<<
gpu_name
);
if
(
!
_settings
->
gpu_preference
.
empty
()
&&
_settings
->
gpu_preference
==
gpu_name
)
{
score
=
std
::
numeric_limits
<
int
>::
max
();
}
if
(
score
>
top_score
)
{
top_score
=
score
;
top_gpu
=
gpu
;
...
...
@@ -487,6 +510,8 @@ namespace mirrage::graphic {
MIRRAGE_FAIL
(
"Couldn't find a GPU that supports vulkan and all required features."
);
}
MIRRAGE_INFO
(
"Selected GPU: "
<<
top_gpu
.
getProperties
().
deviceName
);
auto
cfg
=
vk
::
DeviceCreateInfo
{};
cfg
.
setEnabledLayerCount
(
gsl
::
narrow
<
uint32_t
>
(
_enabled_layers
.
size
()));
cfg
.
setPpEnabledLayerNames
(
_enabled_layers
.
data
());
...
...
@@ -495,9 +520,9 @@ namespace mirrage::graphic {
auto
supported_extensions
=
top_gpu
.
enumerateDeviceExtensionProperties
();
auto
extension_supported
=
[
&
](
const
char
*
e
)
{
return
supported_extensions
.
end
()
!=
std
::
find_if
(
supported_extensions
.
begin
(),
supported_extensions
.
end
(),
[
&
](
auto
&
se
)
{
return
!
strcmp
(
se
.
extensionName
,
e
);
});
!=
std
::
find_if
(
supported_extensions
.
begin
(),
supported_extensions
.
end
(),
[
&
](
auto
&
se
)
{
return
!
strcmp
(
se
.
extensionName
,
e
);
});
};
auto
dedicated_alloc_supported
=
false
;
...
...
@@ -554,7 +579,8 @@ namespace mirrage::graphic {
auto
used_queues
=
std
::
vector
<
vk
::
DeviceQueueCreateInfo
>
{};
used_queues
.
reserve
(
queue_families
.
size
());
for
(
auto
&
qf
:
queue_families
)
{
MIRRAGE_INVARIANT
(
std
::
get
<
1
>
(
qf
.
second
).
size
()
==
std
::
get
<
0
>
(
qf
.
second
),
"Size mismatch"
);
MIRRAGE_INVARIANT
(
std
::
get
<
1
>
(
qf
.
second
).
size
()
==
std
::
get
<
0
>
(
qf
.
second
),
"Size mismatch"
);
used_queues
.
emplace_back
(
vk
::
DeviceQueueCreateFlags
(),
qf
.
first
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment