render to texture

This commit is contained in:
InoriRus
2022-02-14 11:58:44 +10:00
parent 9a912716f8
commit 38bde7e8b3
35 changed files with 2119 additions and 1237 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
version: 0.0.8.build-{build} version: 0.0.9.build-{build}
image: Visual Studio 2019 image: Visual Studio 2019
environment: environment:
matrix: matrix:
+1 -1
View File
@@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD)
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000") set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
endif() endif()
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.8) project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.9)
include(src_script.cmake) include(src_script.cmake)
+1
View File
@@ -3,6 +3,7 @@ file(GLOB emulator_src
src/*.cpp src/*.cpp
src/Libs/*.cpp src/Libs/*.cpp
src/Graphics/*.cpp src/Graphics/*.cpp
src/Graphics/Objects/*.cpp
src/Kernel/*.cpp src/Kernel/*.cpp
include/*.h include/*.h
) )
@@ -65,31 +65,30 @@ struct VulkanMemory
uint64_t unique_id = 0; uint64_t unique_id = 0;
}; };
struct VideoOutVulkanImage struct VulkanImage
{ {
VkFormat format = VK_FORMAT_UNDEFINED; VkFormat format = VK_FORMAT_UNDEFINED;
VkExtent2D extent = {}; VkExtent2D extent = {};
VkImage image = nullptr; VkImage image = nullptr;
VkImageView image_view = nullptr; VkImageView image_view = nullptr;
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
Graphics::VulkanMemory memory; Graphics::VulkanMemory memory;
}; };
struct DepthStencilVulkanImage struct VideoOutVulkanImage: public VulkanImage
{ {
VkFormat format = VK_FORMAT_UNDEFINED;
VkExtent2D extent = {};
VkImage image = nullptr;
VkImageView image_view = nullptr;
Graphics::VulkanMemory memory;
}; };
struct TextureVulkanImage struct DepthStencilVulkanImage: public VulkanImage
{
};
struct TextureVulkanImage: public VulkanImage
{
};
struct RenderTextureVulkanImage: public VulkanImage
{ {
VkFormat format = VK_FORMAT_UNDEFINED;
VkExtent2D extent = {};
VkImage image = nullptr;
VkImageView image_view = nullptr;
Graphics::VulkanMemory memory;
}; };
struct VulkanBuffer struct VulkanBuffer
@@ -16,6 +16,7 @@ class CommandProcessor;
struct VideoOutVulkanImage; struct VideoOutVulkanImage;
struct DepthStencilVulkanImage; struct DepthStencilVulkanImage;
struct TextureVulkanImage; struct TextureVulkanImage;
struct RenderTextureVulkanImage;
struct VulkanCommandPool; struct VulkanCommandPool;
struct VulkanBuffer; struct VulkanBuffer;
struct VulkanFramebuffer; struct VulkanFramebuffer;
@@ -82,11 +83,14 @@ void GraphicsRenderWriteBack();
void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, uint32_t thread_group_x, uint32_t thread_group_y, void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, uint32_t thread_group_x, uint32_t thread_group_y,
uint32_t thread_group_z, uint32_t mode); uint32_t thread_group_z, uint32_t mode);
void GraphicsRenderMemoryBarrier(CommandBuffer* buffer); void GraphicsRenderMemoryBarrier(CommandBuffer* buffer);
void GraphicsRenderRenderTextureBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size);
void DeleteFramebuffer(VideoOutVulkanImage* image); void DeleteFramebuffer(VideoOutVulkanImage* image);
void DeleteFramebuffer(DepthStencilVulkanImage* image); void DeleteFramebuffer(DepthStencilVulkanImage* image);
void DeleteFramebuffer(RenderTextureVulkanImage* image);
void DeleteDescriptor(VulkanBuffer* buffer); void DeleteDescriptor(VulkanBuffer* buffer);
void DeleteDescriptor(TextureVulkanImage* image); void DeleteDescriptor(TextureVulkanImage* image);
void DeleteDescriptor(RenderTextureVulkanImage* image);
int GraphicsRenderAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata); int GraphicsRenderAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata);
int GraphicsRenderDeleteEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id); int GraphicsRenderDeleteEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id);
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_DEPTHSTENCILBUFFER_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_DEPTHSTENCILBUFFER_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_DEPTHSTENCILBUFFER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_DEPTHSTENCILBUFFER_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -45,4 +45,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_DEPTHSTENCILBUFFER_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_DEPTHSTENCILBUFFER_H_ */
@@ -1,7 +1,8 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_GPUMEMORY_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_GPUMEMORY_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Kyty/Core/Vector.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
@@ -12,9 +13,7 @@ namespace Kyty::Libs::Graphics {
struct GraphicContext; struct GraphicContext;
struct VulkanMemory; struct VulkanMemory;
struct VulkanBuffer; struct VulkanBuffer;
struct TextureVulkanImage; struct VulkanImage;
struct VideoOutVulkanImage;
struct DepthStencilVulkanImage;
enum class GpuMemoryMode enum class GpuMemoryMode
{ {
@@ -24,7 +23,7 @@ enum class GpuMemoryMode
ReadWrite ReadWrite
}; };
enum class GpuMemoryObjectType enum class GpuMemoryObjectType : uint64_t
{ {
Invalid, Invalid,
VideoOutBuffer, VideoOutBuffer,
@@ -33,7 +32,16 @@ enum class GpuMemoryObjectType
IndexBuffer, IndexBuffer,
VertexBuffer, VertexBuffer,
StorageBuffer, StorageBuffer,
Texture Texture,
RenderTexture,
Max
};
struct GpuMemoryObject
{
GpuMemoryObjectType type = GpuMemoryObjectType::Invalid;
void* obj = nullptr;
}; };
class GpuObject class GpuObject
@@ -68,21 +76,21 @@ void GpuMemoryInit();
void GpuMemorySetAllocatedRange(uint64_t vaddr, uint64_t size); void GpuMemorySetAllocatedRange(uint64_t vaddr, uint64_t size);
void GpuMemoryFree(GraphicContext* ctx, uint64_t vaddr, uint64_t size); void GpuMemoryFree(GraphicContext* ctx, uint64_t vaddr, uint64_t size);
void* GpuMemoryGetObject(GraphicContext* ctx, uint64_t vaddr, uint64_t size, const GpuObject& info); void* GpuMemoryCreateObject(GraphicContext* ctx, uint64_t vaddr, uint64_t size, const GpuObject& info);
void* GpuMemoryGetObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info); void* GpuMemoryCreateObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info);
void GpuMemoryResetHash(GraphicContext* ctx, uint64_t vaddr, uint64_t size, GpuMemoryObjectType type); void GpuMemoryResetHash(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, GpuMemoryObjectType type);
void GpuMemoryDbgDump(); void GpuMemoryDbgDump();
void GpuMemoryFlush(GraphicContext* ctx); void GpuMemoryFlush(GraphicContext* ctx);
void GpuMemoryFrameDone(); void GpuMemoryFrameDone();
void GpuMemoryWriteBack(GraphicContext* ctx); void GpuMemoryWriteBack(GraphicContext* ctx);
Vector<GpuMemoryObject> GpuMemoryFindObjects(uint64_t vaddr, uint64_t size);
bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* mem); bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* mem);
void VulkanFree(GraphicContext* ctx, VulkanMemory* mem); void VulkanFree(GraphicContext* ctx, VulkanMemory* mem);
void VulkanMapMemory(GraphicContext* ctx, VulkanMemory* mem, void** data); void VulkanMapMemory(GraphicContext* ctx, VulkanMemory* mem, void** data);
void VulkanUnmapMemory(GraphicContext* ctx, VulkanMemory* mem); void VulkanUnmapMemory(GraphicContext* ctx, VulkanMemory* mem);
void VulkanBindImageMemory(GraphicContext* ctx, TextureVulkanImage* image, VulkanMemory* mem); void VulkanBindImageMemory(GraphicContext* ctx, VulkanImage* image, VulkanMemory* mem);
void VulkanBindImageMemory(GraphicContext* ctx, VideoOutVulkanImage* image, VulkanMemory* mem);
void VulkanBindImageMemory(GraphicContext* ctx, DepthStencilVulkanImage* image, VulkanMemory* mem);
void VulkanBindBufferMemory(GraphicContext* ctx, VulkanBuffer* buffer, VulkanMemory* mem); void VulkanBindBufferMemory(GraphicContext* ctx, VulkanBuffer* buffer, VulkanMemory* mem);
void GpuMemoryRegisterOwner(uint32_t* owner_handle, const char* name); void GpuMemoryRegisterOwner(uint32_t* owner_handle, const char* name);
@@ -96,4 +104,4 @@ void GpuMemoryUnregisterResource(uint32_t resource_handle);
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_GPUMEMORY_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_INDEXBUFFER_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_INDEXBUFFER_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_INDEXBUFFER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_INDEXBUFFER_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -34,4 +34,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_INDEXBUFFER_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_INDEXBUFFER_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_LABEL_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_LABEL_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -60,4 +60,4 @@ void LabelSet(CommandBuffer* buffer, Label* label);
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_LABEL_H_ */
@@ -0,0 +1,55 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_RENDERTEXTURE_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_RENDERTEXTURE_H_
#include "Kyty/Core/Common.h"
#include "Emulator/Common.h"
#include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
struct GraphicContext;
struct VulkanMemory;
enum class RenderTextureFormat : uint64_t
{
R8G8B8A8Unorm
};
class RenderTextureObject: public GpuObject
{
public:
static constexpr int PARAM_FORMAT = 0;
static constexpr int PARAM_WIDTH = 1;
static constexpr int PARAM_HEIGHT = 2;
static constexpr int PARAM_TILED = 3;
static constexpr int PARAM_NEO = 4;
static constexpr int PARAM_PITCH = 5;
explicit RenderTextureObject(RenderTextureFormat pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo, uint32_t pitch)
{
params[PARAM_FORMAT] = static_cast<uint64_t>(pixel_format);
params[PARAM_WIDTH] = width;
params[PARAM_HEIGHT] = height;
params[PARAM_TILED] = tiled ? 1 : 0;
params[PARAM_NEO] = neo ? 1 : 0;
params[PARAM_PITCH] = pitch;
check_hash = true;
type = Graphics::GpuMemoryObjectType::RenderTexture;
}
void* Create(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, VulkanMemory* mem) const override;
bool Equal(const uint64_t* other) const override;
[[nodiscard]] write_back_func_t GetWriteBackFunc() const override { return nullptr; };
[[nodiscard]] delete_func_t GetDeleteFunc() const override;
[[nodiscard]] update_func_t GetUpdateFunc() const override;
};
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_RENDERTEXTURE_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_STORAGEBUFFER_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_STORAGEBUFFER_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_STORAGEBUFFER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_STORAGEBUFFER_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -37,4 +37,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_STORAGEBUFFER_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_STORAGEBUFFER_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TEXTURE_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURE_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TEXTURE_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURE_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -28,7 +28,7 @@ public:
static constexpr int PARAM_NEO = 6; static constexpr int PARAM_NEO = 6;
static constexpr int PARAM_SWIZZLE = 7; static constexpr int PARAM_SWIZZLE = 7;
TextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, bool htile, bool neo, TextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile, bool neo,
uint32_t swizzle, uint32_t usage) uint32_t swizzle, uint32_t usage)
{ {
params[PARAM_DFMT_NFMT] = (static_cast<uint64_t>(dfmt) << 32u) | nfmt; params[PARAM_DFMT_NFMT] = (static_cast<uint64_t>(dfmt) << 32u) | nfmt;
@@ -36,7 +36,7 @@ public:
params[PARAM_WIDTH_HEIGHT] = (static_cast<uint64_t>(width) << 32u) | height; params[PARAM_WIDTH_HEIGHT] = (static_cast<uint64_t>(width) << 32u) | height;
params[PARAM_USAGE] = usage; params[PARAM_USAGE] = usage;
params[PARAM_LEVELS] = levels; params[PARAM_LEVELS] = levels;
params[PARAM_TILE] = htile ? 1 : 0; params[PARAM_TILE] = tile;
params[PARAM_NEO] = neo ? 1 : 0; params[PARAM_NEO] = neo ? 1 : 0;
params[PARAM_SWIZZLE] = swizzle; params[PARAM_SWIZZLE] = swizzle;
check_hash = true; check_hash = true;
@@ -55,4 +55,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TEXTURE_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_TEXTURE_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VERTEXBUFFER_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VERTEXBUFFER_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VERTEXBUFFER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VERTEXBUFFER_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -34,4 +34,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VERTEXBUFFER_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VERTEXBUFFER_H_ */
@@ -1,10 +1,10 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUTBUFFER_H_ #ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VIDEOOUTBUFFER_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUTBUFFER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VIDEOOUTBUFFER_H_
#include "Kyty/Core/Common.h" #include "Kyty/Core/Common.h"
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Graphics/GpuMemory.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#ifdef KYTY_EMU_ENABLED #ifdef KYTY_EMU_ENABLED
@@ -47,4 +47,4 @@ public:
#endif // KYTY_EMU_ENABLED #endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUTBUFFER_H_ */ #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_OBJECTS_VIDEOOUTBUFFER_H_ */
@@ -15,6 +15,8 @@ enum class TileMode
VideoOutTiled, VideoOutTiled,
TextureLinear, TextureLinear,
TextureTiled, TextureTiled,
// RenderTextureLinear,
// RenderTextureTiled,
}; };
void TileInit(); void TileInit();
@@ -25,8 +27,8 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
void TileGetDepthSize(uint32_t width, uint32_t height, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo, void TileGetDepthSize(uint32_t width, uint32_t height, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo,
uint32_t* stencil_size, uint32_t* htile_size, uint32_t* depth_size, uint32_t* pitch); uint32_t* stencil_size, uint32_t* htile_size, uint32_t* depth_size, uint32_t* pitch);
void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, uint32_t* size, uint32_t* pitch); void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, uint32_t* size, uint32_t* pitch);
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, bool tile, bool neo, void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height); bool neo, uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height);
} // namespace Kyty::Libs::Graphics } // namespace Kyty::Libs::Graphics
@@ -17,7 +17,7 @@ namespace Kyty::Libs::Graphics {
class CommandBuffer; class CommandBuffer;
struct GraphicContext; struct GraphicContext;
struct VulkanBuffer; struct VulkanBuffer;
struct VideoOutVulkanImage; struct VulkanImage;
struct TextureVulkanImage; struct TextureVulkanImage;
struct DepthStencilVulkanImage; struct DepthStencilVulkanImage;
struct VulkanSwapchain; struct VulkanSwapchain;
@@ -30,16 +30,16 @@ struct BufferImageCopy
uint32_t pitch; uint32_t pitch;
}; };
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VideoOutVulkanImage* dst_image); void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image);
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, TextureVulkanImage* dst_image, void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, TextureVulkanImage* dst_image,
const Vector<BufferImageCopy>& regions, uint64_t dst_layout); const Vector<BufferImageCopy>& regions, uint64_t dst_layout);
void UtilBlitImage(CommandBuffer* buffer, VideoOutVulkanImage* src_image, VulkanSwapchain* dst_swapchain); void UtilBlitImage(CommandBuffer* buffer, VulkanImage* src_image, VulkanSwapchain* dst_swapchain);
void UtilFillImage(GraphicContext* ctx, VideoOutVulkanImage* dst_image, const void* src_data, uint64_t size, uint32_t src_pitch); void UtilFillImage(GraphicContext* ctx, VulkanImage* dst_image, const void* src_data, uint64_t size, uint32_t src_pitch);
void UtilFillImage(GraphicContext* ctx, TextureVulkanImage* dst_image, const void* src_data, uint64_t size, void UtilFillImage(GraphicContext* ctx, TextureVulkanImage* dst_image, const void* src_data, uint64_t size,
const Vector<BufferImageCopy>& regions, uint64_t dst_layout); const Vector<BufferImageCopy>& regions, uint64_t dst_layout);
void UtilCopyBuffer(VulkanBuffer* src_buffer, VulkanBuffer* dst_buffer, uint64_t size); void UtilCopyBuffer(VulkanBuffer* src_buffer, VulkanBuffer* dst_buffer, uint64_t size);
void UtilSetImageLayoutOptimal(DepthStencilVulkanImage* image); void UtilSetDepthLayoutOptimal(DepthStencilVulkanImage* image);
void UtilSetImageLayoutOptimal(VideoOutVulkanImage* image); void UtilSetImageLayoutOptimal(VulkanImage* image);
void VulkanCreateBuffer(GraphicContext* gctx, uint64_t size, VulkanBuffer* buffer); void VulkanCreateBuffer(GraphicContext* gctx, uint64_t size, VulkanBuffer* buffer);
void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer); void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer);
-960
View File
@@ -1,960 +0,0 @@
#include "Emulator/Graphics/GpuMemory.h"
#include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/MagicEnum.h"
#include "Kyty/Core/String.h"
#include "Kyty/Core/Threads.h"
#include "Kyty/Core/Vector.h"
#include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Profiler.h"
#include <algorithm>
#include <atomic>
#include <vulkan/vulkan_core.h>
//#define XXH_INLINE_ALL
#include <xxhash/xxhash.h>
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
class GpuMemory
{
public:
GpuMemory() { EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); }
virtual ~GpuMemory() { KYTY_NOT_IMPLEMENTED; }
KYTY_CLASS_NO_COPY(GpuMemory);
bool IsAllocated(uint64_t vaddr, uint64_t size);
void SetAllocatedRange(uint64_t vaddr, uint64_t size);
void Free(GraphicContext* ctx, uint64_t vaddr, uint64_t size);
void* GetObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info);
void ResetHash(GraphicContext* ctx, uint64_t* vaddr, uint64_t* size, int vaddr_num, GpuMemoryObjectType type);
void FrameDone();
// Sync: GPU -> CPU
void WriteBack(GraphicContext* ctx);
// Sync: CPU -> GPU
void Flush(GraphicContext* ctx);
void DbgDump();
private:
static constexpr int OBJ_OVERLAPS_MAX = 2;
static constexpr int VADDR_BLOCKS_MAX = 3;
struct AllocatedRange
{
uint64_t vaddr;
uint64_t size;
};
struct ObjectInfo
{
void* obj = nullptr;
uint64_t params[GpuObject::PARAMS_MAX] = {};
GpuMemoryObjectType type = GpuMemoryObjectType::Invalid;
uint64_t hash[VADDR_BLOCKS_MAX] = {};
GpuObject::write_back_func_t write_back_func = nullptr;
GpuObject::delete_func_t delete_func = nullptr;
GpuObject::update_func_t update_func = nullptr;
uint64_t use_last_frame = 0;
uint64_t use_num = 0;
bool in_use = false;
bool read_only = false;
bool check_hash = false;
VulkanMemory mem;
};
struct Object
{
uint64_t vaddr[VADDR_BLOCKS_MAX] = {};
uint64_t size[VADDR_BLOCKS_MAX] = {};
int vaddr_num = 0;
ObjectInfo overlaps[OBJ_OVERLAPS_MAX];
int overlaps_num = 0;
bool free = true;
};
void Free(GraphicContext* ctx, Object& h);
Core::Mutex m_mutex;
Vector<AllocatedRange> m_allocated;
Vector<Object> m_objects;
uint64_t m_objects_size = 0;
uint64_t m_current_frame = 0;
};
class GpuResources
{
public:
struct Info
{
uint32_t owner = 0;
bool free = true;
uint64_t memory = 0;
size_t size = 0;
String name;
uint32_t type = 0;
uint64_t user_data = 0;
};
GpuResources() { EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); }
virtual ~GpuResources() { KYTY_NOT_IMPLEMENTED; }
KYTY_CLASS_NO_COPY(GpuResources);
uint32_t AddOwner(const String& name);
uint32_t AddResource(uint32_t owner_handle, uint64_t memory, size_t size, const String& name, uint32_t type, uint64_t user_data);
void DeleteOwner(uint32_t owner_handle);
void DeleteResources(uint32_t owner_handle);
void DeleteResource(uint32_t resource_handle);
bool FindInfo(uint64_t memory, Info* dst);
private:
struct Owner
{
String name;
bool free = true;
};
Core::Mutex m_mutex;
Vector<Owner> m_owners;
Vector<Info> m_infos;
};
static GpuMemory* g_gpu_memory = nullptr;
static GpuResources* g_gpu_resources = nullptr;
uint32_t GpuResources::AddOwner(const String& name)
{
Core::LockGuard lock(m_mutex);
Owner n;
n.name = name;
n.free = false;
uint32_t index = 0;
for (auto& b: m_owners)
{
if (b.free)
{
b = n;
return index;
}
index++;
}
m_owners.Add(n);
return index;
}
uint32_t GpuResources::AddResource(uint32_t owner_handle, uint64_t memory, size_t size, const String& name, uint32_t type,
uint64_t user_data)
{
Core::LockGuard lock(m_mutex);
EXIT_NOT_IMPLEMENTED(!m_owners.IndexValid(owner_handle));
EXIT_NOT_IMPLEMENTED(memory == 0);
Info info;
info.owner = owner_handle;
info.memory = memory;
info.free = false;
info.name = name;
info.size = size;
info.type = type;
info.user_data = user_data;
uint32_t index = 0;
for (auto& i: m_infos)
{
if (i.free)
{
i = info;
return index;
}
index++;
}
m_infos.Add(info);
return index;
}
void GpuResources::DeleteOwner(uint32_t owner_handle)
{
Core::LockGuard lock(m_mutex);
EXIT_NOT_IMPLEMENTED(!m_owners.IndexValid(owner_handle));
for (auto& i: m_infos)
{
if (!i.free && i.owner == owner_handle)
{
i.free = true;
}
}
EXIT_NOT_IMPLEMENTED(m_owners[owner_handle].free);
m_owners[owner_handle].free = true;
}
void GpuResources::DeleteResources(uint32_t owner_handle)
{
Core::LockGuard lock(m_mutex);
EXIT_NOT_IMPLEMENTED(!m_owners.IndexValid(owner_handle));
for (auto& i: m_infos)
{
if (!i.free && i.owner == owner_handle)
{
i.free = true;
}
}
}
void GpuResources::DeleteResource(uint32_t resource_handle)
{
Core::LockGuard lock(m_mutex);
EXIT_NOT_IMPLEMENTED(!m_infos.IndexValid(resource_handle));
EXIT_NOT_IMPLEMENTED(m_infos[resource_handle].free);
m_infos[resource_handle].free = true;
}
bool GpuResources::FindInfo(uint64_t memory, Info* dst)
{
EXIT_IF(dst == nullptr);
Core::LockGuard lock(m_mutex);
// NOLINTNEXTLINE(readability-use-anyofallof)
for (const auto& i: m_infos)
{
if (!i.free && memory >= i.memory && memory < i.memory + i.size)
{
*dst = i;
return true;
}
}
return false;
}
void GpuMemory::SetAllocatedRange(uint64_t vaddr, uint64_t size)
{
EXIT_IF(size == 0);
EXIT_NOT_IMPLEMENTED(IsAllocated(vaddr, size));
Core::LockGuard lock(m_mutex);
AllocatedRange r {};
r.vaddr = vaddr;
r.size = size;
m_allocated.Add(r);
}
bool GpuMemory::IsAllocated(uint64_t vaddr, uint64_t size)
{
EXIT_IF(size == 0);
Core::LockGuard lock(m_mutex);
return std::any_of(m_allocated.begin(), m_allocated.end(),
[vaddr, size](auto& r) {
return ((vaddr >= r.vaddr && vaddr < r.vaddr + r.size) ||
((vaddr + size - 1) >= r.vaddr && (vaddr + size - 1) < r.vaddr + r.size));
});
}
static uint64_t calc_hash(const uint8_t* buf, uint64_t size)
{
KYTY_PROFILER_FUNCTION();
return (size > 0 && buf != nullptr ? XXH64(buf, size, 0) : 0);
}
static bool vaddr_equal(const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const uint64_t* vaddr2, const uint64_t* size2,
int vaddr_num2)
{
if (vaddr_num != vaddr_num2)
{
return false;
}
for (int i = 0; i < vaddr_num; i++)
{
if (vaddr[i] != vaddr2[i] || size[i] != size2[i])
{
return false;
}
}
return true;
}
static bool vaddr_overlap(const uint64_t* hvaddr, const uint64_t* hsize, int vaddr_num, uint64_t vaddr, uint64_t size)
{
for (int i = 0; i < vaddr_num; i++)
{
if ((vaddr >= hvaddr[i] && vaddr < hvaddr[i] + hsize[i]) ||
((vaddr + size - 1) >= hvaddr[i] && (vaddr + size - 1) < hvaddr[i] + hsize[i]))
{
return true;
}
}
return false;
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
void* GpuMemory::GetObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info)
{
EXIT_IF(info.type == GpuMemoryObjectType::Invalid);
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num > VADDR_BLOCKS_MAX || vaddr_num <= 0);
Core::LockGuard lock(m_mutex);
uint64_t hash[VADDR_BLOCKS_MAX] = {};
for (int vi = 0; vi < vaddr_num; vi++)
{
EXIT_IF(size[vi] == 0);
if (info.check_hash)
{
hash[vi] = calc_hash(reinterpret_cast<const uint8_t*>(vaddr[vi]), size[vi]);
} else
{
hash[vi] = 0;
}
}
Object* update_object = nullptr;
for (auto& h: m_objects)
{
if (!h.free && vaddr_equal(h.vaddr, h.size, h.vaddr_num, vaddr, size, vaddr_num))
{
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
if (o.type == info.type && info.Equal(o.params))
{
bool need_update = false;
for (int vi = 0; vi < h.vaddr_num; vi++)
{
if (o.hash[vi] != hash[vi])
{
printf("Update (CPU -> GPU): type = %s, vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64 "\n",
Core::EnumName(o.type).C_Str(), h.vaddr[vi], h.size[vi]);
need_update = true;
o.hash[vi] = hash[vi];
}
}
if (need_update)
{
EXIT_IF(o.update_func == nullptr);
o.update_func(ctx, o.params, o.obj, vaddr, size, vaddr_num);
}
o.use_num++;
o.use_last_frame = m_current_frame;
o.in_use = true;
o.read_only = info.read_only;
o.check_hash = info.check_hash;
return o.obj;
}
}
if (h.overlaps_num == 1 &&
(h.overlaps[0].type == GpuMemoryObjectType::VideoOutBuffer && info.type == GpuMemoryObjectType::StorageBuffer))
{
update_object = &h;
break;
}
// EXIT("not implemented");
Free(ctx, h);
break;
}
for (int vi = 0; vi < vaddr_num; vi++)
{
if (!h.free && vaddr_overlap(h.vaddr, h.size, h.overlaps_num, vaddr[vi], size[vi]))
{
if (h.overlaps_num == 1 &&
(h.overlaps[0].type == GpuMemoryObjectType::Label || h.overlaps[0].type == GpuMemoryObjectType::StorageBuffer))
{
Free(ctx, h);
} else
{
KYTY_NOT_IMPLEMENTED;
}
}
}
}
for (int vi = 0; vi < vaddr_num; vi++)
{
EXIT_NOT_IMPLEMENTED(!IsAllocated(vaddr[vi], size[vi]));
}
ObjectInfo o {};
for (int i = 0; i < GpuObject::PARAMS_MAX; i++)
{
o.params[i] = info.params[i];
}
o.type = info.type;
o.obj = nullptr;
for (int vi = 0; vi < vaddr_num; vi++)
{
o.hash[vi] = hash[vi];
}
o.obj = info.Create(ctx, vaddr, size, vaddr_num, &o.mem);
o.write_back_func = info.GetWriteBackFunc();
o.delete_func = info.GetDeleteFunc();
o.update_func = info.GetUpdateFunc();
o.use_num = 1;
o.use_last_frame = m_current_frame;
o.in_use = true;
o.read_only = info.read_only;
o.check_hash = info.check_hash;
bool updated = false;
if (update_object != nullptr)
{
EXIT_IF(update_object->overlaps_num >= OBJ_OVERLAPS_MAX);
update_object->overlaps[update_object->overlaps_num++] = o;
updated = true;
} else
{
for (auto& u: m_objects)
{
if (u.free)
{
u.overlaps_num = 1;
u.overlaps[0] = o;
u.free = false;
for (int vi = 0; vi < vaddr_num; vi++)
{
u.vaddr[vi] = vaddr[vi];
u.size[vi] = size[vi];
m_objects_size += size[vi];
}
u.vaddr_num = vaddr_num;
updated = true;
break;
}
}
}
if (!updated)
{
Object h {};
for (int vi = 0; vi < vaddr_num; vi++)
{
h.vaddr[vi] = vaddr[vi];
h.size[vi] = size[vi];
m_objects_size += size[vi];
}
h.vaddr_num = vaddr_num;
h.overlaps_num = 1;
h.overlaps[0] = o;
h.free = false;
m_objects.Add(h);
}
return o.obj;
}
void GpuMemory::ResetHash(GraphicContext* /*ctx*/, uint64_t* vaddr, uint64_t* size, int vaddr_num, GpuMemoryObjectType type)
{
EXIT_IF(type == GpuMemoryObjectType::Invalid);
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num > VADDR_BLOCKS_MAX || vaddr_num <= 0);
Core::LockGuard lock(m_mutex);
uint64_t new_hash = 0;
for (auto& h: m_objects)
{
if (!h.free && vaddr_equal(h.vaddr, h.size, h.vaddr_num, vaddr, size, vaddr_num))
{
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
if (o.type == type)
{
for (int vi = 0; vi < h.vaddr_num; vi++)
{
printf("ResetHash: type = %s, vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64 ", old_hash = 0x%016" PRIx64
", new_hash = 0x%016" PRIx64 "\n",
Core::EnumName(o.type).C_Str(), h.vaddr[vi], h.size[vi], o.hash[vi], new_hash);
o.hash[vi] = new_hash;
}
}
}
}
}
}
void GpuMemory::Free(GraphicContext* ctx, uint64_t vaddr, uint64_t size)
{
Core::LockGuard lock(m_mutex);
printf("Release gpu objects:\n");
printf("\t gpu_vaddr = 0x%016" PRIx64 "\n", vaddr);
printf("\t size = 0x%016" PRIx64 "\n", size);
EXIT_NOT_IMPLEMENTED(!IsAllocated(vaddr, size));
int index = 0;
for (auto& a: m_allocated)
{
if (a.vaddr == vaddr && a.size == size)
{
m_allocated.RemoveAt(index);
break;
}
index++;
}
EXIT_NOT_IMPLEMENTED(IsAllocated(vaddr, size));
for (auto& h: m_objects)
{
for (int vi = 0; vi < h.vaddr_num; vi++)
{
if (!h.free && (h.vaddr[vi] >= vaddr && h.vaddr[vi] < vaddr + size))
{
Free(ctx, h);
break;
}
}
}
}
void GpuMemory::Free(GraphicContext* ctx, Object& h)
{
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
EXIT_IF(o.delete_func == nullptr);
if (o.delete_func != nullptr)
{
for (int vi = 0; vi < h.vaddr_num; vi++)
{
printf("Delete: type = %s, vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64 "\n", Core::EnumName(o.type).C_Str(),
h.vaddr[vi], h.size[vi]);
}
o.delete_func(ctx, o.obj, &o.mem);
}
}
h.overlaps_num = 0;
h.free = true;
for (int vi = 0; vi < h.vaddr_num; vi++)
{
m_objects_size -= h.size[vi];
}
h.vaddr_num = 0;
}
void GpuMemory::FrameDone()
{
Core::LockGuard lock(m_mutex);
m_current_frame++;
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
void GpuMemory::WriteBack(GraphicContext* ctx)
{
Core::LockGuard lock(m_mutex);
for (auto& h: m_objects)
{
if (!h.free)
{
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
if (o.in_use && /*o.use_last_frame >= m_current_frame &&*/ o.write_back_func != nullptr && !o.read_only)
{
o.write_back_func(ctx, o.obj, h.vaddr, h.size, h.vaddr_num);
for (int vi = 0; vi < h.vaddr_num; vi++)
{
uint64_t new_hash = 0;
if (o.check_hash)
{
new_hash = calc_hash(reinterpret_cast<const uint8_t*>(h.vaddr[vi]), h.size[vi]);
}
printf("WriteBack (GPU -> CPU): type = %s, vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64
", old_hash = 0x%016" PRIx64 ", new_hash = 0x%016" PRIx64 "\n",
Core::EnumName(o.type).C_Str(), h.vaddr[vi], h.size[vi], o.hash[vi], new_hash);
o.hash[vi] = new_hash;
}
for (int oi2 = 0; oi2 < h.overlaps_num; oi2++)
{
if (oi2 != oi)
{
auto& o2 = h.overlaps[oi2];
bool need_update = false;
for (int vi = 0; vi < h.vaddr_num; vi++)
{
uint64_t hash = o.hash[vi];
if (o2.hash[vi] != hash)
{
printf("Update (CPU -> GPU): type = %s, vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64
", old_hash = 0x%016" PRIx64 ", new_hash = 0x%016" PRIx64 "\n",
Core::EnumName(o2.type).C_Str(), h.vaddr[vi], h.size[vi], o2.hash[vi], hash);
o2.hash[vi] = hash;
need_update = true;
}
}
if (need_update)
{
EXIT_IF(o2.update_func == nullptr);
o2.update_func(ctx, o2.params, o2.obj, h.vaddr, h.size, h.vaddr_num);
}
}
}
o.in_use = false;
}
}
}
}
}
void GpuMemory::Flush(GraphicContext* ctx)
{
Core::LockGuard lock(m_mutex);
for (auto& h: m_objects)
{
if (!h.free)
{
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
EXIT_IF(o.update_func == nullptr);
o.update_func(ctx, o.params, o.obj, h.vaddr, h.size, h.vaddr_num);
}
}
}
}
void GpuMemory::DbgDump()
{
Core::LockGuard lock(m_mutex);
printf("--- Gpu Memory ---\n");
for (auto& o: m_allocated)
{
printf("Allocated block: vaddr = 0x%016" PRIx64 ", size = 0x%016" PRIx64 "\n", o.vaddr, o.size);
}
printf("m_current_frame = %" PRIu64 "\n", m_current_frame);
printf("m_objects_size = %" PRIu64 "\n", m_objects_size);
for (auto& h: m_objects)
{
if (!h.free)
{
printf("Object:\n");
for (int vi = 0; vi < h.vaddr_num; vi++)
{
printf("\t vaddr = 0x%016" PRIx64 "\n", h.vaddr[vi]);
printf("\t size = 0x%016" PRIx64 "\n", h.size[vi]);
GpuResources::Info res_info;
if (g_gpu_resources->FindInfo(h.vaddr[vi], &res_info))
{
printf("\t {\n");
printf("\t\t RegisteredResource: %s\n", res_info.name.C_Str());
printf("\t\t addr: %016" PRIx64 "\n", res_info.memory);
printf("\t\t size: %" PRIu64 "\n", res_info.size);
printf("\t\t type: %" PRIu32 "\n", res_info.type);
printf("\t\t user_data: %" PRIu64 "\n", res_info.user_data);
printf("\t }\n");
// EXIT_NOT_IMPLEMENTED(res_info.size != h.size[vi]);
// EXIT_NOT_IMPLEMENTED(res_info.memory != h.vaddr[vi]);
}
}
printf("\t overlaps_num = %d\n", h.overlaps_num);
for (int oi = 0; oi < h.overlaps_num; oi++)
{
auto& o = h.overlaps[oi];
printf("\t [%d] type = %s\n", oi, Core::EnumName(o.type).C_Str());
for (int vi = 0; vi < h.vaddr_num; vi++)
{
printf("\t [%d] hash = 0x%016" PRIx64 "\n", oi, o.hash[vi]);
}
printf("\t [%d] vk_size = 0x%016" PRIx64 "\n", oi, o.mem.requirements.size);
printf("\t [%d] vk_align = 0x%016" PRIx64 "\n", oi, o.mem.requirements.alignment);
printf("\t [%d] vk_type = 0x%08" PRIx32 "\n", oi, o.mem.type);
printf("\t [%d] use_last_frame = %" PRIu64 "\n", oi, o.use_last_frame);
printf("\t [%d] use_num = %" PRIu64 "\n", oi, o.use_num);
printf("\t [%d] in_use = %s\n", oi, o.in_use ? "true" : "false");
printf("\t [%d] read_only = %s\n", oi, o.read_only ? "true" : "false");
printf("\t [%d] check_hash = %s\n", oi, o.check_hash ? "true" : "false");
}
}
}
}
void GpuMemoryInit()
{
EXIT_IF(g_gpu_memory != nullptr);
EXIT_IF(g_gpu_resources != nullptr);
g_gpu_memory = new GpuMemory;
g_gpu_resources = new GpuResources;
}
void GpuMemorySetAllocatedRange(uint64_t vaddr, uint64_t size)
{
EXIT_IF(g_gpu_memory == nullptr);
g_gpu_memory->SetAllocatedRange(vaddr, size);
}
void GpuMemoryFree(GraphicContext* ctx, uint64_t vaddr, uint64_t size)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
g_gpu_memory->Free(ctx, vaddr, size);
}
void* GpuMemoryGetObject(GraphicContext* ctx, uint64_t vaddr, uint64_t size, const GpuObject& info)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
return g_gpu_memory->GetObject(ctx, &vaddr, &size, 1, info);
}
void* GpuMemoryGetObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
return g_gpu_memory->GetObject(ctx, vaddr, size, vaddr_num, info);
}
void GpuMemoryResetHash(GraphicContext* ctx, uint64_t vaddr, uint64_t size, GpuMemoryObjectType type)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
g_gpu_memory->ResetHash(ctx, &vaddr, &size, 1, type);
}
void GpuMemoryDbgDump()
{
EXIT_IF(g_gpu_memory == nullptr);
g_gpu_memory->DbgDump();
}
void GpuMemoryFlush(GraphicContext* ctx)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
// update vulkan objects after CPU-drawing
g_gpu_memory->Flush(ctx);
}
void GpuMemoryFrameDone()
{
EXIT_IF(g_gpu_memory == nullptr);
g_gpu_memory->FrameDone();
}
void GpuMemoryWriteBack(GraphicContext* ctx)
{
EXIT_IF(g_gpu_memory == nullptr);
EXIT_IF(ctx == nullptr);
// update CPU memory after GPU-drawing
g_gpu_memory->WriteBack(ctx);
}
bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* mem)
{
static std::atomic<uint64_t> seq = 0;
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(mem->memory != nullptr);
EXIT_IF(mem->requirements.size == 0);
VkPhysicalDeviceMemoryProperties memory_properties {};
vkGetPhysicalDeviceMemoryProperties(ctx->physical_device, &memory_properties);
uint32_t index = 0;
for (; index < memory_properties.memoryTypeCount; index++)
{
if ((mem->requirements.memoryTypeBits & (static_cast<uint32_t>(1) << index)) != 0 &&
(memory_properties.memoryTypes[index].propertyFlags & mem->property) == mem->property)
{
break;
}
}
mem->type = index;
mem->offset = 0;
VkMemoryAllocateInfo alloc_info {};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.pNext = nullptr;
alloc_info.allocationSize = mem->requirements.size;
alloc_info.memoryTypeIndex = index;
mem->unique_id = ++seq;
return (vkAllocateMemory(ctx->device, &alloc_info, nullptr, &mem->memory) == VK_SUCCESS);
}
void VulkanFree(GraphicContext* ctx, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
vkFreeMemory(ctx->device, mem->memory, nullptr);
mem->memory = nullptr;
}
void VulkanMapMemory(GraphicContext* ctx, VulkanMemory* mem, void** data)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(data == nullptr);
vkMapMemory(ctx->device, mem->memory, mem->offset, mem->requirements.size, 0, data);
}
void VulkanUnmapMemory(GraphicContext* ctx, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
vkUnmapMemory(ctx->device, mem->memory);
}
void VulkanBindImageMemory(GraphicContext* ctx, TextureVulkanImage* image, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(image == nullptr);
vkBindImageMemory(ctx->device, image->image, mem->memory, mem->offset);
}
void VulkanBindImageMemory(GraphicContext* ctx, VideoOutVulkanImage* image, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(image == nullptr);
vkBindImageMemory(ctx->device, image->image, mem->memory, mem->offset);
}
void VulkanBindImageMemory(GraphicContext* ctx, DepthStencilVulkanImage* image, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(image == nullptr);
vkBindImageMemory(ctx->device, image->image, mem->memory, mem->offset);
}
void VulkanBindBufferMemory(GraphicContext* ctx, VulkanBuffer* buffer, VulkanMemory* mem)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(buffer == nullptr);
vkBindBufferMemory(ctx->device, buffer->buffer, mem->memory, mem->offset);
}
void GpuMemoryRegisterOwner(uint32_t* owner_handle, const char* name)
{
EXIT_IF(g_gpu_resources == nullptr);
EXIT_IF(owner_handle == nullptr);
EXIT_IF(name == nullptr);
*owner_handle = g_gpu_resources->AddOwner(String::FromUtf8(name));
}
void GpuMemoryRegisterResource(uint32_t* resource_handle, uint32_t owner_handle, const void* memory, size_t size, const char* name,
uint32_t type, uint64_t user_data)
{
EXIT_IF(g_gpu_resources == nullptr);
EXIT_IF(resource_handle == nullptr);
EXIT_IF(name == nullptr);
*resource_handle =
g_gpu_resources->AddResource(owner_handle, reinterpret_cast<uint64_t>(memory), size, String::FromUtf8(name), type, user_data);
}
void GpuMemoryUnregisterAllResourcesForOwner(uint32_t owner_handle)
{
EXIT_IF(g_gpu_resources == nullptr);
g_gpu_resources->DeleteResources(owner_handle);
}
void GpuMemoryUnregisterOwnerAndResources(uint32_t owner_handle)
{
EXIT_IF(g_gpu_resources == nullptr);
g_gpu_resources->DeleteOwner(owner_handle);
}
void GpuMemoryUnregisterResource(uint32_t resource_handle)
{
EXIT_IF(g_gpu_resources == nullptr);
g_gpu_resources->DeleteResource(resource_handle);
}
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
+2 -2
View File
@@ -5,11 +5,11 @@
#include "Kyty/Core/String.h" #include "Kyty/Core/String.h"
#include "Emulator/Config.h" #include "Emulator/Config.h"
#include "Emulator/Graphics/GpuMemory.h"
#include "Emulator/Graphics/GraphicsRender.h" #include "Emulator/Graphics/GraphicsRender.h"
#include "Emulator/Graphics/GraphicsRun.h" #include "Emulator/Graphics/GraphicsRun.h"
#include "Emulator/Graphics/HardwareContext.h" #include "Emulator/Graphics/HardwareContext.h"
#include "Emulator/Graphics/Label.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Graphics/Objects/Label.h"
#include "Emulator/Graphics/Pm4.h" #include "Emulator/Graphics/Pm4.h"
#include "Emulator/Graphics/Tile.h" #include "Emulator/Graphics/Tile.h"
#include "Emulator/Graphics/VideoOut.h" #include "Emulator/Graphics/VideoOut.h"
+297 -134
View File
@@ -6,20 +6,21 @@
#include "Kyty/Math/Rand.h" #include "Kyty/Math/Rand.h"
#include "Emulator/Config.h" #include "Emulator/Config.h"
#include "Emulator/Graphics/DepthStencilBuffer.h"
#include "Emulator/Graphics/GpuMemory.h"
#include "Emulator/Graphics/GraphicContext.h" #include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Graphics/HardwareContext.h" #include "Emulator/Graphics/HardwareContext.h"
#include "Emulator/Graphics/IndexBuffer.h" #include "Emulator/Graphics/Objects/DepthStencilBuffer.h"
#include "Emulator/Graphics/Label.h" #include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Graphics/Objects/IndexBuffer.h"
#include "Emulator/Graphics/Objects/Label.h"
#include "Emulator/Graphics/Objects/RenderTexture.h"
#include "Emulator/Graphics/Objects/StorageBuffer.h"
#include "Emulator/Graphics/Objects/Texture.h"
#include "Emulator/Graphics/Objects/VertexBuffer.h"
#include "Emulator/Graphics/Objects/VideoOutBuffer.h"
#include "Emulator/Graphics/Shader.h" #include "Emulator/Graphics/Shader.h"
#include "Emulator/Graphics/StorageBuffer.h"
#include "Emulator/Graphics/Texture.h"
#include "Emulator/Graphics/Tile.h" #include "Emulator/Graphics/Tile.h"
#include "Emulator/Graphics/Utils.h" #include "Emulator/Graphics/Utils.h"
#include "Emulator/Graphics/VertexBuffer.h"
#include "Emulator/Graphics/VideoOut.h" #include "Emulator/Graphics/VideoOut.h"
#include "Emulator/Graphics/VideoOutBuffer.h"
#include "Emulator/Graphics/Window.h" #include "Emulator/Graphics/Window.h"
#include "Emulator/Kernel/EventQueue.h" #include "Emulator/Kernel/EventQueue.h"
#include "Emulator/Kernel/Pthread.h" #include "Emulator/Kernel/Pthread.h"
@@ -111,7 +112,7 @@ public:
void DeleteAllPipelines(); void DeleteAllPipelines();
private: private:
static constexpr uint32_t MAX_PIPELINES = 16; static constexpr uint32_t MAX_PIPELINES = 32;
struct Pipeline struct Pipeline
{ {
@@ -168,11 +169,10 @@ public:
void Free(VulkanDescriptorSet* set); void Free(VulkanDescriptorSet* set);
VulkanDescriptorSet* GetDescriptor(Stage stage, int storage_buffers_num, VulkanBuffer** storage_buffers, int textures2d_sampled_num, VulkanDescriptorSet* GetDescriptor(Stage stage, int storage_buffers_num, VulkanBuffer** storage_buffers, int textures2d_sampled_num,
TextureVulkanImage** textures2d_sampled, int textures2d_storage_num, VulkanImage** textures2d_sampled, int textures2d_storage_num, VulkanImage** textures2d_storage,
TextureVulkanImage** textures2d_storage, int samplers_num, uint64_t* samplers, int gds_buffers_num, int samplers_num, uint64_t* samplers, int gds_buffers_num, VulkanBuffer** gds_buffers);
VulkanBuffer** gds_buffers);
void FreeDescriptor(VulkanBuffer* buffer); void FreeDescriptor(VulkanBuffer* buffer);
void FreeDescriptor(TextureVulkanImage* image); void FreeDescriptor(VulkanImage* image);
private: private:
struct Set struct Set
@@ -241,8 +241,8 @@ public:
KYTY_CLASS_NO_COPY(FramebufferCache); KYTY_CLASS_NO_COPY(FramebufferCache);
VulkanFramebuffer* CreateFramebuffer(RenderColorInfo* color, RenderDepthInfo* depth); VulkanFramebuffer* CreateFramebuffer(RenderColorInfo* color, RenderDepthInfo* depth);
void FreeFramebuffer(VideoOutVulkanImage* image); void FreeFramebufferByColor(VulkanImage* image);
void FreeFramebuffer(DepthStencilVulkanImage* image); void FreeFramebufferByDepth(DepthStencilVulkanImage* image);
private: private:
VideoOutVulkanImage* CreateDummyBuffer(VkFormat format, uint32_t width, uint32_t height); VideoOutVulkanImage* CreateDummyBuffer(VkFormat format, uint32_t width, uint32_t height);
@@ -349,13 +349,25 @@ struct RenderDepthInfo
VkStencilOpState stencil_front = {}; VkStencilOpState stencil_front = {};
VkStencilOpState stencil_back = {}; VkStencilOpState stencil_back = {};
DepthStencilVulkanImage* vulkan_buffer = nullptr; DepthStencilVulkanImage* vulkan_buffer = nullptr;
uint64_t vaddr[3] = {};
uint64_t size[3] = {};
int vaddr_num = 0;
};
enum class RenderColorType
{
NoColorOutput,
DisplayBuffer,
OffscreenBuffer,
RenderTexture,
}; };
struct RenderColorInfo struct RenderColorInfo
{ {
VideoOutVulkanImage* vulkan_buffer = nullptr; RenderColorType type = RenderColorType::NoColorOutput;
uint64_t base_addr = 0; VulkanImage* vulkan_buffer = nullptr;
uint64_t buffer_size = 0; uint64_t base_addr = 0;
uint64_t buffer_size = 0;
}; };
class CommandPool class CommandPool
@@ -550,7 +562,7 @@ static void z_check(const DepthRenderTarget& z)
EXIT_NOT_IMPLEMENTED(z.z_info.format != 0x00000003); EXIT_NOT_IMPLEMENTED(z.z_info.format != 0x00000003);
EXIT_NOT_IMPLEMENTED(z.z_info.tile_mode_index != (Config::IsNeo() ? 0x00000002 : 0)); EXIT_NOT_IMPLEMENTED(z.z_info.tile_mode_index != (Config::IsNeo() ? 0x00000002 : 0));
EXIT_NOT_IMPLEMENTED(z.z_info.num_samples != 0x00000000); EXIT_NOT_IMPLEMENTED(z.z_info.num_samples != 0x00000000);
EXIT_NOT_IMPLEMENTED(z.z_info.tile_surface_enable != true); // EXIT_NOT_IMPLEMENTED(z.z_info.tile_surface_enable != true);
EXIT_NOT_IMPLEMENTED(z.z_info.expclear_enabled != false); EXIT_NOT_IMPLEMENTED(z.z_info.expclear_enabled != false);
EXIT_NOT_IMPLEMENTED(z.z_info.zrange_precision != 0x00000001); EXIT_NOT_IMPLEMENTED(z.z_info.zrange_precision != 0x00000001);
} }
@@ -594,11 +606,11 @@ static void z_check(const DepthRenderTarget& z)
EXIT_NOT_IMPLEMENTED(z.z_write_base_addr == 0); EXIT_NOT_IMPLEMENTED(z.z_write_base_addr == 0);
EXIT_NOT_IMPLEMENTED(z.stencil_info.format != 0 && z.stencil_write_base_addr == 0); EXIT_NOT_IMPLEMENTED(z.stencil_info.format != 0 && z.stencil_write_base_addr == 0);
// EXIT_NOT_IMPLEMENTED(z.pitch_div8_minus1 != 0x000000ff); // EXIT_NOT_IMPLEMENTED(z.pitch_div8_minus1 != 0x000000ff);
EXIT_NOT_IMPLEMENTED(z.height_div8_minus1 != 0x0000008f); // EXIT_NOT_IMPLEMENTED(z.height_div8_minus1 != 0x0000008f);
// EXIT_NOT_IMPLEMENTED(z.slice_div64_minus1 != 0x00008fff); // EXIT_NOT_IMPLEMENTED(z.slice_div64_minus1 != 0x00008fff);
EXIT_NOT_IMPLEMENTED(z.htile_data_base_addr == 0); // EXIT_NOT_IMPLEMENTED(z.htile_data_base_addr == 0);
EXIT_NOT_IMPLEMENTED(z.width != 0x00000780); // EXIT_NOT_IMPLEMENTED(z.width != 0x00000780);
EXIT_NOT_IMPLEMENTED(z.height != 0x00000438); // EXIT_NOT_IMPLEMENTED(z.height != 0x00000438);
} }
} }
@@ -1142,7 +1154,7 @@ VulkanFramebuffer* FramebufferCache::CreateFramebuffer(RenderColorInfo* color, R
(color->vulkan_buffer->extent.width != depth->vulkan_buffer->extent.width || (color->vulkan_buffer->extent.width != depth->vulkan_buffer->extent.width ||
color->vulkan_buffer->extent.height != depth->vulkan_buffer->extent.height)); color->vulkan_buffer->extent.height != depth->vulkan_buffer->extent.height));
VideoOutVulkanImage* vulkan_buffer = VulkanImage* vulkan_buffer =
(with_color ? color->vulkan_buffer (with_color ? color->vulkan_buffer
: CreateDummyBuffer(VK_FORMAT_B8G8R8A8_SRGB, depth->vulkan_buffer->extent.width, depth->vulkan_buffer->extent.height)); : CreateDummyBuffer(VK_FORMAT_B8G8R8A8_SRGB, depth->vulkan_buffer->extent.width, depth->vulkan_buffer->extent.height));
@@ -1247,7 +1259,7 @@ VulkanFramebuffer* FramebufferCache::CreateFramebuffer(RenderColorInfo* color, R
return framebuffer; return framebuffer;
} }
void FramebufferCache::FreeFramebuffer(VideoOutVulkanImage* image) void FramebufferCache::FreeFramebufferByColor(VulkanImage* image)
{ {
EXIT_IF(g_render_ctx == nullptr); EXIT_IF(g_render_ctx == nullptr);
EXIT_IF(image == nullptr); EXIT_IF(image == nullptr);
@@ -1277,7 +1289,7 @@ void FramebufferCache::FreeFramebuffer(VideoOutVulkanImage* image)
} }
} }
void FramebufferCache::FreeFramebuffer(DepthStencilVulkanImage* image) void FramebufferCache::FreeFramebufferByDepth(DepthStencilVulkanImage* image)
{ {
EXIT_IF(g_render_ctx == nullptr); EXIT_IF(g_render_ctx == nullptr);
EXIT_IF(image == nullptr); EXIT_IF(image == nullptr);
@@ -1328,6 +1340,7 @@ VideoOutVulkanImage* FramebufferCache::CreateDummyBuffer(VkFormat format, uint32
vk_obj->format = format; vk_obj->format = format;
vk_obj->image = nullptr; vk_obj->image = nullptr;
vk_obj->image_view = nullptr; vk_obj->image_view = nullptr;
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageCreateInfo image_info {}; VkImageCreateInfo image_info {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -1341,7 +1354,7 @@ VideoOutVulkanImage* FramebufferCache::CreateDummyBuffer(VkFormat format, uint32
image_info.arrayLayers = 1; image_info.arrayLayers = 1;
image_info.format = vk_obj->format; image_info.format = vk_obj->format;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.initialLayout = vk_obj->layout;
image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -2460,8 +2473,8 @@ void DescriptorCache::Free(VulkanDescriptorSet* set)
// NOLINTNEXTLINE(readability-function-cognitive-complexity) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
VulkanDescriptorSet* DescriptorCache::GetDescriptor(Stage stage, int storage_buffers_num, VulkanBuffer** storage_buffers, VulkanDescriptorSet* DescriptorCache::GetDescriptor(Stage stage, int storage_buffers_num, VulkanBuffer** storage_buffers,
int textures2d_sampled_num, TextureVulkanImage** textures2d_sampled, int textures2d_sampled_num, VulkanImage** textures2d_sampled,
int textures2d_storage_num, TextureVulkanImage** textures2d_storage, int samplers_num, int textures2d_storage_num, VulkanImage** textures2d_storage, int samplers_num,
uint64_t* samplers, int gds_buffers_num, VulkanBuffer** gds_buffers) uint64_t* samplers, int gds_buffers_num, VulkanBuffer** gds_buffers)
{ {
EXIT_IF(storage_buffers_num < 0 || storage_buffers_num > BUFFERS_MAX); EXIT_IF(storage_buffers_num < 0 || storage_buffers_num > BUFFERS_MAX);
@@ -2736,7 +2749,7 @@ void DescriptorCache::FreeDescriptor(VulkanBuffer* buffer)
} }
} }
void DescriptorCache::FreeDescriptor(TextureVulkanImage* image) void DescriptorCache::FreeDescriptor(VulkanImage* image)
{ {
EXIT_IF(image == nullptr); EXIT_IF(image == nullptr);
@@ -2790,12 +2803,17 @@ VkDescriptorSetLayout DescriptorCache::GetDescriptorSetLayout(Stage stage, int s
void DeleteFramebuffer(VideoOutVulkanImage* image) void DeleteFramebuffer(VideoOutVulkanImage* image)
{ {
g_render_ctx->GetFramebufferCache()->FreeFramebuffer(image); g_render_ctx->GetFramebufferCache()->FreeFramebufferByColor(image);
}
void DeleteFramebuffer(RenderTextureVulkanImage* image)
{
g_render_ctx->GetFramebufferCache()->FreeFramebufferByColor(image);
} }
void DeleteFramebuffer(DepthStencilVulkanImage* image) void DeleteFramebuffer(DepthStencilVulkanImage* image)
{ {
g_render_ctx->GetFramebufferCache()->FreeFramebuffer(image); g_render_ctx->GetFramebufferCache()->FreeFramebufferByDepth(image);
} }
void DeleteDescriptor(VulkanBuffer* buffer) void DeleteDescriptor(VulkanBuffer* buffer)
@@ -2808,6 +2826,11 @@ void DeleteDescriptor(TextureVulkanImage* image)
g_render_ctx->GetDescriptorCache()->FreeDescriptor(image); g_render_ctx->GetDescriptorCache()->FreeDescriptor(image);
} }
void DeleteDescriptor(RenderTextureVulkanImage* image)
{
g_render_ctx->GetDescriptorCache()->FreeDescriptor(image);
}
static void FindRenderDepthInfo(const HardwareContext& hw, RenderDepthInfo* r) static void FindRenderDepthInfo(const HardwareContext& hw, RenderDepthInfo* r)
{ {
EXIT_IF(r == nullptr); EXIT_IF(r == nullptr);
@@ -2817,17 +2840,33 @@ static void FindRenderDepthInfo(const HardwareContext& hw, RenderDepthInfo* r)
const auto& rc = hw.GetRenderControl(); const auto& rc = hw.GetRenderControl();
const auto& dc = hw.GetDepthControl(); const auto& dc = hw.GetDepthControl();
uint32_t size = 0;
uint32_t stencil_size = 0; uint32_t stencil_size = 0;
uint32_t htile_size = 0; uint32_t htile_size = 0;
uint32_t depth_size = 0; uint32_t depth_size = 0;
uint32_t pitch = 0; uint32_t pitch = 0;
if (z.z_info.format == 3)
{
size = (z.slice_div64_minus1 + 1) * 64 * 4;
} else if (z.z_info.format == 1)
{
size = (z.slice_div64_minus1 + 1) * 64 * 2;
}
bool htile = z.z_info.tile_surface_enable; bool htile = z.z_info.tile_surface_enable;
TileGetDepthSize(z.width, z.height, z.z_info.format, z.stencil_info.format, htile, neo, &stencil_size, &htile_size, &depth_size, TileGetDepthSize(z.width, z.height, z.z_info.format, z.stencil_info.format, htile, neo, &stencil_size, &htile_size, &depth_size,
&pitch); &pitch);
EXIT_NOT_IMPLEMENTED(pitch != 0 && (z.pitch_div8_minus1 + 1) * 8 != pitch); if (pitch == 0)
{
depth_size = size;
} else
{
EXIT_NOT_IMPLEMENTED(depth_size != size);
EXIT_NOT_IMPLEMENTED((z.pitch_div8_minus1 + 1) * 8 != pitch);
}
switch (z.z_info.format * 2 + z.stencil_info.format) switch (z.z_info.format * 2 + z.stencil_info.format)
{ {
@@ -2877,117 +2916,170 @@ static void FindRenderDepthInfo(const HardwareContext& hw, RenderDepthInfo* r)
{ {
DepthStencilBufferObject vulkan_buffer_info(r->format, r->width, r->height, htile, neo); DepthStencilBufferObject vulkan_buffer_info(r->format, r->width, r->height, htile, neo);
uint64_t vaddr[3] = {}; r->vaddr_num = 0;
uint64_t size[3] = {};
int vaddr_num = 0;
if (r->depth_buffer_size > 0) if (r->depth_buffer_size > 0)
{ {
vaddr[vaddr_num] = r->depth_buffer_vaddr; r->vaddr[r->vaddr_num] = r->depth_buffer_vaddr;
size[vaddr_num] = r->depth_buffer_size; r->size[r->vaddr_num] = r->depth_buffer_size;
vaddr_num++; r->vaddr_num++;
} }
if (r->stencil_buffer_size > 0) if (r->stencil_buffer_size > 0)
{ {
vaddr[vaddr_num] = r->stencil_buffer_vaddr; r->vaddr[r->vaddr_num] = r->stencil_buffer_vaddr;
size[vaddr_num] = r->stencil_buffer_size; r->size[r->vaddr_num] = r->stencil_buffer_size;
vaddr_num++; r->vaddr_num++;
} }
if (r->htile_buffer_size > 0) if (r->htile_buffer_size > 0)
{ {
vaddr[vaddr_num] = r->htile_buffer_vaddr; r->vaddr[r->vaddr_num] = r->htile_buffer_vaddr;
size[vaddr_num] = r->htile_buffer_size; r->size[r->vaddr_num] = r->htile_buffer_size;
vaddr_num++; r->vaddr_num++;
} }
EXIT_NOT_IMPLEMENTED(vaddr_num == 0); EXIT_NOT_IMPLEMENTED(r->vaddr_num == 0);
r->vulkan_buffer = static_cast<DepthStencilVulkanImage*>( r->vulkan_buffer = static_cast<DepthStencilVulkanImage*>(
GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), vaddr, size, vaddr_num, vulkan_buffer_info)); GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), r->vaddr, r->size, r->vaddr_num, vulkan_buffer_info));
EXIT_NOT_IMPLEMENTED(r->vulkan_buffer == nullptr); EXIT_NOT_IMPLEMENTED(r->vulkan_buffer == nullptr);
} }
} }
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void FindRenderColorInfo(const HardwareContext& hw, RenderColorInfo* r) static void FindRenderColorInfo(const HardwareContext& hw, RenderColorInfo* r)
{ {
EXIT_IF(r == nullptr); EXIT_IF(r == nullptr);
const auto& rt = hw.GetRenderTargets(0); const auto& rt = hw.GetRenderTargets(0);
auto mask = hw.GetRenderTargetMask();
if (rt.base_addr != 0) if (rt.base_addr == 0 || mask == 0)
{
auto width = rt.width;
auto height = rt.height;
auto pitch = (rt.pitch_div8_minus1 + 1) * 8;
auto size = (rt.slice_div64_minus1 + 1) * 64 * 4;
bool tile = false;
uint32_t format = 0;
bool render_to_texture = false;
if (rt.tile_mode == 0x8)
{
tile = false;
} else if (rt.tile_mode == 0xa)
{
tile = true;
} else if (rt.tile_mode == 0xd)
{
tile = true;
render_to_texture = true;
} else
{
EXIT("unknown tile mode: %u\n", rt.tile_mode);
}
if (render_to_texture)
{
EXIT("not implemented");
} else
{
if (rt.format == 0xa && rt.channel_type == 0x6 && rt.channel_order == 0x1)
{
format = 0x80000000;
} else
{
EXIT("unknown format");
}
auto video_image = VideoOut::VideoOutGetImage(rt.base_addr);
if (video_image.image == nullptr)
{
// Offscreen buffer
VideoOutBufferObject vulkan_buffer_info(format, width, height, tile, Config::IsNeo(), pitch);
auto* buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(
Graphics::GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), rt.base_addr, size, vulkan_buffer_info));
EXIT_NOT_IMPLEMENTED(buffer_vulkan == nullptr);
r->base_addr = rt.base_addr;
r->vulkan_buffer = buffer_vulkan;
r->buffer_size = size;
} else
{
// Display buffer
EXIT_NOT_IMPLEMENTED(video_image.buffer_size != size);
EXIT_NOT_IMPLEMENTED(video_image.buffer_pitch != pitch);
r->base_addr = rt.base_addr;
r->vulkan_buffer = video_image.image;
r->buffer_size = video_image.buffer_size;
}
}
} else
{ {
// No color output // No color output
r->type = RenderColorType::NoColorOutput;
r->base_addr = 0; r->base_addr = 0;
r->vulkan_buffer = nullptr; r->vulkan_buffer = nullptr;
r->buffer_size = 0; r->buffer_size = 0;
return;
}
auto width = rt.width;
auto height = rt.height;
auto pitch = (rt.pitch_div8_minus1 + 1) * 8;
auto size = (rt.slice_div64_minus1 + 1) * 64 * 4;
bool tile = false;
uint32_t format = 0;
bool render_to_texture = false;
if (rt.tile_mode == 0x8)
{
tile = false;
} else if (rt.tile_mode == 0xa)
{
tile = true;
} else if (rt.tile_mode == 0xd || rt.tile_mode == 0xe)
{
tile = true;
render_to_texture = true;
} else
{
EXIT("unknown tile mode: %u\n", rt.tile_mode);
}
if (render_to_texture)
{
if (rt.format == 0xa && rt.channel_type == 0x0 && rt.channel_order == 0x0)
{
// Render to texture
RenderTextureObject vulkan_buffer_info(RenderTextureFormat::R8G8B8A8Unorm, width, height, tile, rt.neo_mode, pitch);
auto* buffer_vulkan = static_cast<Graphics::RenderTextureVulkanImage*>(
Graphics::GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), rt.base_addr, size, vulkan_buffer_info));
EXIT_NOT_IMPLEMENTED(buffer_vulkan == nullptr);
r->type = RenderColorType::RenderTexture;
r->base_addr = rt.base_addr;
r->vulkan_buffer = buffer_vulkan;
r->buffer_size = size;
} else
{
EXIT("unknown format");
}
} else
{
if (rt.format == 0xa && rt.channel_type == 0x6 && rt.channel_order == 0x1)
{
format = 0x80000000;
} else
{
EXIT("unknown format");
}
auto video_image = VideoOut::VideoOutGetImage(rt.base_addr);
if (video_image.image == nullptr)
{
// Offscreen buffer
VideoOutBufferObject vulkan_buffer_info(format, width, height, tile, Config::IsNeo(), pitch);
auto* buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(
Graphics::GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), rt.base_addr, size, vulkan_buffer_info));
EXIT_NOT_IMPLEMENTED(buffer_vulkan == nullptr);
r->type = RenderColorType::OffscreenBuffer;
r->base_addr = rt.base_addr;
r->vulkan_buffer = buffer_vulkan;
r->buffer_size = size;
} else
{
// Display buffer
EXIT_NOT_IMPLEMENTED(video_image.buffer_size != size);
EXIT_NOT_IMPLEMENTED(video_image.buffer_pitch != pitch);
r->type = RenderColorType::DisplayBuffer;
r->base_addr = rt.base_addr;
r->vulkan_buffer = video_image.image;
r->buffer_size = video_image.buffer_size;
}
} }
} }
static void InvalidateMemoryObject(const RenderColorInfo& r) static void InvalidateMemoryObject(const RenderColorInfo& r)
{ {
GpuMemoryResetHash(g_render_ctx->GetGraphicCtx(), r.base_addr, r.buffer_size, GpuMemoryObjectType::VideoOutBuffer); bool with_color = (r.vulkan_buffer != nullptr);
if (with_color)
{
if (r.type == RenderColorType::RenderTexture)
{
GpuMemoryResetHash(g_render_ctx->GetGraphicCtx(), &r.base_addr, &r.buffer_size, 1, GpuMemoryObjectType::RenderTexture);
} else if (r.type == RenderColorType::DisplayBuffer || r.type == RenderColorType::OffscreenBuffer)
{
GpuMemoryResetHash(g_render_ctx->GetGraphicCtx(), &r.base_addr, &r.buffer_size, 1, GpuMemoryObjectType::VideoOutBuffer);
}
}
}
static void InvalidateMemoryObject(const RenderDepthInfo& r)
{
bool with_depth = (r.format != VK_FORMAT_UNDEFINED && r.vulkan_buffer != nullptr);
if (with_depth)
{
GpuMemoryResetHash(g_render_ctx->GetGraphicCtx(), r.vaddr, r.size, r.vaddr_num, GpuMemoryObjectType::DepthStencilBuffer);
}
}
static RenderTextureVulkanImage* FindRenderTexture(uint64_t vaddr, uint64_t size)
{
auto objects = GpuMemoryFindObjects(vaddr, size);
for (const auto& obj: objects)
{
if (obj.type == GpuMemoryObjectType::RenderTexture)
{
return static_cast<RenderTextureVulkanImage*>(obj.obj);
}
}
return nullptr;
} }
static void PrepareStorageBuffers(const ShaderStorageResources& storage_buffers, VulkanBuffer** buffers, uint32_t** sgprs) static void PrepareStorageBuffers(const ShaderStorageResources& storage_buffers, VulkanBuffer** buffers, uint32_t** sgprs)
@@ -3026,7 +3118,7 @@ static void PrepareStorageBuffers(const ShaderStorageResources& storage_buffers,
StorageBufferGpuObject buf_info(stride, num_records, read_only); StorageBufferGpuObject buf_info(stride, num_records, read_only);
auto* buf = static_cast<VulkanBuffer*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), addr, size, buf_info)); auto* buf = static_cast<VulkanBuffer*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), addr, size, buf_info));
EXIT_NOT_IMPLEMENTED(buf == nullptr); EXIT_NOT_IMPLEMENTED(buf == nullptr);
@@ -3046,7 +3138,7 @@ static void PrepareStorageBuffers(const ShaderStorageResources& storage_buffers,
} }
// NOLINTNEXTLINE(readability-function-cognitive-complexity) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void PrepareTextures(const ShaderTextureResources& textures, TextureVulkanImage** images, uint32_t** sgprs, bool with_sampler) static void PrepareTextures(const ShaderTextureResources& textures, VulkanImage** images, uint32_t** sgprs, bool with_sampler)
{ {
EXIT_IF(images == nullptr); EXIT_IF(images == nullptr);
EXIT_IF(sgprs == nullptr); EXIT_IF(sgprs == nullptr);
@@ -3059,7 +3151,7 @@ static void PrepareTextures(const ShaderTextureResources& textures, TextureVulka
EXIT_NOT_IMPLEMENTED(r.Base() == 0); EXIT_NOT_IMPLEMENTED(r.Base() == 0);
EXIT_NOT_IMPLEMENTED(r.MinLod() != 0); EXIT_NOT_IMPLEMENTED(r.MinLod() != 0);
EXIT_NOT_IMPLEMENTED(r.Dfmt() != 10 && r.Dfmt() != 37); EXIT_NOT_IMPLEMENTED(r.Dfmt() != 10 && r.Dfmt() != 37);
EXIT_NOT_IMPLEMENTED(r.Nfmt() != 9); EXIT_NOT_IMPLEMENTED(r.Nfmt() != 9 && r.Nfmt() != 0);
// EXIT_NOT_IMPLEMENTED(r.Width() != 511); // EXIT_NOT_IMPLEMENTED(r.Width() != 511);
// EXIT_NOT_IMPLEMENTED(r.Height() != 511); // EXIT_NOT_IMPLEMENTED(r.Height() != 511);
EXIT_NOT_IMPLEMENTED(r.PerfMod() != 7 && r.PerfMod() != 0); EXIT_NOT_IMPLEMENTED(r.PerfMod() != 7 && r.PerfMod() != 0);
@@ -3070,7 +3162,7 @@ static void PrepareTextures(const ShaderTextureResources& textures, TextureVulka
// EXIT_NOT_IMPLEMENTED(r.DstSelW() != 7); // EXIT_NOT_IMPLEMENTED(r.DstSelW() != 7);
EXIT_NOT_IMPLEMENTED(r.BaseLevel() != 0); EXIT_NOT_IMPLEMENTED(r.BaseLevel() != 0);
EXIT_NOT_IMPLEMENTED(r.LastLevel() != 0 && r.LastLevel() != 9); EXIT_NOT_IMPLEMENTED(r.LastLevel() != 0 && r.LastLevel() != 9);
EXIT_NOT_IMPLEMENTED(!(r.TilingIdx() == 8 || r.TilingIdx() == 13)); EXIT_NOT_IMPLEMENTED(!(r.TilingIdx() == 8 || r.TilingIdx() == 13 || r.TilingIdx() == 14));
EXIT_NOT_IMPLEMENTED(!(r.LastLevel() == 0 && r.Pow2Pad() == false) && !(r.LastLevel() == 9 && r.Pow2Pad() == true)); EXIT_NOT_IMPLEMENTED(!(r.LastLevel() == 0 && r.Pow2Pad() == false) && !(r.LastLevel() == 9 && r.Pow2Pad() == true));
EXIT_NOT_IMPLEMENTED(r.Type() != 9); EXIT_NOT_IMPLEMENTED(r.Type() != 9);
EXIT_NOT_IMPLEMENTED(r.Depth() != 0); EXIT_NOT_IMPLEMENTED(r.Depth() != 0);
@@ -3089,17 +3181,22 @@ static void PrepareTextures(const ShaderTextureResources& textures, TextureVulka
auto height = r.Height() + 1; auto height = r.Height() + 1;
auto pitch = r.Pitch() + 1; auto pitch = r.Pitch() + 1;
auto levels = r.LastLevel() - r.BaseLevel() + 1; auto levels = r.LastLevel() - r.BaseLevel() + 1;
bool tile = (r.TilingIdx() != 8); auto tile = r.TilingIdx();
uint32_t swizzle = static_cast<uint32_t>(r.DstSelX()) | (static_cast<uint32_t>(r.DstSelY()) << 8u) | uint32_t swizzle = static_cast<uint32_t>(r.DstSelX()) | (static_cast<uint32_t>(r.DstSelY()) << 8u) |
(static_cast<uint32_t>(r.DstSelZ()) << 16u) | (static_cast<uint32_t>(r.DstSelW()) << 24u); (static_cast<uint32_t>(r.DstSelZ()) << 16u) | (static_cast<uint32_t>(r.DstSelW()) << 24u);
TileGetTextureSize(r.Dfmt(), r.Nfmt(), width, height, pitch, levels, tile, neo, &size, nullptr, nullptr, nullptr); TileGetTextureSize(r.Dfmt(), r.Nfmt(), width, height, pitch, levels, tile, neo, &size, nullptr, nullptr, nullptr);
EXIT_NOT_IMPLEMENTED(size == 0); EXIT_NOT_IMPLEMENTED(size == 0);
TextureObject vulkan_texture_info(r.Dfmt(), r.Nfmt(), width, height, pitch, levels, tile, neo, swizzle, VulkanImage* tex = FindRenderTexture(addr, size);
(with_sampler ? TextureObject::TEXTURE_USAGE_SAMPLED : TextureObject::TEXTURE_USAGE_STORAGE));
auto* tex = static_cast<TextureVulkanImage*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), addr, size, vulkan_texture_info)); if (tex == nullptr)
{
TextureObject vulkan_texture_info(r.Dfmt(), r.Nfmt(), width, height, pitch, levels, tile, neo, swizzle,
(with_sampler ? TextureObject::TEXTURE_USAGE_SAMPLED : TextureObject::TEXTURE_USAGE_STORAGE));
tex = static_cast<TextureVulkanImage*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), addr, size, vulkan_texture_info));
}
EXIT_NOT_IMPLEMENTED(tex == nullptr); EXIT_NOT_IMPLEMENTED(tex == nullptr);
@@ -3205,11 +3302,11 @@ static void BindDescriptors(VkCommandBuffer vk_buffer, VkPipelineBindPoint pipel
(!bind_params.textures2D_without_sampler && bind.textures2D.textures_num > DescriptorCache::TEXTURES_SAMPLED_MAX)); (!bind_params.textures2D_without_sampler && bind.textures2D.textures_num > DescriptorCache::TEXTURES_SAMPLED_MAX));
EXIT_NOT_IMPLEMENTED(bind.samplers.samplers_num > DescriptorCache::SAMPLERS_MAX); EXIT_NOT_IMPLEMENTED(bind.samplers.samplers_num > DescriptorCache::SAMPLERS_MAX);
VulkanBuffer* storage_buffers[DescriptorCache::BUFFERS_MAX]; VulkanBuffer* storage_buffers[DescriptorCache::BUFFERS_MAX];
TextureVulkanImage* textures2d_sampled[DescriptorCache::TEXTURES_SAMPLED_MAX]; VulkanImage* textures2d_sampled[DescriptorCache::TEXTURES_SAMPLED_MAX];
TextureVulkanImage* textures2d_storage[DescriptorCache::TEXTURES_STORAGE_MAX]; VulkanImage* textures2d_storage[DescriptorCache::TEXTURES_STORAGE_MAX];
uint64_t samplers[DescriptorCache::SAMPLERS_MAX]; uint64_t samplers[DescriptorCache::SAMPLERS_MAX];
uint32_t sgprs[DescriptorCache::PUSH_CONSTANTS_MAX]; uint32_t sgprs[DescriptorCache::PUSH_CONSTANTS_MAX];
uint32_t* sgprs_ptr = sgprs; uint32_t* sgprs_ptr = sgprs;
@@ -3343,7 +3440,8 @@ void GraphicsRenderDrawIndex(CommandBuffer* buffer, HardwareContext* ctx, UserCo
uint64_t addr = b.addr; uint64_t addr = b.addr;
uint64_t size = b.stride * b.num_records; uint64_t size = b.stride * b.num_records;
auto* vertices = static_cast<VulkanBuffer*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), addr, size, VertexBufferGpuObject())); auto* vertices =
static_cast<VulkanBuffer*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), addr, size, VertexBufferGpuObject()));
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
@@ -3357,7 +3455,7 @@ void GraphicsRenderDrawIndex(CommandBuffer* buffer, HardwareContext* ctx, UserCo
pipeline->additional_params->ps_bind, VK_SHADER_STAGE_FRAGMENT_BIT, DescriptorCache::Stage::Pixel); pipeline->additional_params->ps_bind, VK_SHADER_STAGE_FRAGMENT_BIT, DescriptorCache::Stage::Pixel);
VulkanBuffer* indices = static_cast<VulkanBuffer*>( VulkanBuffer* indices = static_cast<VulkanBuffer*>(
GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(index_addr), index_size, IndexBufferGpuObject())); GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(index_addr), index_size, IndexBufferGpuObject()));
EXIT_NOT_IMPLEMENTED(indices == nullptr); EXIT_NOT_IMPLEMENTED(indices == nullptr);
@@ -3368,6 +3466,7 @@ void GraphicsRenderDrawIndex(CommandBuffer* buffer, HardwareContext* ctx, UserCo
buffer->EndRenderPass(); buffer->EndRenderPass();
InvalidateMemoryObject(color_info); InvalidateMemoryObject(color_info);
InvalidateMemoryObject(depth_info);
} }
// NOLINTNEXTLINE(readability-function-cognitive-complexity) // NOLINTNEXTLINE(readability-function-cognitive-complexity)
@@ -3448,7 +3547,8 @@ void GraphicsRenderDrawIndexAuto(CommandBuffer* buffer, HardwareContext* ctx, Us
uint64_t addr = b.addr; uint64_t addr = b.addr;
uint64_t size = b.stride * b.num_records; uint64_t size = b.stride * b.num_records;
auto* vertices = static_cast<VulkanBuffer*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), addr, size, VertexBufferGpuObject())); auto* vertices =
static_cast<VulkanBuffer*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), addr, size, VertexBufferGpuObject()));
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
@@ -3479,6 +3579,7 @@ void GraphicsRenderDrawIndexAuto(CommandBuffer* buffer, HardwareContext* ctx, Us
buffer->EndRenderPass(); buffer->EndRenderPass();
InvalidateMemoryObject(color_info); InvalidateMemoryObject(color_info);
InvalidateMemoryObject(depth_info);
} }
void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, uint32_t thread_group_x, uint32_t thread_group_y, void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, uint32_t thread_group_x, uint32_t thread_group_y,
@@ -3535,6 +3636,43 @@ void GraphicsRenderMemoryBarrier(CommandBuffer* buffer)
nullptr); nullptr);
} }
void GraphicsRenderRenderTextureBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size)
{
EXIT_IF(buffer == nullptr);
EXIT_IF(buffer->IsInvalid());
Core::LockGuard lock(g_render_ctx->GetMutex());
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
VulkanImage* image = FindRenderTexture(vaddr, size);
EXIT_NOT_IMPLEMENTED(image == nullptr);
EXIT_NOT_IMPLEMENTED(image->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkImageMemoryBarrier image_memory_barrier {};
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
image_memory_barrier.oldLayout = image->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = image->image;
image_memory_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
image_memory_barrier.subresourceRange.baseMipLevel = 0;
image_memory_barrier.subresourceRange.levelCount = 1;
image_memory_barrier.subresourceRange.baseArrayLayer = 0;
image_memory_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1,
&image_memory_barrier);
image->layout = image_memory_barrier.newLayout;
}
void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value) void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value)
{ {
EXIT_IF(g_render_ctx == nullptr); EXIT_IF(g_render_ctx == nullptr);
@@ -3547,7 +3685,7 @@ void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint32_t* dst_gpu_add
Graphics::LabelGpuObject label_info(value, nullptr, nullptr); Graphics::LabelGpuObject label_info(value, nullptr, nullptr);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3576,7 +3714,7 @@ void GraphicsRenderWriteAtEndOfPipeGds(CommandBuffer* buffer, uint32_t* dst_gpu_
nullptr, args); nullptr, args);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3593,7 +3731,7 @@ void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint64_t* dst_gpu_add
Graphics::LabelGpuObject label_info(value, nullptr, nullptr); Graphics::LabelGpuObject label_info(value, nullptr, nullptr);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3623,7 +3761,7 @@ void GraphicsRenderWriteAtEndOfPipeClockCounter(CommandBuffer* buffer, uint64_t*
nullptr, args); nullptr, args);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3648,7 +3786,7 @@ void GraphicsRenderWriteAtEndOfPipeWithWriteBack(CommandBuffer* buffer, uint64_t
nullptr); nullptr);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3678,7 +3816,7 @@ void GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBack(CommandBuffer* buffer,
}); });
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3701,7 +3839,7 @@ void GraphicsRenderWriteAtEndOfPipeWithInterrupt(CommandBuffer* buffer, uint64_t
}); });
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 8, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3743,7 +3881,7 @@ void GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBackFlip(CommandBuffer* buf
args); args);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -3776,7 +3914,7 @@ void GraphicsRenderWriteAtEndOfPipeWithFlip(CommandBuffer* buffer, uint32_t* dst
nullptr, args); nullptr, args);
auto* label = auto* label =
static_cast<Label*>(GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info)); static_cast<Label*>(GpuMemoryCreateObject(g_render_ctx->GetGraphicCtx(), reinterpret_cast<uint64_t>(dst_gpu_addr), 4, label_info));
LabelSet(buffer, label); LabelSet(buffer, label);
} }
@@ -4069,6 +4207,31 @@ VulkanFramebuffer* CommandBuffer::BeginRenderPass(RenderColorInfo* color, Render
render_pass_info.clearValueCount = with_depth ? 2 : 1; render_pass_info.clearValueCount = with_depth ? 2 : 1;
render_pass_info.pClearValues = clears; render_pass_info.pClearValues = clears;
if (with_color && color->vulkan_buffer->layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
{
VkImageMemoryBarrier image_memory_barrier {};
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
image_memory_barrier.oldLayout = color->vulkan_buffer->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = color->vulkan_buffer->image;
image_memory_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
image_memory_barrier.subresourceRange.baseMipLevel = 0;
image_memory_barrier.subresourceRange.levelCount = 1;
image_memory_barrier.subresourceRange.baseArrayLayer = 0;
image_memory_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1,
&image_memory_barrier);
color->vulkan_buffer->layout = image_memory_barrier.newLayout;
}
vkCmdBeginRenderPass(buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
return framebuffer; return framebuffer;
+37 -10
View File
@@ -70,6 +70,7 @@ public:
void FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache_action, void* dst_gpu_addr, uint32_t value); void FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache_action, void* dst_gpu_addr, uint32_t value);
void WriteBack(); void WriteBack();
void MemoryBarrier(); void MemoryBarrier();
void RenderTextureBarrier(uint64_t vaddr, uint64_t size);
void DispatchDirect(uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode); void DispatchDirect(uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
void WaitFlipDone(uint32_t video_out_handle, uint32_t display_buffer_index); void WaitFlipDone(uint32_t video_out_handle, uint32_t display_buffer_index);
void TriggerEvent(uint32_t event_type, uint32_t event_index); void TriggerEvent(uint32_t event_type, uint32_t event_index);
@@ -1109,6 +1110,15 @@ void CommandProcessor::MemoryBarrier()
GraphicsRenderMemoryBarrier(m_buffer[m_current_buffer]); GraphicsRenderMemoryBarrier(m_buffer[m_current_buffer]);
} }
void CommandProcessor::RenderTextureBarrier(uint64_t vaddr, uint64_t size)
{
Core::LockGuard lock(m_mutex);
EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM);
GraphicsRenderRenderTextureBarrier(m_buffer[m_current_buffer], vaddr, size);
}
void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index) void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index)
{ {
Core::LockGuard lock(m_mutex); Core::LockGuard lock(m_mutex);
@@ -1117,7 +1127,7 @@ void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index)
printf("\t event_type = 0x%08" PRIx32 "\n", event_type); printf("\t event_type = 0x%08" PRIx32 "\n", event_type);
printf("\t event_index = 0x%08" PRIx32 "\n", event_index); printf("\t event_index = 0x%08" PRIx32 "\n", event_index);
if (event_type == 0x00000016 && event_index == 0x00000007) if ((event_type == 0x00000016 || event_type == 0x00000031) && event_index == 0x00000007)
{ {
MemoryBarrier(); MemoryBarrier();
} else } else
@@ -2192,25 +2202,42 @@ KYTY_CP_OP_PARSER(cp_op_acquire_mem)
uint32_t stall_mode = buffer[0] >> 31u; uint32_t stall_mode = buffer[0] >> 31u;
uint32_t cache_action = buffer[0] & 0x7fffffffu; uint32_t cache_action = buffer[0] & 0x7fffffffu;
uint32_t size_lo = buffer[1]; uint64_t size_lo = buffer[1];
uint32_t size_hi = buffer[2]; uint32_t size_hi = buffer[2];
uint32_t base_lo = buffer[3]; uint64_t base_lo = buffer[3];
uint32_t base_hi = buffer[4]; uint32_t base_hi = buffer[4];
uint32_t poll = buffer[5]; uint32_t poll = buffer[5];
EXIT_NOT_IMPLEMENTED(stall_mode != 1); EXIT_NOT_IMPLEMENTED(stall_mode != 1);
EXIT_NOT_IMPLEMENTED(cache_action != 0x00C40000 && cache_action != 0x00400000);
EXIT_NOT_IMPLEMENTED(size_lo != 1);
EXIT_NOT_IMPLEMENTED(size_hi != 0); EXIT_NOT_IMPLEMENTED(size_hi != 0);
EXIT_NOT_IMPLEMENTED(base_lo != 0);
EXIT_NOT_IMPLEMENTED(base_hi != 0); EXIT_NOT_IMPLEMENTED(base_hi != 0);
EXIT_NOT_IMPLEMENTED(poll != 10); EXIT_NOT_IMPLEMENTED(poll != 10);
cp->MemoryBarrier(); switch (cache_action)
if (cache_action == 0x00C40000)
{ {
cp->WriteBack(); case 0x02003fc0:
{
EXIT_NOT_IMPLEMENTED(size_lo == 0);
EXIT_NOT_IMPLEMENTED(base_lo == 0);
cp->RenderTextureBarrier(base_lo << 8u, size_lo << 8u);
}
break;
case 0x00C40000:
{
EXIT_NOT_IMPLEMENTED(size_lo != 1);
EXIT_NOT_IMPLEMENTED(base_lo != 0);
cp->MemoryBarrier();
cp->WriteBack();
}
break;
case 0x00400000:
{
EXIT_NOT_IMPLEMENTED(size_lo != 1);
EXIT_NOT_IMPLEMENTED(base_lo != 0);
cp->MemoryBarrier();
}
break;
default: EXIT("unknown barrier");
} }
return 6; return 6;
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/DepthStencilBuffer.h" #include "Emulator/Graphics/Objects/DepthStencilBuffer.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
@@ -37,6 +37,7 @@ void* DepthStencilBufferObject::Create(GraphicContext* ctx, const uint64_t* vadd
vk_obj->format = pixel_format; vk_obj->format = pixel_format;
vk_obj->image = nullptr; vk_obj->image = nullptr;
vk_obj->image_view = nullptr; vk_obj->image_view = nullptr;
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageCreateInfo image_info {}; VkImageCreateInfo image_info {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -50,7 +51,7 @@ void* DepthStencilBufferObject::Create(GraphicContext* ctx, const uint64_t* vadd
image_info.arrayLayers = 1; image_info.arrayLayers = 1;
image_info.format = vk_obj->format; image_info.format = vk_obj->format;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.initialLayout = vk_obj->layout;
image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -96,7 +97,7 @@ void* DepthStencilBufferObject::Create(GraphicContext* ctx, const uint64_t* vadd
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr); EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
UtilSetImageLayoutOptimal(vk_obj); UtilSetDepthLayoutOptimal(vk_obj);
return vk_obj; return vk_obj;
} }
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/IndexBuffer.h" #include "Emulator/Graphics/Objects/IndexBuffer.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/Label.h" #include "Emulator/Graphics/Objects/Label.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/Threads.h" #include "Kyty/Core/Threads.h"
@@ -0,0 +1,211 @@
#include "Emulator/Graphics/Objects/RenderTexture.h"
#include "Kyty/Core/DbgAssert.h"
#include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Graphics/GraphicsRender.h"
//#include "Emulator/Graphics/Tile.h"
#include "Emulator/Graphics/Utils.h"
#include "Emulator/Profiler.h"
#include <vulkan/vulkan_core.h>
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
void* RenderTextureObject::Create(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, VulkanMemory* mem) const
{
KYTY_PROFILER_BLOCK("RenderTextureObject::Create");
EXIT_IF(vaddr_num != 1 || size == nullptr || vaddr == nullptr);
EXIT_IF(mem == nullptr);
EXIT_IF(ctx == nullptr);
auto pixel_format = params[PARAM_FORMAT];
auto width = params[PARAM_WIDTH];
auto height = params[PARAM_HEIGHT];
VkFormat vk_format = VK_FORMAT_UNDEFINED;
switch (pixel_format) // NOLINT
{
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
default: EXIT("unknown format: %" PRIu64 "\n", pixel_format);
}
EXIT_NOT_IMPLEMENTED(width == 0);
EXIT_NOT_IMPLEMENTED(height == 0);
auto* vk_obj = new RenderTextureVulkanImage;
vk_obj->extent.width = width;
vk_obj->extent.height = height;
vk_obj->format = vk_format;
vk_obj->image = nullptr;
vk_obj->image_view = nullptr;
VkImageCreateInfo image_info {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = nullptr;
image_info.flags = 0;
image_info.imageType = VK_IMAGE_TYPE_2D;
image_info.extent.width = vk_obj->extent.width;
image_info.extent.height = vk_obj->extent.height;
image_info.extent.depth = 1;
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.format = vk_obj->format;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_info.usage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) |
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) |
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_DST_BIT) |
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_SAMPLED_BIT);
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
EXIT_NOT_IMPLEMENTED(vk_obj->image == nullptr);
vkGetImageMemoryRequirements(ctx->device, vk_obj->image, &mem->requirements);
mem->property = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
bool allocated = VulkanAllocate(ctx, mem);
EXIT_NOT_IMPLEMENTED(!allocated);
VulkanBindImageMemory(ctx, vk_obj, mem);
vk_obj->memory = *mem;
printf("RenderTextureObject::Create()\n");
printf("\t mem->requirements.size = %" PRIu64 "\n", mem->requirements.size);
printf("\t width = %" PRIu64 "\n", width);
printf("\t height = %" PRIu64 "\n", height);
printf("\t size = %" PRIu64 "\n", *size);
// EXIT_NOT_IMPLEMENTED(mem->requirements.size > *size);
GetUpdateFunc()(ctx, params, vk_obj, vaddr, size, vaddr_num);
VkImageViewCreateInfo create_info {};
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.image = vk_obj->image;
create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
create_info.format = vk_obj->format;
create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
create_info.subresourceRange.baseArrayLayer = 0;
create_info.subresourceRange.baseMipLevel = 0;
create_info.subresourceRange.layerCount = 1;
create_info.subresourceRange.levelCount = 1;
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
return vk_obj;
}
static bool buffer_is_tiled(uint64_t vaddr, uint64_t size)
{
if ((size & 0x7u) == 0)
{
const auto* ptr = reinterpret_cast<const uint64_t*>(vaddr);
const auto* ptr_end = reinterpret_cast<const uint64_t*>(vaddr + size / 8);
for (uint64_t element = *ptr; ptr < ptr_end; ptr++)
{
if (element != *ptr)
{
return true;
}
}
return false;
}
return true;
}
static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, const uint64_t* vaddr, const uint64_t* size, int vaddr_num)
{
KYTY_PROFILER_BLOCK("RenderTextureObject::update_func");
EXIT_IF(obj == nullptr);
EXIT_IF(ctx == nullptr);
EXIT_IF(params == nullptr);
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num != 1);
auto* vk_obj = static_cast<RenderTextureVulkanImage*>(obj);
bool tiled = (params[RenderTextureObject::PARAM_TILED] != 0);
// bool neo = (params[RenderTextureObject::PARAM_NEO] != 0);
auto pitch = params[RenderTextureObject::PARAM_PITCH];
auto width = params[RenderTextureObject::PARAM_WIDTH];
// auto height = params[RenderTextureObject::PARAM_HEIGHT];
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
if (tiled && buffer_is_tiled(*vaddr, *size))
{
EXIT_NOT_IMPLEMENTED(width != pitch);
auto* temp_buf = new uint8_t[*size];
KYTY_NOT_IMPLEMENTED;
// TODO()
// TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::VideoOutTiled, width, height, neo);
// UtilFillImage(ctx, vk_obj, temp_buf, *size, pitch);
delete[] temp_buf;
} else
{
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, pitch);
}
}
bool RenderTextureObject::Equal(const uint64_t* other) const
{
return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_WIDTH] == other[PARAM_WIDTH] &&
params[PARAM_HEIGHT] == other[PARAM_HEIGHT] && params[PARAM_TILED] == other[PARAM_TILED] &&
params[PARAM_PITCH] == other[PARAM_PITCH] && params[PARAM_PITCH] == other[PARAM_PITCH]);
}
static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
{
KYTY_PROFILER_BLOCK("RenderTextureObject::delete_func");
auto* vk_obj = reinterpret_cast<RenderTextureVulkanImage*>(obj);
EXIT_IF(vk_obj == nullptr);
EXIT_IF(ctx == nullptr);
DeleteDescriptor(vk_obj);
DeleteFramebuffer(vk_obj);
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
VulkanFree(ctx, mem);
delete vk_obj;
}
GpuObject::delete_func_t RenderTextureObject::GetDeleteFunc() const
{
return delete_func;
}
GpuObject::update_func_t RenderTextureObject::GetUpdateFunc() const
{
return update_func;
}
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/StorageBuffer.h" #include "Emulator/Graphics/Objects/StorageBuffer.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/Texture.h" #include "Emulator/Graphics/Objects/Texture.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/Vector.h" #include "Kyty/Core/Vector.h"
@@ -176,6 +176,7 @@ void* TextureObject::Create(GraphicContext* ctx, const uint64_t* vaddr, const ui
vk_obj->format = image_info.format; vk_obj->format = image_info.format;
vk_obj->image = nullptr; vk_obj->image = nullptr;
vk_obj->image_view = nullptr; vk_obj->image_view = nullptr;
vk_obj->layout = image_info.initialLayout;
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image); vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
@@ -227,7 +228,7 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
auto* vk_obj = static_cast<TextureVulkanImage*>(obj); auto* vk_obj = static_cast<TextureVulkanImage*>(obj);
bool tile = (params[TextureObject::PARAM_TILE] != 0); auto tile = params[TextureObject::PARAM_TILE];
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u; auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu; auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u; auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
@@ -248,6 +249,8 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
EXIT_NOT_IMPLEMENTED(levels >= 16); EXIT_NOT_IMPLEMENTED(levels >= 16);
EXIT_NOT_IMPLEMENTED(tile != 8 && tile != 13);
uint32_t level_sizes[16]; uint32_t level_sizes[16];
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr, nullptr); TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr, nullptr);
@@ -285,14 +288,14 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
} }
} }
if (tile) if (tile == 13)
{ {
EXIT_NOT_IMPLEMENTED(pitch != width); EXIT_NOT_IMPLEMENTED(pitch != width);
auto* temp_buf = new uint8_t[*size]; auto* temp_buf = new uint8_t[*size];
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, levels, neo); TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, levels, neo);
UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout)); UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout));
delete[] temp_buf; delete[] temp_buf;
} else } else if (tile == 8)
{ {
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, regions, static_cast<uint64_t>(vk_layout)); UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, regions, static_cast<uint64_t>(vk_layout));
} }
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/VertexBuffer.h" #include "Emulator/Graphics/Objects/VertexBuffer.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
@@ -1,4 +1,4 @@
#include "Emulator/Graphics/VideoOutBuffer.h" #include "Emulator/Graphics/Objects/VideoOutBuffer.h"
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
@@ -37,6 +37,7 @@ void* VideoOutBufferObject::Create(GraphicContext* ctx, const uint64_t* vaddr, c
vk_obj->format = VK_FORMAT_B8G8R8A8_SRGB; vk_obj->format = VK_FORMAT_B8G8R8A8_SRGB;
vk_obj->image = nullptr; vk_obj->image = nullptr;
vk_obj->image_view = nullptr; vk_obj->image_view = nullptr;
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImageCreateInfo image_info {}; VkImageCreateInfo image_info {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -50,7 +51,7 @@ void* VideoOutBufferObject::Create(GraphicContext* ctx, const uint64_t* vaddr, c
image_info.arrayLayers = 1; image_info.arrayLayers = 1;
image_info.format = vk_obj->format; image_info.format = vk_obj->format;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.initialLayout = vk_obj->layout;
image_info.usage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) | image_info.usage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) |
VK_IMAGE_USAGE_TRANSFER_DST_BIT; VK_IMAGE_USAGE_TRANSFER_DST_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
@@ -141,6 +142,8 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
auto width = params[VideoOutBufferObject::PARAM_WIDTH]; auto width = params[VideoOutBufferObject::PARAM_WIDTH];
auto height = params[VideoOutBufferObject::PARAM_HEIGHT]; auto height = params[VideoOutBufferObject::PARAM_HEIGHT];
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
if (tiled && buffer_is_tiled(*vaddr, *size)) if (tiled && buffer_is_tiled(*vaddr, *size))
{ {
EXIT_NOT_IMPLEMENTED(width != pitch); EXIT_NOT_IMPLEMENTED(width != pitch);
@@ -158,7 +161,7 @@ bool VideoOutBufferObject::Equal(const uint64_t* other) const
{ {
return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_WIDTH] == other[PARAM_WIDTH] && return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_WIDTH] == other[PARAM_WIDTH] &&
params[PARAM_HEIGHT] == other[PARAM_HEIGHT] && params[PARAM_TILED] == other[PARAM_TILED] && params[PARAM_HEIGHT] == other[PARAM_HEIGHT] && params[PARAM_TILED] == other[PARAM_TILED] &&
params[PARAM_PITCH] == other[PARAM_PITCH]); params[PARAM_PITCH] == other[PARAM_PITCH] && params[PARAM_NEO] == other[PARAM_NEO]);
} }
static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem) static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
+1 -1
View File
@@ -3012,7 +3012,7 @@ ShaderCode ShaderParsePS(const PixelShaderInfo* regs)
ps_print("ShaderParsePS()", regs->ps_regs); ps_print("ShaderParsePS()", regs->ps_regs);
ps_check(regs->ps_regs); ps_check(regs->ps_regs);
EXIT_NOT_IMPLEMENTED(regs->ps_regs.user_sgpr != regs->ps_user_sgpr.count); EXIT_NOT_IMPLEMENTED(regs->ps_regs.user_sgpr > regs->ps_user_sgpr.count);
const auto* header = GetBinaryInfo(src); const auto* header = GetBinaryInfo(src);
+19 -13
View File
@@ -423,7 +423,7 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
uint32_t padded_height[16] = {0}; uint32_t padded_height[16] = {0};
uint32_t level_sizes[16] = {0}; uint32_t level_sizes[16] = {0};
TileGetTextureSize(dfmt, nfmt, width, height, width, levels, true, neo, nullptr, level_sizes, padded_width, padded_height); TileGetTextureSize(dfmt, nfmt, width, height, width, levels, 13, neo, nullptr, level_sizes, padded_width, padded_height);
uint32_t mip_width = width; uint32_t mip_width = width;
uint32_t mip_height = height; uint32_t mip_height = height;
@@ -611,8 +611,8 @@ void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, u
*pitch = ret_pitch; *pitch = ret_pitch;
} }
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, bool tile, bool neo, void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height) bool neo, uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height)
{ {
struct Padded struct Padded
{ {
@@ -627,7 +627,7 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
uint32_t levels; uint32_t levels;
bool tile; uint32_t tile;
bool neo; bool neo;
uint32_t size[16]; uint32_t size[16];
Padded padded[16]; Padded padded[16];
@@ -635,22 +635,28 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
static const TextureInfo infos[] = { static const TextureInfo infos[] = {
// clang-format off // clang-format off
{ 10, 9, 512, 512, 10, false, false, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, },
{ 10, 9, 512, 512, 10, 8, false, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 9, 512, 512, 10, false, true, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, }, { 10, 9, 512, 512, 10, 8, true, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 9, 512, 512, 10, true, false, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, }, { 10, 9, 512, 512, 10, 13, false, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 9, 512, 512, 10, true, true, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, }, { 10, 9, 512, 512, 10, 13, true, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 37, 9, 512, 512, 10, false, false, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 37, 9, 512, 512, 10, 8, false, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 37, 9, 512, 512, 10, false, true, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 37, 9, 512, 512, 10, 8, true, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 37, 9, 512, 512, 10, true, false, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, }, { 37, 9, 512, 512, 10, 13, false, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, },
{ {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 37, 9, 512, 512, 10, true, true, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, }, { 37, 9, 512, 512, 10, 13, true, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, },
{ {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 0, 256, 256, 9, 14, false, {262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 0, 256, 256, 9, 14, true, {262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// clang-format on // clang-format on
}; };
@@ -684,7 +690,7 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
} }
} }
if (!tile && levels == 1 && dfmt == 10 && nfmt == 9) if (tile == 8 && levels == 1 && dfmt == 10 && nfmt == 9)
{ {
uint32_t size = pitch * height * 4; uint32_t size = pitch * height * 4;
if (total_size != nullptr) if (total_size != nullptr)
+27 -21
View File
@@ -3,9 +3,9 @@
#include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/Vector.h" #include "Kyty/Core/Vector.h"
#include "Emulator/Graphics/GpuMemory.h"
#include "Emulator/Graphics/GraphicContext.h" #include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Graphics/GraphicsRender.h" #include "Emulator/Graphics/GraphicsRender.h"
#include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Profiler.h" #include "Emulator/Profiler.h"
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
@@ -14,11 +14,13 @@
namespace Kyty::Libs::Graphics { namespace Kyty::Libs::Graphics {
static void set_image_layout(VkCommandBuffer buffer, VkImage image, uint32_t levels, VkImageAspectFlags aspect_mask, static void set_image_layout(VkCommandBuffer buffer, VulkanImage* dst_image, uint32_t levels, VkImageAspectFlags aspect_mask,
VkImageLayout old_image_layout, VkImageLayout new_image_layout) VkImageLayout old_image_layout, VkImageLayout new_image_layout)
{ {
EXIT_IF(buffer == nullptr); EXIT_IF(buffer == nullptr);
EXIT_IF(dst_image->layout != old_image_layout);
VkImageMemoryBarrier image_memory_barrier {}; VkImageMemoryBarrier image_memory_barrier {};
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr; image_memory_barrier.pNext = nullptr;
@@ -28,7 +30,7 @@ static void set_image_layout(VkCommandBuffer buffer, VkImage image, uint32_t lev
image_memory_barrier.newLayout = new_image_layout; image_memory_barrier.newLayout = new_image_layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = image; image_memory_barrier.image = dst_image->image;
image_memory_barrier.subresourceRange.aspectMask = aspect_mask; image_memory_barrier.subresourceRange.aspectMask = aspect_mask;
image_memory_barrier.subresourceRange.baseMipLevel = 0; image_memory_barrier.subresourceRange.baseMipLevel = 0;
image_memory_barrier.subresourceRange.levelCount = levels; image_memory_barrier.subresourceRange.levelCount = levels;
@@ -80,9 +82,11 @@ static void set_image_layout(VkCommandBuffer buffer, VkImage image, uint32_t lev
VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
vkCmdPipelineBarrier(buffer, src_stages, dest_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); vkCmdPipelineBarrier(buffer, src_stages, dest_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
dst_image->layout = new_image_layout;
} }
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VideoOutVulkanImage* dst_image) void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image)
{ {
EXIT_IF(src_buffer == nullptr); EXIT_IF(src_buffer == nullptr);
EXIT_IF(src_buffer->buffer == nullptr); EXIT_IF(src_buffer->buffer == nullptr);
@@ -91,8 +95,7 @@ void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()]; auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
set_image_layout(vk_buffer, dst_image->image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, set_image_layout(vk_buffer, dst_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkBufferImageCopy region {}; VkBufferImageCopy region {};
region.bufferOffset = 0; region.bufferOffset = 0;
@@ -109,7 +112,7 @@ void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t
vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
set_image_layout(vk_buffer, dst_image->image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, set_image_layout(vk_buffer, dst_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
} }
@@ -142,16 +145,16 @@ void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, TextureV
index++; index++;
} }
set_image_layout(vk_buffer, dst_image->image, index, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, set_image_layout(vk_buffer, dst_image, index, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, index, region); vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, index, region);
set_image_layout(vk_buffer, dst_image->image, index, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, set_image_layout(vk_buffer, dst_image, index, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
/*VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL*/ static_cast<VkImageLayout>(dst_layout)); /*VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL*/ static_cast<VkImageLayout>(dst_layout));
} }
void UtilBlitImage(CommandBuffer* buffer, VideoOutVulkanImage* src_image, VulkanSwapchain* dst_swapchain) void UtilBlitImage(CommandBuffer* buffer, VulkanImage* src_image, VulkanSwapchain* dst_swapchain)
{ {
EXIT_IF(src_image == nullptr); EXIT_IF(src_image == nullptr);
EXIT_IF(src_image->image == nullptr); EXIT_IF(src_image->image == nullptr);
@@ -159,11 +162,14 @@ void UtilBlitImage(CommandBuffer* buffer, VideoOutVulkanImage* src_image, Vulkan
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()]; auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
auto* blt_dst_image = dst_swapchain->swapchain_images[dst_swapchain->current_index]; VulkanImage swapchain_image {};
set_image_layout(vk_buffer, src_image->image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, swapchain_image.image = dst_swapchain->swapchain_images[dst_swapchain->current_index];
swapchain_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
set_image_layout(vk_buffer, src_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
set_image_layout(vk_buffer, blt_dst_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, set_image_layout(vk_buffer, &swapchain_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageBlit region {}; VkImageBlit region {};
@@ -188,10 +194,10 @@ void UtilBlitImage(CommandBuffer* buffer, VideoOutVulkanImage* src_image, Vulkan
region.dstOffsets[1].y = static_cast<int>(dst_swapchain->swapchain_extent.height); region.dstOffsets[1].y = static_cast<int>(dst_swapchain->swapchain_extent.height);
region.dstOffsets[1].z = 1; region.dstOffsets[1].z = 1;
vkCmdBlitImage(vk_buffer, src_image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, blt_dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vkCmdBlitImage(vk_buffer, src_image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchain_image.image,
1, &region, VK_FILTER_LINEAR); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region, VK_FILTER_LINEAR);
set_image_layout(vk_buffer, src_image->image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, set_image_layout(vk_buffer, src_image, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
} }
@@ -231,7 +237,7 @@ void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer)
buffer->buffer = nullptr; buffer->buffer = nullptr;
} }
void UtilFillImage(GraphicContext* ctx, VideoOutVulkanImage* image, const void* src_data, uint64_t size, uint32_t src_pitch) void UtilFillImage(GraphicContext* ctx, VulkanImage* image, const void* src_data, uint64_t size, uint32_t src_pitch)
{ {
KYTY_PROFILER_FUNCTION(); KYTY_PROFILER_FUNCTION();
@@ -262,7 +268,7 @@ void UtilFillImage(GraphicContext* ctx, VideoOutVulkanImage* image, const void*
VulkanDeleteBuffer(ctx, &staging_buffer); VulkanDeleteBuffer(ctx, &staging_buffer);
} }
void UtilSetImageLayoutOptimal(DepthStencilVulkanImage* image) void UtilSetDepthLayoutOptimal(DepthStencilVulkanImage* image)
{ {
CommandBuffer buffer; CommandBuffer buffer;
buffer.SetQueue(GraphicContext::QUEUE_UTIL); buffer.SetQueue(GraphicContext::QUEUE_UTIL);
@@ -280,14 +286,14 @@ void UtilSetImageLayoutOptimal(DepthStencilVulkanImage* image)
aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT; aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
} }
set_image_layout(vk_buffer, image->image, 1, aspect_mask, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); set_image_layout(vk_buffer, image, 1, aspect_mask, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
buffer.End(); buffer.End();
buffer.Execute(); buffer.Execute();
buffer.WaitForFence(); buffer.WaitForFence();
} }
void UtilSetImageLayoutOptimal(VideoOutVulkanImage* image) void UtilSetImageLayoutOptimal(VulkanImage* image)
{ {
CommandBuffer buffer; CommandBuffer buffer;
buffer.SetQueue(GraphicContext::QUEUE_UTIL); buffer.SetQueue(GraphicContext::QUEUE_UTIL);
@@ -300,7 +306,7 @@ void UtilSetImageLayoutOptimal(VideoOutVulkanImage* image)
VkImageAspectFlags aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT; VkImageAspectFlags aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
set_image_layout(vk_buffer, image->image, 1, aspect_mask, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); set_image_layout(vk_buffer, image, 1, aspect_mask, image->layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
buffer.End(); buffer.End();
buffer.Execute(); buffer.Execute();
+3 -3
View File
@@ -9,10 +9,10 @@
#include "Emulator/Common.h" #include "Emulator/Common.h"
#include "Emulator/Config.h" #include "Emulator/Config.h"
#include "Emulator/Graphics/GpuMemory.h"
#include "Emulator/Graphics/GraphicsRender.h" #include "Emulator/Graphics/GraphicsRender.h"
#include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Graphics/Objects/VideoOutBuffer.h"
#include "Emulator/Graphics/Tile.h" #include "Emulator/Graphics/Tile.h"
#include "Emulator/Graphics/VideoOutBuffer.h"
#include "Emulator/Graphics/Window.h" #include "Emulator/Graphics/Window.h"
#include "Emulator/Kernel/Pthread.h" #include "Emulator/Kernel/Pthread.h"
#include "Emulator/Libs/Errno.h" #include "Emulator/Libs/Errno.h"
@@ -845,7 +845,7 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* con
ctx->buffers[i + start_index].buffer = addresses[i]; ctx->buffers[i + start_index].buffer = addresses[i];
ctx->buffers[i + start_index].buffer_size = buffer_size; ctx->buffers[i + start_index].buffer_size = buffer_size;
ctx->buffers[i + start_index].buffer_pitch = buffer_pitch; ctx->buffers[i + start_index].buffer_pitch = buffer_pitch;
ctx->buffers[i + start_index].buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(Graphics::GpuMemoryGetObject( ctx->buffers[i + start_index].buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(Graphics::GpuMemoryCreateObject(
g_video_out_context->GetGraphicCtx(), reinterpret_cast<uint64_t>(addresses[i]), buffer_size, vulkan_buffer_info)); g_video_out_context->GetGraphicCtx(), reinterpret_cast<uint64_t>(addresses[i]), buffer_size, vulkan_buffer_info));
EXIT_NOT_IMPLEMENTED(ctx->buffers[i + start_index].buffer_vulkan == nullptr); EXIT_NOT_IMPLEMENTED(ctx->buffers[i + start_index].buffer_vulkan == nullptr);
+1 -1
View File
@@ -6,8 +6,8 @@
#include "Kyty/Core/Threads.h" #include "Kyty/Core/Threads.h"
#include "Kyty/Core/Vector.h" #include "Kyty/Core/Vector.h"
#include "Emulator/Graphics/GpuMemory.h"
#include "Emulator/Graphics/GraphicsRun.h" #include "Emulator/Graphics/GraphicsRun.h"
#include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Graphics/Window.h" #include "Emulator/Graphics/Window.h"
#include "Emulator/Libs/Errno.h" #include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h" #include "Emulator/Libs/Libs.h"
+11 -11
View File
@@ -27,8 +27,8 @@ public:
InvalCount InvalCount
}; };
KernelSemaPrivate(const String& name, bool fifo, int init_count, int max_count) KernelSemaPrivate(const String& name, bool /*fifo*/, int init_count, int max_count)
: m_name(name), m_fifo_order(fifo), m_count(init_count), m_init_count(init_count), m_max_count(max_count) {}; : m_name(name), /*m_fifo_order(fifo),*/ m_count(init_count), m_init_count(init_count), m_max_count(max_count) {};
virtual ~KernelSemaPrivate(); virtual ~KernelSemaPrivate();
KYTY_CLASS_NO_COPY(KernelSemaPrivate); KYTY_CLASS_NO_COPY(KernelSemaPrivate);
@@ -53,15 +53,15 @@ private:
Deleted Deleted
}; };
Core::Mutex m_mutex; Core::Mutex m_mutex;
Core::CondVar m_cond_var; Core::CondVar m_cond_var;
String m_name; String m_name;
Status m_status = Status::Set; Status m_status = Status::Set;
Vector<int> m_waiting_threads; Vector<int> m_waiting_threads;
[[maybe_unused]] bool m_fifo_order; // bool m_fifo_order;
int m_count; int m_count;
int m_init_count; int m_init_count;
int m_max_count; int m_max_count;
}; };
KernelSemaPrivate::~KernelSemaPrivate() KernelSemaPrivate::~KernelSemaPrivate()