Skip to content

Commit

Permalink
Add shader overrides to the support layer (#59)
Browse files Browse the repository at this point in the history
Adds new options to the support layer for:

* Disabling use of pipeline caches.
* Disable use of relaxed precision
* Enable SPIR-V fuzzing to force a cache miss.
  • Loading branch information
solidpixel authored Jan 23, 2025
1 parent 236cf49 commit 2cfe443
Show file tree
Hide file tree
Showing 7 changed files with 548 additions and 1 deletion.
15 changes: 15 additions & 0 deletions layer_gpu_support/README_LAYER.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ irrespective of other settings.
}
```

## Shaders and Pipelines

The shaders and pipelines override allows some control over how the shader
compiler handles compilation tasks.

#### Configuration options

```jsonc
"shader": {
"disable_cache": false, // Disable use of binary caches
"disable_relaxed_precision": false, // Disable use of relaxed precision decoration
"enable_spirv_fuzz": false // Enable SPIR-V fuzzing to change binary hash
}
```

- - -

_Copyright © 2025, Arm Limited and contributors._
5 changes: 5 additions & 0 deletions layer_gpu_support/layer_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@
}
},
"queue": false
},
"shader": {
"disable_cache": false,
"disable_relaxed_precision": false,
"enable_spirv_fuzz": false
}
}
1 change: 1 addition & 0 deletions layer_gpu_support/source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ add_library(
instance.cpp
layer_config.cpp
layer_device_functions_dispatch.cpp
layer_device_functions_pipelines.cpp
layer_device_functions_queue.cpp
layer_device_functions_render_pass.cpp
layer_device_functions_trace_rays.cpp
Expand Down
52 changes: 52 additions & 0 deletions layer_gpu_support/source/layer_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void LayerConfig::parse_serialization_options(
bool s_stream_tx_pre = s_stream.at("transfer").at("pre");
bool s_stream_tx_post = s_stream.at("transfer").at("post");

// Write after all options read from JSON so we know it parsed correctly
serialize_queues = (!s_none) && (s_all || s_queue);
serialize_dispatch_pre = (!s_none) && (s_all || s_stream_c_pre);
serialize_dispatch_post = (!s_none) && (s_all || s_stream_c_post);
Expand All @@ -86,6 +87,29 @@ void LayerConfig::parse_serialization_options(
LAYER_LOG(" - Serialize transfer post: %d", serialize_transfer_post);
}

/* See header for documentation. */
void LayerConfig::parse_shader_options(
const json& config
) {
// Decode serialization state
json shader = config.at("shader");

bool disable_program_cache = shader.at("disable_cache");
bool disable_program_relaxed_precision = shader.at("disable_relaxed_precision");
bool enable_program_fuzz_spirv_hash = shader.at("enable_spirv_fuzz");

// Write after all options read from JSON so we know it parsed correctly
shader_disable_program_cache = disable_program_cache;
shader_disable_program_relaxed_precision = disable_program_relaxed_precision;
shader_enable_program_fuzz_spirv_hash = enable_program_fuzz_spirv_hash;

LAYER_LOG("Layer shader configuration");
LAYER_LOG("==========================");
LAYER_LOG(" - Disable binary cache: %d", shader_disable_program_cache);
LAYER_LOG(" - Disable relaxed precision %d", shader_disable_program_relaxed_precision);
LAYER_LOG(" - Enable SPIR-V hash fuzzer: %d", shader_enable_program_fuzz_spirv_hash);
}

/* See header for documentation. */
LayerConfig::LayerConfig()
{
Expand Down Expand Up @@ -128,6 +152,16 @@ LayerConfig::LayerConfig()
LAYER_ERR("Failed to read serialization config, using defaults");
LAYER_ERR("Error: %s", e.what());
}

try
{
parse_shader_options(data);
}
catch(const json::out_of_range& e)
{
LAYER_ERR("Failed to read shader config, using defaults");
LAYER_ERR("Error: %s", e.what());
}
}

/* See header for documentation. */
Expand Down Expand Up @@ -183,3 +217,21 @@ bool LayerConfig::serialize_cmdstream_transfer_post() const
{
return serialize_transfer_post;
}

/* See header for documentation. */
bool LayerConfig::shader_disable_cache() const
{
return shader_disable_program_cache;
}

/* See header for documentation. */
bool LayerConfig::shader_disable_relaxed_precision() const
{
return shader_disable_program_relaxed_precision;
}

/* See header for documentation. */
bool LayerConfig::shader_fuzz_spirv_hash() const
{
return shader_enable_program_fuzz_spirv_hash;
}
45 changes: 44 additions & 1 deletion layer_gpu_support/source/layer_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class LayerConfig
*/
LayerConfig();

// Config queries for serializer

/**
* @brief True if config wants to serialize before compute workloads.
*/
Expand Down Expand Up @@ -94,16 +96,42 @@ class LayerConfig
*/
bool serialize_cmdstream_transfer_post() const;

// Config queries for shaders

/**
* @brief True if config wants to disable shader caching.
*/
bool shader_disable_cache() const;

/**
* @brief True if config wants to disable use of relaxed precision.
*/
bool shader_disable_relaxed_precision() const;

/**
* @brief True if config wants to enable SPIR-V hash fuzzing.
*/
bool shader_fuzz_spirv_hash() const;

private:
/**
* @brief Parse the serialization options for the serializer.
* @brief Parse the configuration options for the serializer.
*
* @param config The JSON configuration.
*
* @throws json::out_of_bounds if required fields are missing.
*/
void parse_serialization_options(const json& config);

/**
* @brief Parse the configuration options for the shader module.
*
* @param config The JSON configuration.
*
* @throws json::out_of_bounds if required fields are missing.
*/
void parse_shader_options(const json& config);

private:
/**
* @brief True if we force serialize across queues.
Expand Down Expand Up @@ -149,4 +177,19 @@ class LayerConfig
* @brief True if we force serialize after transfer workloads.
*/
bool serialize_transfer_post { false };

/**
* @brief True if we force disable executable binary caching.
*/
bool shader_disable_program_cache { false };

/**
* @brief True if we force remove use of relaxed precision decoration.
*/
bool shader_disable_program_relaxed_precision { false };

/**
* @brief True if we change SPIR-V to change the program hash.
*/
bool shader_enable_program_fuzz_spirv_hash { false };
};
58 changes: 58 additions & 0 deletions layer_gpu_support/source/layer_device_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,61 @@ VKAPI_ATTR VkResult VKAPI_CALL layer_vkQueueSubmit2KHR<user_tag>(
uint32_t submitCount,
const VkSubmitInfo2* pSubmits,
VkFence fence);

// Functions for pipelines

/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateShaderModule<user_tag>(
VkDevice device,
const VkShaderModuleCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkShaderModule* pShaderModule);

/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateShadersEXT<user_tag>(
VkDevice device,
uint32_t createInfoCount,
const VkShaderCreateInfoEXT* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkShaderEXT* pShaders);


/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkGetPipelineKeyKHR<user_tag>(
VkDevice device,
const VkPipelineCreateInfoKHR* pPipelineCreateInfo,
VkPipelineBinaryKeyKHR* pPipelineKey);

/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateComputePipelines<user_tag>(
VkDevice device,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkComputePipelineCreateInfo* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);

/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateGraphicsPipelines<user_tag>(
VkDevice device,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkGraphicsPipelineCreateInfo* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);

/* See Vulkan API for documentation. */
template<>
VKAPI_ATTR VkResult VKAPI_CALL layer_vkCreateRayTracingPipelinesKHR<user_tag>(
VkDevice device,
VkDeferredOperationKHR deferredOperation,
VkPipelineCache pipelineCache,
uint32_t createInfoCount,
const VkRayTracingPipelineCreateInfoKHR* pCreateInfos,
const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines);
Loading

0 comments on commit 2cfe443

Please sign in to comment.