diff options
author | Julian Eisel <julian@blender.org> | 2020-07-01 18:13:57 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-07-01 18:13:57 +0300 |
commit | 0829cebeb024095c268f190c34daa8ae9a5a224c (patch) | |
tree | 12ee5a4a1c2a32e12eff47c8eb9bb0ed217791c1 /source/blender/gpu/intern | |
parent | cfde6ebf450594faa57c4bfeaecff10fe512c91b (diff) | |
parent | 42be3964eb201180f6b0fa1ff6ce43b8c3845bc2 (diff) |
Merge branch 'master' into asset-uuid--archivedasset-uuid--archived
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 38 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 75 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw_smoke.c | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 23 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_platform.c | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_state.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 13 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_buffer.c | 29 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_vertex_format.c | 14 |
10 files changed, 145 insertions, 60 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index cef90d57ef5..9c21f9040da 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -34,6 +34,7 @@ #include "BLI_hash.h" #include "BLI_math.h" #include "BLI_math_color.h" +#include "BLI_math_color_blend.h" #include "BLI_utildefines.h" #include "DNA_meshdata_types.h" @@ -227,12 +228,13 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, const int *sculpt_face_sets, const int face_sets_color_seed, const int face_sets_color_default, + const MPropCol *vtcol, const int update_flags) { const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; - const bool show_vcol = vcol && (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; const bool show_face_sets = sculpt_face_sets && (update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0; + const bool show_vcol = (vcol || vtcol) && (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; bool empty_mask = true; bool default_face_set = true; @@ -244,8 +246,8 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, GPUVertBufRaw pos_step = {0}; GPUVertBufRaw nor_step = {0}; GPUVertBufRaw msk_step = {0}; - GPUVertBufRaw col_step = {0}; GPUVertBufRaw fset_step = {0}; + GPUVertBufRaw col_step = {0}; GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.pos, &pos_step); GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.nor, &nor_step); @@ -312,25 +314,33 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, *(uchar *)GPU_vertbuf_raw_step(&msk_step) = cmask; empty_mask = empty_mask && (cmask == 0); - + /* Vertex Colors. */ if (show_vcol) { - const uint loop_index = lt->tri[j]; - const MLoopCol *mcol = &vcol[loop_index]; - ushort scol[4]; - scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]); - scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]); - scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]); - scol[3] = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f)); - memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol)); + ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + if (vtcol) { + scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]); + scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]); + scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]); + scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]); + memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol)); + } + else { + const uint loop_index = lt->tri[j]; + const MLoopCol *mcol = &vcol[loop_index]; + scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]); + scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]); + scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]); + scol[3] = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f)); + memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol)); + } } - /* Face Sets. */ memcpy(GPU_vertbuf_raw_step(&fset_step), face_set_color, sizeof(uchar) * 3); } } - - gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); } + + gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); } /* Get material index from the first face of this buffer. */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index b03b0fc0b1e..f07e3ed70d7 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -60,7 +60,8 @@ #include "PIL_time.h" -static void gpu_free_image_immediate(Image *ima); +static void gpu_free_image(Image *ima, const bool immediate); +static void gpu_free_unused_buffers(void); //* Checking powers of two for images since OpenGL ES requires it */ #ifdef WITH_DDS @@ -859,9 +860,13 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, return NULL; } + /* Free any unused GPU textures, since we know we are in a thread with OpenGL + * context and might as well ensure we have as much space free as possible. */ + gpu_free_unused_buffers(); + /* currently, gpu refresh tagging is used by ima sequences */ if (ima->gpuflag & IMA_GPU_REFRESH) { - gpu_free_image_immediate(ima); + gpu_free_image(ima, true); ima->gpuflag &= ~IMA_GPU_REFRESH; } @@ -1338,63 +1343,65 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i #endif } -static LinkNode *image_free_queue = NULL; -static ThreadMutex img_queue_mutex = BLI_MUTEX_INITIALIZER; +/* Delayed GPU texture free. Image datablocks can be deleted by any thread, + * but there may not be any active OpenGL context. In that case we push them + * into a queue and free the buffers later. */ +static LinkNode *gpu_texture_free_queue = NULL; +static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER; -static void gpu_queue_image_for_free(Image *ima) +static void gpu_free_unused_buffers() { - BLI_mutex_lock(&img_queue_mutex); - BLI_linklist_prepend(&image_free_queue, ima); - BLI_mutex_unlock(&img_queue_mutex); -} - -void GPU_free_unused_buffers(Main *bmain) -{ - if (!BLI_thread_is_main()) { + if (gpu_texture_free_queue == NULL) { return; } - BLI_mutex_lock(&img_queue_mutex); - - /* images */ - for (LinkNode *node = image_free_queue; node; node = node->next) { - Image *ima = node->link; + BLI_mutex_lock(&gpu_texture_queue_mutex); - /* check in case it was freed in the meantime */ - if (bmain && BLI_findindex(&bmain->images, ima) != -1) { - GPU_free_image(ima); + if (gpu_texture_free_queue != NULL) { + for (LinkNode *node = gpu_texture_free_queue; node; node = node->next) { + GPUTexture *tex = node->link; + GPU_texture_free(tex); } - } - BLI_linklist_free(image_free_queue, NULL); - image_free_queue = NULL; + BLI_linklist_free(gpu_texture_free_queue, NULL); + gpu_texture_free_queue = NULL; + } - BLI_mutex_unlock(&img_queue_mutex); + BLI_mutex_unlock(&gpu_texture_queue_mutex); } -static void gpu_free_image_immediate(Image *ima) +static void gpu_free_image(Image *ima, const bool immediate) { for (int eye = 0; eye < 2; eye++) { for (int i = 0; i < TEXTARGET_COUNT; i++) { - /* free glsl image binding */ if (ima->gputexture[i][eye] != NULL) { - GPU_texture_free(ima->gputexture[i][eye]); + if (immediate) { + GPU_texture_free(ima->gputexture[i][eye]); + } + else { + BLI_mutex_lock(&gpu_texture_queue_mutex); + BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]); + BLI_mutex_unlock(&gpu_texture_queue_mutex); + } + ima->gputexture[i][eye] = NULL; } } } - ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE); + ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE; } -void GPU_free_image(Image *ima) +void GPU_free_unused_buffers() { - if (!BLI_thread_is_main()) { - gpu_queue_image_for_free(ima); - return; + if (BLI_thread_is_main()) { + gpu_free_unused_buffers(); } +} - gpu_free_image_immediate(ima); +void GPU_free_image(Image *ima) +{ + gpu_free_image(ima, BLI_thread_is_main()); } void GPU_free_images(Main *bmain) diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/gpu/intern/gpu_draw_smoke.c index 80c59ed47c9..67947df0ff7 100644 --- a/source/blender/gpu/intern/gpu_draw_smoke.c +++ b/source/blender/gpu/intern/gpu_draw_smoke.c @@ -99,6 +99,7 @@ static void create_color_ramp(const struct ColorBand *coba, float *data) { for (int i = 0; i < TFUNC_WIDTH; i++) { BKE_colorband_evaluate(coba, (float)i / TFUNC_WIDTH, &data[i * 4]); + straight_to_premul_v4(&data[i * 4]); } } @@ -115,7 +116,7 @@ static GPUTexture *create_transfer_function(int type, const struct ColorBand *co break; } - GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_RGBA8, data, NULL); + GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_SRGB8_A8, data, NULL); MEM_freeN(data); diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index ab55fcfb1e0..fbeb2edc266 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -71,7 +71,7 @@ static struct GPUGlobal { int samples_color_texture_max; float line_width_range[2]; /* workaround for different calculation of dfdy factors on GPUs. Some GPUs/drivers - * calculate dfdy in shader differently when drawing to an offscreen buffer. First + * calculate dfdy in shader differently when drawing to an off-screen buffer. First * number is factor on screen and second is off-screen */ float dfdyfactors[2]; float max_anisotropy; @@ -84,9 +84,9 @@ static struct GPUGlobal { * GL_TEXTURE_MAX_LEVEL is higher than the target mip. * We need a workaround in this cases. */ bool mip_render_workaround; - /* There is an issue with the glBlitFramebuffer on MacOS with radeon pro graphics. - * Blitting depth with GL_DEPTH24_STENCIL8 is buggy so the workaround is to use - * GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will + /* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics. + * Blitting depth with#GL_DEPTH24_STENCIL8 is buggy so the workaround is to use + * #GPU_DEPTH32F_STENCIL8. Then Blitting depth will work but blitting stencil will * still be broken. */ bool depth_blitting_workaround; /* Crappy driver don't know how to map framebuffer slot to output vars... @@ -96,7 +96,7 @@ static struct GPUGlobal { /* Some crappy Intel drivers don't work well with shaders created in different * rendering contexts. */ bool context_local_shaders_workaround; - /* Intel drivers exhibit artifacts when using glCopyImageSubData & workbench antialiasing. + /* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing. * (see T76273) */ bool texture_copy_workaround; } GG = {1, 0}; @@ -288,6 +288,19 @@ void gpu_extensions_init(void) } } + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && + strstr(renderer, "AMD VERDE")) { + /* We have issues with this specific renderer. (see T74024) */ + GG.unused_fb_slot_workaround = true; + GG.broken_amd_driver = true; + } + + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) && + strstr(version, "Mesa 19.3.4")) { + /* Fix slowdown on this particular driver. (see T77641) */ + GG.broken_amd_driver = true; + } + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { if (strstr(renderer, "AMD Radeon Pro") || strstr(renderer, "AMD Radeon R9") || strstr(renderer, "AMD Radeon RX")) { diff --git a/source/blender/gpu/intern/gpu_platform.c b/source/blender/gpu/intern/gpu_platform.c index a758787466f..5cabde61bc3 100644 --- a/source/blender/gpu/intern/gpu_platform.c +++ b/source/blender/gpu/intern/gpu_platform.c @@ -44,6 +44,8 @@ static struct GPUPlatformGlobal { char *gpu_name; } GPG = {false}; +/* Remove this? */ +#if 0 typedef struct GPUPlatformSupportTest { eGPUSupportLevel support_level; eGPUDeviceType device; @@ -53,6 +55,7 @@ typedef struct GPUPlatformSupportTest { const char *renderer; const char *version; } GPUPlatformSupportTest; +#endif eGPUSupportLevel GPU_platform_support_level(void) { diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 8c03567b95f..711147a61e9 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -117,6 +117,7 @@ extern char datatoc_gpu_shader_2D_point_uniform_size_varying_color_outline_aa_ve extern char datatoc_gpu_shader_2D_edituvs_points_vert_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_facedots_vert_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_edges_vert_glsl[]; +extern char datatoc_gpu_shader_2D_edituvs_edges_frag_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_faces_vert_glsl[]; extern char datatoc_gpu_shader_2D_edituvs_stretch_vert_glsl[]; @@ -1171,12 +1172,12 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { [GPU_SHADER_2D_UV_EDGES] = { .vert = datatoc_gpu_shader_2D_edituvs_edges_vert_glsl, - .frag = datatoc_gpu_shader_flat_color_frag_glsl, + .frag = datatoc_gpu_shader_2D_edituvs_edges_frag_glsl, }, [GPU_SHADER_2D_UV_EDGES_SMOOTH] = { .vert = datatoc_gpu_shader_2D_edituvs_edges_vert_glsl, - .frag = datatoc_gpu_shader_2D_smooth_color_frag_glsl, + .frag = datatoc_gpu_shader_2D_edituvs_edges_frag_glsl, .defs = "#define SMOOTH_COLOR\n", }, [GPU_SHADER_2D_UV_FACES] = diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.c index 908f5fa5771..30b258a73d1 100644 --- a/source/blender/gpu/intern/gpu_state.c +++ b/source/blender/gpu/intern/gpu_state.c @@ -208,7 +208,7 @@ typedef struct { uint is_cull_face : 1; uint is_depth_test : 1; uint is_dither : 1; - uint is_lighting : 1; + /* uint is_lighting : 1; */ /* UNUSED */ uint is_line_smooth : 1; uint is_color_logic_op : 1; uint is_multisample : 1; diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index a985d45162c..56e82b94fd2 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -677,12 +677,14 @@ static bool gpu_texture_check_capacity( GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type) { if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_ANY) || + GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_OFFICIAL) || GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL)) { /* Some AMD drivers have a faulty `GL_PROXY_TEXTURE_..` check. * (see T55888, T56185, T59351). * Checking with `GL_PROXY_TEXTURE_..` doesn't prevent `Out Of Memory` issue, * it just states that the OGL implementation can support the texture. - * So manually check the maximum size and maximum number of layers. */ + * So manually check the maximum size and maximum number of layers. + * Same thing happens on Nvidia/macOS 10.15 (T78175). */ switch (proxy) { case GL_PROXY_TEXTURE_2D_ARRAY: if ((tex->d < 0) || (tex->d > GPU_max_texture_layers())) { @@ -1772,8 +1774,13 @@ void GPU_texture_unbind(GPUTexture *tex) void GPU_texture_unbind_all(void) { if (GLEW_ARB_multi_bind) { - glBindTextures(0, GPU_max_textures(), NULL); - glBindSamplers(0, GPU_max_textures(), NULL); + /* Some drivers crash because of the NULL array even if that's explicitly + * allowed by the spec... *sigh* (see T77549). */ + GLuint texs[32] = {0}; + int count = min_ii(32, GPU_max_textures()); + + glBindTextures(0, count, texs); + glBindSamplers(0, count, texs); return; } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index 25daabe601d..3b4d469542c 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -85,6 +85,35 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, } } +GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts) +{ + GPUVertBuf *verts_dst = GPU_vertbuf_create(GPU_USAGE_STATIC); + /* Full copy. */ + *verts_dst = *verts; + GPU_vertformat_copy(&verts_dst->format, &verts->format); + + if (verts->vbo_id) { + uint buffer_sz = GPU_vertbuf_size_get(verts); + + verts_dst->vbo_id = GPU_buf_alloc(); + + glBindBuffer(GL_COPY_READ_BUFFER, verts->vbo_id); + glBindBuffer(GL_COPY_WRITE_BUFFER, verts_dst->vbo_id); + + glBufferData(GL_COPY_WRITE_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); + + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, buffer_sz); +#if VRAM_USAGE + vbo_memory_usage += GPU_vertbuf_size_get(verts); +#endif + } + + if (verts->data) { + verts_dst->data = MEM_dupallocN(verts->data); + } + return verts_dst; +} + /** Same as discard but does not free. */ void GPU_vertbuf_clear(GPUVertBuf *verts) { diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index b84a7e0f554..585a22277b2 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -262,6 +262,20 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name) return -1; } +void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr_id, const char *new_name) +{ + BLI_assert(attr_id > -1 && attr_id < format->attr_len); + GPUVertAttr *attr = &format->attrs[attr_id]; + char *attr_name = (char *)GPU_vertformat_attr_name_get(format, attr, 0); + BLI_assert(strlen(attr_name) == strlen(new_name)); + int i = 0; + while (attr_name[i] != '\0') { + attr_name[i] = new_name[i]; + i++; + } + attr->name_len = 1; +} + /* Encode 8 original bytes into 11 safe bytes. */ static void safe_bytes(char out[11], const char data[8]) { |