Possible fix for T62999: Crash when select in edit mode.
Apparently some drivers don't allow `glReadPixel` read out pixels of texture boundaries. Intersect `rect` to avoid such cases.
This commit is contained in:
parent
dfa470ec33
commit
d5cb425b87
Notes:
blender-bot
2023-02-14 03:13:20 +01:00
Referenced by commit fbfa5890bf
, Fix build errors
Referenced by issue #62999, Blender 2.8, Selection tool crashes blender in editmode. Only in Vertex and/or Edge Select.
|
@ -59,6 +59,7 @@
|
|||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_select.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
|
@ -2547,8 +2548,23 @@ void DRW_framebuffer_select_id_release(ARegion *ar)
|
|||
/* Read a block of pixels from the select frame buffer. */
|
||||
void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf)
|
||||
{
|
||||
/* clamp rect by texture */
|
||||
rcti r = {
|
||||
.xmin = 0,
|
||||
.xmax = GPU_texture_width(g_select_buffer.texture_u32),
|
||||
.ymin = 0,
|
||||
.ymax = GPU_texture_height(g_select_buffer.texture_u32),
|
||||
};
|
||||
|
||||
rcti rect_clamp = *rect;
|
||||
BLI_rcti_isect(&r, rect, &rect_clamp);
|
||||
|
||||
GPU_texture_read_rect(
|
||||
g_select_buffer.texture_u32, GPU_DATA_UNSIGNED_INT, rect, r_buf);
|
||||
g_select_buffer.texture_u32, GPU_DATA_UNSIGNED_INT, &rect_clamp, r_buf);
|
||||
|
||||
if (!BLI_rcti_compare(rect, &rect_clamp)) {
|
||||
GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -52,5 +52,6 @@ void GPU_select_cache_end(void);
|
|||
|
||||
/* utilities */
|
||||
const uint *GPU_select_buffer_near(const uint *buffer, int hits);
|
||||
void GPU_select_buffer_stride_realign(const struct rcti *src, const struct rcti *dst, uint *r_buf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -90,6 +90,30 @@ static void rect_subregion_stride_calc(const rcti *src, const rcti *dst, SubRect
|
|||
r_sub->skip = (uint)(src_x - dst_x);
|
||||
}
|
||||
|
||||
void GPU_select_buffer_stride_realign(
|
||||
const rcti *src, const rcti *dst, uint *r_buf)
|
||||
{
|
||||
SubRectStride sub;
|
||||
rect_subregion_stride_calc(src, dst, &sub);
|
||||
|
||||
int last_px_written = sub.span * sub.span_len - 1;
|
||||
int last_px_id = sub.start + last_px_written + (sub.span_len - 1) * sub.skip;
|
||||
|
||||
while (sub.span_len--) {
|
||||
int i;
|
||||
for (i = sub.span; i--;) {
|
||||
r_buf[last_px_id--] = r_buf[last_px_written--];
|
||||
}
|
||||
if (last_px_written < 0) {
|
||||
break;
|
||||
}
|
||||
for (i = sub.skip; i--;) {
|
||||
r_buf[last_px_id--] = 0u;
|
||||
}
|
||||
}
|
||||
memset(r_buf, 0, (last_px_id + 1) * sizeof(*r_buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore depth clearing as a change,
|
||||
* only check if its been changed _and_ filled in (ignore clearing since XRAY does this).
|
||||
|
|
Loading…
Reference in New Issue