summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine
diff options
context:
space:
mode:
authorTimur Kristóf <[email protected]>2019-05-31 18:43:20 +0200
committerAxel Davy <[email protected]>2019-06-05 23:32:13 +0200
commitc94b70a1781b8fb65be24b7e3a72462426cd86c4 (patch)
tree766e8daed5df3c4413555ac1c74084146652cc6b /src/gallium/state_trackers/nine
parentc1621274401b4bd2de7db1f7a813f6bfce8307f8 (diff)
st/nine: Use tgsi_to_nir when preferred IR is NIR.
This patch allows nine to read the preferred IR from pipe caps and use NIR when that is preferred by the driver, by calling tgsi_to_nir. Also adds some debug options that allow overriding it. Signed-off-by: Timur Kristóf <[email protected]> Reviewed-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/nine')
-rw-r--r--src/gallium/state_trackers/nine/meson.build7
-rw-r--r--src/gallium/state_trackers/nine/nine_ff.c4
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.c124
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.h6
4 files changed, 135 insertions, 6 deletions
diff --git a/src/gallium/state_trackers/nine/meson.build b/src/gallium/state_trackers/nine/meson.build
index 491b7937ab1..7c9e035cafc 100644
--- a/src/gallium/state_trackers/nine/meson.build
+++ b/src/gallium/state_trackers/nine/meson.build
@@ -66,5 +66,10 @@ libnine_st = static_library(
include_directories : [
inc_d3d9, inc_gallium, inc_include, inc_src, inc_gallium_aux,
],
- dependencies : dep_thread,
+ dependencies : [
+ dep_thread, idep_nir, idep_nir_headers
+ ],
+ link_with : [
+ libmesa_gallium
+ ]
)
diff --git a/src/gallium/state_trackers/nine/nine_ff.c b/src/gallium/state_trackers/nine/nine_ff.c
index b38205d6100..5e756b36707 100644
--- a/src/gallium/state_trackers/nine/nine_ff.c
+++ b/src/gallium/state_trackers/nine/nine_ff.c
@@ -1060,7 +1060,7 @@ nine_ff_build_vs(struct NineDevice9 *device, struct vs_build_ctx *vs)
ureg_END(ureg);
nine_ureg_tgsi_dump(ureg, FALSE);
- return ureg_create_shader_and_destroy(ureg, device->context.pipe);
+ return nine_create_shader_with_so_and_destroy(ureg, device->context.pipe, NULL);
}
/* PS FF constants layout:
@@ -1555,7 +1555,7 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key)
ureg_END(ureg);
nine_ureg_tgsi_dump(ureg, FALSE);
- return ureg_create_shader_and_destroy(ureg, device->context.pipe);
+ return nine_create_shader_with_so_and_destroy(ureg, device->context.pipe, NULL);
}
static struct NineVertexShader9 *
diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c
index 212fd60255a..93910f90741 100644
--- a/src/gallium/state_trackers/nine/nine_shader.c
+++ b/src/gallium/state_trackers/nine/nine_shader.c
@@ -34,6 +34,7 @@
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_dump.h"
+#include "nir/tgsi_to_nir.h"
#define DBG_CHANNEL DBG_SHADER
@@ -3789,6 +3790,123 @@ static void parse_shader(struct shader_translator *tx)
ureg_END(tx->ureg);
}
+#define NINE_SHADER_DEBUG_OPTION_NIR_VS (1 << 0)
+#define NINE_SHADER_DEBUG_OPTION_NIR_PS (1 << 1)
+#define NINE_SHADER_DEBUG_OPTION_NO_NIR_VS (1 << 2)
+#define NINE_SHADER_DEBUG_OPTION_NO_NIR_PS (1 << 3)
+#define NINE_SHADER_DEBUG_OPTION_DUMP_NIR (1 << 4)
+#define NINE_SHADER_DEBUG_OPTION_DUMP_TGSI (1 << 5)
+
+static const struct debug_named_value nine_shader_debug_options[] = {
+ { "nir_vs", NINE_SHADER_DEBUG_OPTION_NIR_VS, "Use NIR for vertex shaders even if the driver doesn't prefer it." },
+ { "nir_ps", NINE_SHADER_DEBUG_OPTION_NIR_PS, "Use NIR for pixel shaders even if the driver doesn't prefer it." },
+ { "no_nir_vs", NINE_SHADER_DEBUG_OPTION_NO_NIR_VS, "Never use NIR for vertex shaders even if the driver prefers it." },
+ { "no_nir_ps", NINE_SHADER_DEBUG_OPTION_NO_NIR_PS, "Never use NIR for pixel shaders even if the driver prefers it." },
+ { "dump_nir", NINE_SHADER_DEBUG_OPTION_DUMP_NIR, "Print translated NIR shaders." },
+ { "dump_tgsi", NINE_SHADER_DEBUG_OPTION_DUMP_TGSI, "Print TGSI shaders." },
+ DEBUG_NAMED_VALUE_END /* must be last */
+};
+
+static inline boolean
+nine_shader_get_debug_flag(uint64_t flag)
+{
+ static uint64_t flags = 0;
+ static boolean first_run = TRUE;
+
+ if (unlikely(first_run)) {
+ first_run = FALSE;
+ flags = debug_get_flags_option("NINE_SHADER", nine_shader_debug_options, 0);
+
+ // Check old TGSI dump envvar too
+ if (debug_get_bool_option("NINE_TGSI_DUMP", FALSE)) {
+ flags |= NINE_SHADER_DEBUG_OPTION_DUMP_TGSI;
+ }
+ }
+
+ return !!(flags & flag);
+}
+
+static void
+nine_pipe_nir_shader_state_from_tgsi(struct pipe_shader_state *state, const struct tgsi_token *tgsi_tokens,
+ struct pipe_screen *screen)
+{
+ struct nir_shader *nir = tgsi_to_nir(tgsi_tokens, screen);
+
+ if (unlikely(nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_DUMP_NIR))) {
+ nir_print_shader(nir, stdout);
+ }
+
+ state->type = PIPE_SHADER_IR_NIR;
+ state->tokens = NULL;
+ state->ir.nir = nir;
+ memset(&state->stream_output, 0, sizeof(state->stream_output));
+}
+
+static void *
+nine_ureg_create_shader(struct ureg_program *ureg,
+ struct pipe_context *pipe,
+ const struct pipe_stream_output_info *so)
+{
+ struct pipe_shader_state state;
+ const struct tgsi_token *tgsi_tokens;
+ struct pipe_screen *screen = pipe->screen;
+
+ tgsi_tokens = ureg_finalize(ureg);
+ if (!tgsi_tokens)
+ return NULL;
+
+ assert(((struct tgsi_header *) &tgsi_tokens[0])->HeaderSize >= 2);
+ enum pipe_shader_type shader_type = ((struct tgsi_processor *) &tgsi_tokens[1])->Processor;
+
+ int preferred_ir = screen->get_shader_param(screen, shader_type, PIPE_SHADER_CAP_PREFERRED_IR);
+ bool prefer_nir = (preferred_ir == PIPE_SHADER_IR_NIR);
+ bool use_nir = prefer_nir ||
+ ((shader_type == PIPE_SHADER_VERTEX) && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NIR_VS)) ||
+ ((shader_type == PIPE_SHADER_FRAGMENT) && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NIR_PS));
+
+ /* Allow user to override preferred IR, this is very useful for debugging */
+ if (unlikely(shader_type == PIPE_SHADER_VERTEX && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NO_NIR_VS)))
+ use_nir = false;
+ if (unlikely(shader_type == PIPE_SHADER_FRAGMENT && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NO_NIR_PS)))
+ use_nir = false;
+
+ DUMP("shader type: %s, preferred IR: %s, selected IR: %s\n",
+ shader_type == PIPE_SHADER_VERTEX ? "VS" : "PS",
+ prefer_nir ? "NIR" : "TGSI",
+ use_nir ? "NIR" : "TGSI");
+
+ if (use_nir) {
+ nine_pipe_nir_shader_state_from_tgsi(&state, tgsi_tokens, screen);
+ } else {
+ pipe_shader_state_from_tgsi(&state, tgsi_tokens);
+ }
+
+ assert(state.tokens || state.ir.nir);
+
+ if (so)
+ state.stream_output = *so;
+
+ switch (shader_type) {
+ case PIPE_SHADER_VERTEX:
+ return pipe->create_vs_state(pipe, &state);
+ case PIPE_SHADER_FRAGMENT:
+ return pipe->create_fs_state(pipe, &state);
+ default:
+ unreachable("unsupported shader type");
+ }
+}
+
+
+void *
+nine_create_shader_with_so_and_destroy(struct ureg_program *p,
+ struct pipe_context *pipe,
+ const struct pipe_stream_output_info *so)
+{
+ void *result = nine_ureg_create_shader(p, pipe, so);
+ ureg_destroy(p);
+ return result;
+}
+
HRESULT
nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info, struct pipe_context *pipe)
{
@@ -3984,7 +4102,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info,
if (info->process_vertices)
ureg_DECL_constant2D(tx->ureg, 0, 2, 4); /* Viewport data */
- if (debug_get_bool_option("NINE_TGSI_DUMP", FALSE)) {
+ if (unlikely(nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_DUMP_TGSI))) {
const struct tgsi_token *toks = ureg_get_tokens(tx->ureg, NULL);
tgsi_dump(toks, 0);
ureg_free_tokens(toks);
@@ -3995,9 +4113,9 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info,
tx->output_info,
tx->num_outputs,
&(info->so));
- info->cso = ureg_create_shader_with_so_and_destroy(tx->ureg, pipe, &(info->so));
+ info->cso = nine_create_shader_with_so_and_destroy(tx->ureg, pipe, &(info->so));
} else
- info->cso = ureg_create_shader_and_destroy(tx->ureg, pipe);
+ info->cso = nine_create_shader_with_so_and_destroy(tx->ureg, pipe, NULL);
if (!info->cso) {
hr = D3DERR_DRIVERINTERNALERROR;
FREE(info->lconstf.data);
diff --git a/src/gallium/state_trackers/nine/nine_shader.h b/src/gallium/state_trackers/nine/nine_shader.h
index 65dc2efd62a..5abdbe24472 100644
--- a/src/gallium/state_trackers/nine/nine_shader.h
+++ b/src/gallium/state_trackers/nine/nine_shader.h
@@ -33,6 +33,7 @@
struct NineDevice9;
struct NineVertexDeclaration9;
+struct ureg_program;
struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */
{
@@ -108,6 +109,11 @@ struct nine_vs_output_info
int output_index;
};
+void *
+nine_create_shader_with_so_and_destroy(struct ureg_program *p,
+ struct pipe_context *pipe,
+ const struct pipe_stream_output_info *so);
+
HRESULT
nine_translate_shader(struct NineDevice9 *device,
struct nine_shader_info *,