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:
authorClément Foucault <foucault.clem@gmail.com>2020-03-10 06:46:56 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-03-10 06:47:37 +0300
commitc971e812d5e2e5c45ed262ccd3bccfcf547b9ff7 (patch)
tree601a657aa7c741a9ba5ed4b80ad5d180612063fe /source/blender/draw/intern/draw_cache_impl_gpencil.c
parentbf1b323b154433ab4701a7ab455cdecaa3867819 (diff)
Fix T74536: Grease pencil immediately crashes on macOS
It seems like OSX drivers are using standard attributes for passing gl_VertexID and gl_InstanceID to the vertex shader, and count them in the limit of MAX_VERTEX_ATTRIBS. This patch make sure to never use more than 13 attributes by packing some attributes together.
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_gpencil.c')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index c6cedd3f1d2..1464cb9364d 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -166,23 +166,20 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd)
/* MUST match the format below. */
typedef struct gpStrokeVert {
- /** Mat is float because we need to pack other float attribs with it. */
- float mat, strength, stroke_id, point_id;
+ int32_t mat, stroke_id, point_id, packed_asp_hard_rot;
/** Position and thickness packed in the same attribute. */
float pos[3], thickness;
- float uv_fill[2], u_stroke, v_rot;
- /** Aspect ratio and hardnes. */
- float aspect_ratio, hardness;
+ /** UV and strength packed in the same attribute. */
+ float uv_fill[2], u_stroke, strength;
} gpStrokeVert;
static GPUVertFormat *gpencil_stroke_format(void)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "ma", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "ma", GPU_COMP_I32, 4, GPU_FETCH_INT);
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- GPU_vertformat_attr_add(&format, "hard", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* IMPORTANT: This means having only 4 attributes to fit into GPU module limit of 16 attrib. */
GPU_vertformat_multiload_enable(&format, 4);
}
@@ -249,6 +246,29 @@ static int gpencil_stroke_is_cyclic(const bGPDstroke *gps)
return ((gps->flag & GP_STROKE_CYCLIC) != 0) && (gps->totpoints > 2);
}
+BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float hard)
+{
+ int32_t packed = 0;
+ /* Aspect uses 9 bits */
+ float asp_normalized = (asp > 1.0f) ? (1.0f / asp) : asp;
+ packed |= (int32_t)unit_float_to_uchar_clamp(asp_normalized);
+ /* Store if inversed in the 9th bit. */
+ if (asp > 1.0f) {
+ packed |= 1 << 8;
+ }
+ /* Rotation uses 9 bits */
+ /* Rotation are in [-90°..90°] range, so we can encode the sign of the angle + the cosine
+ * because the cosine will always be positive. */
+ packed |= (int32_t)unit_float_to_uchar_clamp(cosf(rot)) << 9;
+ /* Store sine sign in 9th bit. */
+ if (rot < 0.0f) {
+ packed |= 1 << 17;
+ }
+ /* Hardness uses 8 bits */
+ packed |= (int32_t)unit_float_to_uchar_clamp(hard) << 18;
+ return packed;
+}
+
static void gpencil_buffer_add_point(gpStrokeVert *verts,
gpColorVert *cols,
const bGPDstroke *gps,
@@ -275,15 +295,14 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
vert->u_stroke = pt->uv_fac;
vert->stroke_id = gps->runtime.stroke_start;
vert->point_id = v;
- /* Rotation are in [-90°..90°] range, so we can encode the sign of the angle + the cosine
- * because the cosine will always be positive. */
- vert->v_rot = cosf(pt->uv_rot) * signf(pt->uv_rot);
vert->thickness = max_ff(0.0f, gps->thickness * pt->pressure) * (round_cap1 ? 1.0 : -1.0);
/* Tag endpoint material to -1 so they get discarded by vertex shader. */
vert->mat = (is_endpoint) ? -1 : (gps->mat_nr % GP_MATERIAL_BUFFER_LEN);
- vert->aspect_ratio = gps->aspect_ratio[0] / max_ff(gps->aspect_ratio[1], 1e-8);
- vert->hardness = gps->hardeness;
+ float aspect_ratio = gps->aspect_ratio[0] / max_ff(gps->aspect_ratio[1], 1e-8);
+
+ vert->packed_asp_hard_rot = pack_rotation_aspect_hardness(
+ pt->uv_rot, aspect_ratio, gps->hardeness);
}
static void gpencil_buffer_add_stroke(gpStrokeVert *verts,