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)
|
int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bool compare, bool mipmap, bool is_data)
|
||||||
{
|
{
|
||||||
unsigned int *bind = NULL;
|
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 */
|
* a high precision format only if it is available */
|
||||||
use_high_bit_depth = true;
|
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 */
|
/* 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) {
|
else if (ibuf->userflags & IB_RECT_INVALID) {
|
||||||
IMB_rect_from_float(ibuf);
|
IMB_rect_from_float(ibuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO unneeded when float images are correctly treated as linear always */
|
/* TODO unneeded when float images are correctly treated as linear always */
|
||||||
if (!is_data)
|
if (!is_data) {
|
||||||
do_color_management = true;
|
do_color_management = true;
|
||||||
|
}
|
||||||
if (ibuf->rect == NULL)
|
|
||||||
IMB_rect_from_float(ibuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* currently, tpage refresh is used by ima sequences */
|
/* 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 (use_high_bit_depth) {
|
||||||
if (do_color_management) {
|
if (do_color_management) {
|
||||||
srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "floar_buf_col_cor");
|
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,
|
gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
|
||||||
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);
|
|
||||||
frect = srgb_frect + texwinsy * ibuf->x + texwinsx;
|
frect = srgb_frect + texwinsy * ibuf->x + texwinsx;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -650,13 +721,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo
|
|||||||
if (use_high_bit_depth) {
|
if (use_high_bit_depth) {
|
||||||
if (do_color_management) {
|
if (do_color_management) {
|
||||||
frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor");
|
frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor");
|
||||||
IMB_buffer_float_from_float(
|
gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
frect = ibuf->rect_float;
|
frect = ibuf->rect_float;
|
||||||
|
Reference in New Issue
Block a user