video_core: Some bloodborne hacks

This commit is contained in:
IndecisiveTurtle 2024-08-29 19:52:50 +03:00
parent 66e96dd944
commit f00ec3ddbc
6 changed files with 92 additions and 4 deletions

View file

@ -1066,7 +1066,16 @@ ScePthread PThreadPool::Create() {
}
}
#ifdef _WIN64
auto* ret = new PthreadInternal{};
#else
// TODO: Linux specific hack
static u8* hint_address = reinterpret_cast<u8*>(0x7FFFFC000ULL);
auto* ret = reinterpret_cast<PthreadInternal*>(
mmap(hint_address, sizeof(PthreadInternal), PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0));
hint_address += Common::AlignUp(sizeof(PthreadInternal), 4_KB);
#endif
ret->is_free = false;
ret->is_detached = false;
ret->is_almost_done = false;

View file

@ -436,6 +436,7 @@ void Translator::EmitFlowControl(u32 pc, const GcnInst& inst) {
case Opcode::S_CBRANCH_SCC1:
case Opcode::S_CBRANCH_VCCNZ:
case Opcode::S_CBRANCH_VCCZ:
case Opcode::S_CBRANCH_EXECNZ:
case Opcode::S_BRANCH:
return;
default:

View file

@ -226,6 +226,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
regs.SetDefaults();
break;
}
case PM4ItOpcode::DrawIndirect: {
break;
}
case PM4ItOpcode::SetConfigReg: {
const auto* set_data = reinterpret_cast<const PM4CmdSetData*>(header);
const auto reg_addr = ConfigRegWordOffset + set_data->reg_offset;

View file

@ -107,6 +107,74 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
Shader::PushData push_data{};
u32 binding{};
if (info->pgm_hash == 0x3d5ebf4e) {
const auto& src = info->texture_buffers[0];
const auto src_sharp = src.GetSharp(*info);
const auto& dst = info->texture_buffers[1];
const auto dst_sharp = dst.GetSharp(*info);
if (dst_sharp.base_address == 0x510e0000 || dst_sharp.base_address == 0x1926e0000 ||
dst_sharp.base_address == 0x1d42e0000) {
VideoCore::ImageViewInfo view_info;
view_info.format = vk::Format::eR8G8B8A8Unorm;
view_info.type = vk::ImageViewType::e2D;
view_info.range.extent.layers = 1;
view_info.range.extent.levels = 1;
AmdGpu::Image src_image;
src_image.base_address = src_sharp.base_address >> 8;
src_image.base_level = 0;
src_image.width = 1920 - 1;
src_image.height = 1080 - 1;
src_image.depth = 1;
src_image.data_format = u64(AmdGpu::DataFormat::Format8_8_8_8);
src_image.num_format = u64(AmdGpu::NumberFormat::Unorm);
src_image.dst_sel_x = 4;
src_image.dst_sel_y = 5;
src_image.dst_sel_z = 6;
src_image.dst_sel_w = 7;
src_image.pitch = 1920 - 1;
src_image.type = u64(AmdGpu::ImageType::Color2D);
src_image.tiling_index = u64(AmdGpu::TilingMode::Display_MacroTiled);
VideoCore::ImageInfo src_info{src_image};
const auto src_id = texture_cache.FindImage(src_info);
auto& src_img = texture_cache.GetImage(src_id);
src_img.Transit(vk::ImageLayout::eTransferSrcOptimal,
vk::AccessFlagBits::eTransferRead);
src_image.base_address = dst_sharp.base_address >> 8;
VideoCore::ImageInfo dst_info{src_image};
const auto dst_id = texture_cache.FindImage(dst_info);
auto& dst_img = texture_cache.GetImage(dst_id);
dst_img.Transit(vk::ImageLayout::eTransferDstOptimal,
vk::AccessFlagBits::eTransferWrite);
const auto cmdbuf = scheduler.CommandBuffer();
scheduler.EndRendering();
const vk::ImageCopy copy = {
.srcSubresource =
{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.srcOffset = {0, 0, 0},
.dstSubresource =
{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.dstOffset = {0, 0, 0},
.extent = {1920, 1080, 1},
};
cmdbuf.copyImage(src_img.image, vk::ImageLayout::eTransferSrcOptimal, dst_img.image,
vk::ImageLayout::eTransferDstOptimal, copy);
return false;
}
}
for (const auto& desc : info->buffers) {
const auto vsharp = desc.GetSharp(*info);
const bool is_storage = desc.IsStorage(vsharp);
@ -166,7 +234,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a CS shader (buffer)");
}
}
if (desc.is_written) {
if (desc.is_written && info->pgm_hash != 0xfefebf9f && info->pgm_hash != 0x3d5ebf4e) {
texture_cache.InvalidateMemory(address, size, true);
}
const u32 alignment = instance.TexelBufferMinAlignment();

View file

@ -49,7 +49,9 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() {
}
const ComputePipeline* PipelineCache::GetComputePipeline() {
RefreshComputeKey();
if (!RefreshComputeKey()) {
return nullptr;
}
const auto [it, is_new] = compute_pipelines.try_emplace(compute_key);
if (is_new) {
it.value() = std::make_unique<ComputePipeline>(instance, scheduler, *pipeline_cache,
@ -167,11 +169,16 @@ void PipelineCache::RefreshGraphicsKey() {
}
}
void PipelineCache::RefreshComputeKey() {
bool PipelineCache::RefreshComputeKey() {
u32 binding{};
const auto* cs_pgm = &liverpool->regs.cs_program;
const GuestProgram guest_pgm{cs_pgm, Shader::Stage::Compute};
if (guest_pgm.hash == 0xa509af23 || guest_pgm.hash == 0x4ca76892 || guest_pgm.hash == 0xa954e79d ||
guest_pgm.hash == 0x42f2a521 || guest_pgm.hash == 0x2da7fe60) {
return false;
}
std::tie(infos[0], modules[0], compute_key) = shader_cache->GetProgram(guest_pgm, binding);
return true;
}
} // namespace Vulkan

View file

@ -31,7 +31,7 @@ public:
private:
void RefreshGraphicsKey();
void RefreshComputeKey();
bool RefreshComputeKey();
private:
const Instance& instance;