[Mesa-dev] [PATCH 07/12] radeonsi: add VS blit shader creation

Marek Olšák maraeo at gmail.com
Fri Oct 6 14:10:10 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

no users yet
---
 src/gallium/drivers/radeonsi/si_pipe.c            |  10 ++
 src/gallium/drivers/radeonsi/si_pipe.h            |   5 +
 src/gallium/drivers/radeonsi/si_shader.c          | 114 ++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_shader.h          |  12 +++
 src/gallium/drivers/radeonsi/si_shader_internal.h |   1 +
 src/gallium/drivers/radeonsi/si_state.h           |   2 +
 src/gallium/drivers/radeonsi/si_state_shaders.c   |  75 +++++++++++++-
 7 files changed, 217 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index cf4e357..f922f17 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -77,20 +77,30 @@ static void si_destroy_context(struct pipe_context *context)
 	if (sctx->custom_dsa_flush)
 		sctx->b.b.delete_depth_stencil_alpha_state(&sctx->b.b, sctx->custom_dsa_flush);
 	if (sctx->custom_blend_resolve)
 		sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_resolve);
 	if (sctx->custom_blend_fmask_decompress)
 		sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fmask_decompress);
 	if (sctx->custom_blend_eliminate_fastclear)
 		sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_eliminate_fastclear);
 	if (sctx->custom_blend_dcc_decompress)
 		sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_dcc_decompress);
+	if (sctx->vs_blit_pos)
+		sctx->b.b.delete_vs_state(&sctx->b.b, sctx->vs_blit_pos);
+	if (sctx->vs_blit_pos_layered)
+		sctx->b.b.delete_vs_state(&sctx->b.b, sctx->vs_blit_pos_layered);
+	if (sctx->vs_blit_color)
+		sctx->b.b.delete_vs_state(&sctx->b.b, sctx->vs_blit_color);
+	if (sctx->vs_blit_color_layered)
+		sctx->b.b.delete_vs_state(&sctx->b.b, sctx->vs_blit_color_layered);
+	if (sctx->vs_blit_texcoord)
+		sctx->b.b.delete_vs_state(&sctx->b.b, sctx->vs_blit_texcoord);
 
 	if (sctx->blitter)
 		util_blitter_destroy(sctx->blitter);
 
 	si_common_context_cleanup(&sctx->b);
 
 	LLVMDisposeTargetMachine(sctx->tm);
 
 	si_saved_cs_reference(&sctx->current_saved_cs, NULL);
 
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 97dd875..c45cc2d 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -313,20 +313,25 @@ struct si_saved_cs {
 };
 
 struct si_context {
 	struct r600_common_context	b;
 	struct blitter_context		*blitter;
 	void				*custom_dsa_flush;
 	void				*custom_blend_resolve;
 	void				*custom_blend_fmask_decompress;
 	void				*custom_blend_eliminate_fastclear;
 	void				*custom_blend_dcc_decompress;
+	void				*vs_blit_pos;
+	void				*vs_blit_pos_layered;
+	void				*vs_blit_color;
+	void				*vs_blit_color_layered;
+	void				*vs_blit_texcoord;
 	struct si_screen		*screen;
 	LLVMTargetMachineRef		tm; /* only non-threaded compilation */
 	struct si_shader_ctx_state	fixed_func_tcs_shader;
 	struct r600_resource		*wait_mem_scratch;
 	unsigned			wait_mem_number;
 	uint16_t			prefetch_L2_mask;
 
 	bool				gfx_flush_in_progress:1;
 	bool				compute_is_busy:1;
 
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index c6cb45b..da53ac3 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -447,25 +447,111 @@ static LLVMValueRef extract_double_to_float(struct si_shader_context *ctx,
 {
 	LLVMBuilderRef builder = ctx->ac.builder;
 	LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx->ac.context);
 	LLVMValueRef dvec2 = LLVMBuildBitCast(builder, vec4,
 					      LLVMVectorType(f64, 2), "");
 	LLVMValueRef index = LLVMConstInt(ctx->i32, double_index, 0);
 	LLVMValueRef value = LLVMBuildExtractElement(builder, dvec2, index, "");
 	return LLVMBuildFPTrunc(builder, value, ctx->f32, "");
 }
 
+static LLVMValueRef unpack_sint16(struct si_shader_context *ctx,
+				 LLVMValueRef i32, unsigned index)
+{
+	assert(index <= 1);
+
+	if (index == 1)
+		return LLVMBuildAShr(ctx->ac.builder, i32,
+				     LLVMConstInt(ctx->i32, 16, 0), "");
+
+	return LLVMBuildSExt(ctx->ac.builder,
+			     LLVMBuildTrunc(ctx->ac.builder, i32,
+					    ctx->ac.i16, ""),
+			     ctx->i32, "");
+}
+
 void si_llvm_load_input_vs(
 	struct si_shader_context *ctx,
 	unsigned input_index,
 	LLVMValueRef out[4])
 {
+	unsigned vs_blit_property =
+		ctx->shader->selector->info.properties[TGSI_PROPERTY_VS_BLIT_SGPRS];
+
+	if (vs_blit_property) {
+		LLVMValueRef vertex_id = ctx->abi.vertex_id;
+		LLVMValueRef sel_x1 = LLVMBuildICmp(ctx->ac.builder,
+						    LLVMIntULE, vertex_id,
+						    ctx->i32_1, "");
+		/* Use LLVMIntNE, because we have 3 vertices and only
+		 * the middle one should use y2.
+		 */
+		LLVMValueRef sel_y1 = LLVMBuildICmp(ctx->ac.builder,
+						    LLVMIntNE, vertex_id,
+						    ctx->i32_1, "");
+
+		if (input_index == 0) {
+			/* Position: */
+			LLVMValueRef x1y1 = LLVMGetParam(ctx->main_fn,
+							 ctx->param_vs_blit_inputs);
+			LLVMValueRef x2y2 = LLVMGetParam(ctx->main_fn,
+							 ctx->param_vs_blit_inputs + 1);
+
+			LLVMValueRef x1 = unpack_sint16(ctx, x1y1, 0);
+			LLVMValueRef y1 = unpack_sint16(ctx, x1y1, 1);
+			LLVMValueRef x2 = unpack_sint16(ctx, x2y2, 0);
+			LLVMValueRef y2 = unpack_sint16(ctx, x2y2, 1);
+
+			LLVMValueRef x = LLVMBuildSelect(ctx->ac.builder, sel_x1,
+							 x1, x2, "");
+			LLVMValueRef y = LLVMBuildSelect(ctx->ac.builder, sel_y1,
+							 y1, y2, "");
+
+			out[0] = LLVMBuildSIToFP(ctx->ac.builder, x, ctx->f32, "");
+			out[1] = LLVMBuildSIToFP(ctx->ac.builder, y, ctx->f32, "");
+			out[2] = LLVMGetParam(ctx->main_fn,
+					      ctx->param_vs_blit_inputs + 2);
+			out[3] = ctx->ac.f32_1;
+			return;
+		}
+
+		/* Color or texture coordinates: */
+		assert(input_index == 1);
+
+		if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_COLOR) {
+			for (int i = 0; i < 4; i++) {
+				out[i] = LLVMGetParam(ctx->main_fn,
+						      ctx->param_vs_blit_inputs + 3 + i);
+			}
+		} else {
+			assert(vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD);
+			LLVMValueRef x1 = LLVMGetParam(ctx->main_fn,
+						       ctx->param_vs_blit_inputs + 3);
+			LLVMValueRef y1 = LLVMGetParam(ctx->main_fn,
+						       ctx->param_vs_blit_inputs + 4);
+			LLVMValueRef x2 = LLVMGetParam(ctx->main_fn,
+						       ctx->param_vs_blit_inputs + 5);
+			LLVMValueRef y2 = LLVMGetParam(ctx->main_fn,
+						       ctx->param_vs_blit_inputs + 6);
+
+			out[0] = LLVMBuildSelect(ctx->ac.builder, sel_x1,
+						 x1, x2, "");
+			out[1] = LLVMBuildSelect(ctx->ac.builder, sel_y1,
+						 y1, y2, "");
+			out[2] = LLVMGetParam(ctx->main_fn,
+					      ctx->param_vs_blit_inputs + 7);
+			out[3] = LLVMGetParam(ctx->main_fn,
+					      ctx->param_vs_blit_inputs + 8);
+		}
+		return;
+	}
+
 	unsigned chan;
 	unsigned fix_fetch;
 	unsigned num_fetches;
 	unsigned fetch_stride;
 
 	LLVMValueRef t_list_ptr;
 	LLVMValueRef t_offset;
 	LLVMValueRef t_list;
 	LLVMValueRef vertex_index;
 	LLVMValueRef input[3];
@@ -4249,36 +4335,64 @@ enum {
 
 static void create_function(struct si_shader_context *ctx)
 {
 	struct si_shader *shader = ctx->shader;
 	struct si_function_info fninfo;
 	LLVMTypeRef returns[16+32*4];
 	unsigned i, num_return_sgprs;
 	unsigned num_returns = 0;
 	unsigned num_prolog_vgprs = 0;
 	unsigned type = ctx->type;
+	unsigned vs_blit_property =
+		shader->selector->info.properties[TGSI_PROPERTY_VS_BLIT_SGPRS];
 
 	si_init_function_info(&fninfo);
 
 	/* Set MERGED shaders. */
 	if (ctx->screen->b.chip_class >= GFX9) {
 		if (shader->key.as_ls || type == PIPE_SHADER_TESS_CTRL)
 			type = SI_SHADER_MERGED_VERTEX_TESSCTRL; /* LS or HS */
 		else if (shader->key.as_es || type == PIPE_SHADER_GEOMETRY)
 			type = SI_SHADER_MERGED_VERTEX_OR_TESSEVAL_GEOMETRY;
 	}
 
 	LLVMTypeRef v3i32 = LLVMVectorType(ctx->i32, 3);
 
 	switch (type) {
 	case PIPE_SHADER_VERTEX:
 		declare_global_desc_pointers(ctx, &fninfo);
+
+		if (vs_blit_property) {
+			ctx->param_vs_blit_inputs = fninfo.num_params;
+			add_arg(&fninfo, ARG_SGPR, ctx->i32); /* i16 x1, y1 */
+			add_arg(&fninfo, ARG_SGPR, ctx->i32); /* i16 x2, y2 */
+			add_arg(&fninfo, ARG_SGPR, ctx->f32); /* depth */
+
+			if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_COLOR) {
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color0 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color1 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color2 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* color3 */
+			} else if (vs_blit_property == SI_VS_BLIT_SGPRS_POS_TEXCOORD) {
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.x1 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.y1 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.x2 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.y2 */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.z */
+				add_arg(&fninfo, ARG_SGPR, ctx->f32); /* texcoord.w */
+			}
+
+			/* VGPRs */
+			declare_vs_input_vgprs(ctx, &fninfo, &num_prolog_vgprs);
+			break;
+		}
+
 		declare_per_stage_desc_pointers(ctx, &fninfo, true);
 		declare_vs_specific_input_sgprs(ctx, &fninfo);
 
 		if (shader->key.as_es) {
 			assert(!shader->selector->nir);
 			ctx->param_es2gs_offset = add_arg(&fninfo, ARG_SGPR, ctx->i32);
 		} else if (shader->key.as_ls) {
 			assert(!shader->selector->nir);
 			/* no extra parameters */
 		} else {
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index f457f8e..ba80f55 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -169,20 +169,22 @@ enum {
 
 	/* all VS variants */
 	SI_SGPR_VERTEX_BUFFERS	= SI_NUM_RESOURCE_SGPRS,
 	SI_SGPR_VERTEX_BUFFERS_HI,
 	SI_SGPR_BASE_VERTEX,
 	SI_SGPR_START_INSTANCE,
 	SI_SGPR_DRAWID,
 	SI_SGPR_VS_STATE_BITS,
 	SI_VS_NUM_USER_SGPR,
 
+	SI_SGPR_VS_BLIT_DATA = SI_SGPR_CONST_AND_SHADER_BUFFERS,
+
 	/* TES */
 	SI_SGPR_TES_OFFCHIP_LAYOUT = SI_NUM_RESOURCE_SGPRS,
 	SI_SGPR_TES_OFFCHIP_ADDR_BASE64K,
 	SI_TES_NUM_USER_SGPR,
 
 	/* GFX6-8: TCS only */
 	GFX6_SGPR_TCS_OFFCHIP_LAYOUT = SI_NUM_RESOURCE_SGPRS,
 	GFX6_SGPR_TCS_OUT_OFFSETS,
 	GFX6_SGPR_TCS_OUT_LAYOUT,
 	GFX6_SGPR_TCS_IN_LAYOUT,
@@ -256,20 +258,30 @@ enum {
 #define C_VS_STATE_LS_OUT_PATCH_SIZE		0xFFE000FF
 #define S_VS_STATE_LS_OUT_VERTEX_SIZE(x)	(((unsigned)(x) & 0xFF) << 24)
 #define C_VS_STATE_LS_OUT_VERTEX_SIZE		0x00FFFFFF
 
 /* SI-specific system values. */
 enum {
 	TGSI_SEMANTIC_DEFAULT_TESSOUTER_SI = TGSI_SEMANTIC_COUNT,
 	TGSI_SEMANTIC_DEFAULT_TESSINNER_SI,
 };
 
+enum {
+	/* Use a property enum that VS wouldn't use. */
+	TGSI_PROPERTY_VS_BLIT_SGPRS = TGSI_PROPERTY_FS_COORD_ORIGIN,
+
+	/* These represent the number of SGPRs the shader uses. */
+	SI_VS_BLIT_SGPRS_POS = 3,
+	SI_VS_BLIT_SGPRS_POS_COLOR = 7,
+	SI_VS_BLIT_SGPRS_POS_TEXCOORD = 9,
+};
+
 /* For VS shader key fix_fetch. */
 enum {
 	SI_FIX_FETCH_NONE = 0,
 	SI_FIX_FETCH_A2_SNORM,
 	SI_FIX_FETCH_A2_SSCALED,
 	SI_FIX_FETCH_A2_SINT,
 	SI_FIX_FETCH_RGBA_32_UNORM,
 	SI_FIX_FETCH_RGBX_32_UNORM,
 	SI_FIX_FETCH_RGBA_32_SNORM,
 	SI_FIX_FETCH_RGBX_32_SNORM,
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 932e457..5c736f6 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -127,20 +127,21 @@ struct si_shader_context {
 	int param_vertex_index0;
 	/* VS states and layout of LS outputs / TCS inputs at the end
 	 *   [0] = clamp vertex color
 	 *   [1] = indexed
 	 *   [8:20] = stride between patches in DW = num_inputs * num_vertices * 4
 	 *            max = 32*32*4 + 32*4
 	 *   [24:31] = stride between vertices in DW = num_inputs * 4
 	 *             max = 32*4
 	 */
 	int param_vs_state_bits;
+	int param_vs_blit_inputs;
 	/* HW VS */
 	int param_streamout_config;
 	int param_streamout_write_index;
 	int param_streamout_offset[4];
 
 	/* API TCS & TES */
 	/* Layout of TCS outputs in the offchip buffer
 	 * # 6 bits
 	 *   [0:5] = the number of patches per threadgroup, max = NUM_PATCHES (40)
 	 * # 6 bits
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 9cc323d..fa2c147 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -395,20 +395,22 @@ void si_update_fb_dirtiness_after_rendering(struct si_context *sctx);
 void si_emit_dpbb_state(struct si_context *sctx, struct r600_atom *state);
 
 /* si_state_shaders.c */
 bool si_update_shaders(struct si_context *sctx);
 void si_init_shader_functions(struct si_context *sctx);
 bool si_init_shader_cache(struct si_screen *sscreen);
 void si_destroy_shader_cache(struct si_screen *sscreen);
 void si_get_active_slot_masks(const struct tgsi_shader_info *info,
 			      uint32_t *const_and_shader_buffers,
 			      uint64_t *samplers_and_images);
+void *si_get_blit_vs(struct si_context *sctx, enum blitter_attrib_type type,
+		     unsigned num_layers);
 
 /* si_state_draw.c */
 void si_init_ia_multi_vgt_param_table(struct si_context *sctx);
 void si_emit_cache_flush(struct si_context *sctx);
 void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo);
 void si_draw_rectangle(struct blitter_context *blitter,
 		       void *vertex_elements_cso,
 		       blitter_get_vs_func get_vs,
 		       int x1, int y1, int x2, int y2,
 		       float depth, unsigned num_instances,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 1fadc7e..d3b5dd5 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -884,21 +884,27 @@ static void si_shader_vs(struct si_screen *sscreen, struct si_shader *shader,
 
 	if (gs) {
 		vgpr_comp_cnt = 0; /* only VertexID is needed for GS-COPY. */
 		num_user_sgprs = SI_GSCOPY_NUM_USER_SGPR;
 	} else if (shader->selector->type == PIPE_SHADER_VERTEX) {
 		/* VGPR0-3: (VertexID, InstanceID / StepRate0, PrimID, InstanceID)
 		 * If PrimID is disabled. InstanceID / StepRate1 is loaded instead.
 		 * StepRate0 is set to 1. so that VGPR3 doesn't have to be loaded.
 		 */
 		vgpr_comp_cnt = enable_prim_id ? 2 : (shader->info.uses_instanceid ? 1 : 0);
-		num_user_sgprs = SI_VS_NUM_USER_SGPR;
+
+		if (info->properties[TGSI_PROPERTY_VS_BLIT_SGPRS]) {
+			num_user_sgprs = SI_SGPR_VS_BLIT_DATA +
+					 info->properties[TGSI_PROPERTY_VS_BLIT_SGPRS];
+		} else {
+			num_user_sgprs = SI_VS_NUM_USER_SGPR;
+		}
 	} else if (shader->selector->type == PIPE_SHADER_TESS_EVAL) {
 		vgpr_comp_cnt = enable_prim_id ? 3 : 2;
 		num_user_sgprs = SI_TES_NUM_USER_SGPR;
 	} else
 		unreachable("invalid shader selector type");
 
 	/* VS is required to export at least one param. */
 	nparams = MAX2(shader->info.nr_param_exports, 1);
 	si_pm4_set_reg(pm4, R_0286C4_SPI_VS_OUT_CONFIG,
 		       S_0286C4_VS_EXPORT_COUNT(nparams - 1));
@@ -2036,21 +2042,22 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
 
 	/* Record which streamout buffers are enabled. */
 	for (i = 0; i < sel->so.num_outputs; i++) {
 		sel->enabled_streamout_buffer_mask |=
 			(1 << sel->so.output[i].output_buffer) <<
 			(sel->so.output[i].stream * 4);
 	}
 
 	/* The prolog is a no-op if there are no inputs. */
 	sel->vs_needs_prolog = sel->type == PIPE_SHADER_VERTEX &&
-			       sel->info.num_inputs;
+			       sel->info.num_inputs &&
+			       !sel->info.properties[TGSI_PROPERTY_VS_BLIT_SGPRS];
 
 	/* Set which opcode uses which (i,j) pair. */
 	if (sel->info.uses_persp_opcode_interp_centroid)
 		sel->info.uses_persp_centroid = true;
 
 	if (sel->info.uses_linear_opcode_interp_centroid)
 		sel->info.uses_linear_centroid = true;
 
 	if (sel->info.uses_persp_opcode_interp_offset ||
 	    sel->info.uses_persp_opcode_interp_sample)
@@ -3390,20 +3397,84 @@ static void si_emit_scratch_state(struct si_context *sctx,
 	radeon_set_context_reg(cs, R_0286E8_SPI_TMPRING_SIZE,
 			       sctx->spi_tmpring_size);
 
 	if (sctx->scratch_buffer) {
 		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
 				      sctx->scratch_buffer, RADEON_USAGE_READWRITE,
 				      RADEON_PRIO_SCRATCH_BUFFER);
 	}
 }
 
+void *si_get_blit_vs(struct si_context *sctx, enum blitter_attrib_type type,
+		     unsigned num_layers)
+{
+	struct pipe_context *pipe = &sctx->b.b;
+	unsigned vs_blit_property;
+	void **vs;
+
+	switch (type) {
+	case UTIL_BLITTER_ATTRIB_NONE:
+		vs = num_layers > 1 ? &sctx->vs_blit_pos_layered :
+				      &sctx->vs_blit_pos;
+		vs_blit_property = SI_VS_BLIT_SGPRS_POS;
+		break;
+	case UTIL_BLITTER_ATTRIB_COLOR:
+		vs = num_layers > 1 ? &sctx->vs_blit_color_layered :
+				      &sctx->vs_blit_color;
+		vs_blit_property = SI_VS_BLIT_SGPRS_POS_COLOR;
+		break;
+	case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
+	case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
+		assert(num_layers == 1);
+		vs = &sctx->vs_blit_texcoord;
+		vs_blit_property = SI_VS_BLIT_SGPRS_POS_TEXCOORD;
+		break;
+	default:
+		assert(0);
+		return NULL;
+	}
+	if (*vs)
+		return *vs;
+
+	struct ureg_program *ureg = ureg_create(PIPE_SHADER_VERTEX);
+	if (!ureg)
+		return NULL;
+
+	/* Tell the shader to load VS inputs from SGPRs: */
+	ureg_property(ureg, TGSI_PROPERTY_VS_BLIT_SGPRS, vs_blit_property);
+
+	/* This is just a pass-through shader with 1-3 MOV instructions. */
+	ureg_MOV(ureg,
+		 ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0),
+		 ureg_DECL_vs_input(ureg, 0));
+
+	if (type != UTIL_BLITTER_ATTRIB_NONE) {
+		ureg_MOV(ureg,
+			 ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0),
+			 ureg_DECL_vs_input(ureg, 1));
+	}
+
+	if (num_layers > 1) {
+		struct ureg_src instance_id =
+			ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);
+		struct ureg_dst layer =
+			ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
+
+		ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X),
+			 ureg_scalar(instance_id, TGSI_SWIZZLE_X));
+	}
+	ureg_END(ureg);
+
+	*vs = ureg_create_shader_and_destroy(ureg, pipe);
+	return *vs;
+}
+
 void si_init_shader_functions(struct si_context *sctx)
 {
 	si_init_atom(sctx, &sctx->spi_map, &sctx->atoms.s.spi_map, si_emit_spi_map);
 	si_init_atom(sctx, &sctx->scratch_state, &sctx->atoms.s.scratch_state,
 		     si_emit_scratch_state);
 
 	sctx->b.b.create_vs_state = si_create_shader_selector;
 	sctx->b.b.create_tcs_state = si_create_shader_selector;
 	sctx->b.b.create_tes_state = si_create_shader_selector;
 	sctx->b.b.create_gs_state = si_create_shader_selector;
-- 
2.7.4



More information about the mesa-dev mailing list