mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-29 23:03:18 +00:00
video_core: Bloodborne stabilization pt1 (#543)
* shader_recompiler: Writelane elimination pass + null image fix * spirv: Implement image derivatives * texture_cache: Reduce page bit size * clang format * slot_vector: Back to debug assert * vk_graphics_pipeline: Handle null tsharp * spirv: Revert some change * vk_instance: Support primitive restart on list topology * page_manager: Adjust windows exception handler * clang format * Remove subres tracking * Will be done separately
This commit is contained in:
parent
9e4fc17e6c
commit
c79b10edc1
25 changed files with 187 additions and 107 deletions
|
@ -179,6 +179,10 @@ struct Image {
|
|||
return base_address << 8;
|
||||
}
|
||||
|
||||
operator bool() const noexcept {
|
||||
return base_address != 0;
|
||||
}
|
||||
|
||||
u32 DstSelect() const {
|
||||
return dst_sel_x | (dst_sel_y << 3) | (dst_sel_z << 6) | (dst_sel_w << 9);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ struct PageManager::Impl {
|
|||
if (ec == EXCEPTION_ACCESS_VIOLATION) {
|
||||
const auto info = pExp->ExceptionRecord->ExceptionInformation;
|
||||
if (info[0] == 1) { // Write violation
|
||||
rasterizer->InvalidateMemory(info[1], sizeof(u64));
|
||||
const VAddr addr_aligned = Common::AlignDown(info[1], PAGESIZE);
|
||||
rasterizer->InvalidateMemory(addr_aligned, PAGESIZE);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
} /* else {
|
||||
UNREACHABLE();
|
||||
|
@ -199,7 +200,8 @@ struct PageManager::Impl {
|
|||
const greg_t err = ctx->uc_mcontext.gregs[REG_ERR];
|
||||
#endif
|
||||
if (err & 0x2) {
|
||||
rasterizer->InvalidateMemory(address, sizeof(u64));
|
||||
const VAddr addr_aligned = Common::AlignDown(address, PAGESIZE);
|
||||
rasterizer->InvalidateMemory(addr_aligned, PAGESIZE);
|
||||
} else {
|
||||
// Read not supported!
|
||||
UNREACHABLE();
|
||||
|
|
|
@ -396,13 +396,18 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
|
|||
|
||||
boost::container::static_vector<AmdGpu::Image, 16> tsharps;
|
||||
for (const auto& image_desc : stage->images) {
|
||||
const auto& tsharp = tsharps.emplace_back(
|
||||
stage->ReadUd<AmdGpu::Image>(image_desc.sgpr_base, image_desc.dword_offset));
|
||||
VideoCore::ImageInfo image_info{tsharp};
|
||||
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
|
||||
const auto& image_view = texture_cache.FindTexture(image_info, view_info);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout);
|
||||
const auto tsharp =
|
||||
stage->ReadUd<AmdGpu::Image>(image_desc.sgpr_base, image_desc.dword_offset);
|
||||
if (tsharp) {
|
||||
tsharps.emplace_back(tsharp);
|
||||
VideoCore::ImageInfo image_info{tsharp};
|
||||
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
|
||||
const auto& image_view = texture_cache.FindTexture(image_info, view_info);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout);
|
||||
} else {
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
|
||||
}
|
||||
set_writes.push_back({
|
||||
.dstSet = VK_NULL_HANDLE,
|
||||
.dstBinding = binding++,
|
||||
|
|
|
@ -210,6 +210,8 @@ bool Instance::CreateDevice() {
|
|||
color_write_en &= add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||
const bool calibrated_timestamps = add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME);
|
||||
const bool robustness = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
const bool topology_restart =
|
||||
add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME);
|
||||
|
||||
// These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2
|
||||
// with extensions.
|
||||
|
@ -330,6 +332,9 @@ bool Instance::CreateDevice() {
|
|||
vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT{
|
||||
.vertexInputDynamicState = true,
|
||||
},
|
||||
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT{
|
||||
.primitiveTopologyListRestart = true,
|
||||
},
|
||||
#ifdef __APPLE__
|
||||
feature_chain.get<vk::PhysicalDevicePortabilitySubsetFeaturesKHR>(),
|
||||
#endif
|
||||
|
@ -351,6 +356,9 @@ bool Instance::CreateDevice() {
|
|||
if (!workgroup_memory_explicit_layout) {
|
||||
device_chain.unlink<vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
|
||||
}
|
||||
if (!topology_restart) {
|
||||
device_chain.unlink<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
|
||||
}
|
||||
if (robustness) {
|
||||
device_chain.get<vk::PhysicalDeviceRobustness2FeaturesEXT>().nullDescriptor =
|
||||
feature_chain.get<vk::PhysicalDeviceRobustness2FeaturesEXT>().nullDescriptor;
|
||||
|
|
|
@ -280,9 +280,6 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
|||
DumpShader(code, hash, stage, "bin");
|
||||
}
|
||||
|
||||
block_pool.ReleaseContents();
|
||||
inst_pool.ReleaseContents();
|
||||
|
||||
if (stage != Shader::Stage::Fragment && stage != Shader::Stage::Vertex) {
|
||||
LOG_ERROR(Render_Vulkan, "Unsupported shader stage {}. PL creation skipped.", stage);
|
||||
return {};
|
||||
|
|
|
@ -219,7 +219,12 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
|
|||
guest_address = image.Address();
|
||||
|
||||
mips_layout.reserve(resources.levels);
|
||||
tiling_idx = image.tiling_index;
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void ImageInfo::UpdateSize() {
|
||||
mips_layout.clear();
|
||||
MipInfo mip_info{};
|
||||
guest_size_bytes = 0;
|
||||
for (auto mip = 0u; mip < resources.levels; ++mip) {
|
||||
|
@ -265,7 +270,7 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
|
|||
ASSERT(!props.is_block);
|
||||
ASSERT(num_samples == 1);
|
||||
std::tie(mip_info.pitch, mip_info.size) =
|
||||
ImageSizeMacroTiled(mip_w, mip_h, bpp, num_samples, image.tiling_index);
|
||||
ImageSizeMacroTiled(mip_w, mip_h, bpp, num_samples, tiling_idx);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -29,6 +29,8 @@ struct ImageInfo {
|
|||
bool IsPacked() const;
|
||||
bool IsDepthStencil() const;
|
||||
|
||||
void UpdateSize();
|
||||
|
||||
struct {
|
||||
VAddr cmask_addr;
|
||||
VAddr fmask_addr;
|
||||
|
@ -69,6 +71,7 @@ struct ImageInfo {
|
|||
boost::container::small_vector<MipInfo, 14> mips_layout;
|
||||
VAddr guest_address{0};
|
||||
u32 guest_size_bytes{0};
|
||||
u32 tiling_idx{0}; // TODO: merge with existing!
|
||||
};
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -18,11 +18,15 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
|
|||
BufferCache& buffer_cache_, PageManager& tracker_)
|
||||
: instance{instance_}, scheduler{scheduler_}, buffer_cache{buffer_cache_}, tracker{tracker_},
|
||||
tile_manager{instance, scheduler} {
|
||||
ImageInfo info;
|
||||
ImageInfo info{};
|
||||
info.pixel_format = vk::Format::eR8G8B8A8Unorm;
|
||||
info.type = vk::ImageType::e2D;
|
||||
info.tiling_idx = u32(AmdGpu::TilingMode::Texture_MicroTiled);
|
||||
info.num_bits = 32;
|
||||
info.UpdateSize();
|
||||
const ImageId null_id = slot_images.insert(instance, scheduler, info);
|
||||
ASSERT(null_id.index == 0);
|
||||
slot_images[null_id].flags = ImageFlagBits{};
|
||||
|
||||
ImageViewInfo view_info;
|
||||
void(slot_image_views.insert(instance, view_info, slot_images[null_id], null_id));
|
||||
|
|
|
@ -28,7 +28,7 @@ class TextureCache {
|
|||
using Entry = boost::container::small_vector<ImageId, 16>;
|
||||
static constexpr size_t AddressSpaceBits = 39;
|
||||
static constexpr size_t FirstLevelBits = 9;
|
||||
static constexpr size_t PageBits = 22;
|
||||
static constexpr size_t PageBits = 20;
|
||||
};
|
||||
using PageTable = MultiLevelPageTable<Traits>;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue