Externals: rslc with gl_Layer in a pixel stage

The vendored rslc takes gl_Layer in a pixel stage, so the stereoscopic
pixel shaders, which read the layer the geometry stage chose, compile
for Vulkan and Direct3D.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-11-06 18:30:50 +01:00
1 parent c11f067627
commit 27a5d7f434
5 files changed
+65 -13

No files matched your search

+44 -4
View File
@@ -1329,7 +1329,7 @@ static bool dx_interface(struct dx_emit *e)
const struct rslc_prog *pr = &e->c->prog;
bool frag = e->c->stage == RSLC_STAGE_FRAGMENT;
struct dx_packer pk;
uint32_t i, pass;
uint32_t i, layer, pass;
if (e->c->stage == RSLC_STAGE_COMPUTE)
return true;
@@ -1375,6 +1375,44 @@ static bool dx_interface(struct dx_emit *e)
return false;
dv->has_home = true;
}
/* a pixel stage reading gl_Layer: the position, then the layer, where
* the geometry stage writes them, the position declared even when
* unread */
layer = 0;
for (i = 1; frag && i < pr->nvars; i++)
{
const struct rslc_var *v = pr->vars[i];
if (v->global && v->storage == RSLC_ST_BUILTIN && e->used[i]
&& v->builtin == RSLC_BI_LAYER)
layer = i;
}
if (layer)
{
uint32_t reg;
uint8_t comp;
for (i = 1; i < pr->nvars; i++)
{
const struct rslc_var *v = pr->vars[i];
if (v->global && v->storage == RSLC_ST_BUILTIN && e->used[i]
&& v->builtin == RSLC_BI_FRAGCOORD)
break;
}
if (!dx_pack(e, &pk, 4, 1, DX_GROUP_ALONE, &reg, &comp)
|| !dx_sig_add(e, true, "SV_Position", 0, reg, 0, DX_SV_POSITION, DX_CT_FLOAT, 4,
DX_INTERP_NOPERSPECTIVE))
return false;
if (i < pr->nvars)
{
e->vars[i].home = dx_place_of(DXO_INPUT, reg);
e->vars[i].has_home = true;
}
if (!dx_pack(e, &pk, 1, 1, DX_GROUP_ALONE, &reg, &comp)
|| !dx_sig_add(e, true, "SV_RenderTargetArrayIndex", 0, reg, 0, DX_SV_RTINDEX,
DX_CT_UINT, 1, DX_INTERP_CONSTANT))
return false;
e->vars[layer].home = dx_place_of(DXO_INPUT, reg);
e->vars[layer].has_home = true;
}
for (i = 1; i < pr->nvars; i++)
{
const struct rslc_var *v = pr->vars[i];
@@ -1386,6 +1424,8 @@ static bool dx_interface(struct dx_emit *e)
uint8_t comp;
if (!v->global || v->storage != RSLC_ST_BUILTIN || !e->used[i])
continue;
if (layer && (v->builtin == RSLC_BI_FRAGCOORD || v->builtin == RSLC_BI_LAYER))
continue;
switch (v->builtin)
{
case RSLC_BI_FRAGCOORD: name = "SV_Position"; sv = DX_SV_POSITION; n = 4; break;
@@ -1486,7 +1526,7 @@ static bool dx_interface(struct dx_emit *e)
struct dx_var *dv = &e->vars[i];
uint32_t n, reg;
uint8_t comp;
if (!v->global || v->storage != RSLC_ST_BUILTIN || !e->used[i])
if (!v->global || v->storage != RSLC_ST_BUILTIN || !e->used[i] || v->dir != RSLC_DIR_OUT)
continue;
if (pass != (v->builtin == RSLC_BI_POSITION ? 0u : v->builtin == RSLC_BI_LAYER ? 1u : 2u))
continue;
@@ -4693,8 +4733,8 @@ static bool dx_decls(struct dx_emit *e)
}
if (frag)
{
op = s->sv ? (s->sv == DX_SV_POSITION ? DX_DCL_INPUT_PS_SIV : DX_DCL_INPUT_PS_SGV)
: DX_DCL_INPUT_PS;
op = s->sv ? (s->sv == DX_SV_POSITION || s->sv == DX_SV_RTINDEX ? DX_DCL_INPUT_PS_SIV
: DX_DCL_INPUT_PS_SGV) : DX_DCL_INPUT_PS;
if (op != DX_DCL_INPUT_PS_SGV)
fl = (uint32_t)s->interp << 11;
}
+3
View File
@@ -5062,6 +5062,7 @@ static void pr_hlsl_semantic(struct rslc_pr *p, const struct rslc_var *v, bool i
case RSLC_BI_FRONTFACING: pr_s(p, "SV_IsFrontFace"); return;
case RSLC_BI_SAMPLEID: pr_s(p, "SV_SampleIndex"); return;
#ifdef RSLC_EXTENDED
case RSLC_BI_LAYER: pr_s(p, "SV_RenderTargetArrayIndex"); return;
case RSLC_BI_GLOBALINVOCATIONID: pr_s(p, "SV_DispatchThreadID"); return;
case RSLC_BI_LOCALINVOCATIONID: pr_s(p, "SV_GroupThreadID"); return;
case RSLC_BI_WORKGROUPID: pr_s(p, "SV_GroupID"); return;
@@ -5173,6 +5174,7 @@ static bool pr_hlsl_builtin_in(const struct rslc_var *v, bool *in_struct)
case RSLC_BI_FRONTFACING:
case RSLC_BI_SAMPLEID:
#ifdef RSLC_EXTENDED
case RSLC_BI_LAYER:
case RSLC_BI_GLOBALINVOCATIONID:
case RSLC_BI_LOCALINVOCATIONID:
case RSLC_BI_WORKGROUPID:
@@ -6417,6 +6419,7 @@ static bool pr_msl(struct rslc_pr *p, struct rslc_result *result)
case RSLC_BI_INSTANCEINDEX: attr = "uint gl_InstanceIndex_in [[instance_id]]"; break;
case RSLC_BI_SAMPLEID: attr = "uint gl_SampleID_in [[sample_id]]"; break;
#ifdef RSLC_EXTENDED
case RSLC_BI_LAYER: attr = "uint gl_Layer_in [[render_target_array_index]]"; break;
case RSLC_BI_GLOBALINVOCATIONID:
attr = "uint3 gl_GlobalInvocationID [[thread_position_in_grid]]"; break;
case RSLC_BI_LOCALINVOCATIONID:
+6 -3
View File
@@ -3492,7 +3492,8 @@ static bool rslc_p_is_lvalue(struct rslc_parser *p, uint32_t e)
if (v->storage == RSLC_ST_BUILTIN)
return v->builtin == RSLC_BI_POSITION || v->builtin == RSLC_BI_FRAGDEPTH
|| v->builtin == RSLC_BI_POINTSIZE || v->builtin == RSLC_BI_CLIPDISTANCE
|| v->builtin == RSLC_BI_CULLDISTANCE || v->builtin == RSLC_BI_LAYER;
|| v->builtin == RSLC_BI_CULLDISTANCE
|| (v->builtin == RSLC_BI_LAYER && v->dir == RSLC_DIR_OUT);
return true;
}
case RSLC_OP_MEMBER:
@@ -6210,7 +6211,8 @@ static bool rslc_p_run(struct rslc_ctx *c)
#ifdef RSLC_EXTENDED
if (!rslc_p_builtin_var(p, "gl_SampleID", p->t_int, RSLC_BI_SAMPLEID, RSLC_DIR_IN)
|| !rslc_p_builtin_var(p, "gl_HelperInvocation", p->t_bool,
RSLC_BI_HELPERINVOCATION, RSLC_DIR_IN))
RSLC_BI_HELPERINVOCATION, RSLC_DIR_IN)
|| !rslc_p_builtin_var(p, "gl_Layer", p->t_int, RSLC_BI_LAYER, RSLC_DIR_IN))
return false;
#endif
}
@@ -6435,7 +6437,8 @@ struct rslc_builder *rslc_b_begin(const struct rslc_opts *opts, enum rslc_stage
|| !rslc_p_builtin_var(p, "gl_FrontFacing", p->t_bool, RSLC_BI_FRONTFACING, RSLC_DIR_IN))
return b;
#ifdef RSLC_EXTENDED
else if (!rslc_p_builtin_var(p, "gl_SampleID", p->t_int, RSLC_BI_SAMPLEID, RSLC_DIR_IN))
else if (!rslc_p_builtin_var(p, "gl_SampleID", p->t_int, RSLC_BI_SAMPLEID, RSLC_DIR_IN)
|| !rslc_p_builtin_var(p, "gl_Layer", p->t_int, RSLC_BI_LAYER, RSLC_DIR_IN))
return b;
#endif
return b;
+8 -3
View File
@@ -1230,6 +1230,7 @@ struct spv_emit
bool need_groupnonuniformarith;
bool need_sampledbuffer;
bool need_samplerateshading;
bool need_geometry; /* a pixel stage reading gl_Layer */
bool need_clipdistance;
bool writes_fragdepth; /* the entry point declares DepthReplacing */
bool need_culldistance;
@@ -4699,8 +4700,12 @@ static bool spv_builtin_var(struct spv_emit *e, const struct rslc_var *v)
return false;
if (!spv_decorate1(e, id, SPV_DEC_BUILTIN, bi) || !spv_w(e, &e->entry_iface, id))
return false;
/* an integer fragment input is flat, a builtin too */
if (v->builtin == RSLC_BI_SAMPLEID && !spv_decorate(e, id, SPV_DEC_FLAT))
/* an integer fragment input is flat, a builtin too; a pixel stage
* reading the layer needs the geometry capability */
if (v->builtin == RSLC_BI_LAYER && sc == SPV_SC_INPUT)
e->need_geometry = true;
if ((v->builtin == RSLC_BI_SAMPLEID || (v->builtin == RSLC_BI_LAYER && sc == SPV_SC_INPUT))
&& !spv_decorate(e, id, SPV_DEC_FLAT))
return false;
if ((v->precision == RSLC_PREC_LOW || v->precision == RSLC_PREC_MEDIUM)
&& !spv_decorate(e, id, SPV_DEC_RELAXEDPRECISION))
@@ -5070,7 +5075,7 @@ static bool rslc_emit_spirv(struct rslc_ctx *c, struct rslc_result *result)
/* header-ish sections */
if (!spv_inst1(e, SPV_SEC_CAPS, SpvOpCapability, SPV_CAP_SHADER))
return false;
if (c->stage == RSLC_STAGE_GEOMETRY
if ((c->stage == RSLC_STAGE_GEOMETRY || e->need_geometry)
&& !spv_inst1(e, SPV_SEC_CAPS, SpvOpCapability, SPV_CAP_GEOMETRY))
return false;
if (e->need_sampledbuffer && !spv_inst1(e, SPV_SEC_CAPS, SpvOpCapability, SPV_CAP_SAMPLEDBUFFER))
+4 -3
View File
@@ -395,7 +395,7 @@ struct rslc_var
#define RSLC_BI_CLIPDISTANCE 9 /* RSLC_EXTENDED */
#define RSLC_BI_CULLDISTANCE 10 /* RSLC_EXTENDED */
#define RSLC_BI_INVOCATIONID 11 /* RSLC_EXTENDED, geometry */
#define RSLC_BI_LAYER 12 /* RSLC_EXTENDED, geometry */
#define RSLC_BI_LAYER 12 /* RSLC_EXTENDED, geometry out, fragment in */
#define RSLC_BI_GLOBALINVOCATIONID 13 /* RSLC_EXTENDED, compute */
#define RSLC_BI_LOCALINVOCATIONID 14
#define RSLC_BI_WORKGROUPID 15
@@ -425,9 +425,10 @@ struct rslc_var
* the least maxClipDistances Vulkan guarantees. */
#define RSLC_MAX_CLIP 8
/* The integer builtins HLSL and MSL hand over as uint. */
/* The integer builtins HLSL and MSL hand over as uint (gl_Layer: a
* pixel stage's, the only stage those printers take it in). */
#define RSLC_BI_IS_UINT_IN(b) ((b) == RSLC_BI_VERTEXINDEX || (b) == RSLC_BI_INSTANCEINDEX \
|| (b) == RSLC_BI_SAMPLEID)
|| (b) == RSLC_BI_SAMPLEID || (b) == RSLC_BI_LAYER)
/* A uniform block or push-constant block. */
struct rslc_blockdecl