[Mesa-dev] [PATCH v2 05/31] nvc0: add support for NIR
Karol Herbst
kherbst at redhat.com
Thu Jan 4 15:01:51 UTC 2018
not all those nir options are actually required, it just made the work a
little easier.
TODO:
there is a little memory leak, because the nir shader is duplicated twice.
this has to be done though, we just need to clean it up properly
v2: fix asserts
parse compute shaders
don't lower bitfield_insert
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
src/gallium/drivers/nouveau/Makefile.sources | 1 +
src/gallium/drivers/nouveau/codegen/nv50_ir.cpp | 3 +
src/gallium/drivers/nouveau/codegen/nv50_ir.h | 1 +
.../drivers/nouveau/codegen/nv50_ir_from_nir.cpp | 69 ++++++++++++++++++++++
src/gallium/drivers/nouveau/meson.build | 10 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 16 ++++-
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 41 ++++++++++++-
src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 27 ++++++++-
8 files changed, 159 insertions(+), 9 deletions(-)
create mode 100644 src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
diff --git a/src/gallium/drivers/nouveau/Makefile.sources b/src/gallium/drivers/nouveau/Makefile.sources
index ec344c6316..c6a1aff711 100644
--- a/src/gallium/drivers/nouveau/Makefile.sources
+++ b/src/gallium/drivers/nouveau/Makefile.sources
@@ -117,6 +117,7 @@ NV50_CODEGEN_SOURCES := \
codegen/nv50_ir_emit_nv50.cpp \
codegen/nv50_ir_from_common.cpp \
codegen/nv50_ir_from_common.h \
+ codegen/nv50_ir_from_nir.cpp \
codegen/nv50_ir_from_tgsi.cpp \
codegen/nv50_ir_graph.cpp \
codegen/nv50_ir_graph.h \
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
index 6f12df70a1..b95ba8e4e9 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
@@ -1231,6 +1231,9 @@ nv50_ir_generate_code(struct nv50_ir_prog_info *info)
prog->optLevel = info->optLevel;
switch (info->bin.sourceRep) {
+ case PIPE_SHADER_IR_NIR:
+ ret = prog->makeFromNIR(info) ? 0 : -2;
+ break;
case PIPE_SHADER_IR_TGSI:
ret = prog->makeFromTGSI(info) ? 0 : -2;
break;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
index bc15992df0..41e2ede676 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
@@ -1254,6 +1254,7 @@ public:
inline void del(Function *fn, int& id) { allFuncs.remove(id); }
inline void add(Value *rval, int& id) { allRValues.insert(rval, id); }
+ bool makeFromNIR(struct nv50_ir_prog_info *);
bool makeFromTGSI(struct nv50_ir_prog_info *);
bool convertToSSA();
bool optimizeSSA(int level);
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
new file mode 100644
index 0000000000..6bccd14bce
--- /dev/null
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst <kherbst at redhat.com>
+ */
+
+#include "compiler/nir/nir.h"
+
+#include "codegen/nv50_ir.h"
+#include "codegen/nv50_ir_from_common.h"
+#include "codegen/nv50_ir_util.h"
+
+namespace {
+
+using namespace nv50_ir;
+
+class Converter : public ConverterCommon
+{
+public:
+ Converter(Program *, nir_shader *, nv50_ir_prog_info *);
+
+ bool run();
+private:
+ nir_shader *nir;
+};
+
+Converter::Converter(Program *prog, nir_shader *nir, nv50_ir_prog_info *info)
+ : ConverterCommon(prog, info),
+ nir(nir) {}
+
+bool
+Converter::run()
+{
+ return false;
+}
+
+} // unnamed namespace
+
+namespace nv50_ir {
+
+bool
+Program::makeFromNIR(struct nv50_ir_prog_info *info)
+{
+ nir_shader *nir = (nir_shader*)info->bin.source;
+ Converter converter(this, nir, info);
+ bool result = converter.run();
+ tlsSize = info->bin.tlsSpace;
+ return result;
+}
+
+} // namespace nv50_ir
diff --git a/src/gallium/drivers/nouveau/meson.build b/src/gallium/drivers/nouveau/meson.build
index bd608e0410..1b85cdb206 100644
--- a/src/gallium/drivers/nouveau/meson.build
+++ b/src/gallium/drivers/nouveau/meson.build
@@ -131,6 +131,7 @@ files_libnouveau = files(
'codegen/nv50_ir_emit_nv50.cpp',
'codegen/nv50_ir_from_common.cpp',
'codegen/nv50_ir_from_common.h',
+ 'codegen/nv50_ir_from_nir.cpp',
'codegen/nv50_ir_from_tgsi.cpp',
'codegen/nv50_ir_graph.cpp',
'codegen/nv50_ir_graph.h',
@@ -210,8 +211,9 @@ files_libnouveau = files(
libnouveau = static_library(
'nouveau',
- [files_libnouveau],
- include_directories : [inc_src, inc_include, inc_gallium, inc_gallium_aux],
+ [files_libnouveau, nir_opcodes_h],
+ include_directories : [inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_common],
+
c_args : [c_vis_args],
cpp_args : [cpp_vis_args],
dependencies : [dep_libdrm, dep_libdrm_nouveau],
@@ -222,11 +224,11 @@ nouveau_compiler = executable(
'nouveau_compiler.c',
include_directories : [inc_src, inc_include, inc_gallium, inc_gallium_aux],
dependencies : [dep_libdrm, dep_libdrm_nouveau, dep_lmsensors],
- link_with : [libnouveau, libgallium, libmesa_util],
+ link_with : [libnouveau, libgallium, libmesa_util, libnir],
build_by_default : false,
)
driver_nouveau = declare_dependency(
compile_args : '-DGALLIUM_NOUVEAU',
- link_with : [libnouveauwinsys, libnouveau],
+ link_with : [libnouveauwinsys, libnouveau, libnir],
)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 0b305af316..5d896e341a 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -22,6 +22,7 @@
#include "pipe/p_defines.h"
+#include "compiler/nir/nir.h"
#include "tgsi/tgsi_ureg.h"
#include "nvc0/nvc0_context.h"
@@ -569,8 +570,19 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
info->type = prog->type;
info->target = chipset;
- info->bin.sourceRep = PIPE_SHADER_IR_TGSI;
- info->bin.source = (void *)prog->pipe.tokens;
+ switch (prog->pipe.type) {
+ case PIPE_SHADER_IR_TGSI:
+ info->bin.sourceRep = PIPE_SHADER_IR_TGSI;
+ info->bin.source = (void *)prog->pipe.tokens;
+ break;
+ case PIPE_SHADER_IR_NIR:
+ info->bin.sourceRep = PIPE_SHADER_IR_NIR;
+ info->bin.source = (void *)nir_shader_clone(NULL, prog->pipe.ir.nir);
+ break;
+ default:
+ assert(!"unsupported IR!");
+ break;
+ }
#ifdef DEBUG
info->target = debug_get_num_option("NV50_PROG_CHIPSET", chipset);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 02562dd4eb..1df9a3bb98 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -26,6 +26,7 @@
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
#include "pipe/p_screen.h"
+#include "compiler/nir/nir.h"
#include "nouveau_vp3_video.h"
@@ -357,7 +358,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
case PIPE_SHADER_CAP_PREFERRED_IR:
return PIPE_SHADER_IR_TGSI;
case PIPE_SHADER_CAP_SUPPORTED_IRS:
- return 1 << PIPE_SHADER_IR_TGSI;
+ return 1 << PIPE_SHADER_IR_TGSI |
+ 1 << PIPE_SHADER_IR_NIR;
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
@@ -782,6 +784,41 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size)
return 0;
}
+static const nir_shader_compiler_options nir_options = {
+ .fuse_ffma = false, // nir doesn't track mad vs fma
+ .lower_flrp32 = true,
+ .lower_flrp64 = true,
+ .lower_fpow = true,
+ .lower_fmod32 = true,
+ .lower_fmod64 = true,
+ .lower_uadd_carry = true,
+ .lower_usub_borrow = true,
+ .lower_ffract = true,
+ .lower_pack_half_2x16 = true,
+ .lower_pack_unorm_2x16 = true,
+ .lower_pack_snorm_2x16 = true,
+ .lower_pack_unorm_4x8 = true,
+ .lower_pack_snorm_4x8 = true,
+ .lower_unpack_half_2x16 = true,
+ .lower_unpack_unorm_2x16 = true,
+ .lower_unpack_snorm_2x16 = true,
+ .lower_unpack_unorm_4x8 = true,
+ .lower_unpack_snorm_4x8 = true,
+ .lower_extract_byte = true,
+ .lower_extract_word = true,
+ .native_integers = true,
+ .lower_cs_local_index_from_id = true,
+ .max_unroll_iterations = 32,
+};
+
+static const void *
+nvc0_screen_get_compiler_options(struct pipe_screen *pscreen,
+ enum pipe_shader_ir ir,
+ enum pipe_shader_type shader)
+{
+ return &nir_options;
+}
+
#define FAIL_SCREEN_INIT(str, err) \
do { \
NOUVEAU_ERR(str, err); \
@@ -848,6 +885,8 @@ nvc0_screen_create(struct nouveau_device *dev)
pscreen->get_paramf = nvc0_screen_get_paramf;
pscreen->get_driver_query_info = nvc0_screen_get_driver_query_info;
pscreen->get_driver_query_group_info = nvc0_screen_get_driver_query_group_info;
+ // nir stuff
+ pscreen->get_compiler_options = nvc0_screen_get_compiler_options;
nvc0_screen_init_resource_functions(pscreen);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 99d45a238a..b301411bbe 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -27,6 +27,7 @@
#include "util/u_transfer.h"
#include "tgsi/tgsi_parse.h"
+#include "compiler/nir/nir.h"
#include "nvc0/nvc0_stateobj.h"
#include "nvc0/nvc0_context.h"
@@ -580,9 +581,19 @@ nvc0_sp_state_create(struct pipe_context *pipe,
return NULL;
prog->type = type;
+ prog->pipe.type = cso->type;
- if (cso->tokens)
+ switch(cso->type) {
+ case PIPE_SHADER_IR_TGSI:
prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+ break;
+ case PIPE_SHADER_IR_NIR:
+ prog->pipe.ir.nir = nir_shader_clone(NULL, cso->ir.nir);
+ break;
+ default:
+ assert(!"unsupported IR!");
+ break;
+ }
if (cso->stream_output.num_outputs)
prog->pipe.stream_output = cso->stream_output;
@@ -602,6 +613,7 @@ nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
nvc0_program_destroy(nvc0_context(pipe), prog);
FREE((void *)prog->pipe.tokens);
+ ralloc_free(prog->pipe.ir.nir);
FREE(prog);
}
@@ -695,12 +707,23 @@ nvc0_cp_state_create(struct pipe_context *pipe,
if (!prog)
return NULL;
prog->type = PIPE_SHADER_COMPUTE;
+ prog->pipe.type = cso->ir_type;
prog->cp.smem_size = cso->req_local_mem;
prog->cp.lmem_size = cso->req_private_mem;
prog->parm_size = cso->req_input_mem;
- prog->pipe.tokens = tgsi_dup_tokens((const struct tgsi_token *)cso->prog);
+ switch(cso->ir_type) {
+ case PIPE_SHADER_IR_TGSI:
+ prog->pipe.tokens = tgsi_dup_tokens((const struct tgsi_token *)cso->prog);
+ break;
+ case PIPE_SHADER_IR_NIR:
+ prog->pipe.ir.nir = nir_shader_clone(NULL, cso->prog);
+ break;
+ default:
+ assert(!"unsupported IR!");
+ break;
+ }
prog->translated = nvc0_program_translate(
prog, nvc0_context(pipe)->screen->base.device->chipset,
--
2.14.3
More information about the mesa-dev
mailing list