mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 19:36:55 +02:00
shader: fix auxiliary position exports
This commit is contained in:
@@ -64,7 +64,7 @@ void CopyProgramInputsAndOutputs(EmitterState& state, const IR::Program& program
|
||||
}
|
||||
|
||||
uint32_t OutputVariableForExport(const EmitterState& state, const IR::ExportInfo& exp) {
|
||||
if (exp.kind == IR::ExportTargetKind::Position) {
|
||||
if (exp.kind == IR::ExportTargetKind::Position && exp.index == 0) {
|
||||
return state.per_vertex_variable;
|
||||
}
|
||||
if (exp.kind == IR::ExportTargetKind::MrtZ) {
|
||||
|
||||
@@ -367,6 +367,49 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
||||
return vector;
|
||||
}
|
||||
|
||||
void EmitAuxPositionExport(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo& exp) {
|
||||
auto& state = ctx.state;
|
||||
for (uint32_t component = 0; component < 4; component++) {
|
||||
if ((exp.en & (1u << component)) == 0) {
|
||||
continue;
|
||||
}
|
||||
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)});
|
||||
state.builder.AddFunction({OpStore, state.layer_variable, layer});
|
||||
continue;
|
||||
}
|
||||
if (!output.point_size && output.clip_distance == UINT32_MAX &&
|
||||
output.cull_distance == UINT32_MAX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto raw = ExportRawComponent(ctx, data, component);
|
||||
const auto f32 = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitcast, TypeF32(state), f32, raw});
|
||||
if (output.point_size) {
|
||||
state.builder.AddFunction({OpStore, state.point_size_variable, f32});
|
||||
continue;
|
||||
}
|
||||
auto StoreDistance = [&](uint32_t variable, uint32_t index) {
|
||||
if (index == UINT32_MAX) {
|
||||
return;
|
||||
}
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpAccessChain, TypePointer(state, StorageClassOutput, TypeF32(state)), pointer,
|
||||
variable, ConstantU32(state, index)});
|
||||
state.builder.AddFunction({OpStore, pointer, f32});
|
||||
};
|
||||
StoreDistance(state.clip_distance_variable, output.clip_distance);
|
||||
StoreDistance(state.cull_distance_variable, output.cull_distance);
|
||||
}
|
||||
}
|
||||
|
||||
void EmitExport(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
auto& state = ctx.state;
|
||||
const auto& exp = ctx.Export(inst);
|
||||
@@ -384,6 +427,10 @@ void EmitExport(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
}
|
||||
EmitIfCondition(state, exec, [&]() {
|
||||
const auto data = ctx.Arg(inst, 0);
|
||||
if (exp.kind == IR::ExportTargetKind::Position && exp.index != 0) {
|
||||
EmitAuxPositionExport(ctx, data, exp);
|
||||
return;
|
||||
}
|
||||
if (exp.kind == IR::ExportTargetKind::MrtZ) {
|
||||
if ((exp.en & 1u) != 0u && state.depth_variable != 0) {
|
||||
const auto raw = ExportRawComponent(ctx, data, 0);
|
||||
|
||||
@@ -39,6 +39,8 @@ enum : uint32_t {
|
||||
MemoryModelGLSL450 = 1,
|
||||
CapabilityShader = 1,
|
||||
CapabilityImageGatherExtended = 25,
|
||||
CapabilityClipDistance = 32,
|
||||
CapabilityCullDistance = 33,
|
||||
CapabilitySampled1D = 43,
|
||||
CapabilityImage1D = 44,
|
||||
CapabilityImageQuery = 50,
|
||||
@@ -47,6 +49,7 @@ enum : uint32_t {
|
||||
CapabilityGroupNonUniformBallot = 64,
|
||||
CapabilityGroupNonUniformShuffle = 65,
|
||||
CapabilitySignedZeroInfNanPreserve = 4466,
|
||||
CapabilityShaderViewportIndexLayerEXT = 5254,
|
||||
CapabilityFragmentBarycentricKHR = 5284,
|
||||
CapabilityComputeDerivativeGroupQuadsKHR = 5288,
|
||||
StorageClassUniformConstant = 0,
|
||||
@@ -77,6 +80,10 @@ enum : uint32_t {
|
||||
|
||||
enum : uint32_t {
|
||||
BuiltInPosition = 0,
|
||||
BuiltInPointSize = 1,
|
||||
BuiltInClipDistance = 3,
|
||||
BuiltInCullDistance = 4,
|
||||
BuiltInLayer = 9,
|
||||
BuiltInFragCoord = 15,
|
||||
BuiltInFrontFacing = 17,
|
||||
BuiltInSampleMask = 20,
|
||||
@@ -359,6 +366,12 @@ struct EmitterState {
|
||||
uint32_t pixel_valid_mask_variable = 0;
|
||||
uint32_t subgroup_local_invocation_id_variable = 0;
|
||||
uint32_t per_vertex_variable = 0;
|
||||
uint32_t point_size_variable = 0;
|
||||
uint32_t clip_distance_variable = 0;
|
||||
uint32_t cull_distance_variable = 0;
|
||||
uint32_t layer_variable = 0;
|
||||
uint32_t clip_distance_count = 0;
|
||||
uint32_t cull_distance_count = 0;
|
||||
uint32_t depth_variable = 0;
|
||||
uint32_t sample_mask_variable = 0;
|
||||
std::vector<InputBinding> inputs;
|
||||
|
||||
@@ -130,6 +130,10 @@ uint32_t SampleMaskArrayType(EmitterState& state) {
|
||||
return state.builder.Type(OpTypeArray, {TypeI32(state), ConstantU32(state, 1)});
|
||||
}
|
||||
|
||||
uint32_t F32ArrayType(EmitterState& state, uint32_t count) {
|
||||
return state.builder.Type(OpTypeArray, {TypeF32(state), ConstantU32(state, count)});
|
||||
}
|
||||
|
||||
void DefineDescriptorVariables(EmitterState& state) {
|
||||
if (DescriptorBinding(state, IR::DescriptorBindingKind::Buffers) != nullptr) {
|
||||
const auto count =
|
||||
@@ -420,6 +424,23 @@ void AllocateOutputVariables(EmitterState& state) {
|
||||
binding.variable_id =
|
||||
AllocateSharedOutputVariable(state, state.per_vertex_variable);
|
||||
break;
|
||||
case IR::StageOutputKind::PointSize:
|
||||
binding.variable_id =
|
||||
AllocateSharedOutputVariable(state, state.point_size_variable);
|
||||
break;
|
||||
case IR::StageOutputKind::ClipDistance:
|
||||
binding.variable_id =
|
||||
AllocateSharedOutputVariable(state, state.clip_distance_variable);
|
||||
state.clip_distance_count = std::max(state.clip_distance_count, binding.index + 1);
|
||||
break;
|
||||
case IR::StageOutputKind::CullDistance:
|
||||
binding.variable_id =
|
||||
AllocateSharedOutputVariable(state, state.cull_distance_variable);
|
||||
state.cull_distance_count = std::max(state.cull_distance_count, binding.index + 1);
|
||||
break;
|
||||
case IR::StageOutputKind::Layer:
|
||||
binding.variable_id = AllocateSharedOutputVariable(state, state.layer_variable);
|
||||
break;
|
||||
case IR::StageOutputKind::Depth:
|
||||
binding.variable_id = AllocateSharedOutputVariable(state, state.depth_variable);
|
||||
break;
|
||||
@@ -495,6 +516,16 @@ void AddOutputAnnotationsAndNames(EmitterState& state) {
|
||||
state.builder.AddName(PerVertexType(state), "gl_PerVertex");
|
||||
state.builder.AddName(state.per_vertex_variable, "outPerVertex");
|
||||
}
|
||||
auto AddBuiltIn = [&](uint32_t variable, const char* name, uint32_t builtin) {
|
||||
if (variable != 0) {
|
||||
state.builder.AddName(variable, name);
|
||||
state.builder.AddAnnotation({OpDecorate, variable, DecorationBuiltIn, builtin});
|
||||
}
|
||||
};
|
||||
AddBuiltIn(state.point_size_variable, "gl_PointSize", BuiltInPointSize);
|
||||
AddBuiltIn(state.clip_distance_variable, "gl_ClipDistance", BuiltInClipDistance);
|
||||
AddBuiltIn(state.cull_distance_variable, "gl_CullDistance", BuiltInCullDistance);
|
||||
AddBuiltIn(state.layer_variable, "gl_Layer", BuiltInLayer);
|
||||
if (state.depth_variable != 0) {
|
||||
state.builder.AddName(state.depth_variable, "gl_FragDepth");
|
||||
state.builder.AddAnnotation(
|
||||
@@ -613,6 +644,16 @@ void DefineModule(EmitterState& state) {
|
||||
|
||||
state.builder.RequireCapability(CapabilityShader);
|
||||
state.builder.RequireCapability(CapabilitySignedZeroInfNanPreserve);
|
||||
if (state.clip_distance_variable != 0) {
|
||||
state.builder.RequireCapability(CapabilityClipDistance);
|
||||
}
|
||||
if (state.cull_distance_variable != 0) {
|
||||
state.builder.RequireCapability(CapabilityCullDistance);
|
||||
}
|
||||
if (state.layer_variable != 0) {
|
||||
state.builder.RequireCapability(CapabilityShaderViewportIndexLayerEXT);
|
||||
state.builder.RequireExtension("SPV_EXT_shader_viewport_index_layer");
|
||||
}
|
||||
if (state.requirements.image_gather_extended) {
|
||||
state.builder.RequireCapability(CapabilityImageGatherExtended);
|
||||
}
|
||||
@@ -733,6 +774,30 @@ void DefineModule(EmitterState& state) {
|
||||
state.per_vertex_variable, TypePointer(state, StorageClassOutput, PerVertexType(state)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
if (state.point_size_variable != 0) {
|
||||
state.builder.DefineGlobalVariable(
|
||||
state.point_size_variable, TypePointer(state, StorageClassOutput, TypeF32(state)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
if (state.clip_distance_variable != 0) {
|
||||
state.builder.DefineGlobalVariable(
|
||||
state.clip_distance_variable,
|
||||
TypePointer(state, StorageClassOutput,
|
||||
F32ArrayType(state, state.clip_distance_count)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
if (state.cull_distance_variable != 0) {
|
||||
state.builder.DefineGlobalVariable(
|
||||
state.cull_distance_variable,
|
||||
TypePointer(state, StorageClassOutput,
|
||||
F32ArrayType(state, state.cull_distance_count)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
if (state.layer_variable != 0) {
|
||||
state.builder.DefineGlobalVariable(
|
||||
state.layer_variable, TypePointer(state, StorageClassOutput, TypeU32(state)),
|
||||
StorageClassOutput);
|
||||
}
|
||||
for (const auto& binding: state.outputs) {
|
||||
if (binding.kind == IR::StageOutputKind::Parameter ||
|
||||
binding.kind == IR::StageOutputKind::Mrt) {
|
||||
|
||||
Reference in New Issue
Block a user