Files
test/source/blender/draw/intern/attribute_convert.hh
Hans Goudey 91627b3d47 GPU: Remove int float fetch mode combination
This commit finishes removing the uses of the integer to float
vertex buffer fetch mode. Previous commits noted below already started
that process. The last usage was geometry attributes. Now integers are
converted to floats as part of the existing upload process.

The change makes the Vulkan vertex buffer type conversion unused, so
it's removed. That's nice because Vulkan vertex buffers go from 1040 to
568 bytes in size and have significantly less overhead on creation.

Related:
- 153abc372e
- 1e1ac2bb9b
- 617858e453

Pull Request: https://projects.blender.org/blender/blender/pulls/138873
2025-05-15 15:29:12 +02:00

149 lines
5.1 KiB
C++

/* SPDX-FileCopyrightText: 2005 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#include "BLI_color.hh"
#include "BLI_generic_span.hh"
#include "BLI_math_quaternion_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_string_ref.hh"
#include "DNA_customdata_types.h" /* #eCustomDataType. */
#include "GPU_vertex_format.hh"
namespace blender::gpu {
class VertBuf;
}
/**
* Component length of 3 is used for scalars because implicit conversion is done by OpenGL from a
* scalar `s` will produce `float4(s, 0, 0, 1)`. However, following the Blender convention, it
* should be `float4(s, s, s, 1)`.
*/
constexpr int COMPONENT_LEN_SCALAR = 3;
namespace blender::draw {
/**
* Utility to convert from the type used in the attributes to the types for GPU vertex buffers.
*/
template<typename T> struct AttributeConverter {
using VBOType = void;
};
template<> struct AttributeConverter<bool> {
using VBOType = VecBase<float, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const bool &value)
{
return VBOType(value);
}
};
template<> struct AttributeConverter<int8_t> {
using VBOType = VecBase<float, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const int8_t &value)
{
return VecBase<float, COMPONENT_LEN_SCALAR>(value);
}
};
template<> struct AttributeConverter<int> {
using VBOType = VecBase<float, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const int &value)
{
return VecBase<float, COMPONENT_LEN_SCALAR>(value);
}
};
template<> struct AttributeConverter<int2> {
using VBOType = float2;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 2;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const int2 &value)
{
return float2(value.x, value.y);
}
};
template<> struct AttributeConverter<float> {
using VBOType = VecBase<float, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float &value)
{
return VBOType(value);
}
};
template<> struct AttributeConverter<float2> {
using VBOType = float2;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 2;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float2 &value)
{
return value;
}
};
template<> struct AttributeConverter<float3> {
using VBOType = float3;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 3;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float3 &value)
{
return value;
}
};
template<> struct AttributeConverter<ColorGeometry4b> {
/* 16 bits are required to store the color in linear space without precision loss. */
using VBOType = ushort4;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_U16;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
static VBOType convert(const ColorGeometry4b &value)
{
return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]),
ushort(value.a * 257)};
}
};
template<> struct AttributeConverter<ColorGeometry4f> {
using VBOType = ColorGeometry4f;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const ColorGeometry4f &value)
{
return value;
}
};
template<> struct AttributeConverter<math::Quaternion> {
using VBOType = float4;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const math::Quaternion &value)
{
return float4(value.w, value.x, value.y, value.z);
}
};
GPUVertFormat init_format_for_attribute(eCustomDataType data_type, StringRef vbo_name);
void vertbuf_data_extract_direct(GSpan attribute, gpu::VertBuf &vbo);
} // namespace blender::draw