diff --git a/src/Core/PS4/GPU/video_out_buffer.h b/src/Core/PS4/GPU/video_out_buffer.h index d3be8090..e3624178 100644 --- a/src/Core/PS4/GPU/video_out_buffer.h +++ b/src/Core/PS4/GPU/video_out_buffer.h @@ -9,4 +9,10 @@ enum class VideoOutBufferFormat : u64 { R8G8B8A8Srgb, B8G8R8A8Srgb, }; + +class VideoOutBufferObj { + public: + explicit VideoOutBufferObj(VideoOutBufferFormat pixel_format, u32 width, u32 height, bool is_tiled, bool is_neo, u32 pitch) { + } +}; } diff --git a/src/Core/PS4/HLE/ErrorCodes.h b/src/Core/PS4/HLE/ErrorCodes.h index 50014a29..06c3014d 100644 --- a/src/Core/PS4/HLE/ErrorCodes.h +++ b/src/Core/PS4/HLE/ErrorCodes.h @@ -17,5 +17,6 @@ constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue +constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot already used constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h index 238697f9..c586063c 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h @@ -1,12 +1,19 @@ #pragma once #include #include +#include using namespace HLE::Libs::Graphics::VideoOut; namespace HLE::Graphics::Objects { -//class FlipQueue; +struct VideoOutBufferInfo { + const void* buffer = nullptr; + HLE::Libs::Graphics::VideoOutVulkanImage* buffer_render = nullptr; + u64 buffer_size = 0; + u64 buffer_pitch = 0; + int set_id = 0; +}; struct VideoConfigInternal { Lib::Mutex m_mutex; @@ -16,7 +23,7 @@ struct VideoConfigInternal { SceVideoOutVblankStatus m_vblank_status; std::vector m_flip_evtEq; int m_flip_rate = 0; - + VideoOutBufferInfo buffers[16]; std::vector buffers_sets; int buffers_registration_index = 0; }; diff --git a/src/Core/PS4/HLE/Graphics/graphics_ctx.h b/src/Core/PS4/HLE/Graphics/graphics_ctx.h index 074e8626..48972da7 100644 --- a/src/Core/PS4/HLE/Graphics/graphics_ctx.h +++ b/src/Core/PS4/HLE/Graphics/graphics_ctx.h @@ -1,7 +1,7 @@ #pragma once + #include -#include -#include +#include #include "Lib/Threads.h" namespace HLE::Libs::Graphics { @@ -19,6 +19,39 @@ struct GraphicCtx { VkInstance m_instance = nullptr; VkPhysicalDevice m_physical_device = nullptr; VkDevice m_device = nullptr; - VulkanQueueInfo queues[11]; //VULKAN_QUEUES_NUM + VulkanQueueInfo queues[11]; // VULKAN_QUEUES_NUM }; + +enum class VulkanImageType { Unknown, VideoOut}; + +struct VulkanMemory { + VkMemoryRequirements requirements = {}; + VkMemoryPropertyFlags property = 0; + VkDeviceMemory memory = nullptr; + VkDeviceSize offset = 0; + u32 type = 0; + u64 unique_id = 0; +}; + +struct VulkanImage { + static constexpr int VIEW_MAX = 4; + static constexpr int VIEW_DEFAULT = 0; + static constexpr int VIEW_BGRA = 1; + static constexpr int VIEW_DEPTH_TEXTURE = 2; + + explicit VulkanImage(VulkanImageType type) : type(type) {} + + VulkanImageType type = VulkanImageType::Unknown; + VkFormat format = VK_FORMAT_UNDEFINED; + VkExtent2D extent = {}; + VkImage image = nullptr; + VkImageView image_view[VIEW_MAX] = {}; + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; + VulkanMemory memory; +}; + +struct VideoOutVulkanImage : public VulkanImage { + VideoOutVulkanImage() : VulkanImage(VulkanImageType::VideoOut) {} +}; + } // namespace HLE::Libs::Graphics \ No newline at end of file diff --git a/src/Core/PS4/HLE/Graphics/video_out.cpp b/src/Core/PS4/HLE/Graphics/video_out.cpp index f5ddeb19..ac0749d1 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.cpp +++ b/src/Core/PS4/HLE/Graphics/video_out.cpp @@ -1,8 +1,10 @@ #include "video_out.h" +#include #include #include #include +#include #include #include #include @@ -12,7 +14,7 @@ #include "Objects/video_out_ctx.h" #include "Util/Singleton.h" -#include +#include "emulator.h" namespace HLE::Libs::Graphics::VideoOut { @@ -160,9 +162,10 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co int registration_index = ctx->buffers_registration_index++; Emulator::checkAndWaitForGraphicsInit(); + // TODO Graphics::RenderCreateCxt(); - //try to calculate buffer size - u64 buffer_size = 1280 * 720 * 4; //TODO hardcoded value should be redone + // try to calculate buffer size + u64 buffer_size = 1280 * 720 * 4; // TODO hardcoded value should be redone u64 buffer_pitch = attribute->pitchInPixel; VideoOutBufferSetInternal buf{}; @@ -174,7 +177,29 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co ctx->buffers_sets.push_back(buf); + GPU::VideoOutBufferFormat format = GPU::VideoOutBufferFormat::Unknown; + if (attribute->pixelFormat == 0x80000000) { + format = GPU::VideoOutBufferFormat::B8G8R8A8Srgb; + } else if (attribute->pixelFormat == 0x80002200) { + format = GPU::VideoOutBufferFormat::R8G8B8A8Srgb; + } + + GPU::VideoOutBufferObj buffer_info(format, attribute->width, attribute->height, attribute->tilingMode == 0, Config::isNeoMode(), buffer_pitch); + + for (int i = 0; i < bufferNum; i++) { + if (ctx->buffers[i + startIndex].buffer != nullptr) { + LOG_TRACE_IF(log_file_videoout, "buffer slot {} is occupied!\n", i + startIndex); + return SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED; + } + + ctx->buffers[i + startIndex].set_id = registration_index; + ctx->buffers[i + startIndex].buffer = addresses[i]; + ctx->buffers[i + startIndex].buffer_size = buffer_size; + ctx->buffers[i + startIndex].buffer_pitch = buffer_pitch; + // ctx->buffers[i + startIndex].buffer_vulkan = TODO!!! + LOG_INFO_IF(log_file_videoout, "buffers[{}] = {}\n", i + startIndex, reinterpret_cast(addresses[i])); + } return registration_index; }