Optimization for initial display of high res textures in viewport
Multi-thread all the color space conversion operations. Gives speedup from 0.8 to 0.1 seconds on a model with 4k etxture on it.
This commit is contained in:
@@ -509,6 +509,81 @@ static void gpu_verify_reflection(Image *ima)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct VerifyTreadInitData {
|
||||
ImBuf *ibuf;
|
||||
float *srgb_frect;
|
||||
} VerifyTreadInitData;
|
||||
|
||||
typedef struct VerifyThreadData {
|
||||
ImBuf *ibuf;
|
||||
float *srgb_frect;
|
||||
int start_line;
|
||||
int height;
|
||||
} VerifyThreadData;
|
||||
|
||||
static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect,
|
||||
ImBuf *ibuf,
|
||||
const int start_line,
|
||||
const int height)
|
||||
{
|
||||
size_t offset = ibuf->channels * start_line * ibuf->x;
|
||||
float *current_srgb_frect = srgb_frect + offset;
|
||||
float *current_rect_float = ibuf->rect_float + offset;
|
||||
IMB_buffer_float_from_float(current_srgb_frect,
|
||||
current_rect_float,
|
||||
ibuf->channels,
|
||||
IB_PROFILE_SRGB,
|
||||
IB_PROFILE_LINEAR_RGB, true,
|
||||
ibuf->x, height,
|
||||
ibuf->x, ibuf->x);
|
||||
IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height);
|
||||
/* Clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images. */
|
||||
IMB_buffer_float_clamp(current_srgb_frect, ibuf->x, height);
|
||||
}
|
||||
|
||||
static void verify_thread_init(void *data_v,
|
||||
int start_line,
|
||||
int height,
|
||||
void *init_data_v)
|
||||
{
|
||||
VerifyThreadData *data = (VerifyThreadData *) data_v;
|
||||
VerifyTreadInitData *init_data = (VerifyTreadInitData *) init_data_v;
|
||||
data->ibuf = init_data->ibuf;
|
||||
data->srgb_frect = init_data->srgb_frect;
|
||||
data->start_line = start_line;
|
||||
data->height = height;
|
||||
}
|
||||
|
||||
static void *verify_thread_do(void *data_v)
|
||||
{
|
||||
VerifyThreadData *data = (VerifyThreadData *)data_v;
|
||||
gpu_verify_high_bit_srgb_buffer_slice(data->srgb_frect,
|
||||
data->ibuf,
|
||||
data->start_line,
|
||||
data->height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect,
|
||||
ImBuf *ibuf)
|
||||
{
|
||||
if (ibuf->y < 64) {
|
||||
gpu_verify_high_bit_srgb_buffer_slice(srgb_frect,
|
||||
ibuf,
|
||||
0, ibuf->y);
|
||||
}
|
||||
else {
|
||||
VerifyTreadInitData init_data;
|
||||
init_data.ibuf = ibuf;
|
||||
init_data.srgb_frect = srgb_frect;
|
||||
IMB_processor_apply_threaded(ibuf->y,
|
||||
sizeof(VerifyThreadData),
|
||||
&init_data,
|
||||
verify_thread_init,
|
||||
verify_thread_do);
|
||||
}
|
||||
}
|
||||
|
||||
int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bool compare, bool mipmap, bool is_data)
|
||||
{
|
||||
unsigned int *bind = NULL;
|
||||
@@ -575,17 +650,18 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo
|
||||
* a high precision format only if it is available */
|
||||
use_high_bit_depth = true;
|
||||
}
|
||||
else if (ibuf->rect == NULL) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
/* we may skip this in high precision, but if not, we need to have a valid buffer here */
|
||||
else if (ibuf->userflags & IB_RECT_INVALID) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
/* TODO unneeded when float images are correctly treated as linear always */
|
||||
if (!is_data)
|
||||
if (!is_data) {
|
||||
do_color_management = true;
|
||||
|
||||
if (ibuf->rect == NULL)
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* currently, tpage refresh is used by ima sequences */
|
||||
@@ -622,12 +698,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo
|
||||
if (use_high_bit_depth) {
|
||||
if (do_color_management) {
|
||||
srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "floar_buf_col_cor");
|
||||
IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
|
||||
ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true,
|
||||
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
|
||||
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
|
||||
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
|
||||
gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
|
||||
frect = srgb_frect + texwinsy * ibuf->x + texwinsx;
|
||||
}
|
||||
else {
|
||||
@@ -650,13 +721,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo
|
||||
if (use_high_bit_depth) {
|
||||
if (do_color_management) {
|
||||
frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor");
|
||||
IMB_buffer_float_from_float(
|
||||
srgb_frect, ibuf->rect_float,
|
||||
ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true,
|
||||
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y);
|
||||
/* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */
|
||||
IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y);
|
||||
gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
|
||||
}
|
||||
else
|
||||
frect = ibuf->rect_float;
|
||||
|
Reference in New Issue
Block a user