Commit 43311040 authored by Timur Kristóf's avatar Timur Kristóf Committed by Timur Kristóf
Browse files

st/nine: Use tgsi_to_nir_pipe when preferred IR is NIR.



This patch gives nine the ability to use NIR when that
is the IR that the driver prefers.
Signed-off-by: Timur Kristóf's avatarTimur Kristóf <timur.kristof@gmail.com>
parent 19e44ade
......@@ -3,6 +3,7 @@ include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
-I$(top_srcdir)/include/D3D9 \
-I$(top_builddir)/src/compiler/nir \
$(GALLIUM_CFLAGS) \
$(VISIBILITY_CFLAGS)
......
......@@ -64,7 +64,12 @@ libnine_st = static_library(
nine_st_files,
c_args : c_vis_args,
include_directories : [
inc_d3d9, inc_gallium, inc_include, inc_src, inc_gallium_aux,
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
]
)
......@@ -16,6 +16,7 @@
#include "nine_helpers.h"
#include "nine_pipe.h"
#include "nine_dump.h"
#include "nine_shader.h"
#include "pipe/p_context.h"
#include "tgsi/tgsi_ureg.h"
......@@ -1060,7 +1061,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, PIPE_SHADER_VERTEX, NULL);
}
/* PS FF constants layout:
......@@ -1555,7 +1556,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, PIPE_SHADER_FRAGMENT, NULL);
}
static struct NineVertexShader9 *
......
......@@ -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
......@@ -3593,6 +3594,126 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
ureg_MOV(ureg, ureg_writemask(oCol0, TGSI_WRITEMASK_W), src_col);
}
#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 uint64_t nine_shader_debug_flags = 0;
static bool nine_shader_debug_flags_initialized = false;
static inline bool
nine_shader_get_debug_flag(uint64_t flag)
{
if (unlikely(!nine_shader_debug_flags_initialized)) {
// Get all shader debug flags
nine_shader_debug_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)) {
nine_shader_debug_flags |= NINE_SHADER_DEBUG_OPTION_DUMP_TGSI;
}
}
return nine_shader_debug_flags & flag;
}
static void
nine_pipe_nir_shader_state_from_tgsi(struct pipe_shader_state *state, const struct tgsi_token *tgsi_tokens, struct pipe_context *pipe, enum pipe_shader_type shader_type)
{
struct nir_shader *nir;
const struct nir_shader_compiler_options *options;
/* Get NIR compiler options from driver */
options = pipe->screen->get_compiler_options(pipe->screen, PIPE_SHADER_IR_NIR, shader_type);
/* TGSI->NIR conversion */
nir = tgsi_to_nir_pipe(tgsi_tokens, options, pipe);
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,
enum pipe_shader_type shader_type,
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;
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));
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, pipe, shader_type);
} 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,
enum pipe_shader_type shader_type,
const struct pipe_stream_output_info *so)
{
void *result = nine_ureg_create_shader(p, pipe, shader_type, so);
ureg_destroy(p);
return result;
}
#define GET_CAP(n) screen->get_param( \
screen, PIPE_CAP_##n)
#define GET_SHADER_CAP(n) screen->get_shader_param( \
......@@ -3710,8 +3831,12 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info,
ureg_MOV(tx->ureg, ureg_writemask(tx->regs.oFog, TGSI_WRITEMASK_X), ureg_imm1f(tx->ureg, 0.0f));
}
if (info->position_t)
if (info->position_t) {
if (unlikely(!device->driver_caps.window_space_position_support))
fprintf(stderr, "Your driver doesn't support WINDOW_SPACE, but a shader needs it.");
ureg_property(tx->ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE);
}
if (IS_VS && !ureg_dst_is_undef(tx->regs.oPts)) {
struct ureg_dst oPts = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_PSIZE, 0);
......@@ -3818,7 +3943,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);
......@@ -3829,9 +3954,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, processor, &(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, processor, NULL);
if (!info->cso) {
hr = D3DERR_DRIVERINTERNALERROR;
FREE(info->lconstf.data);
......
......@@ -32,6 +32,7 @@
struct NineDevice9;
struct NineVertexDeclaration9;
struct ureg_program;
struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */
{
......@@ -118,6 +119,12 @@ nine_translate_shader(struct NineDevice9 *device,
struct nine_shader_info *,
struct pipe_context *);
void *
nine_create_shader_with_so_and_destroy(struct ureg_program *p,
struct pipe_context *pipe,
enum pipe_shader_type shader_type,
const struct pipe_stream_output_info *so);
struct nine_shader_variant
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment