Skip to content

Commit 8aca6e2

Browse files
committed
Support layer: Add robustBufferAccess overrides
1 parent 8712e51 commit 8aca6e2

File tree

5 files changed

+190
-3
lines changed

5 files changed

+190
-3
lines changed

layer_gpu_support/layer_config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
22
"layer": "VK_LAYER_LGL_gpu_support",
3+
"feature": {
4+
"robustBufferAccess_enable": false,
5+
"robustBufferAccess_disable": false
6+
},
37
"serialize": {
48
"all": false,
59
"none": false,

layer_gpu_support/source/device.cpp

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,17 @@
3535
*/
3636
static std::unordered_map<void*, std::unique_ptr<Device>> g_devices;
3737

38+
/* Predeclare custom DeviceCreatePatch functions */
39+
static void modifyDeviceRobustBufferAccess(Instance& instance,
40+
VkPhysicalDevice physicalDevice,
41+
vku::safe_VkDeviceCreateInfo& createInfo,
42+
std::vector<std::string>& supported);
43+
3844
/* See header for documentation. */
3945
const std::vector<DeviceCreatePatchPtr> Device::createInfoPatches {
4046
enableDeviceVkKhrTimelineSemaphore,
41-
enableDeviceVkExtImageCompressionControl
47+
enableDeviceVkExtImageCompressionControl,
48+
modifyDeviceRobustBufferAccess
4249
};
4350

4451
/* See header for documentation. */
@@ -112,3 +119,95 @@ Device::Device(Instance* _instance,
112119
queueSerializationTimelineSem = nullptr;
113120
}
114121
}
122+
123+
/**
124+
* Allow a force enable/disable of robustBufferAccess feature.
125+
*
126+
* @param instance The layer instance we are running within.
127+
* @param physicalDevice The physical device we are creating a device for.
128+
* @param createInfo The createInfo we can search to find user config.
129+
* @param supported The list of supported extensions.
130+
*/
131+
static void modifyDeviceRobustBufferAccess(Instance& instance,
132+
VkPhysicalDevice physicalDevice,
133+
vku::safe_VkDeviceCreateInfo& createInfo,
134+
std::vector<std::string>& supported)
135+
{
136+
UNUSED(supported);
137+
138+
// Only one of these can be set as an override
139+
// If neither are set then don't change the app settings
140+
bool enableRobustness = instance.config.feature_enable_robustBufferAccess();
141+
bool disableRobustness = instance.config.feature_disable_robustBufferAccess();
142+
143+
// No patch to apply
144+
if (!enableRobustness && !disableRobustness)
145+
{
146+
return;
147+
}
148+
149+
// Query if robustness is supported if we need to force enable
150+
VkPhysicalDeviceFeatures supportedFeatures;
151+
instance.driver.vkGetPhysicalDeviceFeatures(physicalDevice, &supportedFeatures);
152+
if (enableRobustness && !supportedFeatures.robustBufferAccess)
153+
{
154+
LAYER_LOG("Device feature not available: robustBufferAccess");
155+
return;
156+
}
157+
158+
// We know we can const_cast here because createInfo is a safe-struct clone
159+
// Option1 = legacy-style enable
160+
auto* config = const_cast<VkPhysicalDeviceFeatures*>(createInfo.pEnabledFeatures);
161+
162+
// Option2 = modern-style enable
163+
void* pNextBase = const_cast<void*>(createInfo.pNext);
164+
auto* configNext = vku::FindStructInPNextChain<VkPhysicalDeviceFeatures2>(pNextBase);
165+
166+
// Pick the feature struct from either of the valid options
167+
if (!config && configNext)
168+
{
169+
config = &configNext->features;
170+
}
171+
172+
// User provided feature enable struct, so just change that directly
173+
if (config)
174+
{
175+
if (enableRobustness)
176+
{
177+
if(config->robustBufferAccess)
178+
{
179+
LAYER_LOG("Device feature already enabled: robustBufferAccess");
180+
}
181+
else
182+
{
183+
LAYER_LOG("Device feature enabled: robustBufferAccess");
184+
config->robustBufferAccess = VK_TRUE;
185+
}
186+
}
187+
if (disableRobustness)
188+
{
189+
if(!config->robustBufferAccess)
190+
{
191+
LAYER_LOG("Device feature already disabled: robustBufferAccess");
192+
}
193+
194+
LAYER_LOG("Device feature disabled: robustBufferAccess");
195+
config->robustBufferAccess = VK_FALSE;
196+
}
197+
}
198+
// User provided no feature enables, so provide our own structure
199+
else if (enableRobustness)
200+
{
201+
LAYER_LOG("Device feature enabled: robustBufferAccess");
202+
203+
// Create a dynamic copy and transfer ownership to the safe-struct
204+
auto* newFeatures = new VkPhysicalDeviceFeatures;
205+
memset(newFeatures, 0, sizeof(VkPhysicalDeviceFeatures));
206+
createInfo.pEnabledFeatures = newFeatures;
207+
}
208+
// User provided no feature enables, but we don't need one
209+
else if (disableRobustness)
210+
{
211+
LAYER_LOG("Device feature already disabled: robustBufferAccess");
212+
}
213+
}

layer_gpu_support/source/device.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,13 @@
5454

5555
#include <string>
5656
#include <vector>
57+
5758
#include <vulkan/utility/vk_safe_struct.hpp>
5859
#include <vulkan/vk_layer.h>
5960

6061
#include "framework/device_dispatch_table.hpp"
6162
#include "instance.hpp"
6263

63-
64-
6564
/**
6665
* @brief Function pointer type for patching VkDeviceCreateInfo.
6766
*/

layer_gpu_support/source/layer_config.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,37 @@
3737

3838
#include <vulkan/vulkan.h>
3939

40+
/* See header for documentation. */
41+
void LayerConfig::parse_feature_options(const json& config)
42+
{
43+
// Decode serialization state
44+
json feature = config.at("feature");
45+
46+
bool enable_rba = feature.at("robustBufferAccess_enable");
47+
bool disable_rba = feature.at("robustBufferAccess_disable");
48+
49+
const char* rba_state = "default";
50+
if (enable_rba)
51+
{
52+
rba_state = "enabled";
53+
// Ensure we only set one option
54+
disable_rba = false;
55+
}
56+
else if (disable_rba)
57+
{
58+
rba_state = "disabled";
59+
}
60+
61+
// Write after all options read from JSON so we know it parsed correctly
62+
conf_feat_robustBufferAccess_enable = enable_rba;
63+
conf_feat_robustBufferAccess_disable = disable_rba;
64+
65+
LAYER_LOG("Layer feature configuration");
66+
LAYER_LOG("===========================");
67+
LAYER_LOG(" - Robust buffer access: %s", rba_state);
68+
}
69+
70+
4071
/* See header for documentation. */
4172
void LayerConfig::parse_serialization_options(const json& config)
4273
{
@@ -238,6 +269,17 @@ LayerConfig::LayerConfig()
238269
return;
239270
}
240271

272+
try
273+
{
274+
parse_feature_options(data);
275+
}
276+
catch (const json::out_of_range& e)
277+
{
278+
LAYER_ERR("Failed to read feature config, using defaults");
279+
LAYER_ERR("Error: %s", e.what());
280+
}
281+
282+
241283
try
242284
{
243285
parse_serialization_options(data);
@@ -269,6 +311,18 @@ LayerConfig::LayerConfig()
269311
}
270312
}
271313

314+
/* See header for documentation. */
315+
bool LayerConfig::feature_enable_robustBufferAccess() const
316+
{
317+
return conf_feat_robustBufferAccess_enable;
318+
}
319+
320+
/* See header for documentation. */
321+
bool LayerConfig::feature_disable_robustBufferAccess() const
322+
{
323+
return conf_feat_robustBufferAccess_disable;
324+
}
325+
272326
/* See header for documentation. */
273327
bool LayerConfig::serialize_queue() const
274328
{

layer_gpu_support/source/layer_config.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ class LayerConfig
4949
*/
5050
LayerConfig();
5151

52+
// Config queries for features
53+
54+
/**
55+
* @brief True if config wants to serialize across queue submits.
56+
*/
57+
bool feature_enable_robustBufferAccess() const;
58+
59+
/**
60+
* @brief True if config wants to serialize queue submits with the CPU.
61+
*/
62+
bool feature_disable_robustBufferAccess() const;
63+
5264
// Config queries for serializer
5365

5466
/**
@@ -154,6 +166,15 @@ class LayerConfig
154166
uint32_t framebuffer_force_fixed_rate_compression() const;
155167

156168
private:
169+
/**
170+
* @brief Parse the configuration options for the feature module.
171+
*
172+
* @param config The JSON configuration.
173+
*
174+
* @throws json::out_of_bounds if required fields are missing.
175+
*/
176+
void parse_feature_options(const json& config);
177+
157178
/**
158179
* @brief Parse the configuration options for the serializer.
159180
*
@@ -182,6 +203,16 @@ class LayerConfig
182203
void parse_framebuffer_options(const json& config);
183204

184205
private:
206+
/**
207+
* @brief True if we force enable robustBufferAccess.
208+
*/
209+
bool conf_feat_robustBufferAccess_enable {false};
210+
211+
/**
212+
* @brief True if we force disable robustBufferAccess.
213+
*/
214+
bool conf_feat_robustBufferAccess_disable {false};
215+
185216
/**
186217
* @brief True if we force serialize all queue submits.
187218
*/

0 commit comments

Comments
 (0)