mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
shader: add viewport-index exports and indexed raster state
Co-authored-by: Ettore Sartori <85788613+Ekt0re@users.noreply.github.com>
This commit is contained in:
@@ -338,15 +338,24 @@ void EmitAuxPositionExport(ValueEmitContext& ctx, uint32_t data, const IR::Expor
|
||||
}
|
||||
const auto output = IR::DecodePositionExportComponent(
|
||||
state.input_info.vertex->pa_cl_vs_out_cntl, exp.index, component);
|
||||
if (output.layer) {
|
||||
const auto raw = ExportRawComponent(ctx, data, component);
|
||||
const auto layer = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), layer, raw,
|
||||
ConstantU32(state, 0x7ffu)});
|
||||
const auto pointer = state.stage == ShaderType::Mesh
|
||||
? MeshOutputPointer(state, IR::StageOutputKind::Layer)
|
||||
: state.layer_variable;
|
||||
state.builder.AddFunction({OpStore, pointer, layer});
|
||||
if (output.layer || output.viewport) {
|
||||
const auto raw = ExportRawComponent(ctx, data, component);
|
||||
if (output.layer) {
|
||||
const auto layer = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), layer, raw,
|
||||
ConstantU32(state, 0x7ffu)});
|
||||
const auto pointer = state.stage == ShaderType::Mesh
|
||||
? MeshOutputPointer(state, IR::StageOutputKind::Layer)
|
||||
: state.layer_variable;
|
||||
state.builder.AddFunction({OpStore, pointer, layer});
|
||||
}
|
||||
if (output.viewport) {
|
||||
// GFX10 MISC.z packs the viewport index in bits 16..19 alongside the layer.
|
||||
const auto viewport = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitFieldUExtract, TypeU32(state), viewport, raw,
|
||||
ConstantU32(state, 16), ConstantU32(state, 4)});
|
||||
state.builder.AddFunction({OpStore, state.viewport_index_variable, viewport});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!output.point_size && output.clip_distance == UINT32_MAX &&
|
||||
|
||||
@@ -52,6 +52,7 @@ enum : uint32_t {
|
||||
CapabilityGroupNonUniformBallot = 64,
|
||||
CapabilityGroupNonUniformShuffle = 65,
|
||||
CapabilityShaderLayer = 69,
|
||||
CapabilityShaderViewportIndex = 70,
|
||||
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||
CapabilityFragmentBarycentricKHR = 5284,
|
||||
CapabilityComputeDerivativeGroupQuadsKHR = 5288,
|
||||
@@ -91,6 +92,7 @@ enum : uint32_t {
|
||||
BuiltInClipDistance = 3,
|
||||
BuiltInCullDistance = 4,
|
||||
BuiltInLayer = 9,
|
||||
BuiltInViewportIndex = 10,
|
||||
BuiltInFragCoord = 15,
|
||||
BuiltInFrontFacing = 17,
|
||||
BuiltInSampleId = 18,
|
||||
@@ -391,6 +393,7 @@ struct EmitterState {
|
||||
uint32_t clip_distance_variable = 0;
|
||||
uint32_t cull_distance_variable = 0;
|
||||
uint32_t layer_variable = 0;
|
||||
uint32_t viewport_index_variable = 0;
|
||||
uint32_t clip_distance_count = 0;
|
||||
uint32_t cull_distance_count = 0;
|
||||
uint32_t depth_variable = 0;
|
||||
|
||||
@@ -490,6 +490,10 @@ void AllocateOutputVariables(EmitterState& state) {
|
||||
case IR::StageOutputKind::Layer:
|
||||
binding.variable_id = AllocateSharedOutputVariable(state, state.layer_variable);
|
||||
break;
|
||||
case IR::StageOutputKind::ViewportIndex:
|
||||
binding.variable_id =
|
||||
AllocateSharedOutputVariable(state, state.viewport_index_variable);
|
||||
break;
|
||||
case IR::StageOutputKind::Depth:
|
||||
binding.variable_id = AllocateSharedOutputVariable(state, state.depth_variable);
|
||||
break;
|
||||
@@ -583,6 +587,7 @@ void AddOutputAnnotationsAndNames(EmitterState& state) {
|
||||
AddBuiltIn(state.clip_distance_variable, "gl_ClipDistance", BuiltInClipDistance);
|
||||
AddBuiltIn(state.cull_distance_variable, "gl_CullDistance", BuiltInCullDistance);
|
||||
AddBuiltIn(state.layer_variable, "gl_Layer", BuiltInLayer);
|
||||
AddBuiltIn(state.viewport_index_variable, "gl_ViewportIndex", BuiltInViewportIndex);
|
||||
if (state.depth_variable != 0) {
|
||||
state.builder.AddName(state.depth_variable, "gl_FragDepth");
|
||||
state.builder.AddAnnotation(
|
||||
@@ -712,6 +717,10 @@ void DefineModule(EmitterState& state) {
|
||||
state.builder.RequireVersion(0x00010500u);
|
||||
state.builder.RequireCapability(CapabilityShaderLayer);
|
||||
}
|
||||
if (state.viewport_index_variable != 0) {
|
||||
state.builder.RequireVersion(0x00010500u);
|
||||
state.builder.RequireCapability(CapabilityShaderViewportIndex);
|
||||
}
|
||||
if (InputVariableForKind(state, IR::StageInputKind::SampleId) != 0) {
|
||||
state.builder.RequireCapability(CapabilitySampleRateShading);
|
||||
}
|
||||
@@ -874,6 +883,11 @@ void DefineModule(EmitterState& state) {
|
||||
state.layer_variable, TypePointer(state, StorageClassOutput, TypeU32(state)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
if (state.viewport_index_variable != 0) {
|
||||
state.builder.DefineGlobalVariable(
|
||||
state.viewport_index_variable, TypePointer(state, StorageClassOutput, TypeU32(state)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
for (const auto& binding: state.outputs) {
|
||||
if (binding.kind == IR::StageOutputKind::Parameter ||
|
||||
binding.kind == IR::StageOutputKind::Mrt) {
|
||||
|
||||
@@ -181,7 +181,8 @@ enum class StageOutputKind {
|
||||
PointSize,
|
||||
ClipDistance,
|
||||
CullDistance,
|
||||
Layer
|
||||
Layer,
|
||||
ViewportIndex
|
||||
};
|
||||
|
||||
struct PositionExportComponent {
|
||||
|
||||
@@ -324,7 +324,7 @@ void CollectOutputs(const Program& program, const ShaderVertexInputInfo* vertex,
|
||||
const auto output = DecodePositionExportComponent(
|
||||
vertex->pa_cl_vs_out_cntl, export_info.index, component);
|
||||
if (output.viewport) {
|
||||
return Fail("vertex viewport-index export is unsupported");
|
||||
AddOutput(info, StageOutputKind::ViewportIndex, 0, 0, "gl_ViewportIndex");
|
||||
}
|
||||
if (output.point_size) {
|
||||
AddOutput(info, StageOutputKind::PointSize, 0, 0, "gl_PointSize");
|
||||
|
||||
Reference in New Issue
Block a user