Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-07-01 18:13:57 +0300
committerJulian Eisel <julian@blender.org>2020-07-01 18:13:57 +0300
commit0829cebeb024095c268f190c34daa8ae9a5a224c (patch)
tree12ee5a4a1c2a32e12eff47c8eb9bb0ed217791c1 /source/blender/gpu/intern
parentcfde6ebf450594faa57c4bfeaecff10fe512c91b (diff)
parent42be3964eb201180f6b0fa1ff6ce43b8c3845bc2 (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.c38
-rw-r--r--source/blender/gpu/intern/gpu_draw.c75
-rw-r--r--source/blender/gpu/intern/gpu_draw_smoke.c3
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c23
-rw-r--r--source/blender/gpu/intern/gpu_platform.c3
-rw-r--r--source/blender/gpu/intern/gpu_shader.c5
-rw-r--r--source/blender/gpu/intern/gpu_state.c2
-rw-r--r--source/blender/gpu/intern/gpu_texture.c13
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.c29
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.c14
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])
{