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:
authorJason Fielder <jason_apple>2022-04-14 13:01:16 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-04-14 13:01:31 +0300
commit8f0e06a0ca1f4b7f8ea00ec5346a5e55a2620707 (patch)
treece1817dcdfeb8df6ecfbd9c5faaad886dd8e20fb /source/blender/editors/gizmo_library
parente28f07b5c899a3036060e9e3f50a3e878663f02a (diff)
Metal: GPU_PRIM_LINE_LOOP alternative implementations.
Prefer using immVertex3f when 3D shaders are used for 2D rendering due to overhead of vertex padding in hardware. CPU overhead is negligible. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D14494
Diffstat (limited to 'source/blender/editors/gizmo_library')
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c34
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c11
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c109
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c26
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c15
5 files changed, 131 insertions, 64 deletions
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index 8d2aec18451..c6303c197e7 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -82,9 +82,35 @@ void wm_gizmo_vec_draw(
const float color[4], const float (*verts)[3], uint vert_count, uint pos, uint primitive_type)
{
immUniformColor4fv(color);
- immBegin(primitive_type, vert_count);
- for (int i = 0; i < vert_count; i++) {
- immVertex3fv(pos, verts[i]);
+
+ if (primitive_type == GPU_PRIM_LINE_LOOP) {
+ /* Line loop alternative for Metal/Vulkan. */
+ immBegin(GPU_PRIM_LINES, vert_count * 2);
+ immVertex3fv(pos, verts[0]);
+ for (int i = 1; i < vert_count; i++) {
+ immVertex3fv(pos, verts[i]);
+ immVertex3fv(pos, verts[i]);
+ }
+ immVertex3fv(pos, verts[0]);
+ immEnd();
+ }
+ else if (primitive_type == GPU_PRIM_TRI_FAN) {
+ /* Note(Metal): Tri-fan alternative for Metal. Triangle List is more efficient for small
+ * primitive counts. */
+ int tri_count = vert_count - 2;
+ immBegin(GPU_PRIM_TRIS, tri_count * 3);
+ for (int i = 0; i < tri_count; i++) {
+ immVertex3fv(pos, verts[0]);
+ immVertex3fv(pos, verts[i + 1]);
+ immVertex3fv(pos, verts[i + 2]);
+ }
+ immEnd();
+ }
+ else {
+ immBegin(primitive_type, vert_count);
+ for (int i = 0; i < vert_count; i++) {
+ immVertex3fv(pos, verts[i]);
+ }
+ immEnd();
}
- immEnd();
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index 5e20cc73f1a..b326d6d1859 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -74,20 +74,21 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
GPU_viewport_size_get_f(viewport);
GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* Note(Metal): Prefer 3D coordinate for 2D rendering when using 3D shader. */
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
/* TODO: other draw styles. */
if (color[3] == 1.0 && fill_alpha == 1.0 && select == false) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(color);
- imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
+ imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);
- imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
else {
@@ -96,7 +97,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
const float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]};
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
- imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
+ imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
@@ -106,7 +107,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz->line_width * U.pixelsize);
immUniformColor4fv(color);
- imm_draw_circle_wire_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, CIRCLE_RESOLUTION);
immUnbindProgram();
}
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index 4c54aa10c33..e4cb6d149f5 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -99,7 +99,8 @@ static void cage2d_draw_box_corners(const rctf *r,
const float color[3],
const float line_width)
{
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
@@ -112,25 +113,25 @@ static void cage2d_draw_box_corners(const rctf *r,
immBegin(GPU_PRIM_LINES, 16);
- immVertex2f(pos, r->xmin, r->ymin + margin[1]);
- immVertex2f(pos, r->xmin, r->ymin);
- immVertex2f(pos, r->xmin, r->ymin);
- immVertex2f(pos, r->xmin + margin[0], r->ymin);
+ immVertex3f(pos, r->xmin, r->ymin + margin[1], 0.0f);
+ immVertex3f(pos, r->xmin, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmin, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmin + margin[0], r->ymin, 0.0f);
- immVertex2f(pos, r->xmax, r->ymin + margin[1]);
- immVertex2f(pos, r->xmax, r->ymin);
- immVertex2f(pos, r->xmax, r->ymin);
- immVertex2f(pos, r->xmax - margin[0], r->ymin);
+ immVertex3f(pos, r->xmax, r->ymin + margin[1], 0.0f);
+ immVertex3f(pos, r->xmax, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmax, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmax - margin[0], r->ymin, 0.0f);
- immVertex2f(pos, r->xmax, r->ymax - margin[1]);
- immVertex2f(pos, r->xmax, r->ymax);
- immVertex2f(pos, r->xmax, r->ymax);
- immVertex2f(pos, r->xmax - margin[0], r->ymax);
+ immVertex3f(pos, r->xmax, r->ymax - margin[1], 0.0f);
+ immVertex3f(pos, r->xmax, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmax, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmax - margin[0], r->ymax, 0.0f);
- immVertex2f(pos, r->xmin, r->ymax - margin[1]);
- immVertex2f(pos, r->xmin, r->ymax);
- immVertex2f(pos, r->xmin, r->ymax);
- immVertex2f(pos, r->xmin + margin[0], r->ymax);
+ immVertex3f(pos, r->xmin, r->ymax - margin[1], 0.0f);
+ immVertex3f(pos, r->xmin, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmin, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmin + margin[0], r->ymax, 0.0f);
immEnd();
@@ -440,12 +441,35 @@ static void cage2d_draw_box_interaction(const float color[4],
static void imm_draw_point_aspect_2d(
uint pos, float x, float y, float rad_x, float rad_y, bool solid)
{
- immBegin(solid ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
- immVertex2f(pos, x - rad_x, y - rad_y);
- immVertex2f(pos, x - rad_x, y + rad_y);
- immVertex2f(pos, x + rad_x, y + rad_y);
- immVertex2f(pos, x + rad_x, y - rad_y);
- immEnd();
+ if (solid) {
+ /* Note(Metal/AMD): Small Triangle-list primitives more optimal for GPU HW than Trianglestrip.
+ */
+ immBegin(GPU_PRIM_TRIS, 6);
+ immVertex2f(pos, x - rad_x, y - rad_y);
+ immVertex2f(pos, x - rad_x, y + rad_y);
+ immVertex2f(pos, x + rad_x, y + rad_y);
+
+ immVertex2f(pos, x - rad_x, y - rad_y);
+ immVertex2f(pos, x + rad_x, y + rad_y);
+ immVertex2f(pos, x + rad_x, y - rad_y);
+ immEnd();
+ }
+ else {
+ /* Note(Metal/AMD): Small Line-list primitives more optimal for GPU HW than Linestrip. */
+ immBegin(GPU_PRIM_LINES, 8);
+ immVertex2f(pos, x - rad_x, y - rad_y);
+ immVertex2f(pos, x - rad_x, y + rad_y);
+
+ immVertex2f(pos, x - rad_x, y + rad_y);
+ immVertex2f(pos, x + rad_x, y + rad_y);
+
+ immVertex2f(pos, x + rad_x, y + rad_y);
+ immVertex2f(pos, x + rad_x, y - rad_y);
+
+ immVertex2f(pos, x + rad_x, y - rad_y);
+ immVertex2f(pos, x - rad_x, y - rad_y);
+ immEnd();
+ }
}
static void cage2d_draw_circle_wire(const rctf *r,
@@ -455,7 +479,9 @@ static void cage2d_draw_circle_wire(const rctf *r,
const int draw_options,
const float line_width)
{
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* Note(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's.
+ */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fv(color);
@@ -465,17 +491,28 @@ static void cage2d_draw_circle_wire(const rctf *r,
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", line_width * U.pixelsize);
- immBegin(GPU_PRIM_LINE_LOOP, 4);
- immVertex2f(pos, r->xmin, r->ymin);
- immVertex2f(pos, r->xmax, r->ymin);
- immVertex2f(pos, r->xmax, r->ymax);
- immVertex2f(pos, r->xmin, r->ymax);
+ /* Small 'lines' primitives more efficient for hardware processing than linestrip. */
+ immBegin(GPU_PRIM_LINES, 8);
+ immVertex3f(pos, r->xmin, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmax, r->ymin, 0.0f);
+
+ immVertex3f(pos, r->xmax, r->ymin, 0.0f);
+ immVertex3f(pos, r->xmax, r->ymax, 0.0f);
+
+ immVertex3f(pos, r->xmax, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmin, r->ymax, 0.0f);
+
+ immVertex3f(pos, r->xmin, r->ymax, 0.0f);
+ immVertex3f(pos, r->xmin, r->ymin, 0.0f);
immEnd();
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) {
- immBegin(GPU_PRIM_LINE_LOOP, 2);
- immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax);
- immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]);
+ immBegin(GPU_PRIM_LINES, 4);
+ immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
+ immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
+
+ immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1], 0.0f);
+ immVertex3f(pos, BLI_rctf_cent_x(r), r->ymax, 0.0f);
immEnd();
}
@@ -485,10 +522,10 @@ static void cage2d_draw_circle_wire(const rctf *r,
const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
- immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
- immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
- immVertex2f(pos, center[0] - rad[0], center[1] + rad[1]);
+ immVertex3f(pos, center[0] - rad[0], center[1] - rad[1], 0.0f);
+ immVertex3f(pos, center[0] + rad[0], center[1] + rad[1], 0.0f);
+ immVertex3f(pos, center[0] + rad[0], center[1] - rad[1], 0.0f);
+ immVertex3f(pos, center[0] - rad[0], center[1] + rad[1], 0.0f);
immEnd();
}
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
index e1f584bf9e4..a76242404ba 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
@@ -96,7 +96,8 @@ static void dial_geom_draw(const float color[4],
ED_GIZMO_DIAL_DRAW_FLAG_FILL)));
GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
if (clip_plane) {
immBindBuiltinProgram(filled ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR :
@@ -114,18 +115,19 @@ static void dial_geom_draw(const float color[4],
if (filled) {
if (arc_partial_angle == 0.0f) {
if (arc_inner_factor == 0.0f) {
- imm_draw_circle_fill_2d(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
}
else {
- imm_draw_disk_partial_fill_2d(
- pos, 0, 0, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
+ imm_draw_disk_partial_fill_3d(
+ pos, 0.0f, 0.0f, 0.0f, arc_inner_factor, 1.0f, DIAL_RESOLUTION, 0, RAD2DEGF(M_PI * 2));
}
}
else {
float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
- imm_draw_disk_partial_fill_2d(pos,
- 0,
- 0,
+ imm_draw_disk_partial_fill_3d(pos,
+ 0.0f,
+ 0.0f,
+ 0.0f,
arc_inner_factor,
1.0f,
DIAL_RESOLUTION,
@@ -140,15 +142,15 @@ static void dial_geom_draw(const float color[4],
immUniform1f("lineWidth", line_width * U.pixelsize);
if (arc_partial_angle == 0.0f) {
- imm_draw_circle_wire_2d(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION);
if (arc_inner_factor != 0.0f) {
- imm_draw_circle_wire_2d(pos, 0, 0, arc_inner_factor, DIAL_RESOLUTION);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, arc_inner_factor, DIAL_RESOLUTION);
}
}
else {
float arc_partial_deg = RAD2DEGF((M_PI * 2) - arc_partial_angle);
- imm_draw_circle_partial_wire_2d(
- pos, 0, 0, 1.0, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
+ imm_draw_circle_partial_wire_3d(
+ pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
# if 0
if (arc_inner_factor != 0.0f) {
BLI_assert(0);
@@ -186,7 +188,7 @@ static void dial_ghostarc_draw_helpline(const float angle,
immUniformColor4fv(color);
immBegin(GPU_PRIM_LINE_STRIP, 2);
- immVertex3f(pos, 0.0f, 0, 0.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
immVertex3fv(pos, co_outer);
immEnd();
diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
index 447fe1005a1..5fb1173521a 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
@@ -98,7 +98,8 @@ static void move_geom_draw(const wmGizmo *gz,
ED_GIZMO_MOVE_DRAW_FLAG_FILL)));
GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ /* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(filled ? GPU_SHADER_3D_UNIFORM_COLOR :
GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@@ -115,20 +116,20 @@ static void move_geom_draw(const wmGizmo *gz,
if (draw_style == ED_GIZMO_MOVE_STYLE_RING_2D) {
if (filled) {
- imm_draw_circle_fill_2d(pos, 0, 0, radius, DIAL_RESOLUTION);
+ imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
}
else {
- imm_draw_circle_wire_2d(pos, 0, 0, radius, DIAL_RESOLUTION);
+ imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
}
}
else if (draw_style == ED_GIZMO_MOVE_STYLE_CROSS_2D) {
const float radius_diag = M_SQRT1_2 * radius;
immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, radius_diag, radius_diag);
- immVertex2f(pos, -radius_diag, -radius_diag);
+ immVertex3f(pos, radius_diag, radius_diag, 0.0f);
+ immVertex3f(pos, -radius_diag, -radius_diag, 0.0f);
- immVertex2f(pos, -radius_diag, radius_diag);
- immVertex2f(pos, radius_diag, -radius_diag);
+ immVertex3f(pos, -radius_diag, radius_diag, 0.0f);
+ immVertex3f(pos, radius_diag, -radius_diag, 0.0f);
immEnd();
}
else {