mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-12 14:48:52 +00:00
shader_recompiler: Support PointSize and ViewportIndex attributes. (#3541)
This commit is contained in:
@@ -104,10 +104,10 @@ std::string NameOf(Attribute attribute) {
|
||||
return "ClipDistanace";
|
||||
case Attribute::CullDistance:
|
||||
return "CullDistance";
|
||||
case Attribute::RenderTargetId:
|
||||
return "RenderTargetId";
|
||||
case Attribute::ViewportId:
|
||||
return "ViewportId";
|
||||
case Attribute::RenderTargetIndex:
|
||||
return "RenderTargetIndex";
|
||||
case Attribute::ViewportIndex:
|
||||
return "ViewportIndex";
|
||||
case Attribute::VertexId:
|
||||
return "VertexId";
|
||||
case Attribute::PrimitiveId:
|
||||
@@ -158,6 +158,8 @@ std::string NameOf(Attribute attribute) {
|
||||
return "PackedHullInvocationInfo";
|
||||
case Attribute::TessFactorsBufferBase:
|
||||
return "TessFactorsBufferBase";
|
||||
case Attribute::PointSize:
|
||||
return "PointSize";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ enum class Attribute : u64 {
|
||||
// System values
|
||||
ClipDistance = 64,
|
||||
CullDistance = 65,
|
||||
RenderTargetId = 66,
|
||||
ViewportId = 67,
|
||||
RenderTargetIndex = 66,
|
||||
ViewportIndex = 67,
|
||||
VertexId = 68,
|
||||
PrimitiveId = 69,
|
||||
InstanceId = 70,
|
||||
@@ -87,6 +87,7 @@ enum class Attribute : u64 {
|
||||
PackedHullInvocationInfo = 90, // contains patch id within the VGT and invocation ID
|
||||
OffChipLdsBase = 91,
|
||||
TessFactorsBufferBase = 92,
|
||||
PointSize = 93,
|
||||
Max,
|
||||
};
|
||||
|
||||
|
||||
@@ -160,9 +160,12 @@ void CollectShaderInfoPass(IR::Program& program, const Profile& profile) {
|
||||
}
|
||||
}
|
||||
|
||||
if (info.stores.GetAny(IR::Attribute::RenderTargetId)) {
|
||||
if (info.stores.GetAny(IR::Attribute::RenderTargetIndex)) {
|
||||
info.has_layer_output = true;
|
||||
}
|
||||
if (info.stores.GetAny(IR::Attribute::ViewportIndex)) {
|
||||
info.has_viewport_index_output = true;
|
||||
}
|
||||
|
||||
// In case Flatbuf has not already been bound by IR and is needed
|
||||
// to query buffer sizes, bind it now.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#include "common/logging/log.h"
|
||||
#include "shader_recompiler/ir/ir_emitter.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
@@ -17,8 +18,26 @@ inline void ExportPosition(IREmitter& ir, const StageRuntimeInfo& stage, Attribu
|
||||
ir.SetAttribute(attribute, value, comp);
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 index = u32(attribute) - u32(Attribute::Position1);
|
||||
const auto output = stage.outputs[index][comp];
|
||||
if constexpr (std::is_same_v<StageRuntimeInfo, VertexRuntimeInfo>) {
|
||||
// Certain outputs are supposed to be set by the last pre-rasterization stage. We don't
|
||||
// currently have a mechanism for passing these on when emulating rect/quad lists using
|
||||
// tessellation, which comes after, so just ignore the export for now. Note that this
|
||||
// only matters for vertex shaders, as geometry shaders come last in pre-rasterization.
|
||||
const auto last_stage_required = output == Output::PointSize ||
|
||||
output == Output::RenderTargetIndex ||
|
||||
output == Output::ViewportIndex;
|
||||
if (stage.tess_emulated_primitive && last_stage_required) {
|
||||
LOG_WARNING(Render,
|
||||
"{} is exported in vertex shader but tessellation-based primitive "
|
||||
"emulation is active. Not implemented yet.",
|
||||
magic_enum::enum_name(output));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (output) {
|
||||
case Output::ClipDist0:
|
||||
case Output::ClipDist1:
|
||||
@@ -44,20 +63,14 @@ inline void ExportPosition(IREmitter& ir, const StageRuntimeInfo& stage, Attribu
|
||||
ir.SetAttribute(IR::Attribute::CullDistance, value, index);
|
||||
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);
|
||||
case Output::PointSize:
|
||||
ir.SetAttribute(IR::Attribute::PointSize, value);
|
||||
break;
|
||||
case Output::RenderTargetIndex:
|
||||
ir.SetAttribute(IR::Attribute::RenderTargetIndex, value);
|
||||
break;
|
||||
case Output::ViewportIndex:
|
||||
ir.SetAttribute(IR::Attribute::ViewportIndex, value);
|
||||
break;
|
||||
case Output::None:
|
||||
LOG_WARNING(Render_Recompiler, "The {} component of {} isn't mapped, skipping",
|
||||
|
||||
Reference in New Issue
Block a user