Blender V4.3
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 "MEM_guardedalloc.h"
20
21#include "BLI_rect.h"
22
23#include "BLI_utildefines.h"
24#include "BLI_vector.hh"
25
26#include "gpu_backend.hh"
27#include "gpu_query.hh"
28
29#include "gpu_select_private.hh"
30
31using namespace blender;
32using namespace blender::gpu;
33
54
56
58 const rcti *input,
59 const eGPUSelectMode mode,
60 int oldhits)
61{
62 GPU_debug_group_begin("Selection Queries");
63
65 g_query_state.buffer = buffer;
66 g_query_state.mode = mode;
68 g_query_state.oldhits = oldhits;
69
73
78
79 /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see #7997). */
80 GPU_color_mask(true, true, true, true);
81
82 /* In order to save some fill rate we minimize the viewport using rect.
83 * We need to get the region of the viewport so that our geometry doesn't
84 * get rejected before the depth test. Should probably cull rect against
85 * the viewport but this is a rare case I think */
86
87 const int viewport[4] = {
89
90 GPU_viewport(UNPACK4(viewport));
91 GPU_scissor(UNPACK4(viewport));
92 GPU_scissor_test(false);
93
94 /* occlusion queries operates on fragments that pass tests and since we are interested on all
95 * objects in the view frustum independently of their order, we need to disable the depth test */
96 if (mode == GPU_SELECT_ALL) {
97 /* #glQueries on Windows+Intel drivers only works with depth testing turned on.
98 * See #62947 for details */
100 GPU_depth_mask(true);
101 }
102 else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
104 GPU_depth_mask(true);
105 GPU_clear_depth(1.0f);
106 }
107 else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
109 GPU_depth_mask(false);
110 }
111}
112
114{
117 }
118
122
124 /* Second pass should never run if first pass fails,
125 * can read past `buffer_len` in this case. */
130 return true;
131 }
132 return false;
133 }
134 }
135 return true;
136}
137
139{
140 uint hits = 0;
141
144 }
145
149
150 for (int i = 0; i < result.size(); i++) {
151 if (result[i] != 0) {
153 GPUSelectResult hit_result{};
154 hit_result.id = ids[i];
155 hit_result.depth = 0xFFFF;
156 g_query_state.buffer->storage.append(hit_result);
157 hits++;
158 }
159 else {
160 int j;
161 /* search in buffer and make selected object first */
162 for (j = 0; j < g_query_state.oldhits; j++) {
163 if (g_query_state.buffer->storage[j].id == ids[i]) {
164 g_query_state.buffer->storage[j].depth = 0;
165 }
166 }
167 break;
168 }
169 }
170 }
171
172 delete g_query_state.queries;
173 delete g_query_state.ids;
174
178
180
181 return hits;
182}
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
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:22
@ GPU_SELECT_NEAREST_FIRST_PASS
Definition GPU_select.hh:21
@ GPU_SELECT_ALL
Definition GPU_select.hh:19
void GPU_write_mask(eGPUWriteMask mask)
Definition gpu_state.cc:93
void GPU_scissor_test(bool enable)
Definition gpu_state.cc:183
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:239
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:271
eGPUWriteMask GPU_write_mask_get()
Definition gpu_state.cc:227
void GPU_scissor(int x, int y, int width, int height)
Definition gpu_state.cc:188
void GPU_viewport(int x, int y, int width, int height)
Definition gpu_state.cc:194
eGPUDepthTest
Definition GPU_state.hh:107
@ GPU_DEPTH_EQUAL
Definition GPU_state.hh:112
@ GPU_DEPTH_ALWAYS
Definition GPU_state.hh:109
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:111
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_scissor_get(int coords[4])
Definition gpu_state.cc:257
Read Guarded memory(de)allocation.
constexpr int64_t size() const
Definition BLI_span.hh:253
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
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:46
Vector< uint, QUERY_MIN_LEN > * ids
unsigned int id
Definition GPU_select.hh:33