mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-02 16:53:17 +00:00
video_core: Bringup some basic functionality (#145)
* video_core: Remove hack in rasterizer * The hack was to skip the first draw as the display buffer had not been created yet and the texture cache couldn't create one itself. With this patch it now can, using the color buffer parameters from registers * shader_recompiler: Implement attribute loads/stores * video_core: Add basic vertex, index buffer handling and pipeline caching * externals: Make xxhash lowercase
This commit is contained in:
parent
e9f64bb76c
commit
3c90b8ac00
50 changed files with 1030 additions and 383 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/texture_cache/image.h"
|
||||
|
@ -65,6 +66,16 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noe
|
|||
}
|
||||
}
|
||||
|
||||
ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer) noexcept {
|
||||
is_tiled = true;
|
||||
pixel_format = LiverpoolToVK::SurfaceFormat(buffer.info.format, buffer.NumFormat());
|
||||
type = vk::ImageType::e2D;
|
||||
size.width = buffer.Pitch();
|
||||
size.height = buffer.Height();
|
||||
pitch = size.width;
|
||||
guest_size_bytes = buffer.slice.tile_max * (buffer.view.slice_max + 1);
|
||||
}
|
||||
|
||||
UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_)
|
||||
: device{device_}, allocator{allocator_} {}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "common/enum.h"
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/videoout/buffer.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
#include "video_core/texture_cache/image_view.h"
|
||||
#include "video_core/texture_cache/types.h"
|
||||
|
@ -32,6 +33,7 @@ DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
|||
struct ImageInfo {
|
||||
ImageInfo() = default;
|
||||
explicit ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noexcept;
|
||||
explicit ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer) noexcept;
|
||||
|
||||
bool is_tiled = false;
|
||||
vk::Format pixel_format = vk::Format::eUndefined;
|
||||
|
|
|
@ -101,8 +101,8 @@ TextureCache::~TextureCache() {
|
|||
}
|
||||
|
||||
void TextureCache::OnCpuWrite(VAddr address) {
|
||||
const VAddr address_aligned = address & ~((1 << PageBits) - 1);
|
||||
ForEachImageInRegion(address_aligned, 1 << PageBits, [&](ImageId image_id, Image& image) {
|
||||
const VAddr address_aligned = address & ~((1 << PageShift) - 1);
|
||||
ForEachImageInRegion(address_aligned, 1 << PageShift, [&](ImageId image_id, Image& image) {
|
||||
// Ensure image is reuploaded when accessed again.
|
||||
image.flags |= ImageFlagBits::CpuModified;
|
||||
// Untrack image, so the range is unprotected and the guest can write freely.
|
||||
|
@ -137,26 +137,20 @@ Image& TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address) {
|
|||
return image;
|
||||
}
|
||||
|
||||
ImageView& TextureCache::RenderTarget(VAddr cpu_address, u32 pitch) {
|
||||
boost::container::small_vector<ImageId, 2> image_ids;
|
||||
ForEachImageInRegion(cpu_address, pitch * 4, [&](ImageId image_id, Image& image) {
|
||||
if (image.cpu_addr == cpu_address) {
|
||||
image_ids.push_back(image_id);
|
||||
}
|
||||
});
|
||||
ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer) {
|
||||
const ImageInfo info{buffer};
|
||||
auto& image = FindImage(info, buffer.Address());
|
||||
|
||||
ASSERT_MSG(image_ids.size() <= 1, "Overlapping framebuffers not allowed!");
|
||||
auto* image = &slot_images[image_ids.empty() ? ImageId{0} : image_ids.back()];
|
||||
|
||||
ImageViewInfo info;
|
||||
info.format = vk::Format::eB8G8R8A8Srgb;
|
||||
if (const ImageViewId view_id = image->FindView(info); view_id) {
|
||||
ImageViewInfo view_info;
|
||||
view_info.format = info.pixel_format;
|
||||
if (const ImageViewId view_id = image.FindView(view_info); view_id) {
|
||||
return slot_image_views[view_id];
|
||||
}
|
||||
|
||||
const ImageViewId view_id = slot_image_views.insert(instance, scheduler, info, image->image);
|
||||
image->image_view_infos.emplace_back(info);
|
||||
image->image_view_ids.emplace_back(view_id);
|
||||
const ImageViewId view_id =
|
||||
slot_image_views.insert(instance, scheduler, view_info, image.image);
|
||||
image.image_view_infos.emplace_back(view_info);
|
||||
image.image_view_ids.emplace_back(view_id);
|
||||
return slot_image_views[view_id];
|
||||
}
|
||||
|
||||
|
@ -225,13 +219,13 @@ void TextureCache::UnregisterImage(ImageId image_id) {
|
|||
ForEachPage(image.cpu_addr, image.info.guest_size_bytes, [this, image_id](u64 page) {
|
||||
const auto page_it = page_table.find(page);
|
||||
if (page_it == page_table.end()) {
|
||||
ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PageBits);
|
||||
ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PageShift);
|
||||
return;
|
||||
}
|
||||
auto& image_ids = page_it.value();
|
||||
const auto vector_it = std::ranges::find(image_ids, image_id);
|
||||
if (vector_it == image_ids.end()) {
|
||||
ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", page << PageBits);
|
||||
ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", page << PageShift);
|
||||
return;
|
||||
}
|
||||
image_ids.erase(vector_it);
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
Image& FindImage(const ImageInfo& info, VAddr cpu_address);
|
||||
|
||||
/// Retrieves the render target with specified properties
|
||||
ImageView& RenderTarget(VAddr cpu_address, u32 pitch);
|
||||
ImageView& RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer);
|
||||
|
||||
/// Reuploads image contents.
|
||||
void RefreshImage(Image& image);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue