mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
some cleanup
This commit is contained in:
parent
0b75adb7c8
commit
2749b3819c
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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{};
|
||||
|
Loading…
Reference in New Issue
Block a user