summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker/st_program.c
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-12-21 21:34:11 -0500
committerRob Clark <[email protected]>2016-05-17 14:22:46 -0400
commit1e93b0caa10d9d9090eaa3bd517a5144930f28a4 (patch)
treed382c6e6defaff4dba20623d468134bbc69507b2 /src/mesa/state_tracker/st_program.c
parent2bbb140be3cbc8e8428f21083b21abd7246ddc6e (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.c128
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));