diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index 457a9bd513cce146a2a8216daf6534953d0a013b..a09b07dfd4976f2b8b3171952d29d97e478c9749 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -385,6 +385,14 @@ ttn_emit_declaration(struct ttn_compile *c) else var->data.location = FRAG_RESULT_DATA0 + semantic_index; } + switch (decl->Declaration.ValueType) { + case TGSI_RETURN_TYPE_SINT: + var->type = glsl_ivec4_type(); + break; + case TGSI_RETURN_TYPE_UINT: + var->type = glsl_uvec4_type(); + break; + } break; } case TGSI_SEMANTIC_POSITION: diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 6c573fc6f4b3c35602c264c23fd3df7e78e6e19f..d36017a3adc12fc858559479ee0c9e8bc721bef6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -112,7 +112,7 @@ tgsi_default_declaration( void ) declaration.Array = 0; declaration.Atomic = 0; declaration.MemType = TGSI_MEMORY_TYPE_GLOBAL; - declaration.Padding = 0; + declaration.ValueType = TGSI_RETURN_TYPE_UNKNOWN; return declaration; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index fdbc37220d081423e19b50b2baf974c22a24b011..8ca3e7fd6ca3e269155cf930f9d2742146222ec8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -144,6 +144,7 @@ struct ureg_program unsigned last; unsigned array_id; bool invariant; + unsigned value_type; /* = TGSI_RETURN_TYPE_* */ } output[UREG_MAX_OUTPUT]; unsigned nr_outputs, nr_output_regs; @@ -502,6 +503,17 @@ ureg_DECL_output(struct ureg_program *ureg, 0, 1); } +struct ureg_dst +ureg_DECL_output_typed(struct ureg_program *ureg, + enum tgsi_semantic name, + unsigned index, + enum tgsi_return_type value_type) +{ + struct ureg_dst dst = ureg_DECL_output(ureg, name, index); + ureg->output[ureg->nr_outputs - 1].value_type = value_type; + return dst; +} + struct ureg_dst ureg_DECL_output_array(struct ureg_program *ureg, enum tgsi_semantic semantic_name, @@ -1511,16 +1523,17 @@ ureg_memory_insn(struct ureg_program *ureg, static void -emit_decl_semantic(struct ureg_program *ureg, - unsigned file, - unsigned first, - unsigned last, - enum tgsi_semantic semantic_name, - unsigned semantic_index, - unsigned streams, - unsigned usage_mask, - unsigned array_id, - bool invariant) +emit_decl_semantic_typed(struct ureg_program *ureg, + unsigned file, + unsigned first, + unsigned last, + enum tgsi_semantic semantic_name, + unsigned semantic_index, + unsigned streams, + unsigned usage_mask, + unsigned array_id, + bool invariant, + enum tgsi_return_type value_type) { union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); @@ -1532,6 +1545,7 @@ emit_decl_semantic(struct ureg_program *ureg, out[0].decl.Semantic = 1; out[0].decl.Array = array_id != 0; out[0].decl.Invariant = invariant; + out[0].decl.ValueType = value_type; out[1].value = 0; out[1].decl_range.First = first; @@ -1551,6 +1565,23 @@ emit_decl_semantic(struct ureg_program *ureg, } } +static void +emit_decl_semantic(struct ureg_program *ureg, + unsigned file, + unsigned first, + unsigned last, + enum tgsi_semantic semantic_name, + unsigned semantic_index, + unsigned streams, + unsigned usage_mask, + unsigned array_id, + bool invariant) +{ + emit_decl_semantic_typed(ureg, file, first, last, + semantic_name, semantic_index, streams, usage_mask, array_id, + invariant, TGSI_RETURN_TYPE_UNKNOWN); +} + static void emit_decl_atomic_2d(struct ureg_program *ureg, unsigned first, @@ -1941,31 +1972,34 @@ static void emit_decls( struct ureg_program *ureg ) if (ureg->supports_any_inout_decl_range) { for (i = 0; i < ureg->nr_outputs; i++) { - emit_decl_semantic(ureg, - TGSI_FILE_OUTPUT, - ureg->output[i].first, - ureg->output[i].last, - ureg->output[i].semantic_name, - ureg->output[i].semantic_index, - ureg->output[i].streams, - ureg->output[i].usage_mask, - ureg->output[i].array_id, - ureg->output[i].invariant); + emit_decl_semantic_typed(ureg, + TGSI_FILE_OUTPUT, + ureg->output[i].first, + ureg->output[i].last, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index, + ureg->output[i].streams, + ureg->output[i].usage_mask, + ureg->output[i].array_id, + ureg->output[i].invariant, + ureg->output[i].value_type); + } } else { for (i = 0; i < ureg->nr_outputs; i++) { for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) { - emit_decl_semantic(ureg, - TGSI_FILE_OUTPUT, - j, j, - ureg->output[i].semantic_name, - ureg->output[i].semantic_index + - (j - ureg->output[i].first), - ureg->output[i].streams, - ureg->output[i].usage_mask, - 0, - ureg->output[i].invariant); + emit_decl_semantic_typed(ureg, + TGSI_FILE_OUTPUT, + j, j, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index + + (j - ureg->output[i].first), + ureg->output[i].streams, + ureg->output[i].usage_mask, + 0, + ureg->output[i].invariant, + ureg->output[i].value_type); } } } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index 76efe956fcd45cc9bda46130f9e4e7e7965a7803..15cf5feb10d10365e70f3228190e65c9010873ef 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -254,6 +254,12 @@ ureg_DECL_output(struct ureg_program *, enum tgsi_semantic semantic_name, unsigned semantic_index); +struct ureg_dst +ureg_DECL_output_typed(struct ureg_program *, + enum tgsi_semantic semantic_name, + unsigned semantic_index, + enum tgsi_return_type value_type); + struct ureg_dst ureg_DECL_output_array(struct ureg_program *ureg, enum tgsi_semantic semantic_name, diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 9ecb041bdd9176359c06d6adf01a7d7034fad112..bb43b165acbd5faf0dfdb94a17cccb89787c1f1e 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -273,9 +273,9 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR ); - out = ureg_DECL_output( ureg, - TGSI_SEMANTIC_COLOR, - 0 ); + out = ureg_DECL_output_typed( ureg, + TGSI_SEMANTIC_COLOR, + 0, dtype); temp = ureg_DECL_temporary(ureg); diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index fa62638292789a1b942ef084f4d38c86877b36da..f0a56a724a2f08f39d805ca3b4972b91bddf7c7c 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -113,6 +113,14 @@ struct ntv_context { SpvId discard_func; SpvId float_array_type[2]; + + bool use_gl_per_vertex; + SpvId per_vertex_block_type[2]; + SpvId per_vertex_in; + SpvId per_vertex_out; + SpvId float_array_1_type; + int gl_in_num_vertices[3]; + int gl_out_num_vertices; }; static SpvId @@ -787,9 +795,157 @@ emit_interpolation(struct ntv_context *ctx, SpvId var_id, } } +enum per_vertex_member { + PV_MEMBER_POSITION = 0, + PV_MEMBER_POINT_SIZE = 1, + PV_MEMBER_CLIP_DISTANCE = 2, + PV_MEMBER_CULL_DISTANCE = 3, + PV_MEMBER_COUNT = 4 +}; + +static inline bool +stage_has_per_vertex_input(gl_shader_stage stage) +{ + return stage == MESA_SHADER_TESS_CTRL || + stage == MESA_SHADER_TESS_EVAL || + stage == MESA_SHADER_GEOMETRY; +} + +static inline bool +stage_has_per_vertex_output(gl_shader_stage stage) +{ + return stage == MESA_SHADER_VERTEX || + stage == MESA_SHADER_TESS_CTRL || + stage == MESA_SHADER_TESS_EVAL || + stage == MESA_SHADER_GEOMETRY; +} + +static inline bool +stage_has_per_vertex(struct ntv_context *ctx) +{ + return ctx->use_gl_per_vertex && + (stage_has_per_vertex_input(ctx->stage) || + stage_has_per_vertex_output(ctx->stage)); +} + +static bool +is_per_vertex_builtin(struct ntv_context *ctx, nir_variable *var) +{ + if (var->data.mode != nir_var_shader_in && + var->data.mode != nir_var_shader_out) + return false; + + if (var->data.mode == nir_var_shader_in && + ctx->stage == MESA_SHADER_VERTEX) { + return false; + } + + if (ctx->stage == MESA_SHADER_FRAGMENT) + return false; + + switch (var->data.location) { + case VARYING_SLOT_POS: + case VARYING_SLOT_PSIZ: + case VARYING_SLOT_CLIP_DIST0: + case VARYING_SLOT_CULL_DIST0: + return true; + default: + return false; + } +} + +static enum per_vertex_member +location_to_per_vertex_member(unsigned location) +{ + switch (location) { + case VARYING_SLOT_POS: + return PV_MEMBER_POSITION; + case VARYING_SLOT_PSIZ: + return PV_MEMBER_POINT_SIZE; + case VARYING_SLOT_CLIP_DIST0: + return PV_MEMBER_CLIP_DISTANCE; + case VARYING_SLOT_CULL_DIST0: + return PV_MEMBER_CULL_DISTANCE; + default: + unreachable("not a per-vertex builtin"); + } +} + +static SpvId +get_per_vertex_member_type(struct ntv_context *ctx, uint32_t member_idx) +{ + switch (member_idx) { + case PV_MEMBER_POSITION: + return get_glsl_type(ctx, glsl_vec4_type()); + case PV_MEMBER_POINT_SIZE: + return get_glsl_type(ctx, glsl_float_type()); + case PV_MEMBER_CLIP_DISTANCE: + case PV_MEMBER_CULL_DISTANCE: + // Use cached type or create it once + if (ctx->float_array_1_type == 0) { + SpvId float_type = get_glsl_type(ctx, glsl_float_type()); + SpvId array_size = spirv_builder_const_uint(&ctx->builder, 32, 6); + ctx->float_array_1_type = spirv_builder_type_array(&ctx->builder, float_type, array_size); + } + return ctx->float_array_1_type; + default: + unreachable("invalid per-vertex member"); + } +} + +static SpvId +create_per_vertex_block_type(struct ntv_context *ctx, bool in) +{ + int index = in ? 0 : 1; + if (ctx->per_vertex_block_type[index] != 0) + return ctx->per_vertex_block_type[index]; + + SpvId vec4_type = get_glsl_type(ctx, glsl_vec4_type()); + SpvId float_type = get_glsl_type(ctx, glsl_float_type()); + SpvId float_array_type = get_per_vertex_member_type(ctx, PV_MEMBER_CLIP_DISTANCE); + + SpvId member_types[PV_MEMBER_COUNT] = { + [PV_MEMBER_POSITION] = vec4_type, + [PV_MEMBER_POINT_SIZE] = float_type, + [PV_MEMBER_CLIP_DISTANCE] = float_array_type, + [PV_MEMBER_CULL_DISTANCE] = float_array_type // Same type as clip distance + }; + + SpvId block_type = spirv_builder_type_struct(&ctx->builder, member_types, PV_MEMBER_COUNT); + + spirv_builder_emit_member_name(&ctx->builder, block_type, PV_MEMBER_POSITION, "gl_Position"); + spirv_builder_emit_member_builtin(&ctx->builder, block_type, PV_MEMBER_POSITION, + SpvBuiltInPosition); + + spirv_builder_emit_member_name(&ctx->builder, block_type, PV_MEMBER_POINT_SIZE, "gl_PointSize"); + spirv_builder_emit_member_builtin(&ctx->builder, block_type, PV_MEMBER_POINT_SIZE, + SpvBuiltInPointSize); + + spirv_builder_emit_member_name(&ctx->builder, block_type, PV_MEMBER_CLIP_DISTANCE, "gl_ClipDistance"); + spirv_builder_emit_member_builtin(&ctx->builder, block_type, PV_MEMBER_CLIP_DISTANCE, + SpvBuiltInClipDistance); + + spirv_builder_emit_member_name(&ctx->builder, block_type, PV_MEMBER_CULL_DISTANCE, "gl_CullDistance"); + spirv_builder_emit_member_builtin(&ctx->builder, block_type, PV_MEMBER_CULL_DISTANCE, + SpvBuiltInCullDistance); + + spirv_builder_emit_name(&ctx->builder, block_type, in ? "gl_PerVertex_0" : "gl_PerVertex"); + spirv_builder_emit_decoration(&ctx->builder, block_type, SpvDecorationBlock); + + ctx->per_vertex_block_type[index] = block_type; + + return block_type; +} + static void emit_input(struct ntv_context *ctx, struct nir_variable *var) { + if (stage_has_per_vertex(ctx) && is_per_vertex_builtin(ctx, var)) { + if (glsl_type_is_array(var->type)) + ctx->gl_in_num_vertices[ctx->stage - 1] = glsl_get_length(var->type); + return; + } + SpvId var_id = input_var_init(ctx, var); if (ctx->stage == MESA_SHADER_VERTEX) spirv_builder_emit_location(&ctx->builder, var_id, @@ -851,6 +1007,12 @@ emit_input(struct ntv_context *ctx, struct nir_variable *var) static void emit_output(struct ntv_context *ctx, struct nir_variable *var) { + if (stage_has_per_vertex(ctx) && is_per_vertex_builtin(ctx, var)) { + if (glsl_type_is_array(var->type)) + ctx->gl_out_num_vertices = glsl_get_length(var->type); + return; + } + SpvId var_type = get_glsl_type(ctx, var->type); /* SampleMask is always an array in spirv */ @@ -3995,6 +4157,104 @@ emit_jump(struct ntv_context *ctx, nir_jump_instr *jump) } } +// Detect if this is a gl_PerVertex access chain and build the complete access +static bool +try_emit_gl_per_vertex_access(struct ntv_context *ctx, nir_deref_instr *deref) +{ + if (!stage_has_per_vertex(ctx)) + return false; + + // Walk up the dereference chain to find components + nir_deref_instr *cur = deref; + nir_deref_instr* array_derefs[2] = {NULL, NULL}; + int num_array_derefs = 0; + nir_deref_instr *struct_deref = NULL; + nir_variable *root_var = NULL; + + // Walk up the chain: current -> parent -> parent... + while (cur) { + switch (cur->deref_type) { + case nir_deref_type_var: + root_var = cur->var; + cur = NULL; // End of chain + break; + case nir_deref_type_array: + if (num_array_derefs >= 2) + return false; + array_derefs[num_array_derefs++] = cur; + cur = nir_deref_instr_parent(cur); + break; + case nir_deref_type_struct: + if (!struct_deref) struct_deref = cur; + cur = nir_deref_instr_parent(cur); + break; + default: + return false; // Unsupported dereference type + } + } + + // Check if this is a gl_PerVertex builtin access + if (!root_var || !is_per_vertex_builtin(ctx, root_var)) + return false; + + // Validate stage compatibility + bool is_output = (root_var->data.mode == nir_var_shader_out); + if (is_output && !stage_has_per_vertex_output(ctx->stage)) + return false; + if (!is_output && !stage_has_per_vertex_input(ctx->stage)) + return false; + + // Build the SPIR-V access chain + SpvId base = is_output ? ctx->per_vertex_out : ctx->per_vertex_in; + SpvId indices[3] = {0, 0, 0}; // Max: [array_index, struct_member, ...] + int num_indices = 0; + + // Add array index if present (for gl_in[i] or gl_out[i]) + bool is_access_per_vertex_array = is_output ? (ctx->stage == MESA_SHADER_TESS_CTRL) : true; + if (is_access_per_vertex_array && num_array_derefs > 0 && array_derefs[num_array_derefs - 1]) { + nir_deref_instr* array_deref = array_derefs[num_array_derefs - 1]; + nir_alu_type itype; + SpvId array_index = get_src(ctx, &array_deref->arr.index, &itype); + if (itype == nir_type_float) + array_index = emit_bitcast(ctx, get_uvec_type(ctx, 32, 1), array_index); + indices[num_indices++] = array_index; + } + + // Add struct member index (always present for gl_PerVertex) + enum per_vertex_member member = location_to_per_vertex_member(root_var->data.location); + SpvId member_index = spirv_builder_const_uint(&ctx->builder, 32, member); + indices[num_indices++] = member_index; + + // Add array index if present (for gl_ClipDistance[i]) + bool is_access_clip_distance = is_access_per_vertex_array ? num_array_derefs > 1 : num_array_derefs > 0; + if (is_access_clip_distance && array_derefs[0]) { + nir_deref_instr* array_deref = array_derefs[0]; + nir_alu_type itype; + SpvId array_index = get_src(ctx, &array_deref->arr.index, &itype); + if (itype == nir_type_float) + array_index = emit_bitcast(ctx, get_uvec_type(ctx, 32, 1), array_index); + indices[num_indices++] = array_index; + } + + // Determine result type and storage class + SpvId member_type = get_per_vertex_member_type(ctx, member); + if (is_access_per_vertex_array) { + member_type = num_array_derefs <= 0 ? ctx->per_vertex_block_type[is_output ? 1 : 0] : + (num_array_derefs > 1 ? get_glsl_type(ctx, glsl_float_type()) : member_type); + } else { + member_type = num_array_derefs > 0 ? get_glsl_type(ctx, glsl_float_type()) : member_type; + } + + SpvStorageClass storage_class = get_storage_class(root_var); + SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder, storage_class, member_type); + + // Generate the access chain + SpvId result = spirv_builder_emit_access_chain(&ctx->builder, ptr_type, base, indices, num_indices); + store_def(ctx, deref->def.index, result, get_nir_alu_type(deref->type)); + + return true; +} + static void emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref) { @@ -4120,6 +4380,9 @@ emit_deref_struct(struct ntv_context *ctx, nir_deref_instr *deref) static void emit_deref(struct ntv_context *ctx, nir_deref_instr *deref) { + if (try_emit_gl_per_vertex_access(ctx, deref)) + return; + switch (deref->deref_type) { case nir_deref_type_var: emit_deref_var(ctx, deref); @@ -4404,6 +4667,51 @@ get_spacing(enum gl_tess_spacing spacing) } } +static void +setup_per_vertex_blocks(struct ntv_context *ctx) +{ + SpvId block_type_in = create_per_vertex_block_type(ctx, true); + SpvId block_type_out = create_per_vertex_block_type(ctx, false); + + if (stage_has_per_vertex_input(ctx->stage)) { + SpvId input_type = block_type_in; + + if (ctx->stage == MESA_SHADER_GEOMETRY || + ctx->stage == MESA_SHADER_TESS_CTRL || + ctx->stage == MESA_SHADER_TESS_EVAL) { + // gl_in[]: array of gl_PerVertex + uint32_t input_vertices = MAX2(ctx->gl_in_num_vertices[ctx->stage - 1], 1); + + SpvId array_size = spirv_builder_const_uint(&ctx->builder, 32, input_vertices); + input_type = spirv_builder_type_array(&ctx->builder, block_type_in, array_size); + } + + SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassInput, input_type); + SpvId var_id = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassInput); + spirv_builder_emit_name(&ctx->builder, var_id, "gl_in"); + ctx->per_vertex_in = var_id; + ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id; + } + + if (stage_has_per_vertex_output(ctx->stage)) { + SpvId output_type = block_type_out; + + // Tessellation control shaders need gl_out[] as an array + if (ctx->stage == MESA_SHADER_TESS_CTRL) { + uint32_t output_vertices = MAX2(ctx->gl_out_num_vertices, 1); + SpvId array_size = spirv_builder_const_uint(&ctx->builder, 32, output_vertices); + output_type = spirv_builder_type_array(&ctx->builder, block_type_out, array_size); + } + + SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassOutput, output_type); + SpvId var_id = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassOutput); + spirv_builder_emit_name(&ctx->builder, var_id, "gl_out"); + + ctx->per_vertex_out = var_id; + ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id; + } +} + struct spirv_shader * nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, const struct zink_screen *screen) { @@ -4572,6 +4880,9 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, const s ctx.vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_pointer, _mesa_key_pointer_equal); + // TODO: set this on a per driver basis + ctx.use_gl_per_vertex = true; + nir_foreach_variable_with_modes(var, s, nir_var_mem_push_const) input_var_init(&ctx, var); @@ -4589,6 +4900,9 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, const s emit_output(&ctx, var); } + if (ctx.use_gl_per_vertex) + setup_per_vertex_blocks(&ctx); + uint32_t tcs_vertices_out_word = 0; unsigned ubo_counter[2] = {0}; diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c index 83ec238d4d1f27b83fd2015c6b51115058803e6b..f02ffda1caad504e633200bb22fbbdbdc1bb665c 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -412,6 +412,28 @@ spirv_builder_emit_member_offset(struct spirv_builder *b, SpvId target, args, ARRAY_SIZE(args)); } +void +spirv_builder_emit_member_builtin(struct spirv_builder *b, SpvId target, + uint32_t member, SpvBuiltIn builtin) +{ + uint32_t args[] = { builtin }; + emit_member_decoration(b, target, member, SpvDecorationBuiltin, + args, ARRAY_SIZE(args)); +} + +void +spirv_builder_emit_member_name(struct spirv_builder *b, SpvId struct_name, + unsigned member, const char *name) +{ + size_t pos = b->debug_names.num_words; + spirv_buffer_prepare(&b->debug_names, b->mem_ctx, 3); + spirv_buffer_emit_word(&b->debug_names, SpvOpMemberName); + spirv_buffer_emit_word(&b->debug_names, struct_name); + spirv_buffer_emit_word(&b->debug_names, member); + int len = spirv_buffer_emit_string(&b->debug_names, b->mem_ctx, name); + b->debug_names.words[pos] |= (3 + len) << 16; +} + SpvId spirv_builder_emit_undef(struct spirv_builder *b, SpvId result_type) { diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h index 2456d2a1bf3eba9ff6e644e85ef313b409fa5763..73facbe8d63583bf43744187eba9089d75c5253f 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h @@ -165,6 +165,14 @@ void spirv_builder_emit_member_offset(struct spirv_builder *b, SpvId target, uint32_t member, uint32_t offset); +void +spirv_builder_emit_member_builtin(struct spirv_builder *b, SpvId target, + uint32_t member, SpvBuiltIn builtin); + +void +spirv_builder_emit_member_name(struct spirv_builder *b, SpvId struct_name, + unsigned member, const char *name); + void spirv_builder_emit_entry_point(struct spirv_builder *b, SpvExecutionModel exec_model, SpvId entry_point, diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 274908d5528c0205410c5c3532c38c197867ef63..a0709d094fe4eca4aba960d0f2bbe38b761e283b 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -857,6 +857,7 @@ zink_init_screen_caps(struct zink_screen *screen) caps->allow_glthread_buffer_subdata_opt = true; caps->nir_samplers_as_deref = true; caps->call_finalize_nir_in_linker = true; + caps->texture_shadow_lod = true; caps->draw_vertex_state = screen->info.have_EXT_vertex_input_dynamic_state; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 170c5e4082b1640f3bb66dea74adb53f10c3fedf..8491f3ede6037710ea971829919ec098a1ffec77 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -134,7 +134,7 @@ struct tgsi_declaration unsigned Array : 1; /**< extra array info? */ unsigned Atomic : 1; /**< atomic only? for TGSI_FILE_BUFFER */ unsigned MemType : 2; /**< TGSI_MEMORY_TYPE_x for TGSI_FILE_MEMORY */ - unsigned Padding : 3; + unsigned ValueType : 3; /**< TGSI_RETURN_TYPE_x */ }; struct tgsi_declaration_range