gallium/util: add shader for stencil-blits
This shader is useful to replicate single bit from a stencil buffer even
when there's no support for PIPE_CAP_SHADER_STENCIL_EXPORT.
This is useful for the D3D12 driver, where the graphics pipeline is the
only way of writing to MSAA stencil-buffers, and not all drivers support
exporting the stencil-value from the shader.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6681>
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index e0e093a..d2f77c4 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -1165,3 +1165,40 @@
return ureg_create_shader_and_destroy(ureg, pipe);
}
+
+void *
+util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src)
+{
+ static const char shader_templ[] =
+ "FRAG\n"
+ "DCL IN[0], GENERIC[0], LINEAR\n"
+ "DCL SAMP[0]\n"
+ "DCL CONST[0][0]\n"
+ "DCL TEMP[0]\n"
+
+ "F2U TEMP[0], IN[0]\n"
+ "TXF_LZ TEMP[0].x, TEMP[0], SAMP[0], %s\n"
+ "AND TEMP[0].x, TEMP[0], CONST[0][0]\n"
+ "USNE TEMP[0].x, TEMP[0], CONST[0][0]\n"
+ "U2F TEMP[0].x, TEMP[0]\n"
+ "KILL_IF -TEMP[0].xxxx\n"
+ "END\n";
+
+ char text[sizeof(shader_templ)+100];
+ struct tgsi_token tokens[1000];
+ struct pipe_shader_state state = { 0 };
+
+ enum tgsi_texture_type tgsi_tex = msaa_src ? TGSI_TEXTURE_2D_MSAA :
+ TGSI_TEXTURE_2D;
+
+ sprintf(text, shader_templ, tgsi_texture_names[tgsi_tex]);
+
+ if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
+ assert(0);
+ return NULL;
+ }
+
+ pipe_shader_state_from_tgsi(&state, tokens);
+
+ return pipe->create_fs_state(pipe, &state);
+}
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 9e024d0..6bc7940 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -168,6 +168,10 @@
const ubyte *tes_semantic_names,
const ubyte *tes_semantic_indexes,
const unsigned vertices_per_patch);
+
+void *
+util_make_fs_stencil_blit(struct pipe_context *pipe, bool msaa_src);
+
#ifdef __cplusplus
}
#endif