some cleanup

This commit is contained in:
Frodo Baggins 2024-12-14 00:13:43 -08:00
parent 0b75adb7c8
commit 2749b3819c
6 changed files with 64 additions and 64 deletions

View File

@ -16,10 +16,6 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_definitions(_DEBUG)
endif()
project(shadPS4)
# Forcing PIE makes sure that the base address is high enough so that it doesn't clash with the PS4 memory.

View File

@ -254,13 +254,8 @@ struct Info {
}
}
// TODO probably not needed
bool FoundTessConstantsSharp() const {
return tess_consts_dword_offset >= 0;
}
void ReadTessConstantBuffer(TessellationDataConstantBuffer& tess_constants) const {
ASSERT(FoundTessConstantsSharp());
ASSERT(tess_consts_dword_offset >= 0); // We've already tracked the V# UD
auto buf = ReadUdReg<AmdGpu::Buffer>(static_cast<u32>(tess_consts_ptr_base),
static_cast<u32>(tess_consts_dword_offset));
VAddr tess_constants_addr = buf.base_address;

View File

@ -392,15 +392,11 @@ void HullShaderTransform(IR::Program& program, RuntimeInfo& runtime_info) {
// The hull outputs tess factors in different formats depending on the shader.
// For triangle domains, it seems to pack the entries into 4 consecutive floats,
// with the 3 edge factors followed by the 1 interior factor.
// For quads, it does the expected 4 edge factors then 2 interior.
// For quads, it does 4 edge factors then 2 interior.
// There is a tess factor stride member of the GNMX hull constants struct in
// a hull program shader binary archive, but this doesn't seem to be
// communicated to the driver. The fixed function tessellator would need to know
// this somehow. It's probably implied by the type of the abstract domain. If
// this is causing problems, good idea to check the hs_regs argument to
// sceGnmSetHsShader. The memory containing the tess factor stride probably
// follows the memory for hs_regs if the app is providing a pointer into the
// program they loaded from disk
// communicated to the driver.
// The layout seems to be implied by the type of the abstract domain.
switch (runtime_info.hs_info.tess_type) {
case AmdGpu::TessellationType::Quad:
ASSERT(gcn_factor_idx < 6);
@ -595,54 +591,63 @@ void DomainShaderTransform(IR::Program& program, RuntimeInfo& runtime_info) {
}
}
// Run before copy prop
// Run before either hull or domain transform
void TessellationPreprocess(IR::Program& program, RuntimeInfo& runtime_info) {
TessellationDataConstantBuffer tess_constants;
Shader::Info& info = program.info;
// Find the TessellationDataConstantBuffer V#
for (IR::Block* block : program.blocks) {
for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) {
case IR::Opcode::LoadSharedU32:
case IR::Opcode::LoadSharedU64:
case IR::Opcode::LoadSharedU128:
case IR::Opcode::WriteSharedU32:
case IR::Opcode::WriteSharedU64:
case IR::Opcode::WriteSharedU128: {
IR::Value addr = inst.Arg(0);
auto read_const_buffer = IR::BreadthFirstSearch(
addr, [](IR::Inst* maybe_tess_const) -> std::optional<IR::Inst*> {
if (maybe_tess_const->GetOpcode() == IR::Opcode::ReadConstBuffer) {
return maybe_tess_const;
auto found_tess_consts_sharp = [&]() -> bool {
switch (inst.GetOpcode()) {
case IR::Opcode::LoadSharedU32:
case IR::Opcode::LoadSharedU64:
case IR::Opcode::LoadSharedU128:
case IR::Opcode::WriteSharedU32:
case IR::Opcode::WriteSharedU64:
case IR::Opcode::WriteSharedU128: {
IR::Value addr = inst.Arg(0);
auto read_const_buffer = IR::BreadthFirstSearch(
addr, [](IR::Inst* maybe_tess_const) -> std::optional<IR::Inst*> {
if (maybe_tess_const->GetOpcode() == IR::Opcode::ReadConstBuffer) {
return maybe_tess_const;
}
return std::nullopt;
});
if (read_const_buffer) {
auto sharp_location = FindTessConstantSharp(read_const_buffer.value());
if (sharp_location) {
if (info.tess_consts_dword_offset >= 0) {
// Its possible theres a readconstbuffer that contributes to an
// LDS address and isnt a TessConstant V# read. Could improve on
// this somehow
ASSERT_MSG(static_cast<s32>(sharp_location->dword_off) ==
info.tess_consts_dword_offset &&
sharp_location->ptr_base ==
info.tess_consts_ptr_base,
"TessConstants V# is ambiguous");
}
InitTessConstants(sharp_location->ptr_base,
static_cast<s32>(sharp_location->dword_off), info,
runtime_info, tess_constants);
return true;
}
return std::nullopt;
});
if (read_const_buffer) {
auto sharp_location = FindTessConstantSharp(read_const_buffer.value());
if (sharp_location) {
if (info.FoundTessConstantsSharp()) {
ASSERT(static_cast<s32>(sharp_location->dword_off) ==
info.tess_consts_dword_offset &&
sharp_location->ptr_base == info.tess_consts_ptr_base);
}
InitTessConstants(sharp_location->ptr_base,
static_cast<s32>(sharp_location->dword_off), info,
runtime_info, tess_constants);
break; // break out of switch and loop
UNREACHABLE_MSG("Failed to match tess constant sharp");
}
UNREACHABLE_MSG("Failed to match tess constant sharp");
return false;
}
continue;
}
default:
continue;
}
default:
return false;
}
}();
break;
if (found_tess_consts_sharp) {
break;
}
}
}
ASSERT(info.FoundTessConstantsSharp());
ASSERT(info.tess_consts_dword_offset >= 0);
TessConstantUseWalker walker;

View File

@ -67,13 +67,15 @@ IR::Program TranslateProgram(std::span<const u32> code, Pools& pools, Info& info
Shader::Optimization::SsaRewritePass(program.post_order_blocks);
Shader::Optimization::IdentityRemovalPass(program.blocks);
Shader::Optimization::ConstantPropagationPass(
program.post_order_blocks); // TODO const fold spam for now while testing
if (info.l_stage == LogicalStage::TessellationControl) {
// Tess passes require previous const prop passes for now (for simplicity). TODO allow
// fine grained folding or opportunistic folding we set an operand to an immediate
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
Shader::Optimization::TessellationPreprocess(program, runtime_info);
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
Shader::Optimization::HullShaderTransform(program, runtime_info);
} else if (info.l_stage == LogicalStage::TessellationEval) {
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
Shader::Optimization::TessellationPreprocess(program, runtime_info);
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
Shader::Optimization::DomainShaderTransform(program, runtime_info);

View File

@ -127,6 +127,18 @@ struct StageSpecialization {
[](auto& spec, const auto& desc, AmdGpu::Sampler sharp) {
spec.force_unnormalized = sharp.force_unnormalized;
});
// Initialize runtime_info fields that rely on analysis in tessellation passes
if (info->l_stage == LogicalStage::TessellationControl ||
info->l_stage == LogicalStage::TessellationEval) {
Shader::TessellationDataConstantBuffer tess_constants;
info->ReadTessConstantBuffer(tess_constants);
if (info->l_stage == LogicalStage::TessellationControl) {
runtime_info.hs_info.InitFromTessConstants(tess_constants);
} else {
runtime_info.vs_info.InitFromTessConstants(tess_constants);
}
}
}
void ForEachSharp(auto& spec_list, auto& desc_list, auto&& func) {

View File

@ -9,7 +9,6 @@
#include "common/path_util.h"
#include "core/debug_state.h"
#include "shader_recompiler/backend/spirv/emit_spirv.h"
#include "shader_recompiler/frontend/tessellation.h"
#include "shader_recompiler/info.h"
#include "shader_recompiler/recompiler.h"
#include "shader_recompiler/runtime_info.h"
@ -533,15 +532,6 @@ PipelineCache::Result PipelineCache::GetProgram(Stage stage, LogicalStage l_stag
auto& program = it_pgm.value();
auto& info = program->info;
info.RefreshFlatBuf();
if (l_stage == LogicalStage::TessellationControl || l_stage == LogicalStage::TessellationEval) {
Shader::TessellationDataConstantBuffer tess_constants;
info.ReadTessConstantBuffer(tess_constants);
if (l_stage == LogicalStage::TessellationControl) {
runtime_info.hs_info.InitFromTessConstants(tess_constants);
} else {
runtime_info.vs_info.InitFromTessConstants(tess_constants);
}
}
const auto spec = Shader::StageSpecialization(info, runtime_info, profile, binding);
size_t perm_idx = program->modules.size();
vk::ShaderModule module{};