Cleanup: GPU: Replace all glReadPixels by GPU equivalent

This commit is contained in:
Clément Foucault 2020-07-16 02:50:55 +02:00
parent ab19abe223
commit 8084b7e6e2
Notes: blender-bot 2023-02-14 10:43:47 +01:00
Referenced by commit 618f31312c, Fix vertex selection error from recent refactor
Referenced by issue #81167, Texture Painting with Paint mask enabled, (de)selecting faces causes a mess with texture slots.
10 changed files with 98 additions and 50 deletions

View File

@ -76,7 +76,7 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
DRW_draw_pass(pass);
float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
GPU_framebuffer_read_color(fb, 0, 0, w, h, 3, 0, data);
GPU_framebuffer_read_color(fb, 0, 0, w, h, 3, 0, GPU_DATA_FLOAT, data);
printf("{");
for (int i = 0; i < w * h * 3; i += 3) {

View File

@ -267,6 +267,7 @@ static void eevee_render_color_result(RenderLayer *rl,
BLI_rcti_size_y(rect),
num_channels,
0,
GPU_DATA_FLOAT,
rp->rect);
}

View File

@ -235,6 +235,7 @@ static void GPENCIL_render_result_combined(struct RenderLayer *rl,
BLI_rcti_size_y(rect),
4,
0,
GPU_DATA_FLOAT,
rp->rect);
}

View File

@ -212,6 +212,7 @@ void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer
BLI_rcti_size_y(rect),
4,
0,
GPU_DATA_FLOAT,
rp->rect);
workbench_render_result_z(render_layer, viewname, rect);

View File

@ -343,7 +343,7 @@ void DRW_hair_update(void)
DRW_draw_pass_subset(g_tf_pass, pr_call->shgrp, pr_call->shgrp);
/* Readback result to main memory. */
GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, data);
GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, GPU_DATA_FLOAT, data);
/* Upload back to VBO. */
GPU_vertbuf_use(pr_call->vbo);
glBufferSubData(GL_ARRAY_BUFFER,

View File

@ -84,14 +84,15 @@ uint *DRW_select_buffer_read(struct Depsgraph *depsgraph,
GPUFrameBuffer *select_id_fb = DRW_engine_select_framebuffer_get();
GPU_framebuffer_bind(select_id_fb);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(rect_clamp.xmin,
rect_clamp.ymin,
BLI_rcti_size_x(&rect_clamp),
BLI_rcti_size_y(&rect_clamp),
GL_RED_INTEGER,
GL_UNSIGNED_INT,
r_buf);
GPU_framebuffer_read_color(select_id_fb,
rect_clamp.xmin,
rect_clamp.ymin,
BLI_rcti_size_x(&rect_clamp),
BLI_rcti_size_y(&rect_clamp),
1,
0,
GPU_DATA_UNSIGNED_INT,
r_buf);
if (!BLI_rcti_compare(rect, &rect_clamp)) {
/* The rect has been clamped so you need to realign the buffer and fill in the blanks */

View File

@ -55,9 +55,10 @@
#include "RNA_access.h"
#include "RNA_define.h"
#include "GPU_glew.h"
#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "GPU_texture.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@ -246,7 +247,7 @@ static void imapaint_project(float matrix[4][4], const float co[3], float pco[4]
}
static void imapaint_tri_weights(float matrix[4][4],
const GLint view[4],
const int view[4],
const float v1[3],
const float v2[3],
const float v3[3],
@ -300,7 +301,7 @@ static void imapaint_pick_uv(
int i, findex;
float p[2], w[3], absw, minabsw;
float matrix[4][4], proj[4][4];
GLint view[4];
int view[4];
const eImagePaintMode mode = scene->toolsettings->imapaint.mode;
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
@ -576,20 +577,16 @@ void paint_sample_color(
}
if (!sample_success) {
glReadBuffer(GL_FRONT);
glReadPixels(
x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
glReadBuffer(GL_BACK);
GPU_frontbuffer_read_pixels(
x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, 4, GPU_DATA_UNSIGNED_BYTE, &col);
}
else {
return;
}
}
else {
glReadBuffer(GL_FRONT);
glReadPixels(
x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
glReadBuffer(GL_BACK);
GPU_frontbuffer_read_pixels(
x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, 4, GPU_DATA_UNSIGNED_BYTE, &col);
}
cp = (uchar *)&col;

View File

@ -28,7 +28,7 @@
extern "C" {
#endif
struct GPUTexture;
#include "GPU_texture.h"
typedef struct GPUAttachment {
struct GPUTexture *tex;
@ -176,8 +176,15 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb,
void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]);
void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int w, int h, float *data);
void GPU_framebuffer_read_color(
GPUFrameBuffer *fb, int x, int y, int w, int h, int channels, int slot, float *data);
void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
int x,
int y,
int w,
int h,
int channels,
int slot,
eGPUDataFormat format,
void *data);
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
int read_slot,
@ -214,6 +221,9 @@ void GPU_clear_color(float red, float green, float blue, float alpha);
void GPU_clear_depth(float depth);
void GPU_clear(eGPUFrameBufferBits flags);
void GPU_frontbuffer_read_pixels(
int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data);
#ifdef __cplusplus
}
#endif

View File

@ -640,31 +640,65 @@ void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int w, int h,
glReadPixels(x, y, w, h, type, GL_FLOAT, data);
}
void GPU_framebuffer_read_color(
GPUFrameBuffer *fb, int x, int y, int w, int h, int channels, int slot, float *data)
static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
{
CHECK_FRAMEBUFFER_IS_BOUND(fb);
switch (format) {
case GPU_DATA_FLOAT:
return GL_FLOAT;
case GPU_DATA_INT:
return GL_INT;
case GPU_DATA_UNSIGNED_INT:
return GL_UNSIGNED_INT;
case GPU_DATA_UNSIGNED_BYTE:
return GL_UNSIGNED_BYTE;
case GPU_DATA_UNSIGNED_INT_24_8:
return GL_UNSIGNED_INT_24_8;
case GPU_DATA_10_11_11_REV:
return GL_UNSIGNED_INT_10F_11F_11F_REV;
default:
BLI_assert(!"Unhandled data format");
return GL_FLOAT;
}
}
GLenum type;
static GLenum gpu_get_gl_channel_type(int channels)
{
switch (channels) {
case 1:
type = GL_RED;
break;
return GL_RED;
case 2:
type = GL_RG;
break;
return GL_RG;
case 3:
type = GL_RGB;
break;
return GL_RGB;
case 4:
type = GL_RGBA;
break;
return GL_RGBA;
default:
BLI_assert(false && "wrong number of read channels");
return;
BLI_assert(!"Wrong number of read channels");
return GL_RED;
}
glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
glReadPixels(x, y, w, h, type, GL_FLOAT, data);
}
static void gpu_framebuffer_read_color_ex(
int x, int y, int w, int h, int channels, GLenum readfb, eGPUDataFormat format, float *data)
{
GLenum type = gpu_get_gl_channel_type(channels);
GLenum gl_format = gpu_get_gl_datatype(format);
glReadBuffer(readfb);
glReadPixels(x, y, w, h, type, gl_format, data);
}
void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
int x,
int y,
int w,
int h,
int channels,
int slot,
eGPUDataFormat format,
void *data)
{
CHECK_FRAMEBUFFER_IS_BOUND(fb);
gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, data);
}
/* read_slot and write_slot are only used for color buffers. */
@ -749,9 +783,9 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
}
/**
* Use this if you need to custom down-sample your texture and use the previous mip level as input.
* This function only takes care of the correct texture handling.
* It execute the callback for each texture level.
* Use this if you need to custom down-sample your texture and use the previous mip level as
* input. This function only takes care of the correct texture handling. It execute the callback
* for each texture level.
*/
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
int max_lvl,
@ -1035,3 +1069,10 @@ void GPU_clear(eGPUFrameBufferBits flags)
{
glClear(convert_buffer_bits_to_gl(flags));
}
void GPU_frontbuffer_read_pixels(
int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
{
glReadBuffer(GL_FRONT);
gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, data);
}

View File

@ -89,6 +89,7 @@
#include "GPU_init_exit.h"
#include "GPU_platform.h"
#include "GPU_state.h"
#include "GPU_texture.h"
#include "UI_resources.h"
@ -2054,9 +2055,7 @@ void WM_window_pixel_sample_read(const wmWindowManager *wm,
GPU_context_active_set(win->gpuctx);
}
glReadBuffer(GL_FRONT);
glReadPixels(pos[0], pos[1], 1, 1, GL_RGB, GL_FLOAT, r_col);
glReadBuffer(GL_BACK);
GPU_frontbuffer_read_pixels(pos[0], pos[1], 1, 1, 3, GPU_DATA_FLOAT, r_col);
if (setup_context) {
if (wm->windrawable) {
@ -2089,10 +2088,7 @@ uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
const uint rect_len = r_size[0] * r_size[1];
uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, r_size[0], r_size[1], GL_RGBA, GL_UNSIGNED_BYTE, rect);
glFinish();
glReadBuffer(GL_BACK);
GPU_frontbuffer_read_pixels(0, 0, r_size[0], r_size[1], 4, GPU_DATA_UNSIGNED_BYTE, rect);
if (setup_context) {
if (wm->windrawable) {