diff options
author | Rob Clark <[email protected]> | 2015-12-21 21:34:11 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2016-05-17 14:22:46 -0400 |
commit | 1e93b0caa10d9d9090eaa3bd517a5144930f28a4 (patch) | |
tree | d382c6e6defaff4dba20623d468134bbc69507b2 /src/mesa/state_tracker/st_program.c | |
parent | 2bbb140be3cbc8e8428f21083b21abd7246ddc6e (diff) |
mesa/st: add support for NIR as possible driver IR
Signed-off-by: Rob Clark <[email protected]>
Acked-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_program.c')
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 128 |
1 files changed, 120 insertions, 8 deletions
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 252e4400087..f2b55379923 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -38,6 +38,8 @@ #include "program/prog_print.h" #include "program/programopt.h" +#include "compiler/nir/nir.h" + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" @@ -54,6 +56,7 @@ #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "st_atifs_to_tgsi.h" +#include "st_nir.h" #include "cso_cache/cso_context.h" @@ -70,10 +73,10 @@ delete_vp_variant(struct st_context *st, struct st_vp_variant *vpv) if (vpv->draw_shader) draw_delete_vertex_shader( st->draw, vpv->draw_shader ); - - if (vpv->tgsi.tokens) + + if (((vpv->tgsi.type == PIPE_SHADER_IR_TGSI)) && vpv->tgsi.tokens) ureg_free_tokens(vpv->tgsi.tokens); - + free( vpv ); } @@ -96,7 +99,7 @@ st_release_vp_variants( struct st_context *st, stvp->variants = NULL; - if (stvp->tgsi.tokens) { + if ((stvp->tgsi.type == PIPE_SHADER_IR_TGSI) && stvp->tgsi.tokens) { tgsi_free_tokens(stvp->tgsi.tokens); stvp->tgsi.tokens = NULL; } @@ -133,7 +136,7 @@ st_release_fp_variants(struct st_context *st, struct st_fragment_program *stfp) stfp->variants = NULL; - if (stfp->tgsi.tokens) { + if ((stfp->tgsi.type == PIPE_SHADER_IR_TGSI) && stfp->tgsi.tokens) { ureg_free_tokens(stfp->tgsi.tokens); stfp->tgsi.tokens = NULL; } @@ -361,9 +364,23 @@ st_translate_vertex_program(struct st_context *st, output_semantic_name[num_outputs] = TGSI_SEMANTIC_EDGEFLAG; output_semantic_index[num_outputs] = 0; - if (!stvp->glsl_to_tgsi) + if (!stvp->glsl_to_tgsi && !stvp->shader_program) _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT); + if (stvp->shader_program) { + nir_shader *nir = st_glsl_to_nir(st, &stvp->Base.Base, + stvp->shader_program, + MESA_SHADER_VERTEX); + + stvp->tgsi.type = PIPE_SHADER_IR_NIR; + stvp->tgsi.ir.nir = nir; + + st_translate_stream_output_info2(&stvp->shader_program->LinkedTransformFeedback, + stvp->result_to_output, + &stvp->tgsi.stream_output); + return true; + } + ureg = ureg_create_with_screen(PIPE_SHADER_VERTEX, st->pipe->screen); if (ureg == NULL) return false; @@ -446,10 +463,27 @@ st_create_vp_variant(struct st_context *st, struct pipe_context *pipe = st->pipe; vpv->key = *key; - vpv->tgsi.tokens = tgsi_dup_tokens(stvp->tgsi.tokens); vpv->tgsi.stream_output = stvp->tgsi.stream_output; vpv->num_inputs = stvp->num_inputs; + if (stvp->tgsi.type == PIPE_SHADER_IR_NIR) { + vpv->tgsi.type = PIPE_SHADER_IR_NIR; + vpv->tgsi.ir.nir = nir_shader_clone(NULL, stvp->tgsi.ir.nir); + if (key->clamp_color) + NIR_PASS_V(vpv->tgsi.ir.nir, nir_lower_clamp_color_outputs); + if (key->passthrough_edgeflags) + NIR_PASS_V(vpv->tgsi.ir.nir, nir_lower_passthrough_edgeflags); + + st_finalize_nir(st, &stvp->Base.Base, vpv->tgsi.ir.nir); + + vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi); + /* driver takes ownership of IR: */ + vpv->tgsi.ir.nir = NULL; + return vpv; + } + + vpv->tgsi.tokens = tgsi_dup_tokens(stvp->tgsi.tokens); + /* Emulate features. */ if (key->clamp_color || key->passthrough_edgeflags) { const struct tgsi_token *tokens; @@ -559,7 +593,7 @@ st_translate_fragment_program(struct st_context *st, memset(inputSlotToAttr, ~0, sizeof(inputSlotToAttr)); - if (!stfp->glsl_to_tgsi) { + if (!stfp->glsl_to_tgsi && !stfp->shader_program) { _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT); if (st->ctx->Const.GLSLFragCoordIsSysVal) _mesa_program_fragment_position_to_sysval(&stfp->Base.Base); @@ -767,6 +801,17 @@ st_translate_fragment_program(struct st_context *st, } } + if (stfp->shader_program) { + nir_shader *nir = st_glsl_to_nir(st, &stfp->Base.Base, + stfp->shader_program, + MESA_SHADER_FRAGMENT); + + stfp->tgsi.type = PIPE_SHADER_IR_NIR; + stfp->tgsi.ir.nir = nir; + + return true; + } + ureg = ureg_create_with_screen(PIPE_SHADER_FRAGMENT, st->pipe->screen); if (ureg == NULL) return false; @@ -881,6 +926,73 @@ st_create_fp_variant(struct st_context *st, if (!variant) return NULL; + if (stfp->tgsi.type == PIPE_SHADER_IR_NIR) { + tgsi.type = PIPE_SHADER_IR_NIR; + tgsi.ir.nir = nir_shader_clone(NULL, stfp->tgsi.ir.nir); + + if (key->clamp_color) + NIR_PASS_V(tgsi.ir.nir, nir_lower_clamp_color_outputs); + + if (key->persample_shading) { + nir_shader *shader = tgsi.ir.nir; + nir_foreach_variable(var, &shader->inputs) + var->data.sample = true; + } + + assert(!(key->bitmap && key->drawpixels)); + + /* glBitmap */ + if (key->bitmap) { + nir_lower_bitmap_options options = {0}; + + variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1; + options.sampler = variant->bitmap_sampler; + options.swizzle_xxxx = (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM); + + NIR_PASS_V(tgsi.ir.nir, nir_lower_bitmap, &options); + } + + /* glDrawPixels (color only) */ + if (key->drawpixels) { + nir_lower_drawpixels_options options = {0}; + unsigned samplers_used = stfp->Base.Base.SamplersUsed; + + /* Find the first unused slot. */ + variant->drawpix_sampler = ffs(~samplers_used) - 1; + options.drawpix_sampler = variant->drawpix_sampler; + samplers_used |= (1 << variant->drawpix_sampler); + + options.pixel_maps = key->pixelMaps; + if (key->pixelMaps) { + variant->pixelmap_sampler = ffs(~samplers_used) - 1; + options.pixelmap_sampler = variant->pixelmap_sampler; + } + + options.scale_and_bias = key->scaleAndBias; + if (key->scaleAndBias) { + _mesa_add_state_reference(params, scale_state); + memcpy(options.scale_state_tokens, scale_state, + sizeof(options.scale_state_tokens)); + _mesa_add_state_reference(params, bias_state); + memcpy(options.bias_state_tokens, bias_state, + sizeof(options.bias_state_tokens)); + } + + _mesa_add_state_reference(params, texcoord_state); + memcpy(options.texcoord_state_tokens, texcoord_state, + sizeof(options.texcoord_state_tokens)); + + NIR_PASS_V(tgsi.ir.nir, nir_lower_drawpixels, &options); + } + + st_finalize_nir(st, &stfp->Base.Base, tgsi.ir.nir); + + variant->driver_shader = pipe->create_fs_state(pipe, &tgsi); + variant->key = *key; + + return variant; + } + tgsi.tokens = stfp->tgsi.tokens; assert(!(key->bitmap && key->drawpixels)); |