[Bf-blender-cvs] [d0d53daeda5] temp-3d-texturing-brush-b: Use compute shader for extraction.
Jeroen Bakker
noreply at git.blender.org
Wed Mar 9 17:25:04 CET 2022
Commit: d0d53daeda52480698808547f5abfa5088880309
Author: Jeroen Bakker
Date: Wed Mar 9 17:24:59 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rBd0d53daeda52480698808547f5abfa5088880309
Use compute shader for extraction.
===================================================================
M source/blender/editors/sculpt_paint/CMakeLists.txt
A source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_c.cc
M source/blender/gpu/CMakeLists.txt
M source/blender/gpu/GPU_shader.h
M source/blender/gpu/GPU_shader_shared.h
M source/blender/gpu/intern/gpu_shader_builtin.c
M source/blender/gpu/intern/gpu_shader_dependency.cc
M source/blender/gpu/intern/gpu_texture_private.hh
A source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
A source/blender/gpu/shaders/infos/gpu_shader_sculpt_pixel_extraction_info.hh
===================================================================
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 7f044ca405c..3fa8eed7338 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -67,6 +67,7 @@ set(SRC
sculpt_smooth.c
sculpt_texture_paint_b.cc
sculpt_texture_paint_pixel_extraction_b.cc
+ #sculpt_texture_paint_pixel_extraction_c.cc
sculpt_transform.c
sculpt_undo.c
sculpt_uv.c
diff --git a/source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_c.cc b/source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_c.cc
new file mode 100644
index 00000000000..d92bf601ccb
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_c.cc
@@ -0,0 +1,191 @@
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_image.h"
+#include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_pbvh.h"
+
+#include "PIL_time_utildefines.h"
+
+#include "BLI_task.h"
+#include "BLI_vector.hh"
+
+#include "IMB_rasterizer.hh"
+
+#include "WM_types.h"
+
+#include "bmesh.h"
+
+#include "ED_uvedit.h"
+
+#include "GPU_compute.h"
+#include "GPU_shader.h"
+#include "GPU_shader_shared.h"
+#include "GPU_texture.h"
+#include "GPU_uniform_buffer.h"
+
+#include "sculpt_intern.h"
+#include "sculpt_texture_paint_intern.hh"
+
+namespace blender::ed::sculpt_paint::texture_paint::barycentric_extraction {
+
+static void init_using_intersection(Object *ob, int totnode, PBVHNode **nodes)
+{
+ Vector<PBVHNode *> nodes_to_initialize;
+ for (int n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+ NodeData *node_data = static_cast<NodeData *>(BKE_pbvh_node_texture_paint_data_get(node));
+ if (node_data != nullptr) {
+ continue;
+ }
+ node_data = MEM_new<NodeData>(__func__);
+ BKE_pbvh_node_texture_paint_data_set(node, node_data, NodeData::free_func);
+ nodes_to_initialize.append(node);
+ }
+ if (nodes_to_initialize.size() == 0) {
+ return;
+ }
+ printf("%ld nodes to initialize\n", nodes_to_initialize.size());
+
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
+ MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
+ if (ldata_uv == nullptr) {
+ return;
+ }
+
+ SculptSession *ss = ob->sculpt;
+ Vector<TexturePaintPolygon> polygons;
+ for (int n = 0; n < nodes_to_initialize.size(); n++) {
+ PBVHNode *node = nodes[n];
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
+ MeshElemMap *vert_map = &ss->pmap[vd.index];
+ for (int j = 0; j < ss->pmap[vd.index].count; j++) {
+ const int poly_index = vert_map->indices[j];
+ const MPoly *p = &ss->mpoly[poly_index];
+ if (p->totloop < 3) {
+ continue;
+ }
+
+ for (int l = 0; l < p->totloop - 2; l++) {
+ const int v1_loop_index = p->loopstart;
+ const int v2_loop_index = p->loopstart + l + 1;
+ const int v3_loop_index = p->loopstart + l + 2;
+ TexturePaintPolygon polygon;
+ polygon.uv[0] = ldata_uv[v1_loop_index].uv;
+ polygon.uv[1] = ldata_uv[v2_loop_index].uv;
+ polygon.uv[2] = ldata_uv[v3_loop_index].uv;
+ polygon.pbvh_node_index = n;
+ polygon.poly_index = poly_index;
+ polygons.append(polygon);
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+ printf("%ld polygons loaded\n", polygons.size());
+
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_SCULPT_PIXEL_EXTRACTION);
+ GPU_shader_bind(shader);
+
+ ImBuf *image_buffer = ss->mode.texture_paint.drawing_target;
+ GPU_shader_uniform_1i(shader, "num_polygons", polygons.size());
+
+ const int polygons_loc = GPU_shader_get_ssbo(shader, "polygons");
+ GPUUniformBuf *polygons_buf = GPU_uniformbuf_create_ex(
+ sizeof(TexturePaintPolygon) * polygons.size(), polygons.data(), __func__);
+ BLI_assert(polygons_loc != -1);
+ GPU_uniformbuf_bind(polygons_buf, polygons_loc);
+
+ GPUTexture *pixels_tex = GPU_texture_create_2d(
+ "gpu_shader_compute_2d", image_buffer->x, image_buffer->y, 1, GPU_RGBA32I, nullptr);
+ GPU_texture_image_bind(pixels_tex, GPU_shader_get_texture_binding(shader, "pixels"));
+ int2 calc_size(256, 256);
+ GPU_compute_dispatch(shader, calc_size.x, calc_size.y, 1);
+ // GPU_compute_dispatch(shader, image_buffer->x, image_buffer->y, 1);
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+ TexturePaintPixel *pixels = static_cast<TexturePaintPixel *>(
+ GPU_texture_read(pixels_tex, GPU_DATA_INT, 0));
+
+#if 1
+ int pixels_added = 0;
+ MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+ for (int y = 0; y < calc_size.y; y++) {
+ for (int x = 0; x < calc_size.x; x++) {
+ int pixel_offset = y * image_buffer->x + x;
+ float2 uv(float(x) / image_buffer->x, float(y) / image_buffer->y);
+ TexturePaintPixel *pixel = &pixels[pixel_offset];
+ printf("%d %d: %d %d\n", x, y, pixel->poly_index, pixel->pbvh_node_index);
+ if (pixel->poly_index == -1 || pixel->pbvh_node_index == -1) {
+ /* No intersection detected.*/
+ continue;
+ }
+ BLI_assert(pixel->pbvh_node_index < nodes_to_initialize.size());
+ PBVHNode *node = nodes_to_initialize[pixel->pbvh_node_index];
+ NodeData *node_data = static_cast<NodeData *>(BKE_pbvh_node_texture_paint_data_get(node));
+ const MPoly *p = &ss->mpoly[pixel->poly_index];
+ const MLoop *loopstart = &ss->mloop[p->loopstart];
+
+ bool intersection_validated = false;
+ for (int l = 0; l < p->totloop - 2; l++) {
+ const int v1_loop_index = p->loopstart;
+ const int v2_loop_index = p->loopstart + l + 1;
+ const int v3_loop_index = p->loopstart + l + 2;
+ const float2 v1_uv = ldata_uv[v1_loop_index].uv;
+ const float2 v2_uv = ldata_uv[v2_loop_index].uv;
+ const float2 v3_uv = ldata_uv[v3_loop_index].uv;
+ float3 weights;
+ barycentric_weights_v2(v1_uv, v2_uv, v3_uv, uv, weights);
+ if (weights[0] < 0.0 || weights[0] > 1.0 || weights[1] < 0.0 || weights[1] > 1.0 ||
+ weights[2] < 0.0 || weights[2] > 1.0) {
+ continue;
+ }
+ const int v1_index = loopstart[0].v;
+ const int v2_index = loopstart[l + 1].v;
+ const int v3_index = loopstart[l + 2].v;
+ const float3 v1_pos = mvert[v1_index].co;
+ const float3 v2_pos = mvert[v2_index].co;
+ const float3 v3_pos = mvert[v3_index].co;
+ float3 local_pos;
+ interp_v3_v3v3v3(local_pos, v1_pos, v2_pos, v3_pos, weights);
+
+ PixelData new_pixel;
+ new_pixel.local_pos = local_pos;
+ new_pixel.pixel_pos = int2(x, y);
+ new_pixel.content = float4(&image_buffer->rect_float[pixel_offset * 4]);
+ new_pixel.flags.dirty = false;
+ node_data->pixels.append(new_pixel);
+ pixels_added += 1;
+
+ intersection_validated = true;
+ break;
+ }
+ BLI_assert(intersection_validated);
+ }
+ }
+ printf("%d pixels added\n", pixels_added);
+#endif
+
+ MEM_freeN(pixels);
+ GPU_shader_unbind();
+ GPU_uniformbuf_free(polygons_buf);
+ GPU_texture_free(pixels_tex);
+}
+} // namespace blender::ed::sculpt_paint::texture_paint::barycentric_extraction
+extern "C" {
+void SCULPT_extract_pixels(Object *ob, PBVHNode **nodes, int totnode)
+{
+ TIMEIT_START(extract_pixels);
+ blender::ed::sculpt_paint::texture_paint::barycentric_extraction::init_using_intersection(
+ ob, totnode, nodes);
+ TIMEIT_END(extract_pixels);
+}
+}
\ No newline at end of file
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 3ad43ef05af..564a285b277 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -354,6 +354,8 @@ set(GLSL_SRC
shaders/gpu_shader_gpencil_stroke_frag.glsl
shaders/gpu_shader_gpencil_stroke_geom.glsl
+ shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
+
shaders/gpu_shader_cfg_world_clip_lib.glsl
shaders/gpu_shader_colorspace_lib.glsl
@@ -433,6 +435,7 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/gpu_shader_simple_lighting_info.hh
shaders/infos/gpu_shader_text_info.hh
shaders/infos/gpu_srgb_to_framebuffer_space_info.hh
+ shaders/infos/gpu_shader_sculpt_pixel_extraction_info.hh
)
set(SHADER_CREATE_INFOS_CONTENT "")
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index ba4f70f7683..aea9687b126 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -341,6 +341,7 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */
/* grease pencil drawing */
GPU_SHADER_GPENCIL_STROKE,
+ GPU_SHADER_SCULPT_PIXEL_EXTRACTION,
/* specialized for widget drawing */
GPU_SHADER_2D_AREA_BORDERS,
GPU_SHADER_2D_WIDGET_BASE,
diff --git a/source/blender/gpu/GPU_shader_shared.h b/source/blender/gpu/GPU_shader_shared.h
index 2e6f1162cb9..92ffe7af502 100644
--- a/source/blender/gpu/GPU_shader_shared.h
+++ b/source/blender/gpu/GPU_shader_shared.h
@@ -66,3 +66,17 @@ struct MultiRectCallData {
float4 calls_data[MAX_CALLS * 3];
};
BLI_STATIC_ASSERT_ALIGN(struct MultiRectCallData, 16)
+
+struct TexturePaintPolygon {
+ float2 uv[3];
+ int pbvh_node_index;
+ int poly_index;
+};
+BLI_STATIC_ASSERT_ALIGN(struct TexturePaintPolygon, 16)
+
+struct TexturePaintPixel {
+ int pbvh_node_index;
+ int poly_index;
+ int2 _pad;
+};
+BLI_STATIC_ASSERT_ALIGN(struct TexturePaintPixel, 16)
diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index dfedb64ce61..bbef84406ef 100644
--- a/source/blender/gpu/intern/gpu_shader_builtin.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -332,6 +332,9 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
[GPU_SHADER_GPENCIL_ST
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list