Fix: Various asserts when creating GPU vertex formats
Caused by 617858e453.
These formats should use types aligned to 4 bytes. That's generally
required by modern GPUs. Uploading with these types also avoids
automatic conversion by the Vulkan backend which is something
we're hoping to remove fully.
In the end this PR removes a bunch of code related to supporting
the older single-byte formats.
Pull Request: https://projects.blender.org/blender/blender/pulls/138836
This commit is contained in:
@@ -72,37 +72,11 @@ namespace blender::draw {
|
||||
|
||||
void DRW_vertbuf_create_wiredata(blender::gpu::VertBuf *vbo, const int vert_len)
|
||||
{
|
||||
static struct {
|
||||
uint wd;
|
||||
} attr_id;
|
||||
|
||||
static const GPUVertFormat format = [&]() {
|
||||
GPUVertFormat format{};
|
||||
/* initialize vertex format */
|
||||
if (!GPU_crappy_amd_driver()) {
|
||||
/* Some AMD drivers strangely crash with a vbo with this format. */
|
||||
attr_id.wd = GPU_vertformat_attr_add(
|
||||
&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
}
|
||||
else {
|
||||
attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
}
|
||||
return format;
|
||||
}();
|
||||
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
GPU_vertbuf_init_with_format(*vbo, format);
|
||||
GPU_vertbuf_data_alloc(*vbo, vert_len);
|
||||
|
||||
if (GPU_vertbuf_get_format(vbo)->stride == 1) {
|
||||
memset(vbo->data<uint8_t>().data(), 0xFF, size_t(vert_len));
|
||||
}
|
||||
else {
|
||||
GPUVertBufRaw wd_step;
|
||||
GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
|
||||
for (int i = 0; i < vert_len; i++) {
|
||||
*((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f;
|
||||
}
|
||||
}
|
||||
vbo->data<float>().fill(1.0f);
|
||||
}
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
@@ -420,7 +420,7 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt)
|
||||
static const GPUVertFormat format = [&]() {
|
||||
GPUVertFormat format{};
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT);
|
||||
attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
||||
return format;
|
||||
}();
|
||||
|
||||
@@ -431,7 +431,7 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt)
|
||||
for (int i = 0; i < vert_len; i++) {
|
||||
const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i);
|
||||
|
||||
char vflag = 0;
|
||||
uint32_t vflag = 0;
|
||||
if (bp->f1 & SELECT) {
|
||||
if (i == rdata->actbp) {
|
||||
vflag |= VFLAG_VERT_ACTIVE;
|
||||
|
||||
@@ -302,7 +302,7 @@ static const GPUVertFormat &mask_format()
|
||||
static const GPUVertFormat &face_set_format()
|
||||
{
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
"fset", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
return format;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "draw_subdivision.hh"
|
||||
#include "extract_mesh.hh"
|
||||
|
||||
#define FORCE_HIDE 255
|
||||
namespace blender::draw {
|
||||
|
||||
struct MEdgeDataPrev {
|
||||
@@ -29,9 +28,8 @@ struct MEdgeDataPrev {
|
||||
* Calculates a factor that is used to identify the minimum angle in the shader to display an edge.
|
||||
* NOTE: Keep in sync with `subdiv_vbo_edge_fac_comp.glsl`.
|
||||
*/
|
||||
template<typename T> T edge_factor_calc(const float3 &a, const float3 &b);
|
||||
|
||||
template<> inline float edge_factor_calc<float>(const float3 &a, const float3 &b)
|
||||
inline float edge_factor_calc(const float3 &a, const float3 &b)
|
||||
{
|
||||
const float cosine = math::dot(a, b);
|
||||
|
||||
@@ -43,19 +41,7 @@ template<> inline float edge_factor_calc<float>(const float3 &a, const float3 &b
|
||||
return fac * factor;
|
||||
}
|
||||
|
||||
template<> inline uint8_t edge_factor_calc<uint8_t>(const float3 &a, const float3 &b)
|
||||
{
|
||||
const float cosine = math::dot(a, b);
|
||||
|
||||
/* Re-scale to the slider range. */
|
||||
float fac = (200 * (cosine - 1.0f)) + 1.0f;
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
/* 255 is a reserved value to force hide the wire. */
|
||||
return fac * 254;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void extract_edge_factor_mesh(const MeshRenderData &mr, MutableSpan<T> vbo_data)
|
||||
static void extract_edge_factor_mesh(const MeshRenderData &mr, MutableSpan<float> vbo_data)
|
||||
{
|
||||
const OffsetIndices faces = mr.faces;
|
||||
const Span<int> corner_edges = mr.corner_edges;
|
||||
@@ -69,12 +55,7 @@ static void extract_edge_factor_mesh(const MeshRenderData &mr, MutableSpan<T> vb
|
||||
for (const int corner : faces[face]) {
|
||||
const int edge = corner_edges[corner];
|
||||
if (!optimal_display_edges.is_empty() && !optimal_display_edges[edge]) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
vbo_data[corner] = 1.0f;
|
||||
}
|
||||
else {
|
||||
vbo_data[corner] = FORCE_HIDE;
|
||||
}
|
||||
vbo_data[corner] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -91,7 +72,7 @@ static void extract_edge_factor_mesh(const MeshRenderData &mr, MutableSpan<T> vb
|
||||
else if (face_count == 1) {
|
||||
/* Calculate the factor for both corners. */
|
||||
const int other_face = medata->data;
|
||||
const T factor = edge_factor_calc<T>(face_normals[other_face], face_normals[face]);
|
||||
const float factor = edge_factor_calc(face_normals[other_face], face_normals[face]);
|
||||
vbo_data[medata->corner_a] = factor;
|
||||
vbo_data[corner] = factor;
|
||||
|
||||
@@ -112,8 +93,7 @@ static void extract_edge_factor_mesh(const MeshRenderData &mr, MutableSpan<T> vb
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void extract_edge_factor_bm(const MeshRenderData &mr, MutableSpan<T> vbo_data)
|
||||
static void extract_edge_factor_bm(const MeshRenderData &mr, MutableSpan<float> vbo_data)
|
||||
{
|
||||
BMesh &bm = *mr.bm;
|
||||
threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) {
|
||||
@@ -124,11 +104,11 @@ static void extract_edge_factor_bm(const MeshRenderData &mr, MutableSpan<T> vbo_
|
||||
const int index = BM_elem_index_get(loop);
|
||||
if (BM_edge_is_manifold(loop->e)) {
|
||||
const BMFace *other_face = loop->radial_next->f;
|
||||
vbo_data[index] = edge_factor_calc<T>(float3(bm_face_no_get(mr, &face)),
|
||||
float3(bm_face_no_get(mr, other_face)));
|
||||
vbo_data[index] = edge_factor_calc(float3(bm_face_no_get(mr, &face)),
|
||||
float3(bm_face_no_get(mr, other_face)));
|
||||
}
|
||||
else {
|
||||
vbo_data[index] = T(0);
|
||||
vbo_data[index] = 0.0f;
|
||||
}
|
||||
loop = loop->next;
|
||||
}
|
||||
@@ -138,51 +118,21 @@ static void extract_edge_factor_bm(const MeshRenderData &mr, MutableSpan<T> vbo_
|
||||
|
||||
gpu::VertBufPtr extract_edge_factor(const MeshRenderData &mr)
|
||||
{
|
||||
if (GPU_crappy_amd_driver() || GPU_minimum_per_vertex_stride() > 1) {
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
gpu::VertBufPtr vbo = gpu::VertBufPtr(GPU_vertbuf_create_with_format(format));
|
||||
GPU_vertbuf_data_alloc(*vbo, mr.corners_num + mr.loose_indices_num);
|
||||
MutableSpan vbo_data = vbo->data<float>();
|
||||
if (mr.extract_type == MeshExtractType::Mesh) {
|
||||
extract_edge_factor_mesh(mr, vbo_data);
|
||||
}
|
||||
else {
|
||||
extract_edge_factor_bm(mr, vbo_data);
|
||||
}
|
||||
vbo_data.take_back(mr.loose_indices_num).fill(0.0f);
|
||||
return vbo;
|
||||
}
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
"wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
gpu::VertBufPtr vbo = gpu::VertBufPtr(GPU_vertbuf_create_with_format(format));
|
||||
GPU_vertbuf_data_alloc(*vbo, mr.corners_num + mr.loose_indices_num);
|
||||
MutableSpan vbo_data = vbo->data<uint8_t>();
|
||||
MutableSpan vbo_data = vbo->data<float>();
|
||||
if (mr.extract_type == MeshExtractType::Mesh) {
|
||||
extract_edge_factor_mesh(mr, vbo_data);
|
||||
}
|
||||
else {
|
||||
extract_edge_factor_bm(mr, vbo_data);
|
||||
}
|
||||
vbo_data.take_back(mr.loose_indices_num).fill(uint8_t(0));
|
||||
vbo_data.take_back(mr.loose_indices_num).fill(0.0f);
|
||||
return vbo;
|
||||
}
|
||||
|
||||
/* Different function than the one used for the non-subdivision case, as we directly take care of
|
||||
* the buggy AMD driver case. */
|
||||
static const GPUVertFormat &get_subdiv_edge_fac_format()
|
||||
{
|
||||
if (GPU_crappy_amd_driver() || GPU_minimum_per_vertex_stride() > 1) {
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
return format;
|
||||
}
|
||||
|
||||
static const GPUVertFormat format = GPU_vertformat_from_attribute(
|
||||
"wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
return format;
|
||||
}
|
||||
|
||||
static gpu::VertBuf *build_poly_other_map_vbo(const DRWSubdivCache &subdiv_cache)
|
||||
{
|
||||
gpu::VertBuf *vbo = GPU_vertbuf_calloc();
|
||||
@@ -231,7 +181,7 @@ gpu::VertBufPtr extract_edge_factor_subdiv(const DRWSubdivCache &subdiv_cache,
|
||||
gpu::VertBuf &pos_nor)
|
||||
{
|
||||
gpu::VertBufPtr vbo = gpu::VertBufPtr(GPU_vertbuf_create_on_device(
|
||||
get_subdiv_edge_fac_format(),
|
||||
GPU_vertformat_from_attribute("wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT),
|
||||
subdiv_cache.num_subdiv_loops + subdiv_loose_edges_num(mr, subdiv_cache) * 2));
|
||||
|
||||
if (mr.faces_num > 0) {
|
||||
|
||||
@@ -1961,7 +1961,7 @@ static void set_nodelink_vertex(gpu::VertBuf *vbo,
|
||||
uint pos_id,
|
||||
uint exp_id,
|
||||
uint v,
|
||||
const uchar uv[2],
|
||||
const float uv[2],
|
||||
const float pos[2],
|
||||
const float exp[2])
|
||||
{
|
||||
@@ -1973,7 +1973,7 @@ static void set_nodelink_vertex(gpu::VertBuf *vbo,
|
||||
static void nodelink_batch_init()
|
||||
{
|
||||
GPUVertFormat format = {0};
|
||||
uint uv_id = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_U8, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
uint uv_id = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint expand_id = GPU_vertformat_attr_add(&format, "expand", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
gpu::VertBuf *vbo = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC);
|
||||
@@ -1988,7 +1988,7 @@ static void nodelink_batch_init()
|
||||
int v = 0;
|
||||
|
||||
for (int k = 0; k < 2; k++) {
|
||||
uchar uv[2] = {0, 0};
|
||||
float uv[2] = {0.0f, 0.0f};
|
||||
float pos[2] = {0.0f, 0.0f};
|
||||
float exp[2] = {0.0f, 1.0f};
|
||||
|
||||
@@ -1999,47 +1999,47 @@ static void nodelink_batch_init()
|
||||
|
||||
/* curve strip */
|
||||
for (int i = 0; i < LINK_RESOL; i++) {
|
||||
uv[0] = 255 * (i / float(LINK_RESOL - 1));
|
||||
uv[1] = 0;
|
||||
uv[0] = (i / float(LINK_RESOL - 1));
|
||||
uv[1] = 0.0f;
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
uv[1] = 255;
|
||||
uv[1] = 1.0f;
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
}
|
||||
/* restart */
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
|
||||
uv[0] = 127;
|
||||
uv[1] = 0;
|
||||
uv[0] = 0.5f;
|
||||
uv[1] = 0.0f;
|
||||
copy_v2_v2(pos, arrow_verts[0]);
|
||||
copy_v2_v2(exp, arrow_expand_axis[0]);
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
/* arrow */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
uv[1] = 0;
|
||||
uv[1] = 0.0f;
|
||||
copy_v2_v2(pos, arrow_verts[i]);
|
||||
copy_v2_v2(exp, arrow_expand_axis[i]);
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
|
||||
uv[1] = 255;
|
||||
uv[1] = 1.0f;
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
}
|
||||
|
||||
/* restart */
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
|
||||
uv[0] = 127;
|
||||
uv[1] = 0;
|
||||
uv[0] = 0.5f;
|
||||
uv[1] = 0.0f;
|
||||
copy_v2_v2(pos, mute_verts[0]);
|
||||
copy_v2_v2(exp, mute_expand_axis[0]);
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
/* bar */
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
uv[1] = 0;
|
||||
uv[1] = 0.0f;
|
||||
copy_v2_v2(pos, mute_verts[i]);
|
||||
copy_v2_v2(exp, mute_expand_axis[i]);
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
|
||||
uv[1] = 255;
|
||||
uv[1] = 1.0f;
|
||||
set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp);
|
||||
}
|
||||
|
||||
@@ -2073,7 +2073,7 @@ static void nodelink_batch_init()
|
||||
g_batch_link.end_color_id = GPU_vertformat_attr_add(
|
||||
&format_inst, "end_color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
g_batch_link.muted_id = GPU_vertformat_attr_add(
|
||||
&format_inst, "domuted", GPU_COMP_U8, 2, GPU_FETCH_INT);
|
||||
&format_inst, "domuted", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
||||
g_batch_link.dim_factor_id = GPU_vertformat_attr_add(
|
||||
&format_inst, "dim_factor", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
g_batch_link.thickness_id = GPU_vertformat_attr_add(
|
||||
@@ -2199,7 +2199,7 @@ static void nodelink_batch_add_link(const SpaceNode &snode,
|
||||
copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.start_color_step),
|
||||
draw_config.start_color);
|
||||
copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.end_color_step), draw_config.end_color);
|
||||
char *muted = (char *)GPU_vertbuf_raw_step(&g_batch_link.muted_step);
|
||||
uint32_t *muted = (uint32_t *)GPU_vertbuf_raw_step(&g_batch_link.muted_step);
|
||||
muted[0] = draw_config.drawmuted;
|
||||
*(float *)GPU_vertbuf_raw_step(&g_batch_link.dim_factor_step) = draw_config.dim_factor;
|
||||
*(float *)GPU_vertbuf_raw_step(&g_batch_link.thickness_step) = draw_config.thickness;
|
||||
|
||||
@@ -29,7 +29,7 @@ void main()
|
||||
# define colEnd (colid_doarrow[1] < 3u ? end_color : node_link_data.colors[colid_doarrow[1]])
|
||||
# define colShadow node_link_data.colors[colid_doarrow[2]]
|
||||
# define doArrow (colid_doarrow[3] != 0u)
|
||||
# define doMuted (domuted[0] != 0u)
|
||||
# define doMuted (domuted[0] != 0)
|
||||
#else
|
||||
float2 P0 = node_link_data.bezierPts[0].xy;
|
||||
float2 P1 = node_link_data.bezierPts[1].xy;
|
||||
|
||||
@@ -77,9 +77,8 @@ TEST(VulkanDataConversion, vertex_format_i32_as_float)
|
||||
test_data[2].pos_i = int2(2, 3);
|
||||
test_data[3].pos_i = int2(3, 4);
|
||||
|
||||
VKWorkarounds workarounds = {};
|
||||
VertexFormatConverter converter;
|
||||
converter.init(&source_format, workarounds);
|
||||
converter.init(&source_format);
|
||||
|
||||
EXPECT_TRUE(converter.needs_conversion());
|
||||
|
||||
@@ -108,9 +107,8 @@ TEST(VulkanDataConversion, vertex_format_u32_as_float)
|
||||
test_data[2].pos_u = uint3(2, 3, 4);
|
||||
test_data[3].pos_u = uint3(3, 4, 5);
|
||||
|
||||
VKWorkarounds workarounds = {};
|
||||
VertexFormatConverter converter;
|
||||
converter.init(&source_format, workarounds);
|
||||
converter.init(&source_format);
|
||||
|
||||
EXPECT_TRUE(converter.needs_conversion());
|
||||
|
||||
@@ -122,96 +120,6 @@ TEST(VulkanDataConversion, vertex_format_u32_as_float)
|
||||
EXPECT_EQ(test_data[3].pos_fl, float3(3.0, 4.0, 5.0));
|
||||
}
|
||||
|
||||
TEST(VulkanDataConversion, vertex_format_r8g8b8)
|
||||
{
|
||||
GPUVertFormat source_format;
|
||||
GPU_vertformat_clear(&source_format);
|
||||
GPU_vertformat_attr_add(&source_format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
VertexFormat_pack(&source_format);
|
||||
|
||||
struct SourceData {
|
||||
uchar3 color;
|
||||
uint8_t _pad;
|
||||
};
|
||||
struct DeviceData {
|
||||
uchar4 color;
|
||||
};
|
||||
|
||||
SourceData test_data_in[4];
|
||||
test_data_in[0].color = uchar3(255, 0, 0);
|
||||
test_data_in[1].color = uchar3(255, 255, 255);
|
||||
test_data_in[2].color = uchar3(255, 0, 0);
|
||||
test_data_in[3].color = uchar3(255, 255, 255);
|
||||
|
||||
VKWorkarounds workarounds = {};
|
||||
VertexFormatConverter converter;
|
||||
converter.init(&source_format, workarounds);
|
||||
|
||||
EXPECT_FALSE(converter.needs_conversion());
|
||||
|
||||
/* Enable workaround for r8g8b8 vertex formats. */
|
||||
workarounds.vertex_formats.r8g8b8 = true;
|
||||
|
||||
converter.init(&source_format, workarounds);
|
||||
EXPECT_TRUE(converter.needs_conversion());
|
||||
|
||||
DeviceData test_data_out[4];
|
||||
converter.convert(test_data_out, test_data_in, 4);
|
||||
|
||||
EXPECT_EQ(test_data_out[0].color, uchar4(255, 0, 0, 255));
|
||||
EXPECT_EQ(test_data_out[1].color, uchar4(255, 255, 255, 255));
|
||||
EXPECT_EQ(test_data_out[2].color, uchar4(255, 0, 0, 255));
|
||||
EXPECT_EQ(test_data_out[3].color, uchar4(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
TEST(VulkanDataConversion, vertex_format_multiple_attributes)
|
||||
{
|
||||
GPUVertFormat source_format;
|
||||
GPU_vertformat_clear(&source_format);
|
||||
GPU_vertformat_attr_add(&source_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
GPU_vertformat_attr_add(&source_format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
GPU_vertformat_attr_add(&source_format, "flag", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
||||
VertexFormat_pack(&source_format);
|
||||
|
||||
struct SourceData {
|
||||
float3 pos;
|
||||
uchar3 color;
|
||||
uint8_t _pad;
|
||||
uint flag;
|
||||
};
|
||||
struct DeviceData {
|
||||
float3 pos;
|
||||
uchar4 color;
|
||||
uint flag;
|
||||
};
|
||||
|
||||
SourceData test_data_in[4];
|
||||
test_data_in[0] = {float3(1.0, 2.0, 3.0), uchar3(255, 0, 0), 0, 0};
|
||||
test_data_in[1] = {float3(4.0, 5.0, 6.0), uchar3(0, 255, 0), 0, 1};
|
||||
test_data_in[2] = {float3(7.0, 8.0, 9.0), uchar3(0, 0, 255), 0, 2};
|
||||
test_data_in[3] = {float3(10.0, 11.0, 12.0), uchar3(255, 255, 255), 0, 3};
|
||||
|
||||
VKWorkarounds workarounds = {};
|
||||
workarounds.vertex_formats.r8g8b8 = true;
|
||||
VertexFormatConverter converter;
|
||||
converter.init(&source_format, workarounds);
|
||||
EXPECT_TRUE(converter.needs_conversion());
|
||||
|
||||
DeviceData test_data_out[4];
|
||||
converter.convert(test_data_out, test_data_in, 4);
|
||||
|
||||
DeviceData expected_data[4];
|
||||
expected_data[0] = {float3(1.0, 2.0, 3.0), uchar4(255, 0, 0, 255), 0};
|
||||
expected_data[1] = {float3(4.0, 5.0, 6.0), uchar4(0, 255, 0, 255), 1};
|
||||
expected_data[2] = {float3(7.0, 8.0, 9.0), uchar4(0, 0, 255, 255), 2};
|
||||
expected_data[3] = {float3(10.0, 11.0, 12.0), uchar4(255, 255, 255, 255), 3};
|
||||
for (int i : IndexRange(4)) {
|
||||
EXPECT_EQ(test_data_out[i].pos, expected_data[i].pos);
|
||||
EXPECT_EQ(test_data_out[i].color, expected_data[i].color);
|
||||
EXPECT_EQ(test_data_out[i].flag, expected_data[i].flag);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VulkanDataConversion, texture_rgb16f_as_floats_to_rgba16f)
|
||||
{
|
||||
const size_t num_pixels = 4;
|
||||
|
||||
@@ -1264,11 +1264,6 @@ static bool attribute_check(const GPUVertAttr attribute,
|
||||
return attribute.comp_type == comp_type && attribute.fetch_mode == fetch_mode;
|
||||
}
|
||||
|
||||
static bool attribute_check(const GPUVertAttr attribute, GPUVertCompType comp_type, uint comp_len)
|
||||
{
|
||||
return attribute.comp_type == comp_type && attribute.comp_len == comp_len;
|
||||
}
|
||||
|
||||
void VertexFormatConverter::reset()
|
||||
{
|
||||
source_format_ = nullptr;
|
||||
@@ -1278,31 +1273,28 @@ void VertexFormatConverter::reset()
|
||||
needs_conversion_ = false;
|
||||
}
|
||||
|
||||
void VertexFormatConverter::init(const GPUVertFormat *vertex_format,
|
||||
const VKWorkarounds &workarounds)
|
||||
void VertexFormatConverter::init(const GPUVertFormat *vertex_format)
|
||||
{
|
||||
source_format_ = vertex_format;
|
||||
device_format_ = vertex_format;
|
||||
|
||||
update_conversion_flags(*source_format_, workarounds);
|
||||
update_conversion_flags(*source_format_);
|
||||
if (needs_conversion_) {
|
||||
init_device_format(workarounds);
|
||||
init_device_format();
|
||||
}
|
||||
}
|
||||
|
||||
void VertexFormatConverter::update_conversion_flags(const GPUVertFormat &vertex_format,
|
||||
const VKWorkarounds &workarounds)
|
||||
void VertexFormatConverter::update_conversion_flags(const GPUVertFormat &vertex_format)
|
||||
{
|
||||
needs_conversion_ = false;
|
||||
|
||||
for (int attr_index : IndexRange(vertex_format.attr_len)) {
|
||||
const GPUVertAttr &vert_attr = vertex_format.attrs[attr_index];
|
||||
update_conversion_flags(vert_attr, workarounds);
|
||||
update_conversion_flags(vert_attr);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexFormatConverter::update_conversion_flags(const GPUVertAttr &vertex_attribute,
|
||||
const VKWorkarounds &workarounds)
|
||||
void VertexFormatConverter::update_conversion_flags(const GPUVertAttr &vertex_attribute)
|
||||
{
|
||||
/* I32/U32 to F32 conversion doesn't exist in vulkan. */
|
||||
if (vertex_attribute.fetch_mode == GPU_FETCH_INT_TO_FLOAT &&
|
||||
@@ -1310,14 +1302,9 @@ void VertexFormatConverter::update_conversion_flags(const GPUVertAttr &vertex_at
|
||||
{
|
||||
needs_conversion_ = true;
|
||||
}
|
||||
/* r8g8b8 formats will be stored as r8g8b8a8. */
|
||||
else if (workarounds.vertex_formats.r8g8b8 && attribute_check(vertex_attribute, GPU_COMP_U8, 3))
|
||||
{
|
||||
needs_conversion_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexFormatConverter::init_device_format(const VKWorkarounds &workarounds)
|
||||
void VertexFormatConverter::init_device_format()
|
||||
{
|
||||
BLI_assert(needs_conversion_);
|
||||
GPU_vertformat_copy(&converted_format_, *source_format_);
|
||||
@@ -1325,7 +1312,7 @@ void VertexFormatConverter::init_device_format(const VKWorkarounds &workarounds)
|
||||
|
||||
for (int attr_index : IndexRange(converted_format_.attr_len)) {
|
||||
GPUVertAttr &vert_attr = converted_format_.attrs[attr_index];
|
||||
make_device_compatible(vert_attr, workarounds, needs_repack);
|
||||
make_device_compatible(vert_attr);
|
||||
}
|
||||
|
||||
if (needs_repack) {
|
||||
@@ -1334,9 +1321,7 @@ void VertexFormatConverter::init_device_format(const VKWorkarounds &workarounds)
|
||||
device_format_ = &converted_format_;
|
||||
}
|
||||
|
||||
void VertexFormatConverter::make_device_compatible(GPUVertAttr &vertex_attribute,
|
||||
const VKWorkarounds &workarounds,
|
||||
bool &r_needs_repack) const
|
||||
void VertexFormatConverter::make_device_compatible(GPUVertAttr &vertex_attribute) const
|
||||
{
|
||||
if (vertex_attribute.fetch_mode == GPU_FETCH_INT_TO_FLOAT &&
|
||||
ELEM(vertex_attribute.comp_type, GPU_COMP_I32, GPU_COMP_U32))
|
||||
@@ -1344,12 +1329,6 @@ void VertexFormatConverter::make_device_compatible(GPUVertAttr &vertex_attribute
|
||||
vertex_attribute.fetch_mode = GPU_FETCH_FLOAT;
|
||||
vertex_attribute.comp_type = GPU_COMP_F32;
|
||||
}
|
||||
else if (workarounds.vertex_formats.r8g8b8 && attribute_check(vertex_attribute, GPU_COMP_U8, 3))
|
||||
{
|
||||
vertex_attribute.comp_len = 4;
|
||||
vertex_attribute.size = 4;
|
||||
r_needs_repack = true;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexFormatConverter::convert(void *device_data,
|
||||
@@ -1412,13 +1391,6 @@ void VertexFormatConverter::convert_attribute(void *device_row_data,
|
||||
*component_out = float(*component_in);
|
||||
}
|
||||
}
|
||||
else if (attribute_check(source_attribute, GPU_COMP_U8, 3) &&
|
||||
attribute_check(device_attribute, GPU_COMP_U8, 4))
|
||||
{
|
||||
const uchar3 *attr_in = static_cast<const uchar3 *>(source_attr_data);
|
||||
uchar4 *attr_out = static_cast<uchar4 *>(device_attr_data);
|
||||
*attr_out = uchar4(attr_in->x, attr_in->y, attr_in->z, 255);
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ struct VertexFormatConverter {
|
||||
* setup the vertex attribute bindings.
|
||||
* - #convert can be called to convert source data to device data.
|
||||
*/
|
||||
void init(const GPUVertFormat *vertex_format, const VKWorkarounds &workarounds);
|
||||
void init(const GPUVertFormat *vertex_format);
|
||||
|
||||
/**
|
||||
* Get the #GPUVertFormat that is compatible with the Vulkan and the active workarounds passed by
|
||||
@@ -174,18 +174,14 @@ struct VertexFormatConverter {
|
||||
* Update conversion flags happens at the start of initialization and updated the
|
||||
* #needs_conversion flag.
|
||||
*/
|
||||
void update_conversion_flags(const GPUVertFormat &vertex_format,
|
||||
const VKWorkarounds &workarounds);
|
||||
void update_conversion_flags(const GPUVertAttr &vertex_attribute,
|
||||
const VKWorkarounds &workarounds);
|
||||
void update_conversion_flags(const GPUVertFormat &vertex_format);
|
||||
void update_conversion_flags(const GPUVertAttr &vertex_attribute);
|
||||
|
||||
/**
|
||||
* Update the conversion_format to contain a device compatible version of the #source_format_.
|
||||
*/
|
||||
void init_device_format(const VKWorkarounds &workarounds);
|
||||
void make_device_compatible(GPUVertAttr &vertex_attribute,
|
||||
const VKWorkarounds &workarounds,
|
||||
bool &needs_repack) const;
|
||||
void init_device_format();
|
||||
void make_device_compatible(GPUVertAttr &vertex_attribute) const;
|
||||
|
||||
void convert_row(void *device_row_data, const void *source_row_data) const;
|
||||
void convert_attribute(void *device_row_data,
|
||||
|
||||
@@ -49,9 +49,7 @@ void VKImmediate::deinit(VKDevice &device)
|
||||
|
||||
uchar *VKImmediate::begin()
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
const VKWorkarounds &workarounds = device.workarounds_get();
|
||||
vertex_format_converter.init(&vertex_format, workarounds);
|
||||
vertex_format_converter.init(&vertex_format);
|
||||
uint add_vertex = prim_type == GPU_PRIM_LINE_LOOP ? 1 : 0;
|
||||
const size_t bytes_needed = vertex_buffer_size(&vertex_format_converter.device_format_get(),
|
||||
vertex_len + add_vertex);
|
||||
|
||||
@@ -184,8 +184,7 @@ void VKVertexBuffer::upload_data()
|
||||
void VKVertexBuffer::device_format_ensure()
|
||||
{
|
||||
if (!vertex_format_converter.is_initialized()) {
|
||||
const VKWorkarounds &workarounds = VKBackend::get().device.workarounds_get();
|
||||
vertex_format_converter.init(&format, workarounds);
|
||||
vertex_format_converter.init(&format);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user