mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 03:54:45 +00:00
texture_cache: image guest address moved into image info
This commit is contained in:
parent
e8302ed5e8
commit
1cea273eb7
11 changed files with 83 additions and 64 deletions
|
@ -182,8 +182,9 @@ bool RendererVulkan::ShowSplash(Frame* frame /*= nullptr*/) {
|
|||
info.size =
|
||||
VideoCore::Extent3D{splash->GetImageInfo().width, splash->GetImageInfo().height, 1};
|
||||
info.pitch = splash->GetImageInfo().width;
|
||||
info.guest_address = VAddr(splash->GetImageData().data());
|
||||
info.guest_size_bytes = splash->GetImageData().size();
|
||||
splash_img.emplace(instance, scheduler, info, VAddr(splash->GetImageData().data()));
|
||||
splash_img.emplace(instance, scheduler, info);
|
||||
texture_cache.RefreshImage(*splash_img);
|
||||
}
|
||||
frame = PrepareFrameInternal(*splash_img);
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute,
|
||||
VAddr cpu_address) {
|
||||
const auto info = VideoCore::ImageInfo{attribute};
|
||||
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
|
||||
const auto image_id = texture_cache.FindImage(info, cpu_address);
|
||||
auto& image = texture_cache.GetImage(image_id);
|
||||
return PrepareFrameInternal(image);
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
VideoCore::Image& RegisterVideoOutSurface(
|
||||
const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) {
|
||||
vo_buffers_addr.emplace_back(cpu_address);
|
||||
const auto info = VideoCore::ImageInfo{attribute};
|
||||
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
|
||||
const auto image_id = texture_cache.FindImage(info, cpu_address);
|
||||
return texture_cache.GetImage(image_id);
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ bool ComputePipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& s
|
|||
for (const auto& image_desc : info.images) {
|
||||
const auto tsharp =
|
||||
info.ReadUd<AmdGpu::Image>(image_desc.sgpr_base, image_desc.dword_offset);
|
||||
const auto& image_view = texture_cache.FindImageView(tsharp, image_desc.is_storage);
|
||||
const auto& image_view = texture_cache.FindTexture(tsharp, image_desc.is_storage);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout);
|
||||
set_writes.push_back({
|
||||
|
|
|
@ -366,7 +366,7 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer&
|
|||
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));
|
||||
const auto& image_view = texture_cache.FindImageView(tsharp, image_desc.is_storage);
|
||||
const auto& image_view = texture_cache.FindTexture(tsharp, image_desc.is_storage);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout);
|
||||
set_writes.push_back({
|
||||
|
|
|
@ -113,7 +113,7 @@ void Rasterizer::BeginRendering() {
|
|||
}
|
||||
|
||||
const auto& hint = liverpool->last_cb_extent[col_buf_id];
|
||||
const auto& image_view = texture_cache.RenderTarget(col_buf, hint);
|
||||
const auto& image_view = texture_cache.FindRenderTarget(col_buf, hint);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
state.width = std::min<u32>(state.width, image.info.size.width);
|
||||
state.height = std::min<u32>(state.height, image.info.size.height);
|
||||
|
@ -136,8 +136,9 @@ void Rasterizer::BeginRendering() {
|
|||
const bool is_clear = regs.depth_render_control.depth_clear_enable ||
|
||||
texture_cache.IsMetaCleared(htile_address);
|
||||
const auto& hint = liverpool->last_db_extent;
|
||||
const auto& image_view = texture_cache.DepthTarget(regs.depth_buffer, htile_address, hint,
|
||||
regs.depth_control.depth_write_enable);
|
||||
const auto& image_view = texture_cache.FindDepthTarget(
|
||||
regs.depth_buffer, regs.depth_view.NumSlices(), htile_address, hint,
|
||||
regs.depth_control.depth_write_enable);
|
||||
const auto& image = texture_cache.GetImage(image_view.image_id);
|
||||
state.width = std::min<u32>(state.width, image.info.size.width);
|
||||
state.height = std::min<u32>(state.height, image.info.size.height);
|
||||
|
|
|
@ -112,9 +112,9 @@ void UniqueImage::Create(const vk::ImageCreateInfo& image_ci) {
|
|||
}
|
||||
|
||||
Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
||||
const ImageInfo& info_, VAddr cpu_addr)
|
||||
const ImageInfo& info_)
|
||||
: instance{&instance_}, scheduler{&scheduler_}, info{info_},
|
||||
image{instance->GetDevice(), instance->GetAllocator()}, cpu_addr{cpu_addr},
|
||||
image{instance->GetDevice(), instance->GetAllocator()}, cpu_addr{info.guest_address},
|
||||
cpu_addr_end{cpu_addr + info.guest_size_bytes} {
|
||||
ASSERT(info.pixel_format != vk::Format::eUndefined);
|
||||
vk::ImageCreateFlags flags{vk::ImageCreateFlagBits::eMutableFormat |
|
||||
|
|
|
@ -69,8 +69,7 @@ private:
|
|||
constexpr Common::SlotId NULL_IMAGE_ID{0};
|
||||
|
||||
struct Image {
|
||||
explicit Image(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler,
|
||||
const ImageInfo& info, VAddr cpu_addr);
|
||||
Image(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, const ImageInfo& info);
|
||||
~Image();
|
||||
|
||||
Image(const Image&) = delete;
|
||||
|
|
|
@ -44,7 +44,8 @@ static vk::ImageType ConvertImageType(AmdGpu::ImageType type) noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noexcept {
|
||||
ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group,
|
||||
VAddr cpu_address) noexcept {
|
||||
const auto& attrib = group.attrib;
|
||||
is_tiled = attrib.tiling_mode == TilingMode::Tile;
|
||||
tiling_mode =
|
||||
|
@ -56,14 +57,16 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noe
|
|||
pitch = attrib.tiling_mode == TilingMode::Linear ? size.width : (size.width + 127) & (~127);
|
||||
const bool is_32bpp = attrib.pixel_format != VideoOutFormat::A16R16G16B16Float;
|
||||
ASSERT(is_32bpp);
|
||||
|
||||
guest_address = cpu_address;
|
||||
if (!is_tiled) {
|
||||
guest_size_bytes = pitch * size.height * 4;
|
||||
return;
|
||||
}
|
||||
if (Config::isNeoMode()) {
|
||||
guest_size_bytes = pitch * ((size.height + 127) & (~127)) * 4;
|
||||
} else {
|
||||
guest_size_bytes = pitch * ((size.height + 63) & (~63)) * 4;
|
||||
if (Config::isNeoMode()) {
|
||||
guest_size_bytes = pitch * ((size.height + 127) & (~127)) * 4;
|
||||
} else {
|
||||
guest_size_bytes = pitch * ((size.height + 63) & (~63)) * 4;
|
||||
}
|
||||
}
|
||||
usage.vo_buffer = true;
|
||||
}
|
||||
|
@ -79,14 +82,17 @@ ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
|||
size.height = hint.Valid() ? hint.height : buffer.Height();
|
||||
size.depth = 1;
|
||||
pitch = size.width;
|
||||
guest_size_bytes = buffer.GetColorSliceSize();
|
||||
resources.layers = buffer.NumSlices();
|
||||
meta_info.cmask_addr = buffer.info.fast_clear ? buffer.CmaskAddress() : 0;
|
||||
meta_info.fmask_addr = buffer.info.compression ? buffer.FmaskAddress() : 0;
|
||||
usage.render_target = true;
|
||||
|
||||
guest_address = buffer.Address();
|
||||
guest_size_bytes = buffer.GetColorSliceSize() * buffer.NumSlices();
|
||||
}
|
||||
|
||||
ImageInfo::ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint) noexcept {
|
||||
ImageInfo::ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, u32 num_slices,
|
||||
VAddr htile_address, const AmdGpu::Liverpool::CbDbExtent& hint) noexcept {
|
||||
is_tiled = false;
|
||||
pixel_format = LiverpoolToVK::DepthFormat(buffer.z_info.format, buffer.stencil_info.format);
|
||||
type = vk::ImageType::e2D;
|
||||
|
@ -95,9 +101,12 @@ ImageInfo::ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, VAddr htile_a
|
|||
size.height = hint.Valid() ? hint.height : buffer.Height();
|
||||
size.depth = 1;
|
||||
pitch = size.width;
|
||||
guest_size_bytes = buffer.GetDepthSliceSize();
|
||||
resources.layers = num_slices;
|
||||
meta_info.htile_addr = buffer.z_info.tile_surface_en ? htile_address : 0;
|
||||
usage.depth_target = true;
|
||||
|
||||
guest_address = buffer.Address();
|
||||
guest_size_bytes = buffer.GetDepthSliceSize() * num_slices;
|
||||
}
|
||||
|
||||
ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
|
||||
|
@ -111,8 +120,11 @@ ImageInfo::ImageInfo(const AmdGpu::Image& image) noexcept {
|
|||
pitch = image.Pitch();
|
||||
resources.levels = image.NumLevels();
|
||||
resources.layers = image.NumLayers();
|
||||
guest_size_bytes = image.GetSize();
|
||||
is_cube = image.GetType() == AmdGpu::ImageType::Cube;
|
||||
usage.texture = true;
|
||||
|
||||
guest_address = image.Address();
|
||||
guest_size_bytes = image.GetSize();
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -13,12 +13,12 @@ namespace VideoCore {
|
|||
|
||||
struct ImageInfo {
|
||||
ImageInfo() = default;
|
||||
explicit ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noexcept;
|
||||
explicit ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint = {}) noexcept;
|
||||
explicit ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint = {}) noexcept;
|
||||
explicit ImageInfo(const AmdGpu::Image& image) noexcept;
|
||||
ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group, VAddr cpu_address) noexcept;
|
||||
ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint = {}) noexcept;
|
||||
ImageInfo(const AmdGpu::Liverpool::DepthBuffer& buffer, u32 num_slices, VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint = {}) noexcept;
|
||||
ImageInfo(const AmdGpu::Image& image) noexcept;
|
||||
|
||||
bool IsTiled() const {
|
||||
return tiling_mode != AmdGpu::TilingMode::Display_Linear;
|
||||
|
@ -42,15 +42,18 @@ struct ImageInfo {
|
|||
u32 vo_buffer : 1;
|
||||
} usage{}; // Usage data tracked during image lifetime
|
||||
|
||||
bool is_cube = false;
|
||||
bool is_tiled = false;
|
||||
bool is_read_only = false;
|
||||
vk::Format pixel_format = vk::Format::eUndefined;
|
||||
vk::ImageType type = vk::ImageType::e1D;
|
||||
SubresourceExtent resources;
|
||||
Extent3D size{1, 1, 1};
|
||||
u32 num_samples = 1;
|
||||
u32 pitch = 0;
|
||||
u32 guest_size_bytes = 0;
|
||||
AmdGpu::TilingMode tiling_mode{AmdGpu::TilingMode::Display_Linear};
|
||||
VAddr guest_address{0};
|
||||
u32 guest_size_bytes{0};
|
||||
};
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -89,7 +89,7 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler&
|
|||
ImageInfo info;
|
||||
info.pixel_format = vk::Format::eR8G8B8A8Unorm;
|
||||
info.type = vk::ImageType::e2D;
|
||||
const ImageId null_id = slot_images.insert(instance, scheduler, info, 0);
|
||||
const ImageId null_id = slot_images.insert(instance, scheduler, info);
|
||||
ASSERT(null_id.index == 0);
|
||||
|
||||
ImageViewInfo view_info;
|
||||
|
@ -112,26 +112,27 @@ void TextureCache::OnCpuWrite(VAddr address) {
|
|||
});
|
||||
}
|
||||
|
||||
ImageId TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address, bool refresh_on_create) {
|
||||
ImageId TextureCache::FindImage(const ImageInfo& info, bool refresh_on_create) {
|
||||
std::unique_lock lock{m_page_table};
|
||||
boost::container::small_vector<ImageId, 2> image_ids;
|
||||
ForEachImageInRegion(cpu_address, info.guest_size_bytes, [&](ImageId image_id, Image& image) {
|
||||
// Address and width must match.
|
||||
if (image.cpu_addr != cpu_address || image.info.size.width != info.size.width) {
|
||||
return;
|
||||
}
|
||||
if (info.IsDepthStencil() != image.info.IsDepthStencil() &&
|
||||
info.pixel_format != vk::Format::eR32Sfloat) {
|
||||
return;
|
||||
}
|
||||
image_ids.push_back(image_id);
|
||||
});
|
||||
ForEachImageInRegion(
|
||||
info.guest_address, info.guest_size_bytes, [&](ImageId image_id, Image& image) {
|
||||
// Address and width must match.
|
||||
if (image.cpu_addr != info.guest_address || image.info.size.width != info.size.width) {
|
||||
return;
|
||||
}
|
||||
if (info.IsDepthStencil() != image.info.IsDepthStencil() &&
|
||||
info.pixel_format != vk::Format::eR32Sfloat) {
|
||||
return;
|
||||
}
|
||||
image_ids.push_back(image_id);
|
||||
});
|
||||
|
||||
ASSERT_MSG(image_ids.size() <= 1, "Overlapping images not allowed!");
|
||||
|
||||
ImageId image_id{};
|
||||
if (image_ids.empty()) {
|
||||
image_id = slot_images.insert(instance, scheduler, info, cpu_address);
|
||||
image_id = slot_images.insert(instance, scheduler, info);
|
||||
RegisterImage(image_id);
|
||||
} else {
|
||||
image_id = image_ids[0];
|
||||
|
@ -169,9 +170,9 @@ ImageView& TextureCache::RegisterImageView(ImageId image_id, const ImageViewInfo
|
|||
return slot_image_views[view_id];
|
||||
}
|
||||
|
||||
ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc, bool is_storage) {
|
||||
ImageView& TextureCache::FindTexture(const AmdGpu::Image& desc, bool is_storage) {
|
||||
const ImageInfo info{desc};
|
||||
const ImageId image_id = FindImage(info, desc.Address());
|
||||
const ImageId image_id = FindImage(info);
|
||||
Image& image = slot_images[image_id];
|
||||
auto& usage = image.info.usage;
|
||||
|
||||
|
@ -190,10 +191,10 @@ ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc, bool is_storag
|
|||
return RegisterImageView(image_id, view_info);
|
||||
}
|
||||
|
||||
ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint) {
|
||||
ImageView& TextureCache::FindRenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint) {
|
||||
const ImageInfo info{buffer, hint};
|
||||
const ImageId image_id = FindImage(info, buffer.Address());
|
||||
const ImageId image_id = FindImage(info);
|
||||
Image& image = slot_images[image_id];
|
||||
image.flags &= ~ImageFlagBits::CpuModified;
|
||||
|
||||
|
@ -207,11 +208,12 @@ ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buff
|
|||
return RegisterImageView(image_id, view_info);
|
||||
}
|
||||
|
||||
ImageView& TextureCache::DepthTarget(const AmdGpu::Liverpool::DepthBuffer& buffer,
|
||||
VAddr htile_address, const AmdGpu::Liverpool::CbDbExtent& hint,
|
||||
bool write_enabled) {
|
||||
const ImageInfo info{buffer, htile_address, hint};
|
||||
const ImageId image_id = FindImage(info, buffer.Address(), false);
|
||||
ImageView& TextureCache::FindDepthTarget(const AmdGpu::Liverpool::DepthBuffer& buffer,
|
||||
u32 num_slices, VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint,
|
||||
bool write_enabled) {
|
||||
const ImageInfo info{buffer, num_slices, htile_address, hint};
|
||||
const ImageId image_id = FindImage(info, false);
|
||||
Image& image = slot_images[image_id];
|
||||
image.flags &= ~ImageFlagBits::CpuModified;
|
||||
|
||||
|
|
|
@ -47,20 +47,21 @@ public:
|
|||
/// Invalidates any image in the logical page range.
|
||||
void OnCpuWrite(VAddr address);
|
||||
|
||||
/// Retrieves the image handle of the image with the provided attributes and address.
|
||||
[[nodiscard]] ImageId FindImage(const ImageInfo& info, VAddr cpu_address,
|
||||
bool refresh_on_create = true);
|
||||
/// Retrieves the image handle of the image with the provided attributes.
|
||||
[[nodiscard]] ImageId FindImage(const ImageInfo& info, bool refresh_on_create = true);
|
||||
|
||||
/// Retrieves an image view with the properties of the specified image descriptor.
|
||||
[[nodiscard]] ImageView& FindImageView(const AmdGpu::Image& image, bool is_storage);
|
||||
[[nodiscard]] ImageView& FindTexture(const AmdGpu::Image& image, bool is_storage);
|
||||
|
||||
/// Retrieves the render target with specified properties
|
||||
[[nodiscard]] ImageView& RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint);
|
||||
[[nodiscard]] ImageView& DepthTarget(const AmdGpu::Liverpool::DepthBuffer& buffer,
|
||||
VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint,
|
||||
bool write_enabled);
|
||||
[[nodiscard]] ImageView& FindRenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint);
|
||||
|
||||
/// Retrieves the depth target with specified properties
|
||||
[[nodiscard]] ImageView& FindDepthTarget(const AmdGpu::Liverpool::DepthBuffer& buffer,
|
||||
u32 num_slices, VAddr htile_address,
|
||||
const AmdGpu::Liverpool::CbDbExtent& hint,
|
||||
bool write_enabled);
|
||||
|
||||
/// Reuploads image contents.
|
||||
void RefreshImage(Image& image);
|
||||
|
|
Loading…
Add table
Reference in a new issue