Blender  V3.3
gpu_select_sample_query.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2014 Blender Foundation. All rights reserved. */
3 
11 #include <cstdlib>
12 
13 #include "GPU_debug.h"
14 #include "GPU_framebuffer.h"
15 #include "GPU_select.h"
16 #include "GPU_state.h"
17 
18 #include "MEM_guardedalloc.h"
19 
20 #include "BLI_rect.h"
21 
22 #include "BLI_utildefines.h"
23 #include "BLI_vector.hh"
24 
25 #include "gpu_backend.hh"
26 #include "gpu_query.hh"
27 
28 #include "gpu_select_private.h"
29 
30 using namespace blender;
31 using namespace blender::gpu;
32 
47  int oldhits;
48 
50  int viewport[4];
51  int scissor[4];
54 };
55 
57 
59  uint buffer_len,
60  const rcti *input,
61  const eGPUSelectMode mode,
62  int oldhits)
63 {
64  GPU_debug_group_begin("Selection Queries");
65 
68  g_query_state.buffer_len = buffer_len;
69  g_query_state.mode = mode;
70  g_query_state.index = 0;
71  g_query_state.oldhits = oldhits;
72 
76 
81 
82  /* Write to color buffer. Seems to fix issues with selecting alpha blended geom (see T7997). */
83  GPU_color_mask(true, true, true, true);
84 
85  /* In order to save some fill rate we minimize the viewport using rect.
86  * We need to get the region of the viewport so that our geometry doesn't
87  * get rejected before the depth test. Should probably cull rect against
88  * the viewport but this is a rare case I think */
89 
90  int viewport[4] = {
92 
93  GPU_viewport(UNPACK4(viewport));
94  GPU_scissor(UNPACK4(viewport));
95  GPU_scissor_test(false);
96 
97  /* occlusion queries operates on fragments that pass tests and since we are interested on all
98  * objects in the view frustum independently of their order, we need to disable the depth test */
99  if (mode == GPU_SELECT_ALL) {
100  /* #glQueries on Windows+Intel drivers only works with depth testing turned on.
101  * See T62947 for details */
103  GPU_depth_mask(true);
104  }
105  else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
107  GPU_depth_mask(true);
108  GPU_clear_depth(1.0f);
109  }
110  else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
112  GPU_depth_mask(false);
113  }
114 }
115 
117 {
120  }
121 
123  g_query_state.ids->append(id);
125 
127  /* Second pass should never run if first pass fails,
128  * can read past `buffer_len` in this case. */
133  return true;
134  }
135  return false;
136  }
137  }
138  return true;
139 }
140 
142 {
143  uint hits = 0;
144  const uint maxhits = g_query_state.buffer_len;
145 
148  }
149 
153 
154  for (int i = 0; i < result.size(); i++) {
155  if (result[i] != 0) {
157  if (hits < maxhits) {
158  g_query_state.buffer[hits].depth = 0xFFFF;
159  g_query_state.buffer[hits].id = ids[i];
160  hits++;
161  }
162  else {
163  hits = -1;
164  break;
165  }
166  }
167  else {
168  int j;
169  /* search in buffer and make selected object first */
170  for (j = 0; j < g_query_state.oldhits; j++) {
171  if (g_query_state.buffer[j].id == ids[i]) {
172  g_query_state.buffer[j].depth = 0;
173  }
174  }
175  break;
176  }
177  }
178  }
179 
180  delete g_query_state.queries;
181  delete g_query_state.ids;
182 
186 
188 
189  return hits;
190 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNPACK2(a)
#define UNPACK4(a)
void GPU_debug_group_end(void)
Definition: gpu_debug.cc:32
void GPU_debug_group_begin(const char *name)
Definition: gpu_debug.cc:21
eGPUSelectMode
Definition: GPU_select.h:19
@ GPU_SELECT_NEAREST_SECOND_PASS
Definition: GPU_select.h:23
@ GPU_SELECT_NEAREST_FIRST_PASS
Definition: GPU_select.h:22
@ GPU_SELECT_ALL
Definition: GPU_select.h:20
void GPU_write_mask(eGPUWriteMask mask)
Definition: gpu_state.cc:90
void GPU_scissor_test(bool enable)
Definition: gpu_state.cc:180
eGPUWriteMask
Definition: GPU_state.h:11
void GPU_depth_mask(bool depth)
Definition: gpu_state.cc:107
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition: gpu_state.cc:95
void GPU_viewport_size_get_i(int coords[4])
Definition: gpu_state.cc:268
void GPU_scissor(int x, int y, int width, int height)
Definition: gpu_state.cc:185
eGPUWriteMask GPU_write_mask_get(void)
Definition: gpu_state.cc:224
void GPU_viewport(int x, int y, int width, int height)
Definition: gpu_state.cc:191
eGPUDepthTest
Definition: GPU_state.h:82
@ GPU_DEPTH_EQUAL
Definition: GPU_state.h:87
@ GPU_DEPTH_ALWAYS
Definition: GPU_state.h:84
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:86
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:236
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
void GPU_scissor_get(int coords[4])
Definition: gpu_state.cc:254
Read Guarded memory(de)allocation.
constexpr int64_t size() const
Definition: BLI_span.hh:240
void append(const T &value)
Definition: BLI_vector.hh:433
virtual QueryPool * querypool_alloc()=0
static GPUBackend * get()
Definition: gpu_context.cc:292
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
void GPU_clear_depth(float depth)
bool gpu_select_query_load_id(uint id)
static GPUSelectQueryState g_query_state
uint gpu_select_query_end()
void gpu_select_query_begin(GPUSelectResult *buffer, uint buffer_len, const rcti *input, const eGPUSelectMode mode, int oldhits)
ccl_global float * buffer
ccl_global KernelShaderEvalInput * input
@ GPU_QUERY_OCCLUSION
Definition: gpu_query.hh:17
Vector< uint, QUERY_MIN_LEN > * ids
unsigned int id
Definition: GPU_select.h:34
unsigned int depth
Definition: GPU_select.h:42