Vulkan: Fix image bind space collision
EEVEE Eval light shader could still make a collision between texture and image bind space making rendering glitch when not using `--debug-gpu`. The problem was that the bind space wasn't aware of the offset that the shader interface was using. Pull Request: https://projects.blender.org/blender/blender/pulls/124140
This commit is contained in:
@@ -85,11 +85,22 @@ class VKBindableResource {
|
||||
void unbind_from_all_contexts();
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset when searching for bindings.
|
||||
*
|
||||
* When shaders combine images and samplers, the images have to be offset to find the correct
|
||||
* shader input. Both textures and images are stored in the uniform list and their ID can be
|
||||
* overlapping.
|
||||
*/
|
||||
static constexpr int BIND_SPACE_IMAGE_OFFSET = 512;
|
||||
|
||||
/**
|
||||
* Blender binds resources at context level (VKStateManager). The bindings are organized in
|
||||
* namespaces.
|
||||
*/
|
||||
template<shader::ShaderCreateInfo::Resource::BindType BindType> class VKBindSpace {
|
||||
template<shader::ShaderCreateInfo::Resource::BindType BindType, int BindOffset = 0>
|
||||
class VKBindSpace {
|
||||
static constexpr int offset = BindOffset;
|
||||
class ResourceBinding {
|
||||
public:
|
||||
int binding;
|
||||
@@ -103,10 +114,11 @@ template<shader::ShaderCreateInfo::Resource::BindType BindType> class VKBindSpac
|
||||
/**
|
||||
* Register a binding to this namespace.
|
||||
*/
|
||||
void bind(int binding,
|
||||
void bind(int binding_,
|
||||
VKBindableResource &resource,
|
||||
const GPUSamplerState sampler_state = GPUSamplerState::default_sampler())
|
||||
{
|
||||
int binding = binding_ >= offset ? binding_ : binding_ + offset;
|
||||
for (ResourceBinding &bind : bindings_) {
|
||||
if (bind.binding == binding) {
|
||||
bind.resource = &resource;
|
||||
|
||||
@@ -16,7 +16,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
{
|
||||
static char PUSH_CONSTANTS_FALLBACK_NAME[] = "push_constants_fallback";
|
||||
static size_t PUSH_CONSTANTS_FALLBACK_NAME_LEN = strlen(PUSH_CONSTANTS_FALLBACK_NAME);
|
||||
static char SUBPASS_FALLBACK_NAME[] = "gpu_sybpass_img_0";
|
||||
static char SUBPASS_FALLBACK_NAME[] = "gpu_subpass_img_0";
|
||||
static size_t SUBPASS_FALLBACK_NAME_LEN = strlen(SUBPASS_FALLBACK_NAME);
|
||||
|
||||
using namespace blender::gpu::shader;
|
||||
@@ -113,7 +113,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
}
|
||||
else if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) {
|
||||
copy_input_name(input, res.image.name, name_buffer_, name_buffer_offset);
|
||||
input->location = input->binding = res.slot + image_offset;
|
||||
input->location = input->binding = res.slot + BIND_SPACE_IMAGE_OFFSET;
|
||||
input++;
|
||||
}
|
||||
}
|
||||
@@ -395,7 +395,8 @@ const ShaderInput *VKShaderInterface::shader_input_get(
|
||||
/* Not really nice, but the binding namespace between OpenGL and Vulkan don't match. To fix
|
||||
* this we need to check if one of both cases return a binding.
|
||||
*/
|
||||
return texture_get((binding >= image_offset) ? binding : binding + image_offset);
|
||||
return texture_get((binding >= BIND_SPACE_IMAGE_OFFSET) ? binding :
|
||||
binding + BIND_SPACE_IMAGE_OFFSET);
|
||||
case shader::ShaderCreateInfo::Resource::BindType::SAMPLER:
|
||||
return texture_get(binding);
|
||||
case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
|
||||
|
||||
@@ -34,15 +34,6 @@ class VKShaderInterface : public ShaderInterface {
|
||||
shader::BuiltinBits shader_builtins_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Offset when searching for a shader input based on a binding number.
|
||||
*
|
||||
* When shaders combine images and samplers, the images have to be offset to find the correct
|
||||
* shader input. Both textures and images are stored in the uniform list and their ID can be
|
||||
* overlapping.
|
||||
*/
|
||||
static constexpr uint32_t image_offset = 512;
|
||||
|
||||
VKShaderInterface() = default;
|
||||
|
||||
void init(const shader::ShaderCreateInfo &info);
|
||||
|
||||
@@ -28,7 +28,8 @@ class VKStateManager : public StateManager {
|
||||
uint texture_unpack_row_length_ = 0;
|
||||
|
||||
VKBindSpace<shader::ShaderCreateInfo::Resource::BindType::SAMPLER> textures_;
|
||||
VKBindSpace<shader::ShaderCreateInfo::Resource::BindType::IMAGE> images_;
|
||||
VKBindSpace<shader::ShaderCreateInfo::Resource::BindType::IMAGE, BIND_SPACE_IMAGE_OFFSET>
|
||||
images_;
|
||||
VKBindSpace<shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER> uniform_buffers_;
|
||||
VKBindSpace<shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER> storage_buffers_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user