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>2022-11-10 15:17:42 +0300
committerJulian Eisel <julian@blender.org>2022-11-10 15:17:42 +0300
commit7246c387435769a169ac24c91434c615df6434b4 (patch)
tree61842e3e0ce85e80720fdd7476d44d2e629f59fd /source/blender/gpu/intern
parentc5f55d17096d373791363e46004176e3f7f7ae52 (diff)
parent0b4bd3ddc016298e868169a541cf6c132b10c587 (diff)
Merge branch 'master' into asset-browser-grid-viewasset-browser-grid-view
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_backend.hh2
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c1475
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc12
-rw-r--r--source/blender/gpu/intern/gpu_context.cc39
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc18
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer_private.hh18
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc11
-rw-r--r--source/blender/gpu/intern/gpu_immediate_private.hh8
-rw-r--r--source/blender/gpu/intern/gpu_immediate_util.c8
-rw-r--r--source/blender/gpu/intern/gpu_index_buffer.cc6
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c8
-rw-r--r--source/blender/gpu/intern/gpu_material.c71
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc8
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c115
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h16
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder.cc53
-rw-r--r--source/blender/gpu/intern/gpu_shader_builder_stubs.cc147
-rw-r--r--source/blender/gpu/intern/gpu_shader_builtin.c5
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc26
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc7
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc4
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh2
-rw-r--r--source/blender/gpu/intern/gpu_shader_log.cc6
-rw-r--r--source/blender/gpu/intern/gpu_state.cc30
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc29
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh10
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc10
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c4
30 files changed, 495 insertions, 1656 deletions
diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh
index d2890efee72..2a545c8114e 100644
--- a/source/blender/gpu/intern/gpu_backend.hh
+++ b/source/blender/gpu/intern/gpu_backend.hh
@@ -38,7 +38,7 @@ class GPUBackend {
virtual void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) = 0;
virtual void compute_dispatch_indirect(StorageBuf *indirect_buf) = 0;
- virtual Context *context_alloc(void *ghost_window) = 0;
+ virtual Context *context_alloc(void *ghost_window, void *ghost_context) = 0;
virtual Batch *batch_alloc() = 0;
virtual DrawList *drawlist_alloc(int list_length) = 0;
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index c871004deac..e1876f6d8ac 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -56,7 +56,6 @@ void GPU_batch_init_ex(GPUBatch *batch,
GPUIndexBuf *elem,
eGPUBatchFlag owns_flag)
{
- BLI_assert(verts != nullptr);
/* Do not pass any other flag */
BLI_assert((owns_flag & ~(GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX)) == 0);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
deleted file mode 100644
index 78f595cbff2..00000000000
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later
- * Copyright 2005 Blender Foundation. All rights reserved. */
-
-/** \file
- * \ingroup gpu
- *
- * Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
- */
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_bitmap.h"
-#include "BLI_ghash.h"
-#include "BLI_math_color.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BKE_DerivedMesh.h"
-#include "BKE_attribute.h"
-#include "BKE_ccg.h"
-#include "BKE_customdata.h"
-#include "BKE_mesh.h"
-#include "BKE_paint.h"
-#include "BKE_pbvh.h"
-#include "BKE_subdiv_ccg.h"
-
-#include "GPU_batch.h"
-#include "GPU_buffers.h"
-
-#include "DRW_engine.h"
-
-#include "gpu_private.h"
-
-#include "bmesh.h"
-
-struct GPU_PBVH_Buffers {
- GPUIndexBuf *index_buf, *index_buf_fast;
- GPUIndexBuf *index_lines_buf, *index_lines_buf_fast;
- GPUVertBuf *vert_buf;
-
- GPUBatch *lines;
- GPUBatch *lines_fast;
- GPUBatch *triangles;
- GPUBatch *triangles_fast;
-
- /* mesh pointers in case buffer allocation fails */
- const MPoly *mpoly;
- const MLoop *mloop;
- const MLoopTri *looptri;
- const MVert *mvert;
-
- const int *face_indices;
- int face_indices_len;
-
- /* grid pointers */
- CCGKey gridkey;
- CCGElem **grids;
- const DMFlagMat *grid_flag_mats;
- BLI_bitmap *const *grid_hidden;
- const int *grid_indices;
- int totgrid;
-
- bool use_bmesh;
- bool clear_bmesh_on_flush;
-
- uint tot_tri, tot_quad;
-
- short material_index;
-
- /* The PBVH ensures that either all faces in the node are
- * smooth-shaded or all faces are flat-shaded */
- bool smooth;
-
- bool show_overlay;
-};
-
-typedef struct GPUAttrRef {
- uchar domain, type;
- ushort cd_offset;
- int layer_idx;
-} GPUAttrRef;
-
-#define MAX_GPU_ATTR 256
-
-typedef struct PBVHGPUFormat {
- GPUVertFormat format;
- uint pos, nor, msk, fset;
- uint col[MAX_GPU_ATTR];
- uint uv[MAX_GPU_ATTR];
- int totcol, totuv;
-
- /* Upload only the active color and UV attributes,
- * used for workbench mode. */
- bool active_attrs_only;
-} PBVHGPUFormat;
-
-PBVHGPUFormat *GPU_pbvh_make_format(void)
-{
- PBVHGPUFormat *vbo_id = MEM_callocN(sizeof(PBVHGPUFormat), "PBVHGPUFormat");
-
- GPU_pbvh_attribute_names_update(PBVH_FACES, vbo_id, NULL, NULL, false);
-
- return vbo_id;
-}
-
-void GPU_pbvh_free_format(PBVHGPUFormat *vbo_id)
-{
- MEM_SAFE_FREE(vbo_id);
-}
-
-static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask,
- eCustomDataMask type_mask,
- const CustomData *vdata,
- const CustomData *edata,
- const CustomData *ldata,
- const CustomData *pdata,
- GPUAttrRef r_cd_attrs[MAX_GPU_ATTR],
- bool active_only,
- int active_type,
- int active_domain,
- const CustomDataLayer *active_layer,
- const CustomDataLayer *render_layer);
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name PBVH Utils
- * \{ */
-
-void gpu_pbvh_init()
-{
-}
-
-void gpu_pbvh_exit()
-{
- /* Nothing to do. */
-}
-
-static CustomDataLayer *get_active_layer(const CustomData *cdata, int type)
-{
- int idx = CustomData_get_active_layer_index(cdata, type);
- return idx != -1 ? cdata->layers + idx : NULL;
-}
-
-static CustomDataLayer *get_render_layer(const CustomData *cdata, int type)
-{
- int idx = CustomData_get_render_layer_index(cdata, type);
- return idx != -1 ? cdata->layers + idx : NULL;
-}
-
-/* Allocates a non-initialized buffer to be sent to GPU.
- * Return is false it indicates that the memory map failed. */
-static bool gpu_pbvh_vert_buf_data_set(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- uint vert_len)
-{
- /* Keep so we can test #GPU_USAGE_DYNAMIC buffer use.
- * Not that format initialization match in both blocks.
- * Do this to keep braces balanced - otherwise indentation breaks. */
-
- if (buffers->vert_buf == NULL) {
- /* Initialize vertex buffer (match 'VertexBufferFormat'). */
- buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&vbo_id->format, GPU_USAGE_STATIC);
- }
- if (GPU_vertbuf_get_data(buffers->vert_buf) == NULL ||
- GPU_vertbuf_get_vertex_len(buffers->vert_buf) != vert_len) {
- /* Allocate buffer if not allocated yet or size changed. */
- GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
- }
-
- return GPU_vertbuf_get_data(buffers->vert_buf) != NULL;
-}
-
-static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
-{
- if (buffers->triangles == NULL) {
- buffers->triangles = GPU_batch_create(prim,
- buffers->vert_buf,
- /* can be NULL if buffer is empty */
- buffers->index_buf);
- }
-
- if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) {
- buffers->triangles_fast = GPU_batch_create(prim, buffers->vert_buf, buffers->index_buf_fast);
- }
-
- if (buffers->lines == NULL) {
- buffers->lines = GPU_batch_create(GPU_PRIM_LINES,
- buffers->vert_buf,
- /* can be NULL if buffer is empty */
- buffers->index_lines_buf);
- }
-
- if ((buffers->lines_fast == NULL) && buffers->index_lines_buf_fast) {
- buffers->lines_fast = GPU_batch_create(
- GPU_PRIM_LINES, buffers->vert_buf, buffers->index_lines_buf_fast);
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Mesh PBVH
- * \{ */
-
-static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt, const bool *hide_poly)
-{
- return !paint_is_face_hidden(lt, hide_poly);
-}
-
-void GPU_pbvh_mesh_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- const Mesh *mesh,
- const MVert *mvert,
- const float *vmask,
- const int *sculpt_face_sets,
- int face_sets_color_seed,
- int face_sets_color_default,
- int update_flags,
- const float (*vert_normals)[3])
-{
- GPUAttrRef vcol_refs[MAX_GPU_ATTR];
- GPUAttrRef cd_uvs[MAX_GPU_ATTR];
-
- const bool *hide_poly = (const bool *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
- const int *material_indices = (const int *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_INT32, "material_index");
-
- const CustomDataLayer *actcol = BKE_id_attributes_active_color_get(&mesh->id);
- eAttrDomain actcol_domain = actcol ? BKE_id_attribute_domain(&mesh->id, actcol) :
- ATTR_DOMAIN_AUTO;
-
- const CustomDataLayer *rendercol = BKE_id_attributes_render_color_get(&mesh->id);
-
- int totcol;
-
- if (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) {
- totcol = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_COLOR,
- CD_MASK_COLOR_ALL,
- &mesh->vdata,
- NULL,
- &mesh->ldata,
- NULL,
- vcol_refs,
- vbo_id->active_attrs_only,
- actcol ? actcol->type : 0,
- actcol_domain,
- actcol,
- rendercol);
- }
- else {
- totcol = 0;
- }
-
- int totuv = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_CORNER,
- CD_MASK_MLOOPUV,
- NULL,
- NULL,
- &mesh->ldata,
- NULL,
- cd_uvs,
- vbo_id->active_attrs_only,
- CD_MLOOPUV,
- ATTR_DOMAIN_CORNER,
- get_active_layer(&mesh->ldata, CD_MLOOPUV),
- get_render_layer(&mesh->ldata, CD_MLOOPUV));
-
- const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_face_sets = sculpt_face_sets &&
- (update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- bool empty_mask = true;
- bool default_face_set = true;
-
- {
- const int totelem = buffers->tot_tri * 3;
-
- /* Build VBO */
- if (gpu_pbvh_vert_buf_data_set(vbo_id, buffers, totelem)) {
- GPUVertBufRaw pos_step = {0};
- GPUVertBufRaw nor_step = {0};
- GPUVertBufRaw msk_step = {0};
- GPUVertBufRaw fset_step = {0};
- GPUVertBufRaw col_step = {0};
- GPUVertBufRaw uv_step = {0};
-
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->pos, &pos_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->nor, &nor_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->msk, &msk_step);
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->fset, &fset_step);
-
- /* calculate normal for each polygon only once */
- uint mpoly_prev = UINT_MAX;
- short no[3] = {0, 0, 0};
-
- if (totuv > 0) {
- for (int uv_i = 0; uv_i < totuv; uv_i++) {
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->uv[uv_i], &uv_step);
-
- GPUAttrRef *ref = cd_uvs + uv_i;
- CustomDataLayer *layer = mesh->ldata.layers + ref->layer_idx;
- MLoopUV *muv = layer->data;
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- for (uint j = 0; j < 3; j++) {
- MLoopUV *muv2 = muv + lt->tri[j];
-
- memcpy(GPU_vertbuf_raw_step(&uv_step), muv2->uv, sizeof(muv2->uv));
- }
- }
- }
- }
-
- for (int col_i = 0; col_i < totcol; col_i++) {
- GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, vbo_id->col[col_i], &col_step);
-
- const MPropCol *pcol = NULL;
- const MLoopCol *mcol = NULL;
-
- GPUAttrRef *ref = vcol_refs + col_i;
- const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? &mesh->vdata : &mesh->ldata;
- const CustomDataLayer *layer = cdata->layers + ref->layer_idx;
-
- bool color_loops = ref->domain == ATTR_DOMAIN_CORNER;
-
- if (layer->type == CD_PROP_COLOR) {
- pcol = (const MPropCol *)layer->data;
- }
- else {
- mcol = (const MLoopCol *)layer->data;
- }
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- const uint vtri[3] = {
- buffers->mloop[lt->tri[0]].v,
- buffers->mloop[lt->tri[1]].v,
- buffers->mloop[lt->tri[2]].v,
- };
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- for (uint j = 0; j < 3; j++) {
- /* Vertex Colors. */
- const uint loop_index = lt->tri[j];
-
- ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
-
- if (pcol) {
- const MPropCol *pcol2 = pcol + (color_loops ? loop_index : vtri[j]);
-
- scol[0] = unit_float_to_ushort_clamp(pcol2->color[0]);
- scol[1] = unit_float_to_ushort_clamp(pcol2->color[1]);
- scol[2] = unit_float_to_ushort_clamp(pcol2->color[2]);
- scol[3] = unit_float_to_ushort_clamp(pcol2->color[3]);
- }
- else {
- const MLoopCol *mcol2 = mcol + (color_loops ? loop_index : vtri[j]);
-
- scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->r]);
- scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->g]);
- scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol2->b]);
- scol[3] = unit_float_to_ushort_clamp(mcol2->a * (1.0f / 255.0f));
- }
-
- memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
- }
- }
- }
-
- for (uint i = 0; i < buffers->face_indices_len; i++) {
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- const uint vtri[3] = {
- buffers->mloop[lt->tri[0]].v,
- buffers->mloop[lt->tri[1]].v,
- buffers->mloop[lt->tri[2]].v,
- };
-
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- /* Face normal and mask */
- if (lt->poly != mpoly_prev && !buffers->smooth) {
- const MPoly *mp = &buffers->mpoly[lt->poly];
- float fno[3];
- BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
- normal_float_to_short_v3(no, fno);
- mpoly_prev = lt->poly;
- }
-
- uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
- if (show_face_sets) {
- const int fset = abs(sculpt_face_sets[lt->poly]);
- /* Skip for the default color Face Set to render it white. */
- if (fset != face_sets_color_default) {
- BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
- default_face_set = false;
- }
- }
-
- float fmask = 0.0f;
- uchar cmask = 0;
- if (show_mask && !buffers->smooth) {
- fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
- cmask = (uchar)(fmask * 255);
- }
-
- for (uint j = 0; j < 3; j++) {
- const MVert *v = &mvert[vtri[j]];
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), v->co);
-
- if (buffers->smooth) {
- normal_float_to_short_v3(no, vert_normals[vtri[j]]);
- }
- copy_v3_v3_short(GPU_vertbuf_raw_step(&nor_step), no);
-
- if (show_mask && buffers->smooth) {
- cmask = (uchar)(vmask[vtri[j]] * 255);
- }
-
- *(uchar *)GPU_vertbuf_raw_step(&msk_step) = cmask;
- empty_mask = empty_mask && (cmask == 0);
- /* Face Sets. */
- memcpy(GPU_vertbuf_raw_step(&fset_step), face_set_color, sizeof(uchar[3]));
- }
- }
- }
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
- }
-
- /* Get material index from the first face of this buffer. */
- const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
- buffers->material_index = material_indices ? material_indices[lt->poly] : 0;
-
- buffers->show_overlay = !empty_mask || !default_face_set;
- buffers->mvert = mvert;
-}
-
-GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh,
- const MLoopTri *looptri,
- const int *face_indices,
- const int face_indices_len)
-{
- GPU_PBVH_Buffers *buffers;
- int i, tottri;
- int tot_real_edges = 0;
-
- const MPoly *polys = BKE_mesh_polys(mesh);
- const MLoop *loops = BKE_mesh_loops(mesh);
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
-
- const bool *hide_poly = (bool *)CustomData_get_layer_named(
- &mesh->pdata, CD_PROP_BOOL, ".hide_poly");
-
- /* smooth or flat for all */
- buffers->smooth = polys[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
-
- buffers->show_overlay = false;
-
- /* Count the number of visible triangles */
- for (i = 0, tottri = 0; i < face_indices_len; i++) {
- const MLoopTri *lt = &looptri[face_indices[i]];
- if (gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- int r_edges[3];
- BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
- for (int j = 0; j < 3; j++) {
- if (r_edges[j] != -1) {
- tot_real_edges++;
- }
- }
- tottri++;
- }
- }
-
- if (tottri == 0) {
- buffers->tot_tri = 0;
-
- buffers->mpoly = polys;
- buffers->mloop = loops;
- buffers->looptri = looptri;
- buffers->face_indices = face_indices;
- buffers->face_indices_len = 0;
-
- return buffers;
- }
-
- /* Fill the only the line buffer. */
- GPUIndexBufBuilder elb_lines;
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tot_real_edges, INT_MAX);
- int vert_idx = 0;
-
- for (i = 0; i < face_indices_len; i++) {
- const MLoopTri *lt = &looptri[face_indices[i]];
-
- /* Skip hidden faces */
- if (!gpu_pbvh_is_looptri_visible(lt, hide_poly)) {
- continue;
- }
-
- int r_edges[3];
- BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
- if (r_edges[0] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 0, vert_idx * 3 + 1);
- }
- if (r_edges[1] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 1, vert_idx * 3 + 2);
- }
- if (r_edges[2] != -1) {
- GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 2, vert_idx * 3 + 0);
- }
-
- vert_idx++;
- }
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
-
- buffers->tot_tri = tottri;
-
- buffers->mpoly = polys;
- buffers->mloop = loops;
- buffers->looptri = looptri;
-
- buffers->face_indices = face_indices;
- buffers->face_indices_len = face_indices_len;
-
- return buffers;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Grid PBVH
- * \{ */
-
-static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers *buffers,
- SubdivCCG *UNUSED(subdiv_ccg),
- const int *UNUSED(face_sets),
- const int *grid_indices,
- uint visible_quad_len,
- int totgrid,
- int gridsize)
-{
- GPUIndexBufBuilder elb, elb_lines;
- GPUIndexBufBuilder elb_fast, elb_lines_fast;
-
- GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
- GPU_indexbuf_init(&elb_fast, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX);
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX);
- GPU_indexbuf_init(&elb_lines_fast, GPU_PRIM_LINES, 4 * totgrid, INT_MAX);
-
- if (buffers->smooth) {
- uint offset = 0;
- const uint grid_vert_len = gridsize * gridsize;
- for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
- uint v0, v1, v2, v3;
- bool grid_visible = false;
-
- BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
-
- for (int j = 0; j < gridsize - 1; j++) {
- for (int k = 0; k < gridsize - 1; k++) {
- /* Skip hidden grid face */
- if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
- continue;
- }
- /* Indices in a Clockwise QUAD disposition. */
- v0 = offset + j * gridsize + k;
- v1 = v0 + 1;
- v2 = v1 + gridsize;
- v3 = v2 - 1;
-
- GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
-
- if (j + 2 == gridsize) {
- GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
- }
- grid_visible = true;
- }
-
- if (grid_visible) {
- GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
- }
- }
-
- if (grid_visible) {
- /* Grid corners */
- v0 = offset;
- v1 = offset + gridsize - 1;
- v2 = offset + grid_vert_len - 1;
- v3 = offset + grid_vert_len - gridsize;
-
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
- }
- }
- }
- else {
- uint offset = 0;
- const uint grid_vert_len = square_uint(gridsize - 1) * 4;
- for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
- bool grid_visible = false;
- BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
-
- uint v0, v1, v2, v3;
- for (int j = 0; j < gridsize - 1; j++) {
- for (int k = 0; k < gridsize - 1; k++) {
- /* Skip hidden grid face */
- if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
- continue;
- }
- /* VBO data are in a Clockwise QUAD disposition. */
- v0 = offset + (j * (gridsize - 1) + k) * 4;
- v1 = v0 + 1;
- v2 = v0 + 2;
- v3 = v0 + 3;
-
- GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
-
- if (j + 2 == gridsize) {
- GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
- }
- grid_visible = true;
- }
-
- if (grid_visible) {
- GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
- }
- }
-
- if (grid_visible) {
- /* Grid corners */
- v0 = offset;
- v1 = offset + (gridsize - 1) * 4 - 3;
- v2 = offset + grid_vert_len - 2;
- v3 = offset + grid_vert_len - (gridsize - 1) * 4 + 3;
-
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
- GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
-
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
- GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
- }
- }
- }
-
- buffers->index_buf = GPU_indexbuf_build(&elb);
- buffers->index_buf_fast = GPU_indexbuf_build(&elb_fast);
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines_fast);
-}
-
-void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
- const struct DMFlagMat *grid_flag_mats,
- const int *grid_indices)
-{
- const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
-
- if (buffers->smooth != smooth) {
- buffers->smooth = smooth;
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
-
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- }
-}
-
-void GPU_pbvh_grid_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- SubdivCCG *subdiv_ccg,
- CCGElem **grids,
- const struct DMFlagMat *grid_flag_mats,
- int *grid_indices,
- int totgrid,
- const int *sculpt_face_sets,
- const int face_sets_color_seed,
- const int face_sets_color_default,
- const struct CCGKey *key,
- const int update_flags)
-{
- const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_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;
- bool empty_mask = true;
- bool default_face_set = true;
-
- int i, j, k, x, y;
-
- /* Build VBO */
- const int has_mask = key->has_mask;
-
- uint vert_per_grid = (buffers->smooth) ? key->grid_area : (square_i(key->grid_size - 1) * 4);
- uint vert_count = totgrid * vert_per_grid;
-
- if (buffers->index_buf == NULL) {
- uint visible_quad_len = BKE_pbvh_count_grid_quads(
- (BLI_bitmap **)buffers->grid_hidden, grid_indices, totgrid, key->grid_size);
-
- /* totally hidden node, return here to avoid BufferData with zero below. */
- if (visible_quad_len == 0) {
- return;
- }
-
- gpu_pbvh_grid_fill_index_buffers(buffers,
- subdiv_ccg,
- sculpt_face_sets,
- grid_indices,
- visible_quad_len,
- totgrid,
- key->grid_size);
- }
-
- uint vbo_index_offset = 0;
- /* Build VBO */
- if (gpu_pbvh_vert_buf_data_set(vbo_id, buffers, vert_count)) {
- GPUIndexBufBuilder elb_lines;
-
- if (buffers->index_lines_buf == NULL) {
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, totgrid * key->grid_area * 2, vert_count);
- }
-
- for (i = 0; i < totgrid; i++) {
- const int grid_index = grid_indices[i];
- CCGElem *grid = grids[grid_index];
- int vbo_index = vbo_index_offset;
-
- uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
-
- if (show_face_sets && subdiv_ccg && sculpt_face_sets) {
- const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, grid_index);
-
- const int fset = abs(sculpt_face_sets[face_index]);
- /* Skip for the default color Face Set to render it white. */
- if (fset != face_sets_color_default) {
- BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
- default_face_set = false;
- }
- }
-
- if (buffers->smooth) {
- for (y = 0; y < key->grid_size; y++) {
- for (x = 0; x < key->grid_size; x++) {
- CCGElem *elem = CCG_grid_elem(key, grid, x, y);
- GPU_vertbuf_attr_set(
- buffers->vert_buf, vbo_id->pos, vbo_index, CCG_elem_co(key, elem));
-
- short no_short[3];
- normal_float_to_short_v3(no_short, CCG_elem_no(key, elem));
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index, no_short);
-
- if (has_mask && show_mask) {
- float fmask = *CCG_elem_mask(key, elem);
- uchar cmask = (uchar)(fmask * 255);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index, &cmask);
- empty_mask = empty_mask && (cmask == 0);
- }
-
- if (show_vcol) {
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index, &vcol);
- }
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index, &face_set_color);
-
- vbo_index += 1;
- }
- }
- vbo_index_offset += key->grid_area;
- }
- else {
- for (j = 0; j < key->grid_size - 1; j++) {
- for (k = 0; k < key->grid_size - 1; k++) {
- CCGElem *elems[4] = {
- CCG_grid_elem(key, grid, k, j),
- CCG_grid_elem(key, grid, k + 1, j),
- CCG_grid_elem(key, grid, k + 1, j + 1),
- CCG_grid_elem(key, grid, k, j + 1),
- };
- float *co[4] = {
- CCG_elem_co(key, elems[0]),
- CCG_elem_co(key, elems[1]),
- CCG_elem_co(key, elems[2]),
- CCG_elem_co(key, elems[3]),
- };
-
- float fno[3];
- short no_short[3];
- /* NOTE: Clockwise indices ordering, that's why we invert order here. */
- normal_quad_v3(fno, co[3], co[2], co[1], co[0]);
- normal_float_to_short_v3(no_short, fno);
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 0, co[0]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 0, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 1, co[1]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 1, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 2, co[2]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 2, no_short);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->pos, vbo_index + 3, co[3]);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->nor, vbo_index + 3, no_short);
-
- if (has_mask && show_mask) {
- float fmask = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) +
- *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) *
- 0.25f;
- uchar cmask = (uchar)(fmask * 255);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 0, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 1, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 2, &cmask);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->msk, vbo_index + 3, &cmask);
- empty_mask = empty_mask && (cmask == 0);
- }
-
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 0, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 1, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 2, &vcol);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->col[0], vbo_index + 3, &vcol);
-
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 0, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 1, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 2, &face_set_color);
- GPU_vertbuf_attr_set(buffers->vert_buf, vbo_id->fset, vbo_index + 3, &face_set_color);
-
- vbo_index += 4;
- }
- }
- vbo_index_offset += square_i(key->grid_size - 1) * 4;
- }
- }
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
- }
-
- /* Get material index from the first face of this buffer. */
- buffers->material_index = grid_flag_mats[grid_indices[0]].mat_nr;
-
- buffers->grids = grids;
- buffers->grid_indices = grid_indices;
- buffers->totgrid = totgrid;
- buffers->grid_flag_mats = grid_flag_mats;
- buffers->gridkey = *key;
- buffers->show_overlay = !empty_mask || !default_face_set;
-}
-
-GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden, bool smooth)
-{
- GPU_PBVH_Buffers *buffers;
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- buffers->grid_hidden = grid_hidden;
- buffers->totgrid = totgrid;
- buffers->smooth = smooth;
-
- buffers->show_overlay = false;
-
- return buffers;
-}
-
-#undef FILL_QUAD_BUFFER
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name BMesh PBVH
- * \{ */
-
-/* Output a BMVert into a VertexBufferFormat array at v_index. */
-static void gpu_bmesh_vert_to_buffer_copy(PBVHGPUFormat *vbo_id,
- BMVert *v,
- GPUVertBuf *vert_buf,
- int v_index,
- const float fno[3],
- const float *fmask,
- const int cd_vert_mask_offset,
- const bool show_mask,
- const bool show_vcol,
- bool *empty_mask)
-{
- /* Vertex should always be visible if it's used by a visible face. */
- BLI_assert(!BM_elem_flag_test(v, BM_ELEM_HIDDEN));
-
- /* Set coord, normal, and mask */
- GPU_vertbuf_attr_set(vert_buf, vbo_id->pos, v_index, v->co);
-
- short no_short[3];
- normal_float_to_short_v3(no_short, fno ? fno : v->no);
- GPU_vertbuf_attr_set(vert_buf, vbo_id->nor, v_index, no_short);
-
- if (show_mask) {
- float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
- uchar cmask = (uchar)(effective_mask * 255);
- GPU_vertbuf_attr_set(vert_buf, vbo_id->msk, v_index, &cmask);
- *empty_mask = *empty_mask && (cmask == 0);
- }
-
- if (show_vcol) {
- const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- GPU_vertbuf_attr_set(vert_buf, vbo_id->col[0], v_index, &vcol);
- }
-
- /* Add default face sets color to avoid artifacts. */
- const uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
- GPU_vertbuf_attr_set(vert_buf, vbo_id->fset, v_index, &face_set);
-}
-
-/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
-static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts, GSet *bm_other_verts)
-{
- GSetIterator gs_iter;
- int totvert = 0;
-
- GSET_ITER (gs_iter, bm_unique_verts) {
- BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- totvert++;
- }
- }
- GSET_ITER (gs_iter, bm_other_verts) {
- BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
- if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- totvert++;
- }
- }
-
- return totvert;
-}
-
-/* Return the total number of visible faces */
-static int gpu_bmesh_face_visible_count(GSet *bm_faces)
-{
- GSetIterator gh_iter;
- int totface = 0;
-
- GSET_ITER (gh_iter, bm_faces) {
- BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- totface++;
- }
- }
-
- return totface;
-}
-
-void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers)
-{
- if (buffers->smooth) {
- /* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- }
- else {
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- }
-}
-
-void GPU_pbvh_bmesh_buffers_update(PBVHGPUFormat *vbo_id,
- GPU_PBVH_Buffers *buffers,
- BMesh *bm,
- GSet *bm_faces,
- GSet *bm_unique_verts,
- GSet *bm_other_verts,
- const int update_flags)
-{
- const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
- const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
- int tottri, totvert;
- bool empty_mask = true;
- BMFace *f = NULL;
-
- /* Count visible triangles */
- tottri = gpu_bmesh_face_visible_count(bm_faces);
-
- if (buffers->smooth) {
- /* Count visible vertices */
- totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
- }
- else {
- totvert = tottri * 3;
- }
-
- if (!tottri) {
- if (BLI_gset_len(bm_faces) != 0) {
- /* Node is just hidden. */
- }
- else {
- buffers->clear_bmesh_on_flush = true;
- }
- buffers->tot_tri = 0;
- return;
- }
-
- /* TODO: make mask layer optional for bmesh buffer. */
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
-
- /* Fill vertex buffer */
- if (!gpu_pbvh_vert_buf_data_set(vbo_id, buffers, totvert)) {
- /* Memory map failed */
- return;
- }
-
- int v_index = 0;
-
- if (buffers->smooth) {
- /* Fill the vertex and triangle buffer in one pass over faces. */
- GPUIndexBufBuilder elb, elb_lines;
- GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, totvert);
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
-
- GHash *bm_vert_to_index = BLI_ghash_int_new_ex("bm_vert_to_index", totvert);
-
- GSetIterator gs_iter;
- GSET_ITER (gs_iter, bm_faces) {
- f = BLI_gsetIterator_getKey(&gs_iter);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- BMVert *v[3];
- BM_face_as_array_vert_tri(f, v);
-
- uint idx[3];
- for (int i = 0; i < 3; i++) {
- void **idx_p;
- if (!BLI_ghash_ensure_p(bm_vert_to_index, v[i], &idx_p)) {
- /* Add vertex to the vertex buffer each time a new one is encountered */
- *idx_p = POINTER_FROM_UINT(v_index);
-
- gpu_bmesh_vert_to_buffer_copy(vbo_id,
- v[i],
- buffers->vert_buf,
- v_index,
- NULL,
- NULL,
- cd_vert_mask_offset,
- show_mask,
- show_vcol,
- &empty_mask);
-
- idx[i] = v_index;
- v_index++;
- }
- else {
- /* Vertex already in the vertex buffer, just get the index. */
- idx[i] = POINTER_AS_UINT(*idx_p);
- }
- }
-
- GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
-
- GPU_indexbuf_add_line_verts(&elb_lines, idx[0], idx[1]);
- GPU_indexbuf_add_line_verts(&elb_lines, idx[1], idx[2]);
- GPU_indexbuf_add_line_verts(&elb_lines, idx[2], idx[0]);
- }
- }
-
- BLI_ghash_free(bm_vert_to_index, NULL, NULL);
-
- buffers->tot_tri = tottri;
- if (buffers->index_buf == NULL) {
- buffers->index_buf = GPU_indexbuf_build(&elb);
- }
- else {
- GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
- }
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- }
- else {
- GSetIterator gs_iter;
-
- GPUIndexBufBuilder elb_lines;
- GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, tottri * 3);
-
- GSET_ITER (gs_iter, bm_faces) {
- f = BLI_gsetIterator_getKey(&gs_iter);
-
- BLI_assert(f->len == 3);
-
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- BMVert *v[3];
- float fmask = 0.0f;
- int i;
-
- BM_face_as_array_vert_tri(f, v);
-
- /* Average mask value */
- for (i = 0; i < 3; i++) {
- fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
- }
- fmask /= 3.0f;
-
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 0, v_index + 1);
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
- GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
-
- for (i = 0; i < 3; i++) {
- gpu_bmesh_vert_to_buffer_copy(vbo_id,
- v[i],
- buffers->vert_buf,
- v_index++,
- f->no,
- &fmask,
- cd_vert_mask_offset,
- show_mask,
- show_vcol,
- &empty_mask);
- }
- }
- }
-
- buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
- buffers->tot_tri = tottri;
- }
-
- /* Get material index from the last face we iterated on. */
- buffers->material_index = (f) ? f->mat_nr : 0;
-
- buffers->show_overlay = !empty_mask;
-
- gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Generic
- * \{ */
-
-GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
-{
- GPU_PBVH_Buffers *buffers;
-
- buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- buffers->use_bmesh = true;
- buffers->smooth = smooth_shading;
- buffers->show_overlay = true;
-
- return buffers;
-}
-
-/**
- * Builds a list of attributes from a set of domains and a set of
- * customdata types.
- *
- * \param active_only: Returns only one item, a #GPUAttrRef to active_layer.
- * \param active_layer: #CustomDataLayer to use for the active layer.
- * \param active_layer: #CustomDataLayer to use for the render layer.
- */
-static int gpu_pbvh_make_attr_offs(eAttrDomainMask domain_mask,
- eCustomDataMask type_mask,
- const CustomData *vdata,
- const CustomData *edata,
- const CustomData *ldata,
- const CustomData *pdata,
- GPUAttrRef r_cd_attrs[MAX_GPU_ATTR],
- bool active_only,
- int active_type,
- int active_domain,
- const CustomDataLayer *active_layer,
- const CustomDataLayer *render_layer)
-{
- const CustomData *cdata_active = active_domain == ATTR_DOMAIN_POINT ? vdata : ldata;
-
- if (!cdata_active) {
- return 0;
- }
-
- if (active_only) {
- int idx = active_layer ? active_layer - cdata_active->layers : -1;
-
- if (idx >= 0 && idx < cdata_active->totlayer) {
- r_cd_attrs[0].cd_offset = cdata_active->layers[idx].offset;
- r_cd_attrs[0].domain = active_domain;
- r_cd_attrs[0].type = active_type;
- r_cd_attrs[0].layer_idx = idx;
-
- return 1;
- }
-
- return 0;
- }
-
- const CustomData *datas[4] = {vdata, edata, pdata, ldata};
-
- int count = 0;
- for (eAttrDomain domain = 0; domain < 4; domain++) {
- const CustomData *cdata = datas[domain];
-
- if (!cdata || !((1 << domain) & domain_mask)) {
- continue;
- }
-
- const CustomDataLayer *cl = cdata->layers;
-
- for (int i = 0; count < MAX_GPU_ATTR && i < cdata->totlayer; i++, cl++) {
- if ((CD_TYPE_AS_MASK(cl->type) & type_mask) && !(cl->flag & CD_FLAG_TEMPORARY)) {
- GPUAttrRef *ref = r_cd_attrs + count;
-
- ref->cd_offset = cl->offset;
- ref->type = cl->type;
- ref->layer_idx = i;
- ref->domain = domain;
-
- count++;
- }
- }
- }
-
- /* Ensure render layer is last, draw cache code seems to need this. */
-
- for (int i = 0; i < count; i++) {
- GPUAttrRef *ref = r_cd_attrs + i;
- const CustomData *cdata = datas[ref->domain];
-
- if (cdata->layers + ref->layer_idx == render_layer) {
- SWAP(GPUAttrRef, r_cd_attrs[i], r_cd_attrs[count - 1]);
- break;
- }
- }
-
- return count;
-}
-
-static bool gpu_pbvh_format_equals(PBVHGPUFormat *a, PBVHGPUFormat *b)
-{
- bool bad = false;
-
- bad |= a->active_attrs_only != b->active_attrs_only;
-
- bad |= a->pos != b->pos;
- bad |= a->fset != b->fset;
- bad |= a->msk != b->msk;
- bad |= a->nor != b->nor;
-
- for (int i = 0; i < MIN2(a->totuv, b->totuv); i++) {
- bad |= a->uv[i] != b->uv[i];
- }
-
- for (int i = 0; i < MIN2(a->totcol, b->totcol); i++) {
- bad |= a->col[i] != b->col[i];
- }
-
- bad |= a->totuv != b->totuv;
- bad |= a->totcol != b->totcol;
-
- return !bad;
-}
-
-bool GPU_pbvh_attribute_names_update(PBVHType pbvh_type,
- PBVHGPUFormat *vbo_id,
- const CustomData *vdata,
- const CustomData *ldata,
- bool active_attrs_only)
-{
- const bool active_only = active_attrs_only;
- PBVHGPUFormat old_format = *vbo_id;
-
- GPU_vertformat_clear(&vbo_id->format);
-
- vbo_id->active_attrs_only = active_attrs_only;
-
- if (vbo_id->format.attr_len == 0) {
- vbo_id->pos = GPU_vertformat_attr_add(
- &vbo_id->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- vbo_id->nor = GPU_vertformat_attr_add(
- &vbo_id->format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- /* TODO: Do not allocate these `.msk` and `.col` when they are not used. */
- vbo_id->msk = GPU_vertformat_attr_add(
- &vbo_id->format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- vbo_id->totcol = 0;
- if (pbvh_type == PBVH_FACES) {
- int ci = 0;
-
- Mesh me_query;
-
- BKE_id_attribute_copy_domains_temp(ID_ME, vdata, NULL, ldata, NULL, NULL, &me_query.id);
-
- const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me_query.id);
- const CustomDataLayer *render_color_layer = BKE_id_attributes_render_color_get(&me_query.id);
- eAttrDomain active_color_domain = active_color_layer ?
- BKE_id_attribute_domain(&me_query.id,
- active_color_layer) :
- ATTR_DOMAIN_POINT;
-
- GPUAttrRef vcol_layers[MAX_GPU_ATTR];
- int totlayer = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_COLOR,
- CD_MASK_COLOR_ALL,
- vdata,
- NULL,
- ldata,
- NULL,
- vcol_layers,
- active_only,
- active_color_layer ? active_color_layer->type : -1,
- active_color_domain,
- active_color_layer,
- render_color_layer);
-
- for (int i = 0; i < totlayer; i++) {
- GPUAttrRef *ref = vcol_layers + i;
- const CustomData *cdata = ref->domain == ATTR_DOMAIN_POINT ? vdata : ldata;
-
- const CustomDataLayer *layer = cdata->layers + ref->layer_idx;
-
- if (vbo_id->totcol < MAX_GPU_ATTR) {
- vbo_id->col[ci++] = GPU_vertformat_attr_add(
- &vbo_id->format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- vbo_id->totcol++;
-
- bool is_render = render_color_layer == layer;
- bool is_active = active_color_layer == layer;
-
- DRW_cdlayer_attr_aliases_add(&vbo_id->format, "c", cdata, layer, is_render, is_active);
- }
- }
- }
-
- /* ensure at least one vertex color layer */
- if (vbo_id->totcol == 0) {
- vbo_id->col[0] = GPU_vertformat_attr_add(
- &vbo_id->format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- vbo_id->totcol = 1;
-
- GPU_vertformat_alias_add(&vbo_id->format, "ac");
- }
-
- vbo_id->fset = GPU_vertformat_attr_add(
- &vbo_id->format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- vbo_id->totuv = 0;
- if (pbvh_type == PBVH_FACES && ldata && CustomData_has_layer(ldata, CD_MLOOPUV)) {
- GPUAttrRef uv_layers[MAX_GPU_ATTR];
- const CustomDataLayer *active = NULL, *render = NULL;
-
- active = get_active_layer(ldata, CD_MLOOPUV);
- render = get_render_layer(ldata, CD_MLOOPUV);
-
- int totlayer = gpu_pbvh_make_attr_offs(ATTR_DOMAIN_MASK_CORNER,
- CD_MASK_MLOOPUV,
- NULL,
- NULL,
- ldata,
- NULL,
- uv_layers,
- active_only,
- CD_MLOOPUV,
- ATTR_DOMAIN_CORNER,
- active,
- render);
-
- vbo_id->totuv = totlayer;
-
- for (int i = 0; i < totlayer; i++) {
- GPUAttrRef *ref = uv_layers + i;
-
- vbo_id->uv[i] = GPU_vertformat_attr_add(
- &vbo_id->format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- const CustomDataLayer *cl = ldata->layers + ref->layer_idx;
- bool is_active = ref->layer_idx == CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
-
- DRW_cdlayer_attr_aliases_add(&vbo_id->format, "u", ldata, cl, cl == render, is_active);
-
- /* Apparently the render attribute is 'a' while active is 'au',
- * at least going by the draw cache extractor code.
- */
- if (cl == render) {
- GPU_vertformat_alias_add(&vbo_id->format, "a");
- }
- }
- }
- }
-
- if (!gpu_pbvh_format_equals(&old_format, vbo_id)) {
- return true;
- }
-
- return false;
-}
-
-GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires)
-{
- if (wires) {
- return (fast && buffers->lines_fast) ? buffers->lines_fast : buffers->lines;
- }
-
- return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles;
-}
-
-bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers)
-{
- return buffers->show_overlay;
-}
-
-short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers)
-{
- return buffers->material_index;
-}
-
-static void gpu_pbvh_buffers_clear(GPU_PBVH_Buffers *buffers)
-{
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
-}
-
-void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers)
-{
- /* Free empty bmesh node buffers. */
- if (buffers->clear_bmesh_on_flush) {
- gpu_pbvh_buffers_clear(buffers);
- buffers->clear_bmesh_on_flush = false;
- }
-
- /* Force flushing to the GPU. */
- if (buffers->vert_buf && GPU_vertbuf_get_data(buffers->vert_buf)) {
- GPU_vertbuf_use(buffers->vert_buf);
- }
-}
-
-void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
-{
- if (buffers) {
- gpu_pbvh_buffers_clear(buffers);
- MEM_freeN(buffers);
- }
-}
-
-/** \} */
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index 75e148e0a8f..4adeac1b49a 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -183,6 +183,8 @@ static std::ostream &operator<<(std::ostream &stream, const GPUInput *input)
return stream << "var_attrs.v" << input->attr->id;
case GPU_SOURCE_UNIFORM_ATTR:
return stream << "unf_attrs[resource_id].attr" << input->uniform_attr->id;
+ case GPU_SOURCE_LAYER_ATTR:
+ return stream << "attr_load_layer(" << input->layer_attr->hash_code << ")";
case GPU_SOURCE_STRUCT:
return stream << "strct" << input->id;
case GPU_SOURCE_TEX:
@@ -386,6 +388,10 @@ void GPUCodegen::generate_resources()
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(slot++, ImageType::FLOAT_1D_ARRAY, name, Frequency::BATCH);
}
+ else if (tex->sky) {
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
+ }
else if (tex->tiled_mapping_name[0] != '\0') {
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(slot++, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
@@ -428,6 +434,10 @@ void GPUCodegen::generate_resources()
info.uniform_buf(2, "UniformAttrs", GPU_ATTRIBUTE_UBO_BLOCK_NAME "[512]", Frequency::BATCH);
}
+ if (!BLI_listbase_is_empty(&graph.layer_attrs)) {
+ info.additional_info("draw_layer_attributes");
+ }
+
info.typedef_source_generated = ss.str();
}
@@ -807,7 +817,7 @@ void GPU_pass_cache_garbage_collect(void)
{
static int lasttime = 0;
const int shadercollectrate = 60; /* hardcoded for now. */
- int ctime = (int)PIL_check_seconds_timer();
+ int ctime = int(PIL_check_seconds_timer());
if (ctime < shadercollectrate + lasttime) {
return;
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index bcc418169b7..7e94538892a 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -33,6 +33,9 @@
# include "gl_backend.hh"
# include "gl_context.hh"
#endif
+#ifdef WITH_VULKAN_BACKEND
+# include "vk_backend.hh"
+#endif
#ifdef WITH_METAL_BACKEND
# include "mtl_backend.hh"
#endif
@@ -94,7 +97,7 @@ Context *Context::get()
/* -------------------------------------------------------------------- */
-GPUContext *GPU_context_create(void *ghost_window)
+GPUContext *GPU_context_create(void *ghost_window, void *ghost_context)
{
{
std::scoped_lock lock(backend_users_mutex);
@@ -105,7 +108,7 @@ GPUContext *GPU_context_create(void *ghost_window)
num_backend_users++;
}
- Context *ctx = GPUBackend::get()->context_alloc(ghost_window);
+ Context *ctx = GPUBackend::get()->context_alloc(ghost_window, ghost_context);
GPU_context_active_set(wrap(ctx));
return wrap(ctx);
@@ -195,7 +198,11 @@ void GPU_render_begin()
{
GPUBackend *backend = GPUBackend::get();
BLI_assert(backend);
- backend->render_begin();
+ /* WORKAROUND: Currently a band-aid for the heist production. Has no side effect for GL backend
+ * but should be fixed for Metal. */
+ if (backend) {
+ backend->render_begin();
+ }
}
void GPU_render_end()
{
@@ -216,9 +223,22 @@ void GPU_render_step()
/** \name Backend selection
* \{ */
-static const eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
+/* NOTE: To enable Metal API, we need to temporarily change this to `GPU_BACKEND_METAL`.
+ * Until a global switch is added, Metal also needs to be enabled in GHOST_ContextCGL:
+ * `m_useMetalForRendering = true`. */
+static eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL;
static GPUBackend *g_backend = nullptr;
+void GPU_backend_type_selection_set(const eGPUBackendType backend)
+{
+ g_backend_type = backend;
+}
+
+eGPUBackendType GPU_backend_type_selection_get()
+{
+ return g_backend_type;
+}
+
bool GPU_backend_supported(void)
{
switch (g_backend_type) {
@@ -228,6 +248,12 @@ bool GPU_backend_supported(void)
#else
return false;
#endif
+ case GPU_BACKEND_VULKAN:
+#ifdef WITH_VULKAN_BACKEND
+ return true;
+#else
+ return false;
+#endif
case GPU_BACKEND_METAL:
#ifdef WITH_METAL_BACKEND
return MTLBackend::metal_is_supported();
@@ -251,6 +277,11 @@ static void gpu_backend_create()
g_backend = new GLBackend;
break;
#endif
+#ifdef WITH_VULKAN_BACKEND
+ case GPU_BACKEND_VULKAN:
+ g_backend = new VKBackend;
+ break;
+#endif
#ifdef WITH_METAL_BACKEND
case GPU_BACKEND_METAL:
g_backend = new MTLBackend;
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index 8d93e49d588..5b50fd66196 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -148,9 +148,9 @@ void FrameBuffer::load_store_config_array(const GPULoadStore *load_store_actions
}
}
-unsigned int FrameBuffer::get_bits_per_pixel()
+uint FrameBuffer::get_bits_per_pixel()
{
- unsigned int total_bits = 0;
+ uint total_bits = 0;
for (GPUAttachment &attachment : attachments_) {
Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
if (tex != nullptr) {
@@ -179,7 +179,7 @@ void FrameBuffer::recursive_downsample(int max_lvl,
/* Some Intel HDXXX have issue with rendering to a mipmap that is below
* the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
* we allow GL_TEXTURE_MAX_LEVEL to be one level lower. In practice it does work! */
- int mip_max = (GPU_mip_render_workaround()) ? mip_lvl : (mip_lvl - 1);
+ int mip_max = GPU_mip_render_workaround() ? mip_lvl : (mip_lvl - 1);
/* Restrict fetches only to previous level. */
tex->mip_range_set(mip_lvl - 1, mip_max);
/* Bind next level. */
@@ -238,6 +238,11 @@ void GPU_framebuffer_free(GPUFrameBuffer *gpu_fb)
delete unwrap(gpu_fb);
}
+const char *GPU_framebuffer_get_name(GPUFrameBuffer *gpu_fb)
+{
+ return unwrap(gpu_fb)->name_get();
+}
+
/* ---------- Binding ----------- */
void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb)
@@ -368,6 +373,11 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *gpu_fb,
}
}
+void GPU_framebuffer_default_size(GPUFrameBuffer *gpu_fb, int width, int height)
+{
+ unwrap(gpu_fb)->size_set(width, height);
+}
+
/* ---------- Viewport & Scissor Region ----------- */
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
@@ -668,7 +678,7 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
unwrap(gpu_offscreen_fb_get(ofs))->bind(false);
}
-void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
+void GPU_offscreen_unbind(GPUOffScreen * /*ofs*/, bool restore)
{
GPUFrameBuffer *fb = nullptr;
if (restore) {
diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh
index 8cecc6b8b15..cb7fd62445c 100644
--- a/source/blender/gpu/intern/gpu_framebuffer_private.hh
+++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh
@@ -40,12 +40,12 @@ typedef enum GPUAttachmentType : int {
inline constexpr GPUAttachmentType operator-(GPUAttachmentType a, int b)
{
- return static_cast<GPUAttachmentType>(static_cast<int>(a) - b);
+ return static_cast<GPUAttachmentType>(int(a) - b);
}
inline constexpr GPUAttachmentType operator+(GPUAttachmentType a, int b)
{
- return static_cast<GPUAttachmentType>(static_cast<int>(a) + b);
+ return static_cast<GPUAttachmentType>(int(a) + b);
}
inline GPUAttachmentType &operator++(GPUAttachmentType &a)
@@ -74,9 +74,9 @@ class FrameBuffer {
/** Set of texture attachments to render to. DEPTH and DEPTH_STENCIL are mutually exclusive. */
GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT];
/** Is true if internal representation need to be updated. */
- bool dirty_attachments_;
+ bool dirty_attachments_ = true;
/** Size of attachment textures. */
- int width_, height_;
+ int width_ = 0, height_ = 0;
/** Debug name. */
char name_[DEBUG_NAME_LEN];
/** Frame-buffer state. */
@@ -95,11 +95,6 @@ class FrameBuffer {
#endif
public:
- /* Reference of a pointer that needs to be cleaned when deallocating the frame-buffer.
- * Points to #BPyGPUFrameBuffer::fb */
- void **ref = nullptr;
-
- public:
FrameBuffer(const char *name);
virtual ~FrameBuffer();
@@ -209,6 +204,11 @@ class FrameBuffer {
{
return attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex;
};
+
+ inline const char *const name_get() const
+ {
+ return name_;
+ };
};
/* Syntactic sugar. */
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 3b4accf9cc5..81c0a65bb7c 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -45,7 +45,7 @@ void immBindShader(GPUShader *shader)
BLI_assert(imm->shader == nullptr);
imm->shader = shader;
- imm->builtin_shader_bound = GPU_SHADER_TEXT; /* Default value. */
+ imm->builtin_shader_bound = std::nullopt;
if (!imm->vertex_format.packed) {
VertexFormat_pack(&imm->vertex_format);
@@ -125,9 +125,12 @@ static void wide_line_workaround_start(GPUPrimType prim_type)
/* No need to change the shader. */
return;
}
+ if (!imm->builtin_shader_bound) {
+ return;
+ }
eGPUBuiltinShader polyline_sh;
- switch (imm->builtin_shader_bound) {
+ switch (*imm->builtin_shader_bound) {
case GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR:
polyline_sh = GPU_SHADER_3D_POLYLINE_CLIPPED_UNIFORM_COLOR;
break;
@@ -180,8 +183,8 @@ static void wide_line_workaround_end()
}
immUnbindProgram();
- immBindBuiltinProgram(imm->prev_builtin_shader);
- imm->prev_builtin_shader = GPU_SHADER_TEXT;
+ immBindBuiltinProgram(*imm->prev_builtin_shader);
+ imm->prev_builtin_shader = std::nullopt;
}
}
diff --git a/source/blender/gpu/intern/gpu_immediate_private.hh b/source/blender/gpu/intern/gpu_immediate_private.hh
index 74ebbdc7ae3..c4e11e7082b 100644
--- a/source/blender/gpu/intern/gpu_immediate_private.hh
+++ b/source/blender/gpu/intern/gpu_immediate_private.hh
@@ -9,6 +9,8 @@
#pragma once
+#include <optional>
+
#include "GPU_batch.h"
#include "GPU_primitive.h"
#include "GPU_shader.h"
@@ -42,9 +44,9 @@ class Immediate {
/** Wide Line workaround. */
/** Previously bound shader to restore after drawing. */
- eGPUBuiltinShader prev_builtin_shader = GPU_SHADER_TEXT;
- /** Builtin shader index. Used to test if the workaround can be done. */
- eGPUBuiltinShader builtin_shader_bound = GPU_SHADER_TEXT;
+ std::optional<eGPUBuiltinShader> prev_builtin_shader;
+ /** Builtin shader index. Used to test if the line width workaround can be done. */
+ std::optional<eGPUBuiltinShader> builtin_shader_bound;
/** Uniform color: Kept here to update the wide-line shader just before #immBegin. */
float uniform_color[4];
diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c
index 743bc058b45..39b5a6a93c0 100644
--- a/source/blender/gpu/intern/gpu_immediate_util.c
+++ b/source/blender/gpu/intern/gpu_immediate_util.c
@@ -195,7 +195,7 @@ static void imm_draw_circle_partial(GPUPrimType prim_type,
float sweep)
{
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments);
@@ -219,7 +219,7 @@ static void imm_draw_circle_partial_3d(GPUPrimType prim_type,
float sweep)
{
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)(M_PI / 2);
+ const float angle_start = -DEG2RADF(start) + (float)(M_PI / 2);
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments);
@@ -259,7 +259,7 @@ static void imm_draw_disk_partial(GPUPrimType prim_type,
CLAMP(sweep, -max_angle, max_angle);
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments * 2);
@@ -289,7 +289,7 @@ static void imm_draw_disk_partial_3d(GPUPrimType prim_type,
CLAMP(sweep, -max_angle, max_angle);
/* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
- const float angle_start = -(DEG2RADF(start)) + (float)M_PI_2;
+ const float angle_start = -DEG2RADF(start) + (float)M_PI_2;
const float angle_end = -(DEG2RADF(sweep) - angle_start);
nsegments += 1;
immBegin(prim_type, nsegments * 2);
diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc
index 3a66f547403..99e47f5452a 100644
--- a/source/blender/gpu/intern/gpu_index_buffer.cc
+++ b/source/blender/gpu/intern/gpu_index_buffer.cc
@@ -76,7 +76,7 @@ void GPU_indexbuf_init(GPUIndexBufBuilder *builder,
#if TRUST_NO_ONE
assert(verts_per_prim != -1);
#endif
- GPU_indexbuf_init_ex(builder, prim_type, prim_len * (uint)verts_per_prim, vertex_len);
+ GPU_indexbuf_init_ex(builder, prim_type, prim_len * uint(verts_per_prim), vertex_len);
}
GPUIndexBuf *GPU_indexbuf_build_on_device(uint index_len)
@@ -388,13 +388,13 @@ void IndexBuf::squeeze_indices_short(uint min_idx,
0xFFFFu :
(max_idx - min_idx);
for (uint i = 0; i < index_len_; i++) {
- ushort_idx[i] = (uint16_t)MIN2(clamp_max_idx, uint_idx[i] - min_idx);
+ ushort_idx[i] = uint16_t(MIN2(clamp_max_idx, uint_idx[i] - min_idx));
}
}
else {
index_base_ = 0;
for (uint i = 0; i < index_len_; i++) {
- ushort_idx[i] = (uint16_t)(uint_idx[i]);
+ ushort_idx[i] = uint16_t(uint_idx[i]);
}
}
}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 34b355eefaf..2dbb4b215bb 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -36,18 +36,10 @@ void GPU_init(void)
gpu_codegen_init();
gpu_batch_init();
-
-#ifndef GPU_STANDALONE
- gpu_pbvh_init();
-#endif
}
void GPU_exit(void)
{
-#ifndef GPU_STANDALONE
- gpu_pbvh_exit();
-#endif
-
gpu_batch_exit();
gpu_codegen_exit();
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 75066b21e7b..ca2a9f5cf28 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -41,15 +41,21 @@
/* Structs */
#define MAX_COLOR_BAND 128
+#define MAX_GPU_SKIES 8
typedef struct GPUColorBandBuilder {
float pixels[MAX_COLOR_BAND][CM_TABLE + 1][4];
int current_layer;
} GPUColorBandBuilder;
+typedef struct GPUSkyBuilder {
+ float pixels[MAX_GPU_SKIES][GPU_SKY_WIDTH * GPU_SKY_HEIGHT][4];
+ int current_layer;
+} GPUSkyBuilder;
+
struct GPUMaterial {
- /* Contains GPUShader and source code for deferred compilation.
- * Can be shared between similar material (i.e: sharing same nodetree topology). */
+ /* Contains #GPUShader and source code for deferred compilation.
+ * Can be shared between similar material (i.e: sharing same node-tree topology). */
GPUPass *pass;
/** UBOs for this material parameters. */
GPUUniformBuf *ubo;
@@ -73,6 +79,10 @@ struct GPUMaterial {
GPUTexture *coba_tex;
/** Builder for coba_tex. */
GPUColorBandBuilder *coba_builder;
+ /** 2D Texture array containing all sky textures. */
+ GPUTexture *sky_tex;
+ /** Builder for sky_tex. */
+ GPUSkyBuilder *sky_builder;
/* Low level node graph(s). Also contains resources needed by the material. */
GPUNodeGraph graph;
@@ -98,6 +108,35 @@ struct GPUMaterial {
/* Functions */
+GPUTexture **gpu_material_sky_texture_layer_set(
+ GPUMaterial *mat, int width, int height, const float *pixels, float *row)
+{
+ /* In order to put all sky textures into one 2D array texture,
+ * we need them to be the same size. */
+ BLI_assert(width == GPU_SKY_WIDTH);
+ BLI_assert(height == GPU_SKY_HEIGHT);
+ UNUSED_VARS_NDEBUG(width, height);
+
+ if (mat->sky_builder == NULL) {
+ mat->sky_builder = MEM_mallocN(sizeof(GPUSkyBuilder), "GPUSkyBuilder");
+ mat->sky_builder->current_layer = 0;
+ }
+
+ int layer = mat->sky_builder->current_layer;
+ *row = (float)layer;
+
+ if (*row == MAX_GPU_SKIES) {
+ printf("Too many sky textures in shader!\n");
+ }
+ else {
+ float *dst = (float *)mat->sky_builder->pixels[layer];
+ memcpy(dst, pixels, sizeof(float) * GPU_SKY_WIDTH * GPU_SKY_HEIGHT * 4);
+ mat->sky_builder->current_layer += 1;
+ }
+
+ return &mat->sky_tex;
+}
+
GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat,
int size,
float *pixels,
@@ -143,6 +182,24 @@ static void gpu_material_ramp_texture_build(GPUMaterial *mat)
mat->coba_builder = NULL;
}
+static void gpu_material_sky_texture_build(GPUMaterial *mat)
+{
+ if (mat->sky_builder == NULL) {
+ return;
+ }
+
+ mat->sky_tex = GPU_texture_create_2d_array("mat_sky",
+ GPU_SKY_WIDTH,
+ GPU_SKY_HEIGHT,
+ mat->sky_builder->current_layer,
+ 1,
+ GPU_RGBA32F,
+ (float *)mat->sky_builder->pixels);
+
+ MEM_freeN(mat->sky_builder);
+ mat->sky_builder = NULL;
+}
+
void GPU_material_free_single(GPUMaterial *material)
{
bool do_free = atomic_sub_and_fetch_uint32(&material->refcount, 1) == 0;
@@ -161,6 +218,9 @@ void GPU_material_free_single(GPUMaterial *material)
if (material->coba_tex != NULL) {
GPU_texture_free(material->coba_tex);
}
+ if (material->sky_tex != NULL) {
+ GPU_texture_free(material->sky_tex);
+ }
if (material->sss_profile != NULL) {
GPU_uniformbuf_free(material->sss_profile);
}
@@ -231,6 +291,12 @@ const GPUUniformAttrList *GPU_material_uniform_attributes(const GPUMaterial *mat
return attrs->count > 0 ? attrs : NULL;
}
+const ListBase *GPU_material_layer_attributes(const GPUMaterial *material)
+{
+ const ListBase *attrs = &material->graph.layer_attrs;
+ return !BLI_listbase_is_empty(attrs) ? attrs : NULL;
+}
+
#if 1 /* End of life code. */
/* Eevee Subsurface scattering. */
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
@@ -684,6 +750,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
ntreeGPUMaterialNodes(localtree, mat);
gpu_material_ramp_texture_build(mat);
+ gpu_material_sky_texture_build(mat);
{
/* Create source code and search pass cache for an already compiled version. */
diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc
index 94fd44f832b..b46860cf0f4 100644
--- a/source/blender/gpu/intern/gpu_matrix.cc
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -429,7 +429,7 @@ void GPU_matrix_frustum_set(
void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far)
{
- float half_height = tanf(fovy * (float)(M_PI / 360.0)) * near;
+ float half_height = tanf(fovy * float(M_PI / 360.0)) * near;
float half_width = half_height * aspect;
GPU_matrix_frustum_set(-half_width, +half_width, -half_height, +half_height, near, far);
}
@@ -669,13 +669,13 @@ BLI_STATIC_ASSERT(GPU_PY_MATRIX_STACK_LEN + 1 == MATRIX_STACK_DEPTH, "define mis
int GPU_matrix_stack_level_get_model_view()
{
GPUMatrixState *state = Context::get()->matrix_state;
- return (int)state->model_view_stack.top;
+ return int(state->model_view_stack.top);
}
int GPU_matrix_stack_level_get_projection()
{
GPUMatrixState *state = Context::get()->matrix_state;
- return (int)state->projection_stack.top;
+ return int(state->projection_stack.top);
}
/** \} */
@@ -700,7 +700,7 @@ float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float di
if (depth_fac == 0.0f) {
/* Hard-code for 24 bit precision. */
int depthbits = 24;
- depth_fac = 1.0f / (float)((1 << depthbits) - 1);
+ depth_fac = 1.0f / float((1 << depthbits) - 1);
}
ofs = (-1.0 / winmat[2][2]) * dist * depth_fac;
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index f82af7538b5..c72e7097b33 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -83,6 +83,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
case GPU_SOURCE_UNIFORM_ATTR:
input->uniform_attr->users++;
break;
+ case GPU_SOURCE_LAYER_ATTR:
+ input->layer_attr->users++;
+ break;
case GPU_SOURCE_TEX:
case GPU_SOURCE_TEX_TILED_MAPPING:
input->texture->users++;
@@ -112,6 +115,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
break;
case GPU_NODE_LINK_IMAGE:
case GPU_NODE_LINK_IMAGE_TILED:
+ case GPU_NODE_LINK_IMAGE_SKY:
case GPU_NODE_LINK_COLORBAND:
input->source = GPU_SOURCE_TEX;
input->texture = link->texture;
@@ -132,6 +136,10 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
input->source = GPU_SOURCE_UNIFORM_ATTR;
input->uniform_attr = link->uniform_attr;
break;
+ case GPU_NODE_LINK_LAYER_ATTR:
+ input->source = GPU_SOURCE_LAYER_ATTR;
+ input->layer_attr = link->layer_attr;
+ break;
case GPU_NODE_LINK_CONSTANT:
input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT;
break;
@@ -262,7 +270,7 @@ static int uniform_attr_sort_cmp(const void *a, const void *b)
return (attr_a->use_dupli && !attr_b->use_dupli);
}
-static unsigned int uniform_attr_list_hash(const void *key)
+static uint uniform_attr_list_hash(const void *key)
{
const GPUUniformAttrList *attrs = key;
return attrs->hash_code;
@@ -415,11 +423,6 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph,
if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) {
attr = MEM_callocN(sizeof(*attr), __func__);
STRNCPY(attr->name, name);
- {
- char attr_name_esc[sizeof(attr->name) * 2];
- BLI_str_escape(attr_name_esc, attr->name, sizeof(attr_name_esc));
- SNPRINTF(attr->name_id_prop, "[\"%s\"]", attr_name_esc);
- }
attr->use_dupli = use_dupli;
attr->hash_code = BLI_ghashutil_strhash_p(attr->name) << 1 | (attr->use_dupli ? 0 : 1);
attr->id = -1;
@@ -434,10 +437,39 @@ static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph,
return attr;
}
+/** Add a new uniform attribute of given type and name. Returns NULL if out of slots. */
+static GPULayerAttr *gpu_node_graph_add_layer_attribute(GPUNodeGraph *graph, const char *name)
+{
+ /* Find existing attribute. */
+ ListBase *attrs = &graph->layer_attrs;
+ GPULayerAttr *attr = attrs->first;
+
+ for (; attr; attr = attr->next) {
+ if (STREQ(attr->name, name)) {
+ break;
+ }
+ }
+
+ /* Add new requested attribute to the list. */
+ if (attr == NULL) {
+ attr = MEM_callocN(sizeof(*attr), __func__);
+ STRNCPY(attr->name, name);
+ attr->hash_code = BLI_ghashutil_strhash_p(attr->name);
+ BLI_addtail(attrs, attr);
+ }
+
+ if (attr != NULL) {
+ attr->users++;
+ }
+
+ return attr;
+}
+
static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
Image *ima,
ImageUser *iuser,
struct GPUTexture **colorband,
+ struct GPUTexture **sky,
GPUNodeLinkType link_type,
eGPUSamplerState sampler_state)
{
@@ -445,7 +477,8 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
int num_textures = 0;
GPUMaterialTexture *tex = graph->textures.first;
for (; tex; tex = tex->next) {
- if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) {
+ if (tex->ima == ima && tex->colorband == colorband && tex->sky == sky &&
+ tex->sampler_state == sampler_state) {
break;
}
num_textures++;
@@ -460,6 +493,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
tex->iuser_available = true;
}
tex->colorband = colorband;
+ tex->sky = sky;
tex->sampler_state = sampler_state;
BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) {
@@ -547,6 +581,17 @@ GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat,
return link;
}
+GPUNodeLink *GPU_layer_attribute(GPUMaterial *mat, const char *name)
+{
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPULayerAttr *attr = gpu_node_graph_add_layer_attribute(graph, name);
+
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_LAYER_ATTR;
+ link->layer_attr = attr;
+ return link;
+}
+
GPUNodeLink *GPU_constant(const float *num)
{
GPUNodeLink *link = gpu_node_link_create();
@@ -580,7 +625,24 @@ GPUNodeLink *GPU_image(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
+ return link;
+}
+
+GPUNodeLink *GPU_image_sky(GPUMaterial *mat,
+ int width,
+ int height,
+ const float *pixels,
+ float *layer,
+ eGPUSamplerState sampler_state)
+{
+ struct GPUTexture **sky = gpu_material_sky_texture_layer_set(mat, width, height, pixels, layer);
+
+ GPUNodeGraph *graph = gpu_material_node_graph(mat);
+ GPUNodeLink *link = gpu_node_link_create();
+ link->link_type = GPU_NODE_LINK_IMAGE_SKY;
+ link->texture = gpu_node_graph_add_texture(
+ graph, NULL, NULL, NULL, sky, link->link_type, sampler_state);
return link;
}
@@ -593,7 +655,7 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
return link;
}
@@ -603,7 +665,7 @@ GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iu
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX);
+ graph, ima, iuser, NULL, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@@ -616,7 +678,7 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
link->texture = gpu_node_graph_add_texture(
- graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX);
+ graph, NULL, NULL, colorband, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@@ -751,14 +813,22 @@ static void gpu_inputs_free(ListBase *inputs)
GPUInput *input;
for (input = inputs->first; input; input = input->next) {
- if (input->source == GPU_SOURCE_ATTR) {
- input->attr->users--;
- }
- else if (input->source == GPU_SOURCE_UNIFORM_ATTR) {
- input->uniform_attr->users--;
- }
- else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) {
- input->texture->users--;
+ switch (input->source) {
+ case GPU_SOURCE_ATTR:
+ input->attr->users--;
+ break;
+ case GPU_SOURCE_UNIFORM_ATTR:
+ input->uniform_attr->users--;
+ break;
+ case GPU_SOURCE_LAYER_ATTR:
+ input->layer_attr->users--;
+ break;
+ case GPU_SOURCE_TEX:
+ case GPU_SOURCE_TEX_TILED_MAPPING:
+ input->texture->users--;
+ break;
+ default:
+ break;
}
if (input->link) {
@@ -810,6 +880,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph)
BLI_freelistN(&graph->textures);
BLI_freelistN(&graph->attributes);
GPU_uniform_attr_list_free(&graph->uniform_attrs);
+ BLI_freelistN(&graph->layer_attrs);
if (graph->used_libraries) {
BLI_gset_free(graph->used_libraries, NULL);
@@ -892,4 +963,10 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
uattrs->count--;
}
}
+
+ LISTBASE_FOREACH_MUTABLE (GPULayerAttr *, attr, &graph->layer_attrs) {
+ if (attr->users == 0) {
+ BLI_freelinkN(&graph->layer_attrs, attr);
+ }
+ }
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 74afb721a1c..de0a0687b13 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -31,6 +31,7 @@ typedef enum eGPUDataSource {
GPU_SOURCE_UNIFORM,
GPU_SOURCE_ATTR,
GPU_SOURCE_UNIFORM_ATTR,
+ GPU_SOURCE_LAYER_ATTR,
GPU_SOURCE_STRUCT,
GPU_SOURCE_TEX,
GPU_SOURCE_TEX_TILED_MAPPING,
@@ -42,11 +43,13 @@ typedef enum {
GPU_NODE_LINK_NONE = 0,
GPU_NODE_LINK_ATTR,
GPU_NODE_LINK_UNIFORM_ATTR,
+ GPU_NODE_LINK_LAYER_ATTR,
GPU_NODE_LINK_COLORBAND,
GPU_NODE_LINK_CONSTANT,
GPU_NODE_LINK_IMAGE,
GPU_NODE_LINK_IMAGE_TILED,
GPU_NODE_LINK_IMAGE_TILED_MAPPING,
+ GPU_NODE_LINK_IMAGE_SKY,
GPU_NODE_LINK_OUTPUT,
GPU_NODE_LINK_UNIFORM,
GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN,
@@ -94,6 +97,8 @@ struct GPUNodeLink {
struct GPUMaterialAttribute *attr;
/* GPU_NODE_LINK_UNIFORM_ATTR */
struct GPUUniformAttr *uniform_attr;
+ /* GPU_NODE_LINK_LAYER_ATTR */
+ struct GPULayerAttr *layer_attr;
/* GPU_NODE_LINK_IMAGE_BLENDER */
struct GPUMaterialTexture *texture;
/* GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN */
@@ -130,6 +135,8 @@ typedef struct GPUInput {
struct GPUMaterialAttribute *attr;
/* GPU_SOURCE_UNIFORM_ATTR */
struct GPUUniformAttr *uniform_attr;
+ /* GPU_SOURCE_LAYER_ATTR */
+ struct GPULayerAttr *layer_attr;
/* GPU_SOURCE_FUNCTION_CALL */
char function_call[64];
};
@@ -170,6 +177,9 @@ typedef struct GPUNodeGraph {
/* The list of uniform attributes. */
GPUUniformAttrList uniform_attrs;
+ /* The list of layer attributes. */
+ ListBase layer_attrs;
+
/** Set of all the GLSL lib code blocks . */
GSet *used_libraries;
} GPUNodeGraph;
@@ -178,6 +188,7 @@ typedef struct GPUNodeGraph {
void gpu_node_graph_prune_unused(GPUNodeGraph *graph);
void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph);
+
/**
* Free intermediate node graph.
*/
@@ -197,6 +208,11 @@ struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
int size,
float *pixels,
float *row);
+/**
+ * Returns the address of the future pointer to sky_tex
+ */
+struct GPUTexture **gpu_material_sky_texture_layer_set(
+ struct GPUMaterial *mat, int width, int height, const float *pixels, float *layer);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder.cc b/source/blender/gpu/intern/gpu_shader_builder.cc
index 9b699c60126..96e3eacd6f5 100644
--- a/source/blender/gpu/intern/gpu_shader_builder.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder.cc
@@ -15,6 +15,8 @@
#include "GPU_init_exit.h"
#include "gpu_shader_create_info_private.hh"
+#include "BLI_vector.hh"
+
#include "CLG_log.h"
namespace blender::gpu::shader_builder {
@@ -41,11 +43,27 @@ void ShaderBuilder::init()
CLG_init();
GHOST_GLSettings glSettings = {0};
- ghost_system_ = GHOST_CreateSystem();
+ switch (GPU_backend_type_selection_get()) {
+ case GPU_BACKEND_OPENGL:
+ glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
+ break;
+
+#ifdef WITH_METAL_BACKEND
+ case GPU_BACKEND_METAL:
+ glSettings.context_type = GHOST_kDrawingContextTypeMetal;
+ break;
+#endif
+
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+
+ ghost_system_ = GHOST_CreateSystemBackground();
ghost_context_ = GHOST_CreateOpenGLContext(ghost_system_, glSettings);
GHOST_ActivateOpenGLContext(ghost_context_);
- gpu_context_ = GPU_context_create(nullptr);
+ gpu_context_ = GPU_context_create(nullptr, ghost_context_);
GPU_init();
}
@@ -73,13 +91,32 @@ int main(int argc, const char *argv[])
int exit_code = 0;
- blender::gpu::shader_builder::ShaderBuilder builder;
- builder.init();
- if (!builder.bake_create_infos()) {
- exit_code = 1;
+ struct NamedBackend {
+ std::string name;
+ eGPUBackendType backend;
+ };
+
+ blender::Vector<NamedBackend> backends_to_validate;
+ backends_to_validate.append({"OpenGL", GPU_BACKEND_OPENGL});
+#ifdef WITH_METAL_BACKEND
+ backends_to_validate.append({"Metal", GPU_BACKEND_METAL});
+#endif
+ for (NamedBackend &backend : backends_to_validate) {
+ GPU_backend_type_selection_set(backend.backend);
+ if (!GPU_backend_supported()) {
+ printf("%s isn't supported on this platform. Shader compilation is skipped\n",
+ backend.name.c_str());
+ continue;
+ }
+ blender::gpu::shader_builder::ShaderBuilder builder;
+ builder.init();
+ if (!builder.bake_create_infos()) {
+ printf("Shader compilation failed for %s backend\n", backend.name.c_str());
+ exit_code = 1;
+ }
+ builder.exit();
}
- builder.exit();
- exit(exit_code);
+ exit(exit_code);
return exit_code;
}
diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
index db14d7fbeb9..65bda7ba858 100644
--- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
+++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc
@@ -41,60 +41,66 @@ UserDef U;
/** \name Stubs of BLI_imbuf_types.h
* \{ */
-void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
+void IMB_freeImBuf(ImBuf * /*ibuf*/)
{
BLI_assert_unreachable();
}
+struct ImBuf *IMB_allocImBuf(unsigned int /*x*/,
+ unsigned int /*y*/,
+ unsigned char /*planes*/,
+ unsigned int /*flags*/)
+{
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Stubs of UI_resources.h
* \{ */
-void UI_GetThemeColor4fv(int UNUSED(colorid), float UNUSED(col[4]))
+void UI_GetThemeColor4fv(int /*colorid*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColor3fv(int UNUSED(colorid), float UNUSED(col[3]))
+void UI_GetThemeColor3fv(int /*colorid*/, float UNUSED(col[3]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShade4fv(int UNUSED(colorid), int UNUSED(offset), float UNUSED(col[4]))
+void UI_GetThemeColorShade4fv(int /*colorid*/, int /*offset*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShadeAlpha4fv(int UNUSED(colorid),
- int UNUSED(coloffset),
- int UNUSED(alphaoffset),
+void UI_GetThemeColorShadeAlpha4fv(int /*colorid*/,
+ int /*coloffset*/,
+ int /*alphaoffset*/,
float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorBlendShade4fv(int UNUSED(colorid1),
- int UNUSED(colorid2),
- float UNUSED(fac),
- int UNUSED(offset),
- float UNUSED(col[4]))
+void UI_GetThemeColorBlendShade4fv(
+ int /*colorid1*/, int /*colorid2*/, float /*fac*/, int /*offset*/, float UNUSED(col[4]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorBlend3ubv(int UNUSED(colorid1),
- int UNUSED(colorid2),
- float UNUSED(fac),
- unsigned char UNUSED(col[3]))
+void UI_GetThemeColorBlend3ubv(int /*colorid1*/,
+ int /*colorid2*/,
+ float /*fac*/,
+ uchar UNUSED(col[3]))
{
BLI_assert_unreachable();
}
-void UI_GetThemeColorShadeAlpha4ubv(int UNUSED(colorid),
- int UNUSED(coloffset),
- int UNUSED(alphaoffset),
- unsigned char UNUSED(col[4]))
+void UI_GetThemeColorShadeAlpha4ubv(int /*colorid*/,
+ int /*coloffset*/,
+ int /*alphaoffset*/,
+ uchar UNUSED(col[4]))
{
BLI_assert_unreachable();
}
@@ -105,28 +111,28 @@ void UI_GetThemeColorShadeAlpha4ubv(int UNUSED(colorid),
/** \name Stubs of BKE_attribute.h
* \{ */
-void BKE_id_attribute_copy_domains_temp(short UNUSED(id_type),
- const struct CustomData *UNUSED(vdata),
- const struct CustomData *UNUSED(edata),
- const struct CustomData *UNUSED(ldata),
- const struct CustomData *UNUSED(pdata),
- const struct CustomData *UNUSED(cdata),
- struct ID *UNUSED(r_id))
+void BKE_id_attribute_copy_domains_temp(short /*id_type*/,
+ const struct CustomData * /*vdata*/,
+ const struct CustomData * /*edata*/,
+ const struct CustomData * /*ldata*/,
+ const struct CustomData * /*pdata*/,
+ const struct CustomData * /*cdata*/,
+ struct ID * /*r_id*/)
{
}
-struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID *UNUSED(id))
+struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID * /*id*/)
{
return nullptr;
}
-struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID *UNUSED(id))
+struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID * /*id*/)
{
return nullptr;
}
-eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
- const struct CustomDataLayer *UNUSED(layer))
+eAttrDomain BKE_id_attribute_domain(const struct ID * /*id*/,
+ const struct CustomDataLayer * /*layer*/)
{
return ATTR_DOMAIN_AUTO;
}
@@ -136,23 +142,23 @@ eAttrDomain BKE_id_attribute_domain(const struct ID *UNUSED(id),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_paint.h
* \{ */
-bool paint_is_face_hidden(const struct MLoopTri *UNUSED(lt), const bool *UNUSED(hide_poly))
+bool paint_is_face_hidden(const struct MLoopTri * /*lt*/, const bool * /*hide_poly*/)
{
BLI_assert_unreachable();
return false;
}
-void BKE_paint_face_set_overlay_color_get(const int UNUSED(face_set),
- const int UNUSED(seed),
+void BKE_paint_face_set_overlay_color_get(const int /*face_set*/,
+ const int /*seed*/,
uchar UNUSED(r_color[4]))
{
BLI_assert_unreachable();
}
-bool paint_is_grid_face_hidden(const unsigned int *UNUSED(grid_hidden),
- int UNUSED(gridsize),
- int UNUSED(x),
- int UNUSED(y))
+bool paint_is_grid_face_hidden(const uint * /*grid_hidden*/,
+ int /*gridsize*/,
+ int /*x*/,
+ int /*y*/)
{
BLI_assert_unreachable();
return false;
@@ -163,16 +169,16 @@ bool paint_is_grid_face_hidden(const unsigned int *UNUSED(grid_hidden),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_mesh.h
* \{ */
-void BKE_mesh_calc_poly_normal(const struct MPoly *UNUSED(mpoly),
- const struct MLoop *UNUSED(loopstart),
- const struct MVert *UNUSED(mvarray),
+void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/,
+ const struct MLoop * /*loopstart*/,
+ const struct MVert * /*mvarray*/,
float UNUSED(r_no[3]))
{
BLI_assert_unreachable();
}
-void BKE_mesh_looptri_get_real_edges(const struct Mesh *UNUSED(mesh),
- const struct MLoopTri *UNUSED(looptri),
+void BKE_mesh_looptri_get_real_edges(const struct Mesh * /*mesh*/,
+ const struct MLoopTri * /*looptri*/,
int UNUSED(r_edges[3]))
{
BLI_assert_unreachable();
@@ -195,42 +201,42 @@ void BKE_material_defaults_free_gpu()
/** \name Stubs of BKE_customdata.h
* \{ */
-int CustomData_get_offset(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_offset(const struct CustomData * /*data*/, int /*type*/)
{
BLI_assert_unreachable();
return 0;
}
-int CustomData_get_named_layer_index(const struct CustomData *UNUSED(data),
- int UNUSED(type),
- const char *UNUSED(name))
+int CustomData_get_named_layer_index(const struct CustomData * /*data*/,
+ int /*type*/,
+ const char * /*name*/)
{
return -1;
}
-int CustomData_get_active_layer_index(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_active_layer_index(const struct CustomData * /*data*/, int /*type*/)
{
return -1;
}
-int CustomData_get_render_layer_index(const struct CustomData *UNUSED(data), int UNUSED(type))
+int CustomData_get_render_layer_index(const struct CustomData * /*data*/, int /*type*/)
{
return -1;
}
-bool CustomData_has_layer(const struct CustomData *UNUSED(data), int UNUSED(type))
+bool CustomData_has_layer(const struct CustomData * /*data*/, int /*type*/)
{
return false;
}
-void *CustomData_get_layer_named(const struct CustomData *UNUSED(data),
- int UNUSED(type),
- const char *UNUSED(name))
+void *CustomData_get_layer_named(const struct CustomData * /*data*/,
+ int /*type*/,
+ const char * /*name*/)
{
return nullptr;
}
-void *CustomData_get_layer(const struct CustomData *UNUSED(data), int UNUSED(type))
+void *CustomData_get_layer(const struct CustomData * /*data*/, int /*type*/)
{
return nullptr;
}
@@ -241,10 +247,10 @@ void *CustomData_get_layer(const struct CustomData *UNUSED(data), int UNUSED(typ
/** \name Stubs of BKE_pbvh.h
* \{ */
-int BKE_pbvh_count_grid_quads(BLI_bitmap **UNUSED(grid_hidden),
- const int *UNUSED(grid_indices),
- int UNUSED(totgrid),
- int UNUSED(gridsize))
+int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/,
+ const int * /*grid_indices*/,
+ int /*totgrid*/,
+ int /*gridsize*/)
{
BLI_assert_unreachable();
return 0;
@@ -255,8 +261,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **UNUSED(grid_hidden),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_subdiv_ccg.h
* \{ */
-int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *UNUSED(subdiv_ccg),
- const int UNUSED(grid_index))
+int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG * /*subdiv_ccg*/, const int /*grid_index*/)
{
BLI_assert_unreachable();
return 0;
@@ -267,18 +272,18 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *UNUSED(subdiv_ccg),
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_node.h
* \{ */
-void ntreeGPUMaterialNodes(struct bNodeTree *UNUSED(localtree), struct GPUMaterial *UNUSED(mat))
+void ntreeGPUMaterialNodes(struct bNodeTree * /*localtree*/, struct GPUMaterial * /*mat*/)
{
BLI_assert_unreachable();
}
-struct bNodeTree *ntreeLocalize(struct bNodeTree *UNUSED(ntree))
+struct bNodeTree *ntreeLocalize(struct bNodeTree * /*ntree*/)
{
BLI_assert_unreachable();
return nullptr;
}
-void ntreeFreeLocalTree(struct bNodeTree *UNUSED(ntree))
+void ntreeFreeLocalTree(struct bNodeTree * /*ntree*/)
{
BLI_assert_unreachable();
}
@@ -288,7 +293,7 @@ void ntreeFreeLocalTree(struct bNodeTree *UNUSED(ntree))
/* -------------------------------------------------------------------- */
/** \name Stubs of bmesh.h
* \{ */
-void BM_face_as_array_vert_tri(BMFace *UNUSED(f), BMVert *UNUSED(r_verts[3]))
+void BM_face_as_array_vert_tri(BMFace * /*f*/, BMVert *UNUSED(r_verts[3]))
{
BLI_assert_unreachable();
}
@@ -297,17 +302,17 @@ void BM_face_as_array_vert_tri(BMFace *UNUSED(f), BMVert *UNUSED(r_verts[3]))
/* -------------------------------------------------------------------- */
/** \name Stubs of DRW_engine.h
* \{ */
-void DRW_deferred_shader_remove(struct GPUMaterial *UNUSED(mat))
+void DRW_deferred_shader_remove(struct GPUMaterial * /*mat*/)
{
BLI_assert_unreachable();
}
-void DRW_cdlayer_attr_aliases_add(struct GPUVertFormat *UNUSED(format),
- const char *UNUSED(base_name),
- const struct CustomData *UNUSED(data),
- const struct CustomDataLayer *UNUSED(cl),
- bool UNUSED(is_active_render),
- bool UNUSED(is_active_layer))
+void DRW_cdlayer_attr_aliases_add(struct GPUVertFormat * /*format*/,
+ const char * /*base_name*/,
+ const struct CustomData * /*data*/,
+ const struct CustomDataLayer * /*cl*/,
+ bool /*is_active_render*/,
+ bool /*is_active_layer*/)
{
}
diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 8a6586e06f6..470643ba863 100644
--- a/source/blender/gpu/intern/gpu_shader_builtin.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -153,6 +153,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.create_info = "gpu_shader_2D_diag_stripes",
},
+ [GPU_SHADER_ICON] =
+ {
+ .name = "GPU_SHADER_ICON",
+ .create_info = "gpu_shader_icon",
+ },
[GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.name = "GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE",
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index a18fdcd32df..ebbddccbe47 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -284,6 +284,7 @@ void gpu_shader_create_info_init()
_info
/* Declare, register and construct the infos. */
+#include "compositor_shader_create_info_list.hh"
#include "gpu_shader_create_info_list.hh"
/* Baked shader data appended to create infos. */
@@ -305,6 +306,31 @@ void gpu_shader_create_info_init()
draw_resource_id_new = draw_resource_id_fallback;
}
+ /* Metal-specific alternatives for Geometry shaders. */
+ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) {
+
+ /* 3D polyline. */
+ gpu_shader_3D_polyline_uniform_color = gpu_shader_3D_polyline_uniform_color_no_geom;
+ gpu_shader_3D_polyline_flat_color = gpu_shader_3D_polyline_flat_color_no_geom;
+ gpu_shader_3D_polyline_smooth_color = gpu_shader_3D_polyline_smooth_color_no_geom;
+ gpu_shader_3D_polyline_uniform_color_clipped =
+ gpu_shader_3D_polyline_uniform_color_clipped_no_geom;
+
+ /* Overlay Edit Mesh. */
+ overlay_edit_mesh_edge = overlay_edit_mesh_edge_no_geom;
+ overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom;
+ overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom;
+ overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom;
+
+ /* Overlay Armature Shape outline. */
+ overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom;
+ overlay_armature_shape_outline_clipped = overlay_armature_shape_outline_clipped_no_geom;
+
+ /* Overlay Motion Path Line. */
+ overlay_motion_path_line = overlay_motion_path_line_no_geom;
+ overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
+ }
+
for (ShaderCreateInfo *info : g_create_infos->values()) {
if (info->do_static_compilation_) {
info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index 2c59cb6e501..7d5b8c891b9 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -24,6 +24,7 @@
extern "C" {
#define SHADER_SOURCE(datatoc, filename, filepath) extern char datatoc[];
+#include "glsl_compositor_source_list.h"
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
#ifdef WITH_OCIO
@@ -109,8 +110,7 @@ struct GPUSource {
}
if ((source.find("drw_debug_") != StringRef::not_found) &&
/* Avoid these two files where it makes no sense to add the dependency. */
- (filename != "common_debug_draw_lib.glsl" &&
- filename != "draw_debug_draw_display_vert.glsl")) {
+ !ELEM(filename, "common_debug_draw_lib.glsl", "draw_debug_draw_display_vert.glsl")) {
builtins |= shader::BuiltinBits::USE_DEBUG_DRAW;
}
check_no_quotes();
@@ -141,7 +141,7 @@ struct GPUSource {
if constexpr (check_whole_word) {
/* Fix false positive if something has "enum" as suffix. */
char previous_char = input[offset - 1];
- if (!(ELEM(previous_char, '\n', '\t', ' ', ':', '(', ','))) {
+ if (!ELEM(previous_char, '\n', '\t', ' ', ':', '(', ',')) {
offset += (reversed) ? -1 : 1;
continue;
}
@@ -846,6 +846,7 @@ void gpu_shader_dependency_init()
#define SHADER_SOURCE(datatoc, filename, filepath) \
g_sources->add_new(filename, new GPUSource(filepath, filename, datatoc, g_functions));
+#include "glsl_compositor_source_list.h"
#include "glsl_draw_source_list.h"
#include "glsl_gpu_source_list.h"
#ifdef WITH_OCIO
diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc
index 6f43b379d31..d9e5e066fea 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.cc
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -22,8 +22,8 @@ ShaderInterface::ShaderInterface() = default;
ShaderInterface::~ShaderInterface()
{
/* Free memory used by name_buffer. */
- MEM_freeN(name_buffer_);
- MEM_freeN(inputs_);
+ MEM_SAFE_FREE(name_buffer_);
+ MEM_SAFE_FREE(inputs_);
}
static void sort_input_list(MutableSpan<ShaderInput> dst)
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 41e06569bdc..d223daa4a61 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -228,6 +228,8 @@ inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBu
return "drw_matrices";
case GPU_UNIFORM_BLOCK_DRW_INFOS:
return "drw_infos";
+ case GPU_UNIFORM_BLOCK_DRW_CLIPPING:
+ return "drw_clipping";
default:
return nullptr;
}
diff --git a/source/blender/gpu/intern/gpu_shader_log.cc b/source/blender/gpu/intern/gpu_shader_log.cc
index dbc36c5afd0..e593c4fa508 100644
--- a/source/blender/gpu/intern/gpu_shader_log.cc
+++ b/source/blender/gpu/intern/gpu_shader_log.cc
@@ -93,10 +93,10 @@ void Shader::print_log(Span<const char *> sources,
}
/* Silence not useful lines. */
- StringRef logref = StringRefNull(log_line).substr(0, (size_t)line_end - (size_t)log_line);
+ StringRef logref = StringRefNull(log_line).substr(0, size_t(line_end) - size_t(log_line));
if (logref.endswith(" shader failed to compile with the following errors:") ||
logref.endswith(" No code generated")) {
- log_line += (size_t)line_end - (size_t)log_line;
+ log_line += size_t(line_end) - size_t(log_line);
continue;
}
@@ -291,7 +291,7 @@ bool GPULogParser::at_any(const char *log_line, const StringRef chars) const
int GPULogParser::parse_number(const char *log_line, char **r_new_position) const
{
- return (int)strtol(log_line, r_new_position, 10);
+ return int(strtol(log_line, r_new_position, 10));
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index a1e0b8867a0..8e9d5cb3184 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -97,10 +97,10 @@ void GPU_color_mask(bool r, bool g, bool b, bool a)
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
- SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED);
- SET_FLAG_FROM_TEST(write_mask, g, (uint32_t)GPU_WRITE_GREEN);
- SET_FLAG_FROM_TEST(write_mask, b, (uint32_t)GPU_WRITE_BLUE);
- SET_FLAG_FROM_TEST(write_mask, a, (uint32_t)GPU_WRITE_ALPHA);
+ SET_FLAG_FROM_TEST(write_mask, r, uint32_t(GPU_WRITE_RED));
+ SET_FLAG_FROM_TEST(write_mask, g, uint32_t(GPU_WRITE_GREEN));
+ SET_FLAG_FROM_TEST(write_mask, b, uint32_t(GPU_WRITE_BLUE));
+ SET_FLAG_FROM_TEST(write_mask, a, uint32_t(GPU_WRITE_ALPHA));
state.write_mask = write_mask;
}
@@ -109,7 +109,7 @@ void GPU_depth_mask(bool depth)
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
- SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH);
+ SET_FLAG_FROM_TEST(write_mask, depth, uint32_t(GPU_WRITE_DEPTH));
state.write_mask = write_mask;
}
@@ -133,13 +133,13 @@ void GPU_state_set(eGPUWriteMask write_mask,
{
StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
- state.write_mask = (uint32_t)write_mask;
- state.blend = (uint32_t)blend;
- state.culling_test = (uint32_t)culling_test;
- state.depth_test = (uint32_t)depth_test;
- state.stencil_test = (uint32_t)stencil_test;
- state.stencil_op = (uint32_t)stencil_op;
- state.provoking_vert = (uint32_t)provoking_vert;
+ state.write_mask = uint32_t(write_mask);
+ state.blend = uint32_t(blend);
+ state.culling_test = uint32_t(culling_test);
+ state.depth_test = uint32_t(depth_test);
+ state.stencil_test = uint32_t(stencil_test);
+ state.stencil_op = uint32_t(stencil_op);
+ state.provoking_vert = uint32_t(provoking_vert);
}
/** \} */
@@ -196,17 +196,17 @@ void GPU_viewport(int x, int y, int width, int height)
void GPU_stencil_reference_set(uint reference)
{
- SET_MUTABLE_STATE(stencil_reference, (uint8_t)reference);
+ SET_MUTABLE_STATE(stencil_reference, uint8_t(reference));
}
void GPU_stencil_write_mask_set(uint write_mask)
{
- SET_MUTABLE_STATE(stencil_write_mask, (uint8_t)write_mask);
+ SET_MUTABLE_STATE(stencil_write_mask, uint8_t(write_mask));
}
void GPU_stencil_compare_mask_set(uint compare_mask)
{
- SET_MUTABLE_STATE(stencil_compare_mask, (uint8_t)compare_mask);
+ SET_MUTABLE_STATE(stencil_compare_mask, uint8_t(compare_mask));
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index bec8b8a0df3..cd1f8bf582c 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -132,6 +132,7 @@ bool Texture::init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
bool Texture::init_view(const GPUTexture *src_,
eGPUTextureFormat format,
+ eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,
@@ -144,7 +145,7 @@ bool Texture::init_view(const GPUTexture *src_,
d_ = src->d_;
layer_start = min_ii(layer_start, src->layer_count() - 1);
layer_len = min_ii(layer_len, (src->layer_count() - layer_start));
- switch (src->type_) {
+ switch (type) {
case GPU_TEXTURE_1D_ARRAY:
h_ = layer_len;
break;
@@ -163,8 +164,7 @@ bool Texture::init_view(const GPUTexture *src_,
mipmaps_ = mip_len;
format_ = format;
format_flag_ = to_format_flag(format);
- /* For now always copy the target. Target aliasing could be exposed later. */
- type_ = src->type_;
+ type_ = type;
if (cube_as_array) {
BLI_assert(type_ & GPU_TEXTURE_CUBE);
type_ = (type_ & ~GPU_TEXTURE_CUBE) | GPU_TEXTURE_2D_ARRAY;
@@ -404,7 +404,26 @@ GPUTexture *GPU_texture_create_view(const char *name,
BLI_assert(mip_len > 0);
BLI_assert(layer_len > 0);
Texture *view = GPUBackend::get()->texture_alloc(name);
- view->init_view(src, format, mip_start, mip_len, layer_start, layer_len, cube_as_array);
+ view->init_view(src,
+ format,
+ unwrap(src)->type_get(),
+ mip_start,
+ mip_len,
+ layer_start,
+ layer_len,
+ cube_as_array);
+ return wrap(view);
+}
+
+GPUTexture *GPU_texture_create_single_layer_view(const char *name, const GPUTexture *src)
+{
+ eGPUTextureFormat format = unwrap(src)->format_get();
+ eGPUTextureType type = unwrap(src)->type_get();
+ BLI_assert(ELEM(type, GPU_TEXTURE_1D, GPU_TEXTURE_2D, GPU_TEXTURE_CUBE));
+ type |= GPU_TEXTURE_ARRAY;
+
+ Texture *view = GPUBackend::get()->texture_alloc(name);
+ view->init_view(src, format, type, 0, 9999, 0, 1, false);
return wrap(view);
}
@@ -463,7 +482,7 @@ void GPU_unpack_row_length_set(uint len)
void GPU_texture_bind_ex(GPUTexture *tex_,
eGPUSamplerState state,
int unit,
- const bool UNUSED(set_number))
+ const bool /*set_number*/)
{
Texture *tex = reinterpret_cast<Texture *>(tex_);
state = (state >= GPU_SAMPLER_MAX) ? tex->sampler_state : state;
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index 8521b0fd77f..124b1751b96 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -108,6 +108,7 @@ class Texture {
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format);
bool init_view(const GPUTexture *src,
eGPUTextureFormat format,
+ eGPUTextureType type,
int mip_start,
int mip_len,
int layer_start,
@@ -430,15 +431,16 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da
case GPU_DEPTH_COMPONENT24:
case GPU_DEPTH_COMPONENT16:
case GPU_DEPTH_COMPONENT32F:
- return data_format == GPU_DATA_FLOAT;
+ return ELEM(data_format, GPU_DATA_FLOAT, GPU_DATA_UINT);
case GPU_DEPTH24_STENCIL8:
case GPU_DEPTH32F_STENCIL8:
- return data_format == GPU_DATA_UINT_24_8;
+ return ELEM(data_format, GPU_DATA_UINT_24_8, GPU_DATA_UINT);
case GPU_R8UI:
case GPU_R16UI:
case GPU_RG16UI:
case GPU_R32UI:
return data_format == GPU_DATA_UINT;
+ case GPU_R32I:
case GPU_RG16I:
case GPU_R16I:
return data_format == GPU_DATA_INT;
@@ -452,6 +454,8 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da
return ELEM(data_format, GPU_DATA_2_10_10_10_REV, GPU_DATA_FLOAT);
case GPU_R11F_G11F_B10F:
return ELEM(data_format, GPU_DATA_10_11_11_REV, GPU_DATA_FLOAT);
+ case GPU_RGBA16F:
+ return ELEM(data_format, GPU_DATA_HALF_FLOAT, GPU_DATA_FLOAT);
default:
return data_format == GPU_DATA_FLOAT;
}
@@ -584,7 +588,7 @@ inline eGPUFrameBufferBits to_framebuffer_bits(eGPUTextureFormat tex_format)
static inline eGPUTextureFormat to_texture_format(const GPUVertFormat *format)
{
- if (format->attr_len > 1 || format->attr_len == 0) {
+ if (format->attr_len == 0) {
BLI_assert_msg(0, "Incorrect vertex format for buffer texture");
return GPU_DEPTH_COMPONENT24;
}
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index a441cfe2fb8..abf5d2dc4c0 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.cc
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -278,7 +278,7 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts_, uint a_idx, GPUVertBufRaw
access->data = (uchar *)verts->data + a->offset;
access->data_init = access->data;
#ifdef DEBUG
- access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride);
+ access->_data_end = access->data_init + size_t(verts->vertex_alloc * format->stride);
#endif
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 897e80293bf..76d95ac1b55 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -251,7 +251,7 @@ static void safe_bytes(char out[11], const char data[8])
}
}
-void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint UNUSED(max_len))
+void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint /*max_len*/)
{
char data[8] = {0};
uint len = strlen(attr_name);
@@ -361,8 +361,12 @@ void VertexFormat_texture_buffer_pack(GPUVertFormat *format)
* minimum per-vertex stride, which mandates 4-byte alignment in Metal.
* This additional alignment padding caused smaller data types, e.g. U16,
* to mis-align. */
- BLI_assert_msg(format->attr_len == 1,
- "Texture buffer mode should only use a single vertex attribute.");
+ for (int i = 0; i < format->attr_len; i++) {
+ /* The buffer texture setup uses the first attribute for type and size.
+ * Make sure all attributes use the same size. */
+ BLI_assert_msg(format->attrs[i].size == format->attrs[0].size,
+ "Texture buffer mode should only use a attributes with the same size.");
+ }
/* Pack vertex format without minimum stride, as this is not required by texture buffers. */
VertexFormat_pack_impl(format, 1);
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 71bdf9e336b..e267d5a2f12 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -147,6 +147,10 @@ static void gpu_viewport_textures_create(GPUViewport *viewport)
if (viewport->depth_tx == NULL) {
viewport->depth_tx = GPU_texture_create_2d(
"dtxl_depth", UNPACK2(size), 1, GPU_DEPTH24_STENCIL8, NULL);
+ if (GPU_clear_viewport_workaround()) {
+ static int depth_clear = 0;
+ GPU_texture_clear(viewport->depth_tx, GPU_DATA_UINT_24_8, &depth_clear);
+ }
}
if (!viewport->depth_tx || !viewport->color_render_tx[0] || !viewport->color_overlay_tx[0]) {