mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-09 13:19:00 +00:00
shader_recompiler: Do not emit Layer when emulating primitive type with tessellation. (#3457)
Layer must be output from the final pre-rasterization stage, so when tessellation is being used the vertex shader cannot set it. We could pass it through to the tessellation shaders in some way, but unless it becomes an issue that's more effort than it's worth.
This commit is contained in:
@@ -10,8 +10,9 @@
|
||||
namespace Shader::IR {
|
||||
|
||||
/// Maps special position export to builtin attribute stores
|
||||
inline void ExportPosition(IREmitter& ir, const auto& stage, Attribute attribute, u32 comp,
|
||||
const IR::F32& value) {
|
||||
template <typename StageRuntimeInfo>
|
||||
inline void ExportPosition(IREmitter& ir, const StageRuntimeInfo& stage, Attribute attribute,
|
||||
u32 comp, const IR::F32& value) {
|
||||
if (attribute == Attribute::Position0) {
|
||||
ir.SetAttribute(attribute, value, comp);
|
||||
return;
|
||||
@@ -44,6 +45,18 @@ inline void ExportPosition(IREmitter& ir, const auto& stage, Attribute attribute
|
||||
break;
|
||||
}
|
||||
case Output::GsMrtIndex:
|
||||
if constexpr (std::is_same_v<StageRuntimeInfo, VertexRuntimeInfo>) {
|
||||
// When using tessellation, layer is supposed to be set by the tessellation evaluation
|
||||
// stage. We don't currently have a mechanism for that when emulating rect/quad lists
|
||||
// using tessellation, so just ignore the write for now. Note that this only matters
|
||||
// for vertex shaders, as geometry shaders come last in the pre-rasterization stage.
|
||||
if (stage.tess_emulated_primitive) {
|
||||
LOG_WARNING(Render,
|
||||
"Exporting Layer from a vertex shader when using tessellation-based "
|
||||
"primitive emulation is currently unsupported.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ir.SetAttribute(IR::Attribute::RenderTargetId, value);
|
||||
break;
|
||||
case Output::None:
|
||||
|
||||
@@ -82,6 +82,7 @@ using OutputMap = std::array<Output, 4>;
|
||||
struct VertexRuntimeInfo {
|
||||
u32 num_outputs;
|
||||
std::array<OutputMap, 3> outputs;
|
||||
bool tess_emulated_primitive{};
|
||||
bool emulate_depth_negative_one_to_one{};
|
||||
bool clip_disable{};
|
||||
u32 step_rate_0;
|
||||
@@ -94,6 +95,7 @@ struct VertexRuntimeInfo {
|
||||
|
||||
bool operator==(const VertexRuntimeInfo& other) const noexcept {
|
||||
return num_outputs == other.num_outputs && outputs == other.outputs &&
|
||||
tess_emulated_primitive == other.tess_emulated_primitive &&
|
||||
emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one &&
|
||||
clip_disable == other.clip_disable && tess_type == other.tess_type &&
|
||||
tess_topology == other.tess_topology &&
|
||||
|
||||
@@ -128,6 +128,9 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS
|
||||
info.vs_info.emulate_depth_negative_one_to_one =
|
||||
!instance.IsDepthClipControlSupported() &&
|
||||
regs.clipper_control.clip_space == Liverpool::ClipSpace::MinusWToW;
|
||||
info.vs_info.tess_emulated_primitive =
|
||||
regs.primitive_type == AmdGpu::PrimitiveType::RectList ||
|
||||
regs.primitive_type == AmdGpu::PrimitiveType::QuadList;
|
||||
info.vs_info.clip_disable = regs.IsClipDisabled();
|
||||
if (l_stage == LogicalStage::TessellationEval) {
|
||||
info.vs_info.tess_type = regs.tess_config.type;
|
||||
|
||||
Reference in New Issue
Block a user