Vulkan: Generate Correct GLSL After Changing Workarounds
During normal execution it isn't possible to switch workarounds. However when running test cases we want to check if shaders and other tests work when work arounds are enabled. Currently shader patches are cached globally. This PR moves the cached shader patch to the device level which is rebuild every time a device needs to be reinitialized. For OpenGL this is also an issue, but harder to solve as the concept device doesn't exist there. Pull Request: https://projects.blender.org/blender/blender/pulls/116042
This commit is contained in:
@@ -6,19 +6,25 @@
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "vk_device.hh"
|
||||
#include <sstream>
|
||||
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_device.hh"
|
||||
#include "vk_memory.hh"
|
||||
#include "vk_state_manager.hh"
|
||||
#include "vk_storage_buffer.hh"
|
||||
#include "vk_texture.hh"
|
||||
#include "vk_vertex_buffer.hh"
|
||||
|
||||
#include "GPU_capabilities.h"
|
||||
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
extern "C" char datatoc_glsl_shader_defines_glsl[];
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
void VKDevice::deinit()
|
||||
@@ -48,6 +54,7 @@ void VKDevice::deinit()
|
||||
vk_queue_family_ = 0;
|
||||
vk_queue_ = VK_NULL_HANDLE;
|
||||
vk_physical_device_properties_ = {};
|
||||
glsl_patch_.clear();
|
||||
}
|
||||
|
||||
bool VKDevice::is_initialized() const
|
||||
@@ -79,6 +86,7 @@ void VKDevice::init(void *ghost_context)
|
||||
|
||||
debug::object_label(device_get(), "LogicalDevice");
|
||||
debug::object_label(queue_get(), "GenericQueue");
|
||||
init_glsl_patch();
|
||||
}
|
||||
|
||||
void VKDevice::init_debug_callbacks()
|
||||
@@ -161,6 +169,45 @@ void VKDevice::init_dummy_color_attachment()
|
||||
dummy_color_attachment_ = std::make_optional(std::reference_wrapper(vk_texture));
|
||||
}
|
||||
|
||||
void VKDevice::init_glsl_patch()
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "#version 450\n";
|
||||
if (GPU_shader_draw_parameters_support()) {
|
||||
ss << "#extension GL_ARB_shader_draw_parameters : enable\n";
|
||||
ss << "#define GPU_ARB_shader_draw_parameters\n";
|
||||
ss << "#define gpu_BaseInstance (gl_BaseInstanceARB)\n";
|
||||
}
|
||||
|
||||
ss << "#define gl_VertexID gl_VertexIndex\n";
|
||||
ss << "#define gpu_InstanceIndex (gl_InstanceIndex)\n";
|
||||
ss << "#define GPU_ARB_texture_cube_map_array\n";
|
||||
ss << "#define gl_InstanceID (gpu_InstanceIndex - gpu_BaseInstance)\n";
|
||||
|
||||
/* TODO(fclem): This creates a validation error and should be already part of Vulkan 1.2. */
|
||||
ss << "#extension GL_ARB_shader_viewport_layer_array: enable\n";
|
||||
if (!workarounds_.shader_output_layer) {
|
||||
ss << "#define gpu_Layer gl_Layer\n";
|
||||
}
|
||||
if (!workarounds_.shader_output_viewport_index) {
|
||||
ss << "#define gpu_ViewportIndex gl_ViewportIndex\n";
|
||||
}
|
||||
|
||||
ss << "#define DFDX_SIGN 1.0\n";
|
||||
ss << "#define DFDY_SIGN 1.0\n";
|
||||
|
||||
/* GLSL Backend Lib. */
|
||||
ss << datatoc_glsl_shader_defines_glsl;
|
||||
glsl_patch_ = ss.str();
|
||||
}
|
||||
|
||||
const char *VKDevice::glsl_patch_get() const
|
||||
{
|
||||
BLI_assert(!glsl_patch_.empty());
|
||||
return glsl_patch_.c_str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Platform/driver/device information
|
||||
* \{ */
|
||||
|
||||
@@ -104,6 +104,8 @@ class VKDevice : public NonCopyable {
|
||||
Vector<VkFramebuffer> discarded_frame_buffers_;
|
||||
Vector<VkImageView> discarded_image_views_;
|
||||
|
||||
std::string glsl_patch_;
|
||||
|
||||
public:
|
||||
VkPhysicalDevice physical_device_get() const
|
||||
{
|
||||
@@ -196,6 +198,9 @@ class VKDevice : public NonCopyable {
|
||||
return workarounds_;
|
||||
}
|
||||
|
||||
const char *glsl_patch_get() const;
|
||||
void init_glsl_patch();
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Resource management
|
||||
* \{ */
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
using namespace blender::gpu::shader;
|
||||
|
||||
extern "C" char datatoc_glsl_shader_defines_glsl[];
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -487,49 +485,6 @@ static const std::string to_stage_name(shaderc_shader_kind stage)
|
||||
return std::string("unknown stage");
|
||||
}
|
||||
|
||||
static char *glsl_patch_get()
|
||||
{
|
||||
static char patch[2048] = "\0";
|
||||
if (patch[0] != '\0') {
|
||||
return patch;
|
||||
}
|
||||
|
||||
const VKWorkarounds &workarounds = VKBackend::get().device_get().workarounds_get();
|
||||
|
||||
size_t slen = 0;
|
||||
/* Version need to go first. */
|
||||
STR_CONCAT(patch, slen, "#version 450\n");
|
||||
|
||||
if (GPU_shader_draw_parameters_support()) {
|
||||
STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n");
|
||||
STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n");
|
||||
STR_CONCAT(patch, slen, "#define gpu_BaseInstance (gl_BaseInstanceARB)\n");
|
||||
}
|
||||
|
||||
STR_CONCAT(patch, slen, "#define gl_VertexID gl_VertexIndex\n");
|
||||
STR_CONCAT(patch, slen, "#define gpu_InstanceIndex (gl_InstanceIndex)\n");
|
||||
STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n");
|
||||
STR_CONCAT(patch, slen, "#define gl_InstanceID (gpu_InstanceIndex - gpu_BaseInstance)\n");
|
||||
|
||||
/* TODO(fclem): This creates a validation error and should be already part of Vulkan 1.2. */
|
||||
STR_CONCAT(patch, slen, "#extension GL_ARB_shader_viewport_layer_array: enable\n");
|
||||
if (!workarounds.shader_output_layer) {
|
||||
STR_CONCAT(patch, slen, "#define gpu_Layer gl_Layer\n");
|
||||
}
|
||||
if (!workarounds.shader_output_viewport_index) {
|
||||
STR_CONCAT(patch, slen, "#define gpu_ViewportIndex gl_ViewportIndex\n");
|
||||
}
|
||||
|
||||
STR_CONCAT(patch, slen, "#define DFDX_SIGN 1.0\n");
|
||||
STR_CONCAT(patch, slen, "#define DFDY_SIGN 1.0\n");
|
||||
|
||||
/* GLSL Backend Lib. */
|
||||
STR_CONCAT(patch, slen, datatoc_glsl_shader_defines_glsl);
|
||||
|
||||
BLI_assert(slen < sizeof(patch));
|
||||
return patch;
|
||||
}
|
||||
|
||||
static std::string combine_sources(Span<const char *> sources)
|
||||
{
|
||||
char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size());
|
||||
@@ -641,7 +596,8 @@ void VKShader::build_shader_module(MutableSpan<const char *> sources,
|
||||
shaderc_fragment_shader,
|
||||
shaderc_compute_shader),
|
||||
"Only forced ShaderC shader kinds are supported.");
|
||||
sources[0] = glsl_patch_get();
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
sources[0] = device.glsl_patch_get();
|
||||
Vector<uint32_t> spirv_module = compile_glsl_to_spirv(sources, stage);
|
||||
build_shader_module(spirv_module, r_shader_module);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user