From ad444f615cc0cd40e75a2fe54b1e9ad8ad5b8437 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 13 Mar 2021 15:06:19 +0100 Subject: [PATCH] elements.comp: use shared array of structs directly The NVIDIA shader compiler bug that forced splitting of the state struct into primitive types is now fixed. Signed-off-by: Elias Naur --- piet-gpu/shader/elements.comp | 47 ++++---------------------------- piet-gpu/shader/elements.spv | Bin 66568 -> 63752 bytes piet-gpu/shader/path_coarse.spv | Bin 37768 -> 37768 bytes 3 files changed, 5 insertions(+), 42 deletions(-) diff --git a/piet-gpu/shader/elements.comp b/piet-gpu/shader/elements.comp index 255dd13..b7b0e9c 100644 --- a/piet-gpu/shader/elements.comp +++ b/piet-gpu/shader/elements.comp @@ -157,16 +157,7 @@ vec2 get_linewidth(State st) { return 0.5 * st.linewidth * vec2(length(st.mat.xz), length(st.mat.yw)); } -// We should be able to use an array of structs but the NV shader compiler -// doesn't seem to like it :/ -//shared State sh_state[WG_SIZE]; -shared vec4 sh_mat[WG_SIZE]; -shared vec2 sh_translate[WG_SIZE]; -shared vec4 sh_bbox[WG_SIZE]; -shared float sh_width[WG_SIZE]; -shared uint sh_flags[WG_SIZE]; -shared uint sh_path_count[WG_SIZE]; -shared uint sh_pathseg_count[WG_SIZE]; +shared State sh_state[WG_SIZE]; shared uint sh_part_ix; shared State sh_prefix; @@ -195,35 +186,15 @@ void main() { th_state[i] = combine_state(th_state[i - 1], map_element(Element_index(ref, i))); } State agg = th_state[N_ROWS - 1]; - sh_mat[gl_LocalInvocationID.x] = agg.mat; - sh_translate[gl_LocalInvocationID.x] = agg.translate; - sh_bbox[gl_LocalInvocationID.x] = agg.bbox; - sh_width[gl_LocalInvocationID.x] = agg.linewidth; - sh_flags[gl_LocalInvocationID.x] = agg.flags; - sh_path_count[gl_LocalInvocationID.x] = agg.path_count; - sh_pathseg_count[gl_LocalInvocationID.x] = agg.pathseg_count; + sh_state[gl_LocalInvocationID.x] = agg; for (uint i = 0; i < LG_WG_SIZE; i++) { barrier(); if (gl_LocalInvocationID.x >= (1 << i)) { - State other; - uint ix = gl_LocalInvocationID.x - (1 << i); - other.mat = sh_mat[ix]; - other.translate = sh_translate[ix]; - other.bbox = sh_bbox[ix]; - other.linewidth = sh_width[ix]; - other.flags = sh_flags[ix]; - other.path_count = sh_path_count[ix]; - other.pathseg_count = sh_pathseg_count[ix]; + State other = sh_state[gl_LocalInvocationID.x - (1 << i)]; agg = combine_state(other, agg); } barrier(); - sh_mat[gl_LocalInvocationID.x] = agg.mat; - sh_translate[gl_LocalInvocationID.x] = agg.translate; - sh_bbox[gl_LocalInvocationID.x] = agg.bbox; - sh_width[gl_LocalInvocationID.x] = agg.linewidth; - sh_flags[gl_LocalInvocationID.x] = agg.flags; - sh_path_count[gl_LocalInvocationID.x] = agg.path_count; - sh_pathseg_count[gl_LocalInvocationID.x] = agg.pathseg_count; + sh_state[gl_LocalInvocationID.x] = agg; } State exclusive; @@ -304,15 +275,7 @@ void main() { State row = exclusive; if (gl_LocalInvocationID.x > 0) { - uint ix = gl_LocalInvocationID.x - 1; - State other; - other.mat = sh_mat[ix]; - other.translate = sh_translate[ix]; - other.bbox = sh_bbox[ix]; - other.linewidth = sh_width[ix]; - other.flags = sh_flags[ix]; - other.path_count = sh_path_count[ix]; - other.pathseg_count = sh_pathseg_count[ix]; + State other = sh_state[gl_LocalInvocationID.x - 1]; row = combine_state(row, other); } for (uint i = 0; i < N_ROWS; i++) { diff --git a/piet-gpu/shader/elements.spv b/piet-gpu/shader/elements.spv index 287aa4e80402434e1fc83e376cea21dcde78d9a5..7857b93afcace676f40e1c112178bde68866ed72 100644 GIT binary patch delta 18208 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 cu6V8Xfvd$kK%1KV delta 20786 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