nouveau: add support for nir

not all those nir options are actually required, it just made the work a
little easier.

v2: fix asserts
    parse compute shaders
    don't lower bitfield_insert
v3: fix memory leak
v4: don't lower fmod32
v5: set lower_all_io_to_temps to false
    fix memory leak because we take over ownership of the nir shader
    merge: use the lowering helper
v6: include TGSI debug header for proper assert call
    add nv50 support
v7: fix Automake build
v8: free shader only for the set shader type
v9: check for IR type inside get_compiler_options
    squash "nouveau: add env var to make nir default"
    fix memory leak when creating compute shaders
    use debug_get_bool_option as it is available in non debug builds
    return failure if unsupported IR is encountered
    don't lower fpow in nir
    lower int 64 divmod inside nir to prevent crashes

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
This commit is contained in:
Karol Herbst 2017-12-10 15:06:45 +01:00
parent a211c92c4b
commit f014ae3c7c
15 changed files with 327 additions and 23 deletions

View File

@ -8,4 +8,7 @@ TARGET_LIB_DEPS += \
$(NOUVEAU_LIBS) \
$(LIBDRM_LIBS)
TARGET_COMPILER_LIB_DEPS = \
$(top_builddir)/src/compiler/nir/libnir.la
endif

View File

@ -25,6 +25,10 @@ include $(top_srcdir)/src/gallium/Automake.inc
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/src/compiler/nir \
-I$(top_srcdir)/src/compiler/nir \
-I$(top_srcdir)/src/mapi \
-I$(top_srcdir)/src/mesa \
$(GALLIUM_DRIVER_CFLAGS) \
$(LIBDRM_CFLAGS) \
$(NOUVEAU_CFLAGS)
@ -47,6 +51,7 @@ nouveau_compiler_SOURCES = \
nouveau_compiler_LDADD = \
libnouveau.la \
$(top_builddir)/src/compiler/nir/libnir.la \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
$(top_builddir)/src/util/libmesautil.la \
$(GALLIUM_COMMON_LIB_DEPS)

View File

@ -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 \

View File

@ -1241,6 +1241,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;

View File

@ -1284,6 +1284,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);

View File

@ -0,0 +1,76 @@
/*
* 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@redhat.com>
*/
#include "compiler/nir/nir.h"
#include "util/u_debug.h"
#include "codegen/nv50_ir.h"
#include "codegen/nv50_ir_from_common.h"
#include "codegen/nv50_ir_lowering_helper.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();
if (!result)
return result;
LoweringHelper lowering;
lowering.run(this);
tlsSize = info->bin.tlsSpace;
return result;
}
} // namespace nv50_ir

View File

@ -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,9 +211,9 @@ files_libnouveau = files(
libnouveau = static_library(
'nouveau',
[files_libnouveau],
[files_libnouveau, nir_opcodes_h],
include_directories : [
inc_src, inc_include, inc_gallium, inc_gallium_aux,
inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_common,
],
c_args : [c_vis_args],
cpp_args : [cpp_vis_args],
@ -224,12 +225,12 @@ nouveau_compiler = executable(
'nouveau_compiler.c',
include_directories : [inc_src, inc_include, inc_gallium, inc_gallium_aux],
dependencies : [dep_libdrm, dep_libdrm_nouveau],
link_with : [libnouveau, libgallium, libmesa_util],
link_with : [libnouveau, libgallium, libmesa_util, libnir],
build_by_default : with_tools.contains('nouveau'),
install : with_tools.contains('nouveau'),
)
driver_nouveau = declare_dependency(
compile_args : '-DGALLIUM_NOUVEAU',
link_with : [libnouveauwinsys, libnouveau],
link_with : [libnouveauwinsys, libnouveau, libnir],
)

View File

@ -180,6 +180,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
if (nv_dbg)
nouveau_mesa_debug = atoi(nv_dbg);
screen->prefer_nir = debug_get_bool_option("NV50_PROG_USE_NIR", false);
/* These must be set before any failure is possible, as the cleanup
* paths assume they're responsible for deleting them.
*/

View File

@ -65,6 +65,8 @@ struct nouveau_screen {
struct disk_cache *disk_shader_cache;
bool prefer_nir;
#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
union {
uint64_t v[29];

View File

@ -22,6 +22,8 @@
#include "pipe/p_defines.h"
#include "compiler/nir/nir.h"
#include "nv50/nv50_program.h"
#include "nv50/nv50_context.h"
@ -333,8 +335,19 @@ nv50_program_translate(struct nv50_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;
info->bin.sourceRep = prog->pipe.type;
switch (prog->pipe.type) {
case PIPE_SHADER_IR_TGSI:
info->bin.source = (void *)prog->pipe.tokens;
break;
case PIPE_SHADER_IR_NIR:
info->bin.source = (void *)nir_shader_clone(NULL, prog->pipe.ir.nir);
break;
default:
assert(!"unsupported IR!");
return false;
}
info->bin.smemSize = prog->cp.smem_size;
info->io.auxCBSlot = 15;
@ -438,6 +451,8 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
info->bin.codeSize);
out:
if (info->bin.sourceRep == PIPE_SHADER_IR_NIR)
ralloc_free((void *)info->bin.source);
FREE(info);
return !ret;
}

View File

@ -27,6 +27,7 @@
#include "util/u_format_s3tc.h"
#include "util/u_screen.h"
#include "pipe/p_screen.h"
#include "compiler/nir/nir.h"
#include "nv50/nv50_context.h"
#include "nv50/nv50_screen.h"
@ -346,6 +347,8 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen,
enum pipe_shader_type shader,
enum pipe_shader_cap param)
{
const struct nouveau_screen *screen = nouveau_screen(pscreen);
switch (shader) {
case PIPE_SHADER_VERTEX:
case PIPE_SHADER_GEOMETRY:
@ -399,7 +402,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen,
case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
return MIN2(16, PIPE_MAX_SAMPLERS);
case PIPE_SHADER_CAP_PREFERRED_IR:
return PIPE_SHADER_IR_TGSI;
return screen->prefer_nir ? PIPE_SHADER_IR_NIR : PIPE_SHADER_IR_TGSI;
case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
return 32;
case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
@ -873,6 +876,44 @@ int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space)
return 1;
}
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 = false,
.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,
.lower_all_io_to_temps = false,
.native_integers = true,
.lower_cs_local_index_from_id = true,
.use_interpolated_input_intrinsics = true,
.max_unroll_iterations = 32,
};
static const void *
nv50_screen_get_compiler_options(struct pipe_screen *pscreen,
enum pipe_shader_ir ir,
enum pipe_shader_type shader)
{
if (ir == PIPE_SHADER_IR_NIR)
return &nir_options;
return NULL;
}
struct nouveau_screen *
nv50_screen_create(struct nouveau_device *dev)
{
@ -918,6 +959,9 @@ nv50_screen_create(struct nouveau_device *dev)
pscreen->get_driver_query_info = nv50_screen_get_driver_query_info;
pscreen->get_driver_query_group_info = nv50_screen_get_driver_query_group_info;
/* nir stuff */
pscreen->get_compiler_options = nv50_screen_get_compiler_options;
nv50_screen_init_resource_functions(pscreen);
if (screen->base.device->chipset < 0x84 ||

View File

@ -28,6 +28,7 @@
#include "util/format_srgb.h"
#include "tgsi/tgsi_parse.h"
#include "compiler/nir/nir.h"
#include "nv50/nv50_stateobj.h"
#include "nv50/nv50_context.h"
@ -756,7 +757,19 @@ nv50_sp_state_create(struct pipe_context *pipe,
return NULL;
prog->type = type;
prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
prog->pipe.type = cso->type;
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 = cso->ir.nir;
break;
default:
assert(!"unsupported IR!");
return NULL;
}
if (cso->stream_output.num_outputs)
prog->pipe.stream_output = cso->stream_output;
@ -775,7 +788,10 @@ nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
nv50_program_destroy(nv50_context(pipe), prog);
FREE((void *)prog->pipe.tokens);
if (prog->pipe.type == PIPE_SHADER_IR_TGSI)
FREE((void *)prog->pipe.tokens);
else if (prog->pipe.type == PIPE_SHADER_IR_NIR)
ralloc_free(prog->pipe.ir.nir);
FREE(prog);
}
@ -837,13 +853,24 @@ nv50_cp_state_create(struct pipe_context *pipe,
if (!prog)
return NULL;
prog->type = PIPE_SHADER_COMPUTE;
prog->pipe.type = cso->ir_type;
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 *)cso->prog;
break;
default:
assert(!"unsupported IR!");
return NULL;
}
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);
return (void *)prog;
}

View File

@ -22,6 +22,7 @@
#include "pipe/p_defines.h"
#include "compiler/nir/nir.h"
#include "tgsi/tgsi_ureg.h"
#include "nvc0/nvc0_context.h"
@ -582,8 +583,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;
info->bin.sourceRep = prog->pipe.type;
switch (prog->pipe.type) {
case PIPE_SHADER_IR_TGSI:
info->bin.source = (void *)prog->pipe.tokens;
break;
case PIPE_SHADER_IR_NIR:
info->bin.source = (void *)nir_shader_clone(NULL, prog->pipe.ir.nir);
break;
default:
assert(!"unsupported IR!");
return false;
}
#ifdef DEBUG
info->target = debug_get_num_option("NV50_PROG_CHIPSET", chipset);
@ -711,6 +723,8 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
#endif
out:
if (info->bin.sourceRep == PIPE_SHADER_IR_NIR)
ralloc_free((void *)info->bin.source);
FREE(info);
return !ret;
}

View File

@ -27,6 +27,7 @@
#include "util/u_format_s3tc.h"
#include "util/u_screen.h"
#include "pipe/p_screen.h"
#include "compiler/nir/nir.h"
#include "nouveau_vp3_video.h"
@ -106,7 +107,8 @@ static int
nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
const struct nouveau_screen *screen = nouveau_screen(pscreen);
struct nouveau_device *dev = screen->device;
switch (param) {
/* non-boolean caps */
@ -233,7 +235,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_USER_VERTEX_BUFFERS:
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TEXTURE_GATHER_SM5:
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
@ -281,8 +282,9 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return class_3d >= NVE4_3D_CLASS; /* needs testing on fermi */
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
case PIPE_CAP_TGSI_BALLOT:
case PIPE_CAP_BINDLESS_TEXTURE:
return class_3d >= NVE4_3D_CLASS;
case PIPE_CAP_BINDLESS_TEXTURE:
return class_3d >= NVE4_3D_CLASS && !screen->prefer_nir;
case PIPE_CAP_TGSI_ATOMFADD:
return class_3d < GM107_3D_CLASS; /* needs additional lowering */
case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
@ -297,6 +299,13 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
return class_3d >= GP100_3D_CLASS;
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
/* TODO: nir doesn't support tg4 with multiple offsets */
return screen->prefer_nir ? 0 : 1;
/* caps has to be turned on with nir */
case PIPE_CAP_INT64_DIVMOD:
return screen->prefer_nir ? 1 : 0;
/* unsupported caps */
case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
@ -323,7 +332,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
case PIPE_CAP_NATIVE_FENCE_FD:
case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
case PIPE_CAP_INT64_DIVMOD:
case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
case PIPE_CAP_MEMOBJ:
@ -375,7 +383,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
enum pipe_shader_type shader,
enum pipe_shader_cap param)
{
const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
const struct nouveau_screen *screen = nouveau_screen(pscreen);
const uint16_t class_3d = screen->class_3d;
switch (shader) {
case PIPE_SHADER_VERTEX:
@ -391,9 +400,10 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
switch (param) {
case PIPE_SHADER_CAP_PREFERRED_IR:
return PIPE_SHADER_IR_TGSI;
return screen->prefer_nir ? PIPE_SHADER_IR_NIR : 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:
@ -886,6 +896,79 @@ nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, bool *can_serialize,
IMMED_NVC0(push, NVC0_3D(CB_BIND(stage)), (index << 4) | (size >= 0));
}
static const nir_shader_compiler_options nir_options = {
.lower_fdiv = false,
.lower_ffma = false,
.fuse_ffma = false, /* nir doesn't track mad vs fma */
.lower_flrp32 = true,
.lower_flrp64 = true,
.lower_fpow = false,
.lower_fsat = false,
.lower_fsqrt = false, // TODO: only before gm200
.lower_fmod32 = true,
.lower_fmod64 = true,
.lower_bitfield_extract = false,
.lower_bitfield_extract_to_shifts = false,
.lower_bitfield_insert = false,
.lower_bitfield_insert_to_shifts = false,
.lower_bitfield_reverse = false,
.lower_bit_count = false,
.lower_bfm = false,
.lower_ifind_msb = false,
.lower_find_lsb = false,
.lower_uadd_carry = true, // TODO
.lower_usub_borrow = true, // TODO
.lower_mul_high = false,
.lower_negate = false,
.lower_sub = false, // TODO
.lower_scmp = true, // TODO: not implemented yet
.lower_idiv = true,
.lower_isign = false, // TODO
.fdot_replicates = false, // TODO
.lower_ffloor = false, // TODO
.lower_ffract = true,
.lower_fceil = false, // TODO
.lower_ldexp = 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,
.lower_all_io_to_temps = false,
.native_integers = true,
.vertex_id_zero_based = false,
.lower_base_vertex = false,
.lower_helper_invocation = false,
.lower_cs_local_index_from_id = true,
.lower_cs_local_id_from_index = false,
.lower_device_index_to_zero = false, // TODO
.lower_wpos_pntc = false, // TODO
.lower_hadd = true, // TODO
.lower_add_sat = true, // TODO
.use_interpolated_input_intrinsics = true,
.lower_mul_2x32_64 = true, // TODO
.max_unroll_iterations = 32,
.lower_int64_options = nir_lower_divmod64, // TODO
.lower_doubles_options = 0, // TODO
};
static const void *
nvc0_screen_get_compiler_options(struct pipe_screen *pscreen,
enum pipe_shader_ir ir,
enum pipe_shader_type shader)
{
if (ir == PIPE_SHADER_IR_NIR)
return &nir_options;
return NULL;
}
#define FAIL_SCREEN_INIT(str, err) \
do { \
NOUVEAU_ERR(str, err); \
@ -960,6 +1043,8 @@ nvc0_screen_create(struct nouveau_device *dev)
pscreen->get_sample_pixel_grid = nvc0_screen_get_sample_pixel_grid;
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);

View File

@ -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"
@ -595,9 +596,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 = cso->ir.nir;
break;
default:
assert(!"unsupported IR!");
return NULL;
}
if (cso->stream_output.num_outputs)
prog->pipe.stream_output = cso->stream_output;
@ -616,7 +627,10 @@ nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
nvc0_program_destroy(nvc0_context(pipe), prog);
FREE((void *)prog->pipe.tokens);
if (prog->pipe.type == PIPE_SHADER_IR_TGSI)
FREE((void *)prog->pipe.tokens);
else if (prog->pipe.type == PIPE_SHADER_IR_NIR)
ralloc_free(prog->pipe.ir.nir);
FREE(prog);
}
@ -710,12 +724,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 *)cso->prog;
break;
default:
assert(!"unsupported IR!");
return NULL;
}
prog->translated = nvc0_program_translate(
prog, nvc0_context(pipe)->screen->base.device->chipset,