If a `DrawGroup` contained both inverted and non-inverted scale the command generate shader would output the `resource_id` content at conflicting indices. This is because the number of instances stored inside the `DrawGroup` are the original count before multiview. Actually, only `start` was taking the multi-view count into account. We cannot modify the value on CPU otherwise it would increase the instance count for each submission. So the fix is to pass the view count to the command generate shader and multiply the instance count where needed. Fix #128085 Pull Request: https://projects.blender.org/blender/blender/pulls/128854
111 lines
3.2 KiB
C++
111 lines
3.2 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*/
|
|
|
|
#ifndef GPU_SHADER
|
|
# include "BLI_span.hh"
|
|
# include "GPU_shader_shared_utils.hh"
|
|
|
|
namespace blender::draw::command {
|
|
|
|
#endif
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Multi Draw
|
|
* \{ */
|
|
|
|
/**
|
|
* A DrawGroup allow to split the command stream into batch-able chunks of commands with
|
|
* the same render state.
|
|
*/
|
|
struct DrawGroup {
|
|
/** Index of next #DrawGroup from the same header. */
|
|
uint next;
|
|
|
|
/**
|
|
* IMPORTANT: All the following 3 members do not take multi-view into account.
|
|
* They only count the number of input instances. The command generation shader must multiply
|
|
* them by view_len to get the correct indices for resource ids.
|
|
*/
|
|
|
|
/** Index of the first instances after sorting. */
|
|
uint start;
|
|
/** Total number of instances (including inverted facing). Needed to issue the draw call. */
|
|
uint len;
|
|
/** Number of non inverted scaling instances in this Group. */
|
|
uint front_facing_len;
|
|
|
|
/** #gpu::Batch values (or subrange of) copied to #DrawCommand after sorting. */
|
|
int vertex_len;
|
|
int vertex_first;
|
|
/* Set to -1 if not an indexed draw. */
|
|
int base_index;
|
|
|
|
/** Atomic counters used during command sorting. GPU only. Reset on CPU. */
|
|
|
|
/* Counts visible and invisble instances. Create drawcalls when it reaches `DrawGroup::len`. */
|
|
uint total_counter;
|
|
/* Counts only visible instance (counting multi-view). Used to issue the drawcalls. */
|
|
uint front_facing_counter;
|
|
uint back_facing_counter;
|
|
|
|
/* CPU specific region of the struct. Should be kept constant after recording.
|
|
* Can be used by GPU but needs to be initialized by GPU before usage. */
|
|
#ifdef GPU_SHADER
|
|
uint _cpu_reserved_1;
|
|
uint _cpu_reserved_2;
|
|
|
|
uint _cpu_reserved_3;
|
|
uint _cpu_reserved_4;
|
|
uint _cpu_reserved_5;
|
|
uint _cpu_reserved_6;
|
|
|
|
#else
|
|
struct {
|
|
/* Specific range of vertex to draw from the #gpu::Batch. */
|
|
uint32_t vertex_first;
|
|
/* Ugly packing to support expanded draws without inflating the struct.
|
|
* Makes vertex range restricted to smaller range for expanded draw. */
|
|
uint32_t expand_prim_type : 4;
|
|
uint32_t expand_prim_len : 3;
|
|
uint32_t vertex_len : 25;
|
|
|
|
/** Needed to create the correct draw call. */
|
|
gpu::Batch *gpu_batch;
|
|
# ifdef WITH_METAL_BACKEND
|
|
GPUShader *gpu_shader;
|
|
# else
|
|
uint64_t _cpu_pad0;
|
|
# endif
|
|
} desc;
|
|
#endif
|
|
};
|
|
BLI_STATIC_ASSERT_ALIGN(DrawGroup, 16)
|
|
|
|
/**
|
|
* Representation of a future draw call inside a DrawGroup. This #DrawPrototype is then
|
|
* converted into #DrawCommand on GPU after visibility and compaction. Multiple
|
|
* #DrawPrototype might get merged into the same final #DrawCommand.
|
|
*/
|
|
struct DrawPrototype {
|
|
/* Reference to parent DrawGroup to get the gpu::Batch vertex / instance count. */
|
|
uint group_id;
|
|
/* Resource handle associated with this call. Also reference visibility. */
|
|
uint resource_handle;
|
|
/* Custom extra value to be used by the engines. */
|
|
uint custom_id;
|
|
/* Number of instances. */
|
|
uint instance_len;
|
|
};
|
|
BLI_STATIC_ASSERT_ALIGN(DrawPrototype, 16)
|
|
|
|
/** \} */
|
|
|
|
#ifndef GPU_SHADER
|
|
}; // namespace blender::draw::command
|
|
#endif
|