Blender V4.5
gpu_select_sample_query.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2014 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <cstdlib>
13
14#include "GPU_debug.hh"
15#include "GPU_framebuffer.hh"
16#include "GPU_select.hh"
17#include "GPU_state.hh"
18
19#include "BLI_rect.h"
20
21#include "BLI_utildefines.h"
22#include "BLI_vector.hh"
23
24#include "gpu_backend.hh"
25#include "gpu_query.hh"
26
27#include "gpu_select_private.hh"
28
29using namespace blender;
30using namespace blender::gpu;
31
52
54
56 const rcti *input,
57 const eGPUSelectMode mode,
58 int oldhits)
59{
60 GPU_debug_group_begin("Selection Queries");
61
63 g_query_state.buffer = buffer;
64 g_query_state.mode = mode;
66 g_query_state.oldhits = oldhits;
67
71
76
77 /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see #7997). */
78 GPU_color_mask(true, true, true, true);
79
80 /* In order to save some fill rate we minimize the viewport using rect.
81 * We need to get the region of the viewport so that our geometry doesn't
82 * get rejected before the depth test. Should probably cull rect against
83 * the viewport but this is a rare case I think */
84
85 const int viewport[4] = {
87
88 GPU_viewport(UNPACK4(viewport));
89 GPU_scissor(UNPACK4(viewport));
90 GPU_scissor_test(false);
91
92 /* occlusion queries operates on fragments that pass tests and since we are interested on all
93 * objects in the view frustum independently of their order, we need to disable the depth test */
94 if (mode == GPU_SELECT_ALL) {
95 /* #glQueries on Windows+Intel drivers only works with depth testing turned on.
96 * See #62947 for details */
98 GPU_depth_mask(true);
99 }
100 else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
102 GPU_depth_mask(true);
103 GPU_clear_depth(1.0f);
104 }
105 else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
107 GPU_depth_mask(false);
108 }
109}
110
112{
115 }
116
120
122 /* Second pass should never run if first pass fails,
123 * can read past `buffer_len` in this case. */
128 return true;
129 }
130 return false;
131 }
132 }
133 return true;
134}
135
137{
138 uint hits = 0;
139
142 }
143
147
148 for (int i = 0; i < result.size(); i++) {
149 if (result[i] != 0) {
151 GPUSelectResult hit_result{};
152 hit_result.id = ids[i];
153 hit_result.depth = 0xFFFF;
154 g_query_state.buffer->storage.append(hit_result);
155 hits++;
156 }
157 else {
158 int j;
159 /* search in buffer and make selected object first */
160 for (j = 0; j < g_query_state.oldhits; j++) {
161 if (g_query_state.buffer->storage[j].id == ids[i]) {
162 g_query_state.buffer->storage[j].depth = 0;
163 }
164 }
165 break;
166 }
167 }
168 }
169
170 delete g_query_state.queries;
171 delete g_query_state.ids;
172
176
178
179 return hits;
180}
#define BLI_assert(a)
Definition BLI_assert.h:46
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
unsigned int uint
#define UNPACK2(a)
#define UNPACK4(a)
void GPU_debug_group_end()
Definition gpu_debug.cc:33
void GPU_debug_group_begin(const char *name)
Definition gpu_debug.cc:22
void GPU_clear_depth(float depth)
eGPUSelectMode
Definition GPU_select.hh:18
@ GPU_SELECT_NEAREST_SECOND_PASS
Definition GPU_select.hh:23
@ GPU_SELECT_NEAREST_FIRST_PASS
Definition GPU_select.hh:22
@ GPU_SELECT_ALL
Definition GPU_select.hh:20
void GPU_write_mask(eGPUWriteMask mask)
Definition gpu_state.cc:93
void GPU_scissor_test(bool enable)
Definition gpu_state.cc:188
eGPUWriteMask
Definition GPU_state.hh:16
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
eGPUDepthTest GPU_depth_test_get()
Definition gpu_state.cc:244
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition gpu_state.cc:98
void GPU_viewport_size_get_i(int coords[4])
Definition gpu_state.cc:282
eGPUWriteMask GPU_write_mask_get()
Definition gpu_state.cc:232
void GPU_scissor(int x, int y, int width, int height)
Definition gpu_state.cc:193
void GPU_viewport(int x, int y, int width, int height)
Definition gpu_state.cc:199
eGPUDepthTest
Definition GPU_state.hh:110
@ GPU_DEPTH_EQUAL
Definition GPU_state.hh:115
@ GPU_DEPTH_ALWAYS
Definition GPU_state.hh:112
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:114
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_scissor_get(int coords[4])
Definition gpu_state.cc:268
constexpr int64_t size() const
Definition BLI_span.hh:252
void append(const T &value)
static GPUBackend * get()
virtual QueryPool * querypool_alloc()=0
virtual void begin_query()=0
virtual void init(GPUQueryType type)=0
virtual void get_occlusion_result(MutableSpan< uint32_t > r_values)=0
virtual void end_query()=0
#define input
bool gpu_select_query_load_id(uint id)
static GPUSelectQueryState g_query_state
uint gpu_select_query_end()
void gpu_select_query_begin(GPUSelectBuffer *buffer, const rcti *input, const eGPUSelectMode mode, int oldhits)
@ GPU_QUERY_OCCLUSION
Definition gpu_query.hh:18
GPUSelectStorage storage
Definition GPU_select.hh:47
Vector< uint, QUERY_MIN_LEN > * ids
unsigned int id
Definition GPU_select.hh:34