Vulkan: Use Point Shaders When Drawing Points
In Vulkan (and Metal) it is not possible to use a global as point size. It needs to be set for each vertex when drawing points. Blender has specialized shaders for that, but not all code respect those shaders. This PR will add an assert inside the vulkan backend when incorrect usage of shaders are detected. Pull Request: https://projects.blender.org/blender/blender/pulls/112906
This commit is contained in:
@@ -1304,8 +1304,7 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
|
||||
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
const uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
|
||||
|
||||
/* Scaling the dots fully with the zoom looks too busy, but a bit of size variation is nice. */
|
||||
const float min_point_size = 2.0f * U.pixelsize;
|
||||
@@ -1368,7 +1367,8 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
|
||||
continue;
|
||||
}
|
||||
|
||||
GPU_point_size(point_size_draw);
|
||||
immUniform1f("size", point_size_draw);
|
||||
immUniform4fv("color", color);
|
||||
immBegin(GPU_PRIM_POINTS, count_x * count_y);
|
||||
|
||||
/* Theoretically drawing on top of lower grid levels could be avoided, but it would also
|
||||
@@ -1377,7 +1377,6 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
|
||||
const float y = start_y + step * i_y;
|
||||
for (int i_x = 0; i_x < count_x; i_x++) {
|
||||
const float x = start_x + step * i_x;
|
||||
immAttr4fv(color_id, color);
|
||||
immVertex2f(pos, x + point_size_offset, y + point_size_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "vk_immediate.hh"
|
||||
#include "vk_memory.hh"
|
||||
#include "vk_shader.hh"
|
||||
#include "vk_shader_interface.hh"
|
||||
#include "vk_state_manager.hh"
|
||||
#include "vk_texture.hh"
|
||||
|
||||
@@ -201,6 +202,12 @@ void VKContext::bind_graphics_pipeline(const GPUPrimType prim_type,
|
||||
{
|
||||
VKShader *shader = unwrap(this->shader);
|
||||
BLI_assert(shader);
|
||||
BLI_assert_msg(
|
||||
prim_type != GPU_PRIM_POINTS || shader->interface_get().is_point_shader(),
|
||||
"GPU_PRIM_POINTS is used with a shader that doesn't set point size before "
|
||||
"drawing fragments. Calling code should be adapted to use a shader that sets the "
|
||||
"gl_PointSize before entering the fragment stage. For example `GPU_SHADER_3D_POINT_*`.");
|
||||
|
||||
shader->update_graphics_pipeline(*this, prim_type, vertex_attribute_object);
|
||||
|
||||
VKPipeline &pipeline = shader->pipeline_get();
|
||||
|
||||
@@ -18,6 +18,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
||||
static size_t PUSH_CONSTANTS_FALLBACK_NAME_LEN = strlen(PUSH_CONSTANTS_FALLBACK_NAME);
|
||||
|
||||
using namespace blender::gpu::shader;
|
||||
shader_builtins_ = info.builtins_;
|
||||
|
||||
attr_len_ = info.vertex_inputs_.size();
|
||||
uniform_len_ = info.push_constants_.size();
|
||||
|
||||
@@ -32,6 +32,8 @@ class VKShaderInterface : public ShaderInterface {
|
||||
|
||||
VKPushConstants::Layout push_constants_layout_;
|
||||
|
||||
shader::BuiltinBits shader_builtins_;
|
||||
|
||||
public:
|
||||
VKShaderInterface() = default;
|
||||
|
||||
@@ -53,6 +55,11 @@ class VKShaderInterface : public ShaderInterface {
|
||||
return static_cast<shader::Type>(attr_types_[location]);
|
||||
}
|
||||
|
||||
bool is_point_shader() const
|
||||
{
|
||||
return (shader_builtins_ & shader::BuiltinBits::POINT_SIZE) == shader::BuiltinBits::POINT_SIZE;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Retrieve the shader input for the given resource.
|
||||
|
||||
Reference in New Issue
Block a user