[Bf-blender-cvs] [50d265e2318] temp-3d-texturing-brush-b: Rasterization in compute shader.
Jeroen Bakker
noreply at git.blender.org
Fri Mar 11 10:23:02 CET 2022
Commit: 50d265e23187647234aa460f14f3baab79e4b470
Author: Jeroen Bakker
Date: Fri Mar 11 10:22:43 2022 +0100
Branches: temp-3d-texturing-brush-b
https://developer.blender.org/rB50d265e23187647234aa460f14f3baab79e4b470
Rasterization in compute shader.
===================================================================
M source/blender/editors/sculpt_paint/sculpt_texture_paint_pixel_extraction_c.cc
M source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
M source/blender/gpu/shaders/infos/gpu_shader_sculpt_pixel_extraction_info.hh
===================================================================
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
index d92bf601ccb..34cb00723fa 100644
--- 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
@@ -31,6 +31,8 @@
#include "GPU_shader_shared.h"
#include "GPU_texture.h"
#include "GPU_uniform_buffer.h"
+#include "GPU_vertex_buffer.h"
+#include "GPU_vertex_format.h"
#include "sculpt_intern.h"
#include "sculpt_texture_paint_intern.hh"
@@ -60,10 +62,32 @@ static void init_using_intersection(Object *ob, int totnode, PBVHNode **nodes)
if (ldata_uv == nullptr) {
return;
}
-
SculptSession *ss = ob->sculpt;
- Vector<TexturePaintPolygon> polygons;
+
+ static GPUVertFormat format = {0};
+ GPU_vertformat_attr_add(&format, "uv1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "uv2", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "uv3", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "node_index", GPU_COMP_I32, 1, GPU_FETCH_INT);
+ GPU_vertformat_attr_add(&format, "poly_index", GPU_COMP_I32, 1, GPU_FETCH_INT);
+
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_SCULPT_PIXEL_EXTRACTION);
+ GPU_shader_bind(shader);
+ const int polygons_loc = GPU_shader_get_ssbo(shader, "polygons");
+ BLI_assert(polygons_loc != -1);
+
+ ImBuf *image_buffer = ss->mode.texture_paint.drawing_target;
+ 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"));
+
+ int pixels_added = 0;
+ int4 clear_pixel(-1);
+ GPU_texture_clear(pixels_tex, GPU_DATA_INT, clear_pixel);
for (int n = 0; n < nodes_to_initialize.size(); n++) {
+ printf("node [%d/%ld]\n", n + 1, nodes_to_initialize.size());
+
+ Vector<TexturePaintPolygon> polygons;
PBVHNode *node = nodes[n];
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
@@ -90,93 +114,89 @@ static void init_using_intersection(Object *ob, int totnode, PBVHNode **nodes)
}
}
BKE_pbvh_vertex_iter_end;
- }
- printf("%ld polygons loaded\n", polygons.size());
+ 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());
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, polygons.size());
+ for (int i = 0; i < polygons.size(); i++) {
+ GPU_vertbuf_vert_set(vbo, i, &polygons[i]);
+ }
+ GPU_vertbuf_bind_as_ssbo(vbo, polygons_loc);
- 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);
+ int2 calc_size(image_buffer->x, image_buffer->y);
- 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) {
+ const int batch_size = 10000;
+ for (int batch = 0; batch * batch_size < polygons.size(); batch++) {
+ printf("batch %d\n", batch);
+ GPU_shader_uniform_1i(shader, "from_polygon", batch * batch_size);
+ GPU_shader_uniform_1i(
+ shader, "to_polygon", min_ii(batch * batch_size + batch_size, polygons.size()));
+ GPU_compute_dispatch(shader, calc_size.x, calc_size.y, 1);
+ }
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+ TexturePaintPixel *pixels = static_cast<TexturePaintPixel *>(
+ GPU_texture_read(pixels_tex, GPU_DATA_INT, 0));
+ GPU_vertbuf_discard(vbo);
+
+ 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 != n) {
+ /* No intersection detected.*/
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(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);
}
- BLI_assert(intersection_validated);
}
+ printf("%d pixels added\n", pixels_added);
+ MEM_freeN(pixels);
}
- 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
diff --git a/source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl b/source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
index 64a0980ff8a..9735af5e7dd 100644
--- a/source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sculpt_pixel_extraction_comp.glsl
@@ -3,42 +3,42 @@ float cross_tri_v2(vec2 v1, v
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list