mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_ASYNCJOB_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_ASYNCJOB_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class AsyncJob
|
||||
{
|
||||
public:
|
||||
using func_t = std::function<void(void*)>;
|
||||
explicit AsyncJob(const char* name): m_name(name) { m_thread = new Core::Thread(ThreadRun, this); }
|
||||
virtual ~AsyncJob()
|
||||
{
|
||||
EXIT_IF(m_thread == nullptr);
|
||||
Core::LockGuard lock(m_mutex);
|
||||
m_need_exit = true;
|
||||
m_cond_var1.Signal();
|
||||
m_thread->Join();
|
||||
delete m_thread;
|
||||
}
|
||||
KYTY_CLASS_NO_COPY(AsyncJob);
|
||||
|
||||
void Execute(func_t func, void* arg = nullptr)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
while (m_func != nullptr)
|
||||
{
|
||||
m_cond_var2.Wait(&m_mutex);
|
||||
}
|
||||
m_func = std::move(func);
|
||||
m_arg = arg;
|
||||
m_cond_var1.Signal();
|
||||
}
|
||||
|
||||
void Wait()
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
while (m_func != nullptr)
|
||||
{
|
||||
m_cond_var2.Wait(&m_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Core::Mutex m_mutex;
|
||||
Core::CondVar m_cond_var1;
|
||||
Core::CondVar m_cond_var2;
|
||||
Core::Thread* m_thread = nullptr;
|
||||
const char* m_name = nullptr;
|
||||
|
||||
func_t m_func = nullptr;
|
||||
void* m_arg = nullptr;
|
||||
bool m_need_exit = false;
|
||||
|
||||
static void ThreadRun(void* data)
|
||||
{
|
||||
// printf("Start AsyncJob Thread: 0x%" PRIx64 "\n", static_cast<uint64_t>(GetCurrentThreadId()));
|
||||
auto* aj = static_cast<AsyncJob*>(data);
|
||||
|
||||
if (aj->m_name != nullptr)
|
||||
{
|
||||
KYTY_PROFILER_THREAD(aj->m_name);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Core::LockGuard lock(aj->m_mutex);
|
||||
while (aj->m_func == nullptr && !aj->m_need_exit)
|
||||
{
|
||||
aj->m_cond_var1.Wait(&aj->m_mutex);
|
||||
}
|
||||
if (aj->m_need_exit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
aj->m_func(aj->m_arg);
|
||||
aj->m_func = nullptr;
|
||||
aj->m_cond_var2.Signal();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_ASYNCJOB_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_DEPTHSTENCILBUFFER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_DEPTHSTENCILBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class DepthStencilBufferObject: 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_HTILE = 3;
|
||||
static constexpr int PARAM_NEO = 4;
|
||||
|
||||
DepthStencilBufferObject(uint64_t vk_format, uint32_t width, uint32_t height, bool htile, bool neo)
|
||||
{
|
||||
params[PARAM_FORMAT] = vk_format;
|
||||
params[PARAM_WIDTH] = width;
|
||||
params[PARAM_HEIGHT] = height;
|
||||
params[PARAM_HTILE] = htile ? 1 : 0;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
check_hash = false;
|
||||
type = Graphics::GpuMemoryObjectType::DepthStencilBuffer;
|
||||
}
|
||||
|
||||
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_DEPTHSTENCILBUFFER_H_ */
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
struct VulkanBuffer;
|
||||
struct TextureVulkanImage;
|
||||
struct VideoOutVulkanImage;
|
||||
struct DepthStencilVulkanImage;
|
||||
|
||||
enum class GpuMemoryMode
|
||||
{
|
||||
NoAccess,
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
};
|
||||
|
||||
enum class GpuMemoryObjectType
|
||||
{
|
||||
Invalid,
|
||||
VideoOutBuffer,
|
||||
DepthStencilBuffer,
|
||||
Label,
|
||||
IndexBuffer,
|
||||
VertexBuffer,
|
||||
StorageBuffer,
|
||||
Texture
|
||||
};
|
||||
|
||||
class GpuObject
|
||||
{
|
||||
public:
|
||||
using write_back_func_t = void (*)(GraphicContext* ctx, void* obj, const uint64_t* vaddr, const uint64_t* size, int vaddr_num);
|
||||
using delete_func_t = void (*)(GraphicContext* ctx, void* obj, VulkanMemory* mem);
|
||||
using update_func_t = void (*)(GraphicContext* ctx, const uint64_t* params, void* obj, const uint64_t* vaddr, const uint64_t* size,
|
||||
int vaddr_num);
|
||||
|
||||
static constexpr int PARAMS_MAX = 8;
|
||||
|
||||
GpuObject() = default;
|
||||
virtual ~GpuObject() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(GpuObject);
|
||||
|
||||
virtual void* Create(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, VulkanMemory* mem) const = 0;
|
||||
virtual bool Equal(const uint64_t* other) const = 0;
|
||||
|
||||
[[nodiscard]] virtual write_back_func_t GetWriteBackFunc() const = 0;
|
||||
[[nodiscard]] virtual delete_func_t GetDeleteFunc() const = 0;
|
||||
[[nodiscard]] virtual update_func_t GetUpdateFunc() const = 0;
|
||||
|
||||
uint64_t params[PARAMS_MAX] = {};
|
||||
bool check_hash = false;
|
||||
bool read_only = false;
|
||||
GpuMemoryObjectType type = GpuMemoryObjectType::Invalid;
|
||||
};
|
||||
|
||||
void GpuMemoryInit();
|
||||
|
||||
void GpuMemorySetAllocatedRange(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* GpuMemoryGetObject(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 GpuMemoryDbgDump();
|
||||
void GpuMemoryFlush();
|
||||
void GpuMemoryFrameDone();
|
||||
void GpuMemoryWriteBack(GraphicContext* ctx);
|
||||
|
||||
bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* mem);
|
||||
void VulkanFree(GraphicContext* ctx, VulkanMemory* mem);
|
||||
void VulkanMapMemory(GraphicContext* ctx, VulkanMemory* mem, void** data);
|
||||
void VulkanUnmapMemory(GraphicContext* ctx, VulkanMemory* mem);
|
||||
void VulkanBindImageMemory(GraphicContext* ctx, TextureVulkanImage* 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 GpuMemoryRegisterOwner(uint32_t* owner_handle, const char* 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);
|
||||
void GpuMemoryUnregisterAllResourcesForOwner(uint32_t owner_handle);
|
||||
void GpuMemoryUnregisterOwnerAndResources(uint32_t owner_handle);
|
||||
void GpuMemoryUnregisterResource(uint32_t resource_handle);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GPUMEMORY_H_ */
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICCONTEXT_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICCONTEXT_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct VulkanSwapchain
|
||||
{
|
||||
VkSwapchainKHR swapchain = nullptr;
|
||||
VkFormat swapchain_format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D swapchain_extent = {};
|
||||
VkImage* swapchain_images = nullptr;
|
||||
VkImageView* swapchain_image_views = nullptr;
|
||||
uint32_t swapchain_images_count = 0;
|
||||
VkSemaphore present_complete_semaphore = nullptr;
|
||||
VkFence present_complete_fence = nullptr;
|
||||
uint32_t current_index = 0;
|
||||
};
|
||||
|
||||
struct VulkanCommandPool
|
||||
{
|
||||
Core::Mutex mutex;
|
||||
VkCommandPool pool = nullptr;
|
||||
VkCommandBuffer* buffers = nullptr;
|
||||
VkFence* fences = nullptr;
|
||||
VkSemaphore* semaphores = nullptr;
|
||||
bool* busy = nullptr;
|
||||
uint32_t buffers_count = 0;
|
||||
};
|
||||
|
||||
struct GraphicContext
|
||||
{
|
||||
static constexpr int QUEUES_NUM = 11;
|
||||
static constexpr int QUEUE_GFX = 8;
|
||||
static constexpr int QUEUE_UTIL = 9;
|
||||
static constexpr int QUEUE_PRESENT = 10;
|
||||
static constexpr int QUEUE_COMPUTE_START = 0;
|
||||
static constexpr int QUEUE_COMPUTE_NUM = 8;
|
||||
|
||||
uint32_t screen_width = 0;
|
||||
uint32_t screen_height = 0;
|
||||
VkInstance instance = nullptr;
|
||||
VkDebugUtilsMessengerEXT debug_messenger = nullptr;
|
||||
VkPhysicalDevice physical_device = nullptr;
|
||||
VkDevice device = nullptr;
|
||||
uint32_t queue_family_index = static_cast<uint32_t>(-1);
|
||||
VkQueue queue[QUEUES_NUM] = {};
|
||||
};
|
||||
|
||||
struct VulkanMemory
|
||||
{
|
||||
VkMemoryRequirements requirements = {};
|
||||
VkMemoryPropertyFlags property = 0;
|
||||
VkDeviceMemory memory = nullptr;
|
||||
VkDeviceSize offset = 0;
|
||||
uint32_t type = 0;
|
||||
uint64_t unique_id = 0;
|
||||
};
|
||||
|
||||
struct VideoOutVulkanImage
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D extent = {};
|
||||
VkImage image = nullptr;
|
||||
VkImageView image_view = nullptr;
|
||||
Graphics::VulkanMemory memory;
|
||||
};
|
||||
|
||||
struct DepthStencilVulkanImage
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D extent = {};
|
||||
VkImage image = nullptr;
|
||||
VkImageView image_view = nullptr;
|
||||
Graphics::VulkanMemory memory;
|
||||
};
|
||||
|
||||
struct TextureVulkanImage
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D extent = {};
|
||||
VkImage image = nullptr;
|
||||
VkImageView image_view = nullptr;
|
||||
Graphics::VulkanMemory memory;
|
||||
};
|
||||
|
||||
struct VulkanBuffer
|
||||
{
|
||||
VkBuffer buffer = nullptr;
|
||||
VulkanMemory memory;
|
||||
VkBufferUsageFlags usage = 0;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICCONTEXT_H_ */
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICS_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICS_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Kernel/EventQueue.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct VsStageRegisters;
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Graphics);
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const VsStageRegisters* vs_regs, uint32_t shader_modifier);
|
||||
int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs);
|
||||
int KYTY_SYSV_ABI GraphicsSetCsShaderWithModifier(uint32_t* cmd, uint64_t size, const uint32_t* cs_regs, uint32_t shader_modifier);
|
||||
int KYTY_SYSV_ABI GraphicsSetEmbeddedVsShader(uint32_t* cmd, uint64_t size, uint32_t id, uint32_t shader_modifier);
|
||||
int KYTY_SYSV_ABI GraphicsDrawIndex(uint32_t* cmd, uint64_t size, uint32_t index_count, const void* index_addr, uint32_t flags,
|
||||
uint32_t type);
|
||||
int KYTY_SYSV_ABI GraphicsDrawIndexAuto(uint32_t* cmd, uint64_t size, uint32_t index_count, uint32_t flags);
|
||||
int KYTY_SYSV_ABI GraphicsSubmitCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes,
|
||||
void* ccb_gpu_addrs[], const uint32_t* ccb_sizes_in_bytes);
|
||||
int KYTY_SYSV_ABI GraphicsSubmitAndFlipCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes,
|
||||
void* ccb_gpu_addrs[], const uint32_t* ccb_sizes_in_bytes, int handle, int index,
|
||||
int flip_mode, int64_t flip_arg);
|
||||
int KYTY_SYSV_ABI GraphicsSubmitDone();
|
||||
void KYTY_SYSV_ABI GraphicsFlushMemory();
|
||||
int KYTY_SYSV_ABI GraphicsAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata);
|
||||
int KYTY_SYSV_ABI GraphicsDeleteEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id);
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState350(uint32_t* cmd, uint64_t size);
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDispatchInitDefaultHardwareState(uint32_t* cmd, uint64_t size);
|
||||
int KYTY_SYSV_ABI GraphicsInsertWaitFlipDone(uint32_t* cmd, uint64_t size, uint32_t video_out_handle, uint32_t display_buffer_index);
|
||||
int KYTY_SYSV_ABI GraphicsDispatchDirect(uint32_t* cmd, uint64_t size, uint32_t thread_group_x, uint32_t thread_group_y,
|
||||
uint32_t thread_group_z, uint32_t mode);
|
||||
uint32_t KYTY_SYSV_ABI GraphicsMapComputeQueue(uint32_t pipe_id, uint32_t queue_id, uint32_t* ring_addr, uint32_t ring_size_dw,
|
||||
uint32_t* read_ptr_addr);
|
||||
int KYTY_SYSV_ABI GraphicsComputeWaitOnAddress(uint32_t* cmd, uint64_t size, uint32_t* gpu_addr, uint32_t mask, uint32_t func,
|
||||
uint32_t ref);
|
||||
void KYTY_SYSV_ABI GraphicsDingDong(uint32_t ring_id, uint32_t offset_dw);
|
||||
void KYTY_SYSV_ABI GraphicsUnmapComputeQueue(uint32_t id);
|
||||
int KYTY_SYSV_ABI GraphicsInsertPushMarker(uint32_t* cmd, uint64_t size, const char* str);
|
||||
int KYTY_SYSV_ABI GraphicsInsertPopMarker(uint32_t* cmd, uint64_t size);
|
||||
uint64_t KYTY_SYSV_ABI GraphicsGetGpuCoreClockFrequency();
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsRegisterOwner(uint32_t* owner_handle, const char* name);
|
||||
int KYTY_SYSV_ABI GraphicsRegisterResource(uint32_t* resource_handle, uint32_t owner_handle, const void* memory, size_t size,
|
||||
const char* name, uint32_t type, uint64_t user_data);
|
||||
int KYTY_SYSV_ABI GraphicsUnregisterAllResourcesForOwner(uint32_t owner_handle);
|
||||
int KYTY_SYSV_ABI GraphicsUnregisterOwnerAndResources(uint32_t owner_handle);
|
||||
int KYTY_SYSV_ABI GraphicsUnregisterResource(uint32_t resource_handle);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICS_H_ */
|
||||
@@ -0,0 +1,92 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRENDER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRENDER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Kernel/EventQueue.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class HardwareContext;
|
||||
class UserConfig;
|
||||
struct VideoOutVulkanImage;
|
||||
struct DepthStencilVulkanImage;
|
||||
struct TextureVulkanImage;
|
||||
struct VulkanCommandPool;
|
||||
struct VulkanBuffer;
|
||||
struct VulkanFramebuffer;
|
||||
struct RenderDepthInfo;
|
||||
struct RenderColorInfo;
|
||||
|
||||
class CommandBuffer
|
||||
{
|
||||
public:
|
||||
CommandBuffer() { Allocate(); }
|
||||
virtual ~CommandBuffer() { Free(); }
|
||||
|
||||
KYTY_CLASS_NO_COPY(CommandBuffer);
|
||||
|
||||
[[nodiscard]] bool IsInvalid() const;
|
||||
|
||||
void Allocate();
|
||||
void Free();
|
||||
void Begin() const;
|
||||
void End() const;
|
||||
void Execute();
|
||||
void ExecuteWithSemaphore();
|
||||
VulkanFramebuffer* BeginRenderPass(RenderColorInfo* color, RenderDepthInfo* depth) const;
|
||||
void EndRenderPass() const;
|
||||
void WaitForFence();
|
||||
void WaitForFenceAndReset();
|
||||
|
||||
[[nodiscard]] uint32_t GetIndex() const { return m_index; }
|
||||
VulkanCommandPool* GetPool() { return m_pool; }
|
||||
[[nodiscard]] bool IsExecute() const { return m_execute; }
|
||||
|
||||
void SetQueue(int queue) { m_queue = queue; }
|
||||
|
||||
private:
|
||||
VulkanCommandPool* m_pool = nullptr;
|
||||
uint32_t m_index = static_cast<uint32_t>(-1);
|
||||
int m_queue = -1;
|
||||
bool m_execute = false;
|
||||
};
|
||||
|
||||
void GraphicsRenderInit();
|
||||
void GraphicsRenderCreateContext();
|
||||
|
||||
void GraphicsRenderDrawIndex(CommandBuffer* buffer, HardwareContext* ctx, UserConfig* ucfg, uint32_t index_type_and_size,
|
||||
uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type);
|
||||
void GraphicsRenderDrawIndexAuto(CommandBuffer* buffer, HardwareContext* ctx, UserConfig* ucfg, uint32_t index_count, uint32_t flags);
|
||||
void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value);
|
||||
void GraphicsRenderWriteAtEndOfPipeClockCounter(CommandBuffer* buffer, uint64_t* dst_gpu_addr);
|
||||
void GraphicsRenderWriteAtEndOfPipe(CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value);
|
||||
void GraphicsRenderWriteAtEndOfPipeGds(CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t dw_offset, uint32_t dw_num);
|
||||
void GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBackFlip(CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value, int handle,
|
||||
int index, int flip_mode, int64_t flip_arg);
|
||||
void GraphicsRenderWriteAtEndOfPipeWithWriteBack(CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value);
|
||||
void GraphicsRenderWriteAtEndOfPipeWithInterrupt(CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value);
|
||||
void GraphicsRenderWriteBack();
|
||||
void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, uint32_t thread_group_x, uint32_t thread_group_y,
|
||||
uint32_t thread_group_z, uint32_t mode);
|
||||
void GraphicsRenderMemoryBarrier(CommandBuffer* buffer);
|
||||
|
||||
void DeleteFramebuffer(VideoOutVulkanImage* image);
|
||||
void DeleteFramebuffer(DepthStencilVulkanImage* image);
|
||||
void DeleteDescriptor(VulkanBuffer* buffer);
|
||||
void DeleteDescriptor(TextureVulkanImage* image);
|
||||
|
||||
int GraphicsRenderAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata);
|
||||
int GraphicsRenderDeleteEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id);
|
||||
|
||||
void GraphicsRenderClearGds(uint64_t dw_offset, uint32_t dw_num, uint32_t clear_value);
|
||||
void GraphicsRenderReadGds(uint32_t* dst, uint32_t dw_offset, uint32_t dw_size);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRENDER_H_ */
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRUN_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRUN_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
void GraphicsRunInit();
|
||||
|
||||
void GraphicsRunSubmit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer, uint32_t num_const_dw);
|
||||
void GraphicsRunSubmitAndFlip(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer, uint32_t num_const_dw,
|
||||
int handle, int index, int flip_mode, int64_t flip_arg);
|
||||
uint32_t GraphicsRunMapComputeQueue(uint32_t pipe_id, uint32_t queue_id, uint32_t* ring_addr, uint32_t ring_size_dw,
|
||||
uint32_t* read_ptr_addr);
|
||||
void GraphicsRunUnmapComputeQueue(uint32_t id);
|
||||
void GraphicsRunWait();
|
||||
void GraphicsRunDone();
|
||||
void GraphicsRunDingDong(uint32_t ring_id, uint32_t offset_dw);
|
||||
int GraphicsRunGetFrameNum();
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GRAPHICSRUN_H_ */
|
||||
@@ -0,0 +1,511 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct RenderTarget
|
||||
{
|
||||
uint64_t base_addr = 0;
|
||||
uint32_t pitch_div8_minus1 = 0;
|
||||
uint32_t fmask_pitch_div8_minus1 = 0;
|
||||
uint32_t slice_div64_minus1 = 0;
|
||||
uint32_t base_array_slice_index = 0;
|
||||
uint32_t last_array_slice_index = 0;
|
||||
bool fmask_compression_enable = false;
|
||||
uint32_t fmask_compression_mode = 0;
|
||||
bool cmask_fast_clear_enable = false;
|
||||
bool dcc_compression_enable = false;
|
||||
bool neo_mode = false;
|
||||
uint32_t cmask_tile_mode = 0;
|
||||
uint32_t cmask_tile_mode_neo = 0;
|
||||
uint32_t format = 0;
|
||||
uint32_t channel_type = 0;
|
||||
uint32_t channel_order = 0;
|
||||
bool force_dest_alpha_to_one = false;
|
||||
uint32_t tile_mode = 0;
|
||||
uint32_t fmask_tile_mode = 0;
|
||||
uint32_t num_samples = 0;
|
||||
uint32_t num_fragments = 0;
|
||||
uint32_t dcc_max_uncompressed_block_size = 0;
|
||||
uint32_t dcc_max_compressed_block_size = 0;
|
||||
uint32_t dcc_min_compressed_block_size = 0;
|
||||
uint32_t dcc_color_transform = 0;
|
||||
bool dcc_enable_overwrite_combiner = false;
|
||||
bool dcc_force_independent_blocks = false;
|
||||
uint64_t cmask_addr = 0;
|
||||
uint32_t cmask_slice_minus1 = 0;
|
||||
uint64_t fmask_addr = 0;
|
||||
uint32_t fmask_slice_minus1 = 0;
|
||||
uint32_t clear_color_word0 = 0;
|
||||
uint32_t clear_color_word1 = 0;
|
||||
uint64_t dcc_addr = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
};
|
||||
|
||||
struct DepthRenderTargetZInfo
|
||||
{
|
||||
uint32_t format = 0;
|
||||
uint32_t tile_mode_index = 0;
|
||||
uint32_t num_samples = 0;
|
||||
bool tile_surface_enable = false;
|
||||
bool expclear_enabled = false;
|
||||
uint32_t zrange_precision = 0;
|
||||
};
|
||||
|
||||
struct DepthRenderTargetStencilInfo
|
||||
{
|
||||
uint32_t format = 0;
|
||||
uint32_t tile_mode_index = 0;
|
||||
uint32_t tile_split = 0;
|
||||
bool expclear_enabled = false;
|
||||
bool tile_stencil_disable = false;
|
||||
};
|
||||
|
||||
struct DepthRenderTargetDepthInfo
|
||||
{
|
||||
uint32_t addr5_swizzle_mask = 0;
|
||||
uint32_t array_mode = 0;
|
||||
uint32_t pipe_config = 0;
|
||||
uint32_t bank_width = 0;
|
||||
uint32_t bank_height = 0;
|
||||
uint32_t macro_tile_aspect = 0;
|
||||
uint32_t num_banks = 0;
|
||||
};
|
||||
|
||||
struct DepthRenderTargetDepthView
|
||||
{
|
||||
uint32_t slice_start = 0;
|
||||
uint32_t slice_max = 0;
|
||||
};
|
||||
|
||||
struct DepthRenderTargetHTileSurface
|
||||
{
|
||||
uint32_t linear = 0;
|
||||
uint32_t full_cache = 0;
|
||||
uint32_t htile_uses_preload_win = 0;
|
||||
uint32_t preload = 0;
|
||||
uint32_t prefetch_width = 0;
|
||||
uint32_t prefetch_height = 0;
|
||||
uint32_t dst_outside_zero_to_one = 0;
|
||||
};
|
||||
|
||||
struct DepthRenderTarget
|
||||
{
|
||||
DepthRenderTargetZInfo z_info;
|
||||
DepthRenderTargetStencilInfo stencil_info;
|
||||
DepthRenderTargetDepthInfo depth_info;
|
||||
DepthRenderTargetDepthView depth_view;
|
||||
DepthRenderTargetHTileSurface htile_surface;
|
||||
|
||||
uint64_t z_read_base_addr = 0;
|
||||
uint64_t stencil_read_base_addr = 0;
|
||||
uint64_t z_write_base_addr = 0;
|
||||
uint64_t stencil_write_base_addr = 0;
|
||||
uint32_t pitch_div8_minus1 = 0;
|
||||
uint32_t height_div8_minus1 = 0;
|
||||
uint32_t slice_div64_minus1 = 0;
|
||||
uint64_t htile_data_base_addr = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
};
|
||||
|
||||
struct RenderControl
|
||||
{
|
||||
bool depth_clear_enable = false;
|
||||
bool stencil_clear_enable = false;
|
||||
bool resummarize_enable = false;
|
||||
bool stencil_compress_disable = false;
|
||||
bool depth_compress_disable = false;
|
||||
bool copy_centroid = false;
|
||||
uint8_t copy_sample = 0;
|
||||
};
|
||||
|
||||
struct ClipControl
|
||||
{
|
||||
uint32_t user_clip_planes = 0;
|
||||
uint32_t user_clip_plane_mode = 0;
|
||||
uint32_t clip_space = 0;
|
||||
uint32_t vertex_kill_mode = 0;
|
||||
uint32_t min_z_clip_enable = 0;
|
||||
uint32_t max_z_clip_enable = 0;
|
||||
bool user_clip_plane_negate_y = false;
|
||||
bool clip_enable = false;
|
||||
bool user_clip_plane_cull_only = false;
|
||||
bool cull_on_clipping_error_disable = false;
|
||||
bool linear_attribute_clip_enable = false;
|
||||
bool force_viewport_index_from_vs_enable = false;
|
||||
};
|
||||
|
||||
struct DepthControl
|
||||
{
|
||||
bool stencil_enable = false;
|
||||
bool z_enable = false;
|
||||
bool z_write_enable = false;
|
||||
bool depth_bounds_enable = false;
|
||||
uint8_t zfunc = 0;
|
||||
bool backface_enable = false;
|
||||
uint8_t stencilfunc = 0;
|
||||
uint8_t stencilfunc_bf = 0;
|
||||
};
|
||||
|
||||
struct ModeControl
|
||||
{
|
||||
bool cull_front = false;
|
||||
bool cull_back = false;
|
||||
bool face = false;
|
||||
uint8_t poly_mode = 0;
|
||||
uint8_t polymode_front_ptype = 0;
|
||||
uint8_t polymode_back_ptype = 0;
|
||||
bool poly_offset_front_enable = false;
|
||||
bool poly_offset_back_enable = false;
|
||||
bool vtx_window_offset_enable = false;
|
||||
bool provoking_vtx_last = false;
|
||||
bool persp_corr_dis = false;
|
||||
};
|
||||
|
||||
struct BlendControl
|
||||
{
|
||||
uint8_t color_srcblend = 0;
|
||||
uint8_t color_comb_fcn = 0;
|
||||
uint8_t color_destblend = 0;
|
||||
uint8_t alpha_srcblend = 0;
|
||||
uint8_t alpha_comb_fcn = 0;
|
||||
uint8_t alpha_destblend = 0;
|
||||
bool separate_alpha_blend = false;
|
||||
bool enable = false;
|
||||
};
|
||||
|
||||
struct Viewport
|
||||
{
|
||||
float zmin = 0.0f;
|
||||
float zmax = 0.0f;
|
||||
float xscale = 0.0f;
|
||||
float xoffset = 0.0f;
|
||||
float yscale = 0.0f;
|
||||
float yoffset = 0.0f;
|
||||
float zscale = 0.0f;
|
||||
float zoffset = 0.0f;
|
||||
};
|
||||
|
||||
struct ScreenViewport
|
||||
{
|
||||
Viewport viewports[15];
|
||||
uint32_t transform_control = 0;
|
||||
int scissor_left = 0;
|
||||
int scissor_top = 0;
|
||||
int scissor_right = 0;
|
||||
int scissor_bottom = 0;
|
||||
uint32_t hw_offset_x = 0;
|
||||
uint32_t hw_offset_y = 0;
|
||||
float guard_band_horz_clip = 0.0f;
|
||||
float guard_band_vert_clip = 0.0f;
|
||||
float guard_band_horz_discard = 0.0f;
|
||||
float guard_band_vert_discard = 0.0f;
|
||||
};
|
||||
|
||||
struct VsStageRegisters
|
||||
{
|
||||
uint32_t m_spiShaderPgmLoVs = 0;
|
||||
uint32_t m_spiShaderPgmHiVs = 0;
|
||||
uint32_t m_spiShaderPgmRsrc1Vs = 0;
|
||||
uint32_t m_spiShaderPgmRsrc2Vs = 0;
|
||||
|
||||
uint32_t m_spiVsOutConfig = 0;
|
||||
uint32_t m_spiShaderPosFormat = 0;
|
||||
uint32_t m_paClVsOutCntl = 0;
|
||||
|
||||
[[nodiscard]] uint64_t GetGpuAddress() const;
|
||||
[[nodiscard]] bool GetStreamoutEnabled() const;
|
||||
[[nodiscard]] uint32_t GetSgprCount() const;
|
||||
[[nodiscard]] uint32_t GetInputComponentsCount() const;
|
||||
[[nodiscard]] uint32_t GetUnknown1() const;
|
||||
[[nodiscard]] uint32_t GetUnknown2() const;
|
||||
};
|
||||
|
||||
struct PsStageRegisters
|
||||
{
|
||||
uint64_t data_addr = 0;
|
||||
uint8_t vgprs = 0;
|
||||
uint8_t sgprs = 0;
|
||||
uint8_t scratch_en = 0;
|
||||
uint8_t user_sgpr = 0;
|
||||
uint8_t wave_cnt_en = 0;
|
||||
uint32_t shader_z_format = 0;
|
||||
uint8_t target_output_mode[8] = {};
|
||||
uint32_t ps_input_ena = 0;
|
||||
uint32_t ps_input_addr = 0;
|
||||
uint32_t ps_in_control = 0;
|
||||
uint32_t baryc_cntl = 0;
|
||||
|
||||
uint8_t conservative_z_export_value = 0;
|
||||
uint8_t shader_z_behavior = 0;
|
||||
bool shader_kill_enable = false;
|
||||
bool shader_z_export_enable = false;
|
||||
bool shader_execute_on_noop = false;
|
||||
|
||||
uint32_t m_cbShaderMask = 0;
|
||||
};
|
||||
|
||||
struct CsStageRegisters
|
||||
{
|
||||
|
||||
uint64_t data_addr = 0;
|
||||
uint32_t num_thread_x = 0;
|
||||
uint32_t num_thread_y = 0;
|
||||
uint32_t num_thread_z = 0;
|
||||
uint8_t vgprs = 0;
|
||||
uint8_t sgprs = 0;
|
||||
uint8_t bulky = 0;
|
||||
uint8_t scratch_en = 0;
|
||||
uint8_t user_sgpr = 0;
|
||||
uint8_t tgid_x_en = 0;
|
||||
uint8_t tgid_y_en = 0;
|
||||
uint8_t tgid_z_en = 0;
|
||||
uint8_t tg_size_en = 0;
|
||||
uint8_t tidig_comp_cnt = 0;
|
||||
uint8_t lds_size = 0;
|
||||
};
|
||||
|
||||
enum class UserSgprType
|
||||
{
|
||||
Unknown,
|
||||
Region,
|
||||
Vsharp
|
||||
};
|
||||
|
||||
struct UserSgprInfo
|
||||
{
|
||||
uint32_t value[16] = {0};
|
||||
UserSgprType type[16] = {};
|
||||
uint32_t count = 0;
|
||||
};
|
||||
|
||||
struct VertexShaderInfo
|
||||
{
|
||||
VsStageRegisters vs_regs;
|
||||
uint32_t vs_shader_modifier = 0;
|
||||
uint32_t vs_embedded_id = 0;
|
||||
UserSgprInfo vs_user_sgpr;
|
||||
bool vs_embedded = false;
|
||||
};
|
||||
|
||||
struct PixelShaderInfo
|
||||
{
|
||||
PsStageRegisters ps_regs;
|
||||
uint32_t ps_interpolator_settings[32] = {0};
|
||||
uint32_t ps_input_num = 0;
|
||||
UserSgprInfo ps_user_sgpr;
|
||||
};
|
||||
|
||||
struct ComputeShaderInfo
|
||||
{
|
||||
CsStageRegisters cs_regs;
|
||||
uint32_t cs_shader_modifier = 0;
|
||||
UserSgprInfo cs_user_sgpr;
|
||||
};
|
||||
|
||||
class HardwareContext
|
||||
{
|
||||
public:
|
||||
HardwareContext() = default;
|
||||
virtual ~HardwareContext() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(HardwareContext);
|
||||
|
||||
void Reset() { *this = HardwareContext(); }
|
||||
|
||||
void SetRenderTarget(uint32_t slot, const RenderTarget& target) { m_render_targets[slot] = target; }
|
||||
[[nodiscard]] const RenderTarget& GetRenderTargets(uint32_t slot) const { return m_render_targets[slot]; }
|
||||
|
||||
void SetBlendControl(uint32_t slot, const BlendControl& control) { m_blend_control[slot] = control; }
|
||||
[[nodiscard]] const BlendControl& GetBlendControl(uint32_t slot) const { return m_blend_control[slot]; }
|
||||
|
||||
void SetRenderTargetMask(uint32_t mask) { m_render_target_mask = mask; }
|
||||
[[nodiscard]] uint32_t GetRenderTargetMask() const { return m_render_target_mask; }
|
||||
|
||||
void SetShaderStages(uint32_t flags) { m_shader_stages = flags; }
|
||||
[[nodiscard]] uint32_t GetShaderStages() const { return m_shader_stages; }
|
||||
|
||||
void SetDepthRenderTarget(const DepthRenderTarget& target) { m_depth_render_target = target; }
|
||||
[[nodiscard]] const DepthRenderTarget& GetDepthRenderTarget() const { return m_depth_render_target; }
|
||||
void SetDepthRenderTargetZInfo(const DepthRenderTargetZInfo& info) { m_depth_render_target.z_info = info; }
|
||||
[[nodiscard]] const DepthRenderTargetZInfo& GetDepthRenderTargetZInfo() const { return m_depth_render_target.z_info; }
|
||||
void SetDepthRenderTargetStencilInfo(const DepthRenderTargetStencilInfo& info) { m_depth_render_target.stencil_info = info; }
|
||||
[[nodiscard]] const DepthRenderTargetStencilInfo& GetDepthRenderTargetStencilInfo() const { return m_depth_render_target.stencil_info; }
|
||||
|
||||
void SetViewportZ(uint32_t viewport_id, float zmin, float zmax)
|
||||
{
|
||||
m_screen_viewport.viewports[viewport_id].zmin = zmin;
|
||||
m_screen_viewport.viewports[viewport_id].zmax = zmax;
|
||||
}
|
||||
void SetViewportScaleOffset(uint32_t viewport_id, float xscale, float xoffset, float yscale, float yoffset, float zscale, float zoffset)
|
||||
{
|
||||
m_screen_viewport.viewports[viewport_id].xscale = xscale;
|
||||
m_screen_viewport.viewports[viewport_id].xoffset = xoffset;
|
||||
m_screen_viewport.viewports[viewport_id].yscale = yscale;
|
||||
m_screen_viewport.viewports[viewport_id].yoffset = yoffset;
|
||||
m_screen_viewport.viewports[viewport_id].zscale = zscale;
|
||||
m_screen_viewport.viewports[viewport_id].zoffset = zoffset;
|
||||
}
|
||||
void SetViewportTransformControl(uint32_t control) { m_screen_viewport.transform_control = control; }
|
||||
void SetScreenScissor(int left, int top, int right, int bottom)
|
||||
{
|
||||
m_screen_viewport.scissor_left = left;
|
||||
m_screen_viewport.scissor_top = top;
|
||||
m_screen_viewport.scissor_right = right;
|
||||
m_screen_viewport.scissor_bottom = bottom;
|
||||
}
|
||||
void SetHardwareScreenOffset(uint32_t offset_x, uint32_t offset_y)
|
||||
{
|
||||
m_screen_viewport.hw_offset_x = offset_x;
|
||||
m_screen_viewport.hw_offset_y = offset_y;
|
||||
}
|
||||
void SetGuardBands(float horz_clip, float vert_clip, float horz_discard, float vert_discard)
|
||||
{
|
||||
m_screen_viewport.guard_band_horz_clip = horz_clip;
|
||||
m_screen_viewport.guard_band_vert_clip = vert_clip;
|
||||
m_screen_viewport.guard_band_horz_discard = horz_discard;
|
||||
m_screen_viewport.guard_band_vert_discard = vert_discard;
|
||||
}
|
||||
[[nodiscard]] const ScreenViewport& GetScreenViewport() const { return m_screen_viewport; }
|
||||
|
||||
void SetVsShader(const VsStageRegisters* vs_regs, uint32_t shader_modifier)
|
||||
{
|
||||
m_vs.vs_regs = *vs_regs;
|
||||
m_vs.vs_shader_modifier = shader_modifier;
|
||||
m_vs.vs_embedded = false;
|
||||
}
|
||||
void SetVsEmbedded(uint32_t id, uint32_t shader_modifier)
|
||||
{
|
||||
m_vs.vs_embedded_id = id;
|
||||
m_vs.vs_shader_modifier = shader_modifier;
|
||||
m_vs.vs_embedded = true;
|
||||
}
|
||||
|
||||
void SetPsShader(const PsStageRegisters* ps_regs) { m_ps.ps_regs = *ps_regs; }
|
||||
|
||||
void SetCsShader(const CsStageRegisters* cs_regs, uint32_t shader_modifier)
|
||||
{
|
||||
m_cs.cs_regs = *cs_regs;
|
||||
m_cs.cs_shader_modifier = shader_modifier;
|
||||
}
|
||||
|
||||
[[nodiscard]] const ClipControl& GetClipControl() const { return m_clip_control; }
|
||||
void SetClipControl(const ClipControl& control) { m_clip_control = control; }
|
||||
[[nodiscard]] const RenderControl& GetRenderControl() const { return m_render_control; }
|
||||
void SetRenderControl(const RenderControl& control) { m_render_control = control; }
|
||||
[[nodiscard]] const DepthControl& GetDepthControl() const { return m_depth_control; }
|
||||
void SetDepthControl(const DepthControl& control) { m_depth_control = control; }
|
||||
[[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; }
|
||||
void SetModeControl(const ModeControl& control) { m_mode_control = control; }
|
||||
|
||||
void SetVsUserSgpr(uint32_t id, uint32_t value, UserSgprType type)
|
||||
{
|
||||
m_vs.vs_user_sgpr.value[id] = value;
|
||||
m_vs.vs_user_sgpr.type[id] = type;
|
||||
m_vs.vs_user_sgpr.count = ((id + 1) > m_vs.vs_user_sgpr.count ? (id + 1) : m_vs.vs_user_sgpr.count);
|
||||
}
|
||||
void SetPsUserSgpr(uint32_t id, uint32_t value, UserSgprType type)
|
||||
{
|
||||
m_ps.ps_user_sgpr.value[id] = value;
|
||||
m_ps.ps_user_sgpr.type[id] = type;
|
||||
m_ps.ps_user_sgpr.count = ((id + 1) > m_ps.ps_user_sgpr.count ? (id + 1) : m_ps.ps_user_sgpr.count);
|
||||
}
|
||||
void SetCsUserSgpr(uint32_t id, uint32_t value, UserSgprType type)
|
||||
{
|
||||
m_cs.cs_user_sgpr.value[id] = value;
|
||||
m_cs.cs_user_sgpr.type[id] = type;
|
||||
m_cs.cs_user_sgpr.count = ((id + 1) > m_cs.cs_user_sgpr.count ? (id + 1) : m_cs.cs_user_sgpr.count);
|
||||
}
|
||||
void SetPsInputSettings(uint32_t id, uint32_t value)
|
||||
{
|
||||
m_ps.ps_interpolator_settings[id] = value;
|
||||
m_ps.ps_input_num = ((id + 1) > m_ps.ps_input_num ? (id + 1) : m_ps.ps_input_num);
|
||||
}
|
||||
|
||||
[[nodiscard]] const PixelShaderInfo& GetPs() const { return m_ps; }
|
||||
[[nodiscard]] const VertexShaderInfo& GetVs() const { return m_vs; }
|
||||
[[nodiscard]] const ComputeShaderInfo& GetCs() const { return m_cs; }
|
||||
|
||||
[[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; }
|
||||
void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; }
|
||||
|
||||
private:
|
||||
BlendControl m_blend_control[8];
|
||||
RenderTarget m_render_targets[8];
|
||||
uint32_t m_render_target_mask = 0;
|
||||
ScreenViewport m_screen_viewport;
|
||||
ClipControl m_clip_control;
|
||||
|
||||
VertexShaderInfo m_vs;
|
||||
PixelShaderInfo m_ps;
|
||||
ComputeShaderInfo m_cs;
|
||||
uint32_t m_shader_stages = 0;
|
||||
|
||||
DepthRenderTarget m_depth_render_target;
|
||||
RenderControl m_render_control;
|
||||
DepthControl m_depth_control;
|
||||
float m_depth_clear_value = 0.0f;
|
||||
|
||||
ModeControl m_mode_control;
|
||||
};
|
||||
|
||||
class UserConfig
|
||||
{
|
||||
public:
|
||||
UserConfig() = default;
|
||||
virtual ~UserConfig() = default;
|
||||
|
||||
KYTY_CLASS_DEFAULT_COPY(UserConfig);
|
||||
|
||||
void Reset() { *this = UserConfig(); }
|
||||
|
||||
void SetPrimitiveType(uint32_t prim_type) { m_prim_type = prim_type; }
|
||||
[[nodiscard]] uint32_t GetPrimType() const { return m_prim_type; }
|
||||
|
||||
private:
|
||||
uint32_t m_prim_type = 0;
|
||||
};
|
||||
|
||||
inline uint64_t VsStageRegisters::GetGpuAddress() const
|
||||
{
|
||||
return (static_cast<uint64_t>(m_spiShaderPgmLoVs) << 8u) | (static_cast<uint64_t>(m_spiShaderPgmHiVs) << 40u);
|
||||
}
|
||||
|
||||
inline bool VsStageRegisters::GetStreamoutEnabled() const
|
||||
{
|
||||
return (m_spiShaderPgmRsrc2Vs & 0x00001000u) != 0u;
|
||||
}
|
||||
|
||||
inline uint32_t VsStageRegisters::GetSgprCount() const
|
||||
{
|
||||
return (m_spiShaderPgmRsrc1Vs >> 6u) & 0xfu;
|
||||
}
|
||||
|
||||
inline uint32_t VsStageRegisters::GetInputComponentsCount() const
|
||||
{
|
||||
return (m_spiShaderPgmRsrc1Vs >> 24u) & 0x3u;
|
||||
}
|
||||
|
||||
inline uint32_t VsStageRegisters::GetUnknown1() const
|
||||
{
|
||||
return m_spiShaderPgmRsrc1Vs & 0xfcfffc3fu;
|
||||
}
|
||||
|
||||
inline uint32_t VsStageRegisters::GetUnknown2() const
|
||||
{
|
||||
return m_spiShaderPgmRsrc2Vs & 0xFFFFEFFFu;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_ */
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_INDEXBUFFER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_INDEXBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class IndexBufferGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
IndexBufferGpuObject()
|
||||
{
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::IndexBuffer;
|
||||
}
|
||||
|
||||
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_INDEXBUFFER_H_ */
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct Label;
|
||||
struct GraphicContext;
|
||||
class CommandBuffer;
|
||||
struct VulkanMemory;
|
||||
|
||||
void LabelInit();
|
||||
|
||||
class LabelGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
using callback_t = bool (*)(const uint64_t* args);
|
||||
|
||||
static constexpr int PARAM_VALUE = 0;
|
||||
static constexpr int PARAM_CALLBACK_1 = 1;
|
||||
static constexpr int PARAM_CALLBACK_2 = 2;
|
||||
static constexpr int PARAM_ARG_1 = 3;
|
||||
static constexpr int PARAM_ARG_2 = 4;
|
||||
static constexpr int PARAM_ARG_3 = 5;
|
||||
static constexpr int PARAM_ARG_4 = 6;
|
||||
|
||||
explicit LabelGpuObject(uint64_t value, callback_t callback_1, callback_t callback_2, const uint64_t* args = nullptr)
|
||||
{
|
||||
params[PARAM_VALUE] = value;
|
||||
params[PARAM_CALLBACK_1] = reinterpret_cast<uint64_t>(callback_1);
|
||||
params[PARAM_CALLBACK_2] = reinterpret_cast<uint64_t>(callback_2);
|
||||
if (args != nullptr)
|
||||
{
|
||||
params[PARAM_ARG_1] = args[0];
|
||||
params[PARAM_ARG_2] = args[1];
|
||||
params[PARAM_ARG_3] = args[2];
|
||||
params[PARAM_ARG_4] = args[3];
|
||||
}
|
||||
check_hash = false;
|
||||
type = Graphics::GpuMemoryObjectType::Label;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
void LabelSet(CommandBuffer* buffer, Label* label);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_LABEL_H_ */
|
||||
@@ -0,0 +1,315 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_PM4_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_PM4_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Core {
|
||||
class File;
|
||||
} // namespace Kyty::Core
|
||||
|
||||
#define KYTY_PM4_GET(u, r, f) (((u) >> Pm4::r##_##f##_SHIFT) & Pm4::r##_##f##_MASK)
|
||||
|
||||
#define KYTY_PM4(len, op, r) \
|
||||
(0xC0000000u | (((static_cast<uint16_t>(len) - 2u) & 0x3fffu) << 16u) | (((op)&0xffu) << 8u) | (((r)&0x3fu) << 2u))
|
||||
|
||||
namespace Kyty::Libs::Graphics::Pm4 {
|
||||
|
||||
constexpr uint32_t IT_NOP = 0x10;
|
||||
constexpr uint32_t IT_SET_BASE = 0x11;
|
||||
constexpr uint32_t IT_CLEAR_STATE = 0x12;
|
||||
constexpr uint32_t IT_INDEX_BUFFER_SIZE = 0x13;
|
||||
constexpr uint32_t IT_DISPATCH_DIRECT = 0x15;
|
||||
constexpr uint32_t IT_DISPATCH_INDIRECT = 0x16;
|
||||
constexpr uint32_t IT_SET_PREDICATION = 0x20;
|
||||
constexpr uint32_t IT_COND_EXEC = 0x22;
|
||||
constexpr uint32_t IT_DRAW_INDIRECT = 0x24;
|
||||
constexpr uint32_t IT_DRAW_INDEX_INDIRECT = 0x25;
|
||||
constexpr uint32_t IT_INDEX_BASE = 0x26;
|
||||
constexpr uint32_t IT_DRAW_INDEX_2 = 0x27;
|
||||
constexpr uint32_t IT_CONTEXT_CONTROL = 0x28;
|
||||
constexpr uint32_t IT_INDEX_TYPE = 0x2A;
|
||||
constexpr uint32_t IT_DRAW_INDIRECT_MULTI = 0x2C;
|
||||
constexpr uint32_t IT_DRAW_INDEX_AUTO = 0x2D;
|
||||
constexpr uint32_t IT_NUM_INSTANCES = 0x2F;
|
||||
constexpr uint32_t IT_INDIRECT_BUFFER_CNST = 0x33;
|
||||
constexpr uint32_t IT_DRAW_INDEX_OFFSET_2 = 0x35;
|
||||
constexpr uint32_t IT_WRITE_DATA = 0x37;
|
||||
constexpr uint32_t IT_MEM_SEMAPHORE = 0x39;
|
||||
constexpr uint32_t IT_DRAW_INDEX_INDIRECT_MULTI = 0x38;
|
||||
constexpr uint32_t IT_WAIT_REG_MEM = 0x3C;
|
||||
constexpr uint32_t IT_INDIRECT_BUFFER = 0x3F;
|
||||
constexpr uint32_t IT_COPY_DATA = 0x40;
|
||||
constexpr uint32_t IT_CP_DMA = 0x41;
|
||||
constexpr uint32_t IT_PFP_SYNC_ME = 0x42;
|
||||
constexpr uint32_t IT_SURFACE_SYNC = 0x43;
|
||||
constexpr uint32_t IT_EVENT_WRITE = 0x46;
|
||||
constexpr uint32_t IT_EVENT_WRITE_EOP = 0x47;
|
||||
constexpr uint32_t IT_EVENT_WRITE_EOS = 0x48;
|
||||
constexpr uint32_t IT_RELEASE_MEM = 0x49;
|
||||
constexpr uint32_t IT_DMA_DATA = 0x50;
|
||||
constexpr uint32_t IT_ACQUIRE_MEM = 0x58;
|
||||
constexpr uint32_t IT_REWIND = 0x59;
|
||||
constexpr uint32_t IT_SET_CONFIG_REG = 0x68;
|
||||
constexpr uint32_t IT_SET_CONTEXT_REG = 0x69;
|
||||
constexpr uint32_t IT_SET_SH_REG = 0x76;
|
||||
constexpr uint32_t IT_SET_QUEUE_REG = 0x78;
|
||||
constexpr uint32_t IT_SET_UCONFIG_REG = 0x79;
|
||||
constexpr uint32_t IT_WRITE_CONST_RAM = 0x81;
|
||||
constexpr uint32_t IT_DUMP_CONST_RAM = 0x83;
|
||||
constexpr uint32_t IT_INCREMENT_CE_COUNTER = 0x84;
|
||||
constexpr uint32_t IT_INCREMENT_DE_COUNTER = 0x85;
|
||||
constexpr uint32_t IT_WAIT_ON_CE_COUNTER = 0x86;
|
||||
constexpr uint32_t IT_WAIT_ON_DE_COUNTER_DIFF = 0x88;
|
||||
constexpr uint32_t IT_DISPATCH_DRAW_PREAMBLE = 0x8C;
|
||||
constexpr uint32_t IT_DISPATCH_DRAW = 0x8D;
|
||||
|
||||
constexpr uint32_t R_ZERO = 0x00;
|
||||
constexpr uint32_t R_VS = 0x01;
|
||||
constexpr uint32_t R_PS = 0x02;
|
||||
constexpr uint32_t R_DRAW_INDEX = 0x03;
|
||||
constexpr uint32_t R_DRAW_INDEX_AUTO = 0x04;
|
||||
constexpr uint32_t R_DRAW_RESET = 0x05;
|
||||
constexpr uint32_t R_WAIT_FLIP_DONE = 0x06;
|
||||
constexpr uint32_t R_CS = 0x07;
|
||||
constexpr uint32_t R_DISPATCH_DIRECT = 0x08;
|
||||
constexpr uint32_t R_DISPATCH_RESET = 0x09;
|
||||
constexpr uint32_t R_DISPATCH_WAIT_MEM = 0x0A;
|
||||
constexpr uint32_t R_PUSH_MARKER = 0x0B;
|
||||
constexpr uint32_t R_POP_MARKER = 0x0C;
|
||||
constexpr uint32_t R_VS_EMBEDDED = 0x0D;
|
||||
|
||||
constexpr uint32_t DB_RENDER_CONTROL = 0x0;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_SHIFT = 0;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_CLEAR_ENABLE_SHIFT = 1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_CLEAR_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_RESUMMARIZE_ENABLE_SHIFT = 4;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_RESUMMARIZE_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_COMPRESS_DISABLE_SHIFT = 5;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_STENCIL_COMPRESS_DISABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_DEPTH_COMPRESS_DISABLE_SHIFT = 6;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_DEPTH_COMPRESS_DISABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_COPY_CENTROID_SHIFT = 7;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_COPY_CENTROID_MASK = 0x1;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_COPY_SAMPLE_SHIFT = 8;
|
||||
constexpr uint32_t DB_RENDER_CONTROL_COPY_SAMPLE_MASK = 0xF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_VIEW = 0x2;
|
||||
constexpr uint32_t DB_DEPTH_VIEW_SLICE_START_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_VIEW_SLICE_START_MASK = 0x7FF;
|
||||
constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_SHIFT = 13;
|
||||
constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_MASK = 0x7FF;
|
||||
|
||||
constexpr uint32_t DB_HTILE_DATA_BASE = 0x5;
|
||||
constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_CLEAR = 0xB;
|
||||
constexpr uint32_t DB_DEPTH_CLEAR_DEPTH_CLEAR_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_CLEAR_DEPTH_CLEAR_MASK = 0xFFFFFFFF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_INFO = 0xF;
|
||||
constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_MASK = 0xF;
|
||||
constexpr uint32_t DB_DEPTH_INFO_ARRAY_MODE_SHIFT = 4;
|
||||
constexpr uint32_t DB_DEPTH_INFO_ARRAY_MODE_MASK = 0xF;
|
||||
constexpr uint32_t DB_DEPTH_INFO_PIPE_CONFIG_SHIFT = 8;
|
||||
constexpr uint32_t DB_DEPTH_INFO_PIPE_CONFIG_MASK = 0x1F;
|
||||
constexpr uint32_t DB_DEPTH_INFO_BANK_WIDTH_SHIFT = 13;
|
||||
constexpr uint32_t DB_DEPTH_INFO_BANK_WIDTH_MASK = 0x3;
|
||||
constexpr uint32_t DB_DEPTH_INFO_BANK_HEIGHT_SHIFT = 15;
|
||||
constexpr uint32_t DB_DEPTH_INFO_BANK_HEIGHT_MASK = 0x3;
|
||||
constexpr uint32_t DB_DEPTH_INFO_MACRO_TILE_ASPECT_SHIFT = 17;
|
||||
constexpr uint32_t DB_DEPTH_INFO_MACRO_TILE_ASPECT_MASK = 0x3;
|
||||
constexpr uint32_t DB_DEPTH_INFO_NUM_BANKS_SHIFT = 19;
|
||||
constexpr uint32_t DB_DEPTH_INFO_NUM_BANKS_MASK = 0x3;
|
||||
|
||||
constexpr uint32_t DB_Z_INFO = 0x10;
|
||||
constexpr uint32_t DB_Z_INFO_FORMAT_SHIFT = 0;
|
||||
constexpr uint32_t DB_Z_INFO_FORMAT_MASK = 0x3;
|
||||
constexpr uint32_t DB_Z_INFO_NUM_SAMPLES_SHIFT = 2;
|
||||
constexpr uint32_t DB_Z_INFO_NUM_SAMPLES_MASK = 0x3;
|
||||
constexpr uint32_t DB_Z_INFO_TILE_MODE_INDEX_SHIFT = 20;
|
||||
constexpr uint32_t DB_Z_INFO_TILE_MODE_INDEX_MASK = 0x7;
|
||||
constexpr uint32_t DB_Z_INFO_TILE_SURFACE_ENABLE_SHIFT = 29;
|
||||
constexpr uint32_t DB_Z_INFO_TILE_SURFACE_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_Z_INFO_ZRANGE_PRECISION_SHIFT = 31;
|
||||
constexpr uint32_t DB_Z_INFO_ZRANGE_PRECISION_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t DB_STENCIL_INFO = 0x11;
|
||||
constexpr uint32_t DB_STENCIL_INFO_FORMAT_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCIL_INFO_FORMAT_MASK = 0x1;
|
||||
constexpr uint32_t DB_STENCIL_INFO_TILE_MODE_INDEX_SHIFT = 20;
|
||||
constexpr uint32_t DB_STENCIL_INFO_TILE_MODE_INDEX_MASK = 0x7;
|
||||
constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_SHIFT = 29;
|
||||
constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t DB_Z_READ_BASE = 0x12;
|
||||
constexpr uint32_t DB_Z_READ_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_Z_READ_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
constexpr uint32_t DB_STENCIL_READ_BASE = 0x13;
|
||||
constexpr uint32_t DB_STENCIL_READ_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCIL_READ_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
constexpr uint32_t DB_Z_WRITE_BASE = 0x14;
|
||||
constexpr uint32_t DB_Z_WRITE_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_Z_WRITE_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15;
|
||||
constexpr uint32_t DB_STENCIL_WRITE_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCIL_WRITE_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_SIZE = 0x16;
|
||||
constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_MASK = 0x7FF;
|
||||
constexpr uint32_t DB_DEPTH_SIZE_HEIGHT_TILE_MAX_SHIFT = 11;
|
||||
constexpr uint32_t DB_DEPTH_SIZE_HEIGHT_TILE_MAX_MASK = 0x7FF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_SLICE = 0x17;
|
||||
constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_MASK = 0x3FFFFF;
|
||||
|
||||
constexpr uint32_t PA_SC_VPORT_ZMIN_0 = 0xB4;
|
||||
|
||||
constexpr uint32_t PA_CL_VPORT_XSCALE = 0x10F;
|
||||
|
||||
constexpr uint32_t SPI_PS_INPUT_CNTL_0 = 0x191;
|
||||
|
||||
constexpr uint32_t CB_BLEND0_CONTROL = 0x1E0;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT = 0;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_MASK = 0x1F;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_COMB_FCN_SHIFT = 5;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_COMB_FCN_MASK = 0x7;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_DESTBLEND_SHIFT = 8;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_DESTBLEND_MASK = 0x1F;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_SRCBLEND_SHIFT = 16;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_SRCBLEND_MASK = 0x1F;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_COMB_FCN_SHIFT = 21;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_COMB_FCN_MASK = 0x7;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_DESTBLEND_SHIFT = 24;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ALPHA_DESTBLEND_MASK = 0x1F;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_SHIFT = 29;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_MASK = 0x1;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ENABLE_SHIFT = 30;
|
||||
constexpr uint32_t CB_BLEND0_CONTROL_ENABLE_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_CONTROL = 0x200;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCIL_ENABLE_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCIL_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_Z_ENABLE_SHIFT = 1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_Z_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_Z_WRITE_ENABLE_SHIFT = 2;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_Z_WRITE_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_DEPTH_BOUNDS_ENABLE_SHIFT = 3;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_DEPTH_BOUNDS_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_ZFUNC_SHIFT = 4;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_ZFUNC_MASK = 0x7;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_BACKFACE_ENABLE_SHIFT = 7;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_BACKFACE_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_SHIFT = 8;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_MASK = 0x7;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_BF_SHIFT = 20;
|
||||
constexpr uint32_t DB_DEPTH_CONTROL_STENCILFUNC_BF_MASK = 0x7;
|
||||
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL = 0x205;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_FRONT_SHIFT = 0;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_FRONT_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_BACK_SHIFT = 1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_BACK_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_FACE_SHIFT = 2;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_FACE_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_MODE_SHIFT = 3;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_MODE_MASK = 0x3;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLYMODE_FRONT_PTYPE_SHIFT = 5;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLYMODE_FRONT_PTYPE_MASK = 0x7;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLYMODE_BACK_PTYPE_SHIFT = 8;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLYMODE_BACK_PTYPE_MASK = 0x7;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE_SHIFT = 11;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE_SHIFT = 12;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE_SHIFT = 16;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST_SHIFT = 19;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST_MASK = 0x1;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS_SHIFT = 20;
|
||||
constexpr uint32_t PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t DB_HTILE_SURFACE = 0x2AF;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_LINEAR_SHIFT = 0;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_LINEAR_MASK = 0x1;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_FULL_CACHE_SHIFT = 1;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_FULL_CACHE_MASK = 0x1;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_HTILE_USES_PRELOAD_WIN_SHIFT = 2;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_HTILE_USES_PRELOAD_WIN_MASK = 0x1;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PRELOAD_SHIFT = 3;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PRELOAD_MASK = 0x1;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_WIDTH_SHIFT = 4;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_WIDTH_MASK = 0x3F;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_HEIGHT_SHIFT = 10;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_HEIGHT_MASK = 0x3F;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_SHIFT = 16;
|
||||
constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t VGT_SHADER_STAGES_EN = 0x2D5;
|
||||
|
||||
constexpr uint32_t CB_COLOR0_BASE = 0x318;
|
||||
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS = 0xA;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT = 0;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK = 0x3F;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT = 6;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK = 0xF;
|
||||
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS = 0xB;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_SHIFT = 0;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_MASK = 0x1;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_SHIFT = 1;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK = 0x1F;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT = 7;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK = 0x0;
|
||||
|
||||
constexpr uint32_t SPI_SHADER_USER_DATA_PS_0 = 0xC;
|
||||
constexpr uint32_t SPI_SHADER_USER_DATA_PS_15 = 0x1B;
|
||||
|
||||
constexpr uint32_t SPI_SHADER_USER_DATA_VS_0 = 0x4C;
|
||||
constexpr uint32_t SPI_SHADER_USER_DATA_VS_15 = 0x5B;
|
||||
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1 = 0x212;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_VGPRS_SHIFT = 0;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_VGPRS_MASK = 0x3F;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_SGPRS_SHIFT = 6;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_SGPRS_MASK = 0xF;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_BULKY_SHIFT = 24;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC1_BULKY_MASK = 0x1;
|
||||
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2 = 0x213;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_SCRATCH_EN_SHIFT = 0;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_SCRATCH_EN_MASK = 0x1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_USER_SGPR_SHIFT = 1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_USER_SGPR_MASK = 0x1F;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_X_EN_SHIFT = 7;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_X_EN_MASK = 0x1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_Y_EN_SHIFT = 8;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_Y_EN_MASK = 0x1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_Z_EN_SHIFT = 9;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TGID_Z_EN_MASK = 0x1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TG_SIZE_EN_SHIFT = 10;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TG_SIZE_EN_MASK = 0x1;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TIDIG_COMP_CNT_SHIFT = 11;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_TIDIG_COMP_CNT_MASK = 0x3;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_SHIFT = 15;
|
||||
constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_MASK = 0x1FF;
|
||||
|
||||
constexpr uint32_t COMPUTE_USER_DATA_0 = 0x240;
|
||||
constexpr uint32_t COMPUTE_USER_DATA_15 = 0x24F;
|
||||
|
||||
void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_dw, uint32_t num_dw);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics::Pm4
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_PM4_H_ */
|
||||
@@ -0,0 +1,554 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct VertexShaderInfo;
|
||||
struct PixelShaderInfo;
|
||||
struct ComputeShaderInfo;
|
||||
|
||||
enum class ShaderType
|
||||
{
|
||||
Unknown,
|
||||
Vertex,
|
||||
Pixel,
|
||||
Fetch,
|
||||
Compute
|
||||
};
|
||||
|
||||
enum class ShaderInstructionType
|
||||
{
|
||||
Unknown,
|
||||
DsAppend,
|
||||
DsConsume,
|
||||
Exp,
|
||||
BufferLoadDword,
|
||||
BufferLoadFormatX,
|
||||
BufferLoadFormatXy,
|
||||
BufferLoadFormatXyz,
|
||||
BufferLoadFormatXyzw,
|
||||
BufferStoreDword,
|
||||
BufferStoreFormatX,
|
||||
ImageSample,
|
||||
TBufferLoadFormatXyzw,
|
||||
SAndn2B64,
|
||||
SAndSaveexecB64,
|
||||
SEndpgm,
|
||||
SCbranchExecz,
|
||||
SLshlB32,
|
||||
SLoadDwordx4,
|
||||
SLoadDwordx8,
|
||||
SBufferLoadDword,
|
||||
SBufferLoadDwordx4,
|
||||
SBufferLoadDwordx8,
|
||||
SBufferLoadDwordx16,
|
||||
SMovB32,
|
||||
SMovB64,
|
||||
SSetpcB64,
|
||||
SSwappcB64,
|
||||
SWaitcnt,
|
||||
SWqmB64,
|
||||
VAddI32,
|
||||
VAndB32,
|
||||
VCmpEqF32,
|
||||
VCmpEqU32,
|
||||
VCmpLeF32,
|
||||
VCmpLeU32,
|
||||
VCmpNeU32,
|
||||
VCmpNeqF32,
|
||||
VCmpxEqU32,
|
||||
VCmpxGtU32,
|
||||
VCndmaskB32,
|
||||
VCvtF32U32,
|
||||
VCvtPkrtzF16F32,
|
||||
VCvtU32F32,
|
||||
VMacF32,
|
||||
VMadakF32,
|
||||
VMadF32,
|
||||
VMaxF32,
|
||||
VMbcntHiU32B32,
|
||||
VMbcntLoU32B32,
|
||||
VMinF32,
|
||||
VMovB32,
|
||||
VMulF32,
|
||||
VInterpP1F32,
|
||||
VInterpP2F32,
|
||||
VRcpF32,
|
||||
VRsqF32,
|
||||
VSadU32,
|
||||
VSqrtF32,
|
||||
VSubF32,
|
||||
VSubI32,
|
||||
VSubrevF32,
|
||||
VSubrevI32,
|
||||
};
|
||||
|
||||
namespace ShaderInstructionFormat {
|
||||
|
||||
enum FormatByte : uint64_t
|
||||
{
|
||||
U = 0,
|
||||
N,
|
||||
D, // operand_to_str(inst.dst)
|
||||
D2, // operand_to_str(inst.dst2)
|
||||
S0, // operand_to_str(inst.src[0])
|
||||
S1, // operand_to_str(inst.src[1])
|
||||
S2, // operand_to_str(inst.src[2])
|
||||
S3, // operand_to_str(inst.src[3])
|
||||
DA2, // operand_array_to_str(inst.dst, 2)
|
||||
DA3, // operand_array_to_str(inst.dst, 3)
|
||||
DA4, // operand_array_to_str(inst.dst, 4)
|
||||
DA8, // operand_array_to_str(inst.dst, 8)
|
||||
DA16, // operand_array_to_str(inst.dst, 16)
|
||||
D2A2, // operand_array_to_str(inst.dst2, 2)
|
||||
D2A3, // operand_array_to_str(inst.dst2, 3)
|
||||
D2A4, // operand_array_to_str(inst.dst2, 4)
|
||||
S0A2, // operand_array_to_str(inst.src[0], 2)
|
||||
S0A3, // operand_array_to_str(inst.src[0], 3)
|
||||
S0A4, // operand_array_to_str(inst.src[0], 4)
|
||||
S1A2, // operand_array_to_str(inst.src[1], 2)
|
||||
S1A3, // operand_array_to_str(inst.src[1], 3)
|
||||
S1A4, // operand_array_to_str(inst.src[1], 4)
|
||||
S1A8, // operand_array_to_str(inst.src[1], 8)
|
||||
S2A2, // operand_array_to_str(inst.src[2], 2)
|
||||
S2A3, // operand_array_to_str(inst.src[2], 3)
|
||||
S2A4, // operand_array_to_str(inst.src[2], 4)
|
||||
Attr, // attr%u.%u <- inst.src[1].constant.u, inst.src[2].constant.u
|
||||
Idxen, // idxen
|
||||
Float4, // format:float4
|
||||
Pos0, // pos0
|
||||
Done, // done
|
||||
Param0, // param0
|
||||
Param1, // param1
|
||||
Param2, // param2
|
||||
Param3, // param3
|
||||
Mrt0, // mrt_color0
|
||||
Compr, // compr
|
||||
Vm, // vm
|
||||
L, // label_%u
|
||||
DmaskF, // dmask:0xf
|
||||
Dmask7, // dmask:0x7
|
||||
Gds, // gds
|
||||
};
|
||||
|
||||
constexpr uint64_t FormatDefine(std::initializer_list<uint64_t> f)
|
||||
{
|
||||
uint64_t r = 0;
|
||||
for (auto n: f)
|
||||
{
|
||||
r = (r << 8u) | n;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
enum Format : uint64_t
|
||||
{
|
||||
Unknown = FormatDefine({U}),
|
||||
Empty = FormatDefine({N}),
|
||||
Imm = FormatDefine({S0}),
|
||||
Label = FormatDefine({L}),
|
||||
Mrt0Vsrc0Vsrc1ComprVmDone = FormatDefine({Mrt0, S0, S1, Compr, Vm, Done}),
|
||||
Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone = FormatDefine({Mrt0, S0, S1, S2, S3, Vm, Done}),
|
||||
Param0Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param0, S0, S1, S2, S3}),
|
||||
Param1Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param1, S0, S1, S2, S3}),
|
||||
Param2Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param2, S0, S1, S2, S3}),
|
||||
Param3Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param3, S0, S1, S2, S3}),
|
||||
Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done = FormatDefine({Pos0, S0, S1, S2, S3, Done}),
|
||||
Saddr = FormatDefine({S0A2}),
|
||||
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
||||
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
||||
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
||||
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
||||
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
||||
Sdst16SvSoffset = FormatDefine({DA16, S0A4, S1}),
|
||||
SVdstSVsrc0 = FormatDefine({D, S0}),
|
||||
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
||||
Sdst2Ssrc02 = FormatDefine({DA2, S0A2}),
|
||||
Sdst2Ssrc02Ssrc12 = FormatDefine({DA2, S0A2, S1A2}),
|
||||
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
||||
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||
VdstVsrc0Vsrc1Smask2 = FormatDefine({D, S0, S1, S2A2}),
|
||||
VdstVsrc0Vsrc1Vsrc2 = FormatDefine({D, S0, S1, S2}),
|
||||
VdstVsrcAttrChan = FormatDefine({D, S0, Attr}),
|
||||
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
||||
VdstGds = FormatDefine({D, Gds})
|
||||
};
|
||||
|
||||
} // namespace ShaderInstructionFormat
|
||||
|
||||
enum class ShaderOperandType
|
||||
{
|
||||
Unknown,
|
||||
LiteralConstant,
|
||||
IntegerInlineConstant,
|
||||
FloatInlineConstant,
|
||||
VccLo,
|
||||
VccHi,
|
||||
ExecLo,
|
||||
ExecHi,
|
||||
ExecZ,
|
||||
Vgpr,
|
||||
Sgpr,
|
||||
M0
|
||||
};
|
||||
|
||||
union ShaderConstant
|
||||
{
|
||||
int32_t i;
|
||||
uint32_t u;
|
||||
float f;
|
||||
};
|
||||
|
||||
struct ShaderOperand
|
||||
{
|
||||
ShaderOperandType type = ShaderOperandType::Unknown;
|
||||
ShaderConstant constant = {0};
|
||||
int register_id = 0;
|
||||
int size = 0;
|
||||
float multiplier = 1.0f;
|
||||
bool negate = false;
|
||||
bool clamp = false;
|
||||
|
||||
bool operator==(const ShaderOperand& other) const
|
||||
{
|
||||
return type == other.type && constant.u == other.constant.u && register_id == other.register_id && size == other.size;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShaderInstruction
|
||||
{
|
||||
uint32_t pc = 0;
|
||||
ShaderInstructionType type = ShaderInstructionType::Unknown;
|
||||
ShaderInstructionFormat::Format format = ShaderInstructionFormat::Unknown;
|
||||
ShaderOperand src[4];
|
||||
int src_num = 0;
|
||||
ShaderOperand dst;
|
||||
ShaderOperand dst2;
|
||||
};
|
||||
|
||||
class ShaderCode
|
||||
{
|
||||
public:
|
||||
ShaderCode() { m_instructions.Expand(128); };
|
||||
virtual ~ShaderCode() = default;
|
||||
KYTY_CLASS_DEFAULT_COPY(ShaderCode);
|
||||
|
||||
[[nodiscard]] const Vector<ShaderInstruction>& GetInstructions() const { return m_instructions; }
|
||||
Vector<ShaderInstruction>& GetInstructions() { return m_instructions; }
|
||||
[[nodiscard]] const Vector<uint32_t>& GetLabels() const { return m_labels; }
|
||||
Vector<uint32_t>& GetLabels() { return m_labels; }
|
||||
|
||||
[[nodiscard]] String DbgDump() const;
|
||||
|
||||
static String DbgInstructionToStr(const ShaderInstruction& inst);
|
||||
|
||||
[[nodiscard]] ShaderType GetType() const { return m_type; }
|
||||
void SetType(ShaderType type) { this->m_type = type; }
|
||||
|
||||
private:
|
||||
Vector<ShaderInstruction> m_instructions;
|
||||
Vector<uint32_t> m_labels;
|
||||
ShaderType m_type = ShaderType::Unknown;
|
||||
};
|
||||
|
||||
struct ShaderId
|
||||
{
|
||||
Vector<uint32_t> ids;
|
||||
|
||||
bool operator==(const ShaderId& other) const { return ids == other.ids; }
|
||||
bool operator!=(const ShaderId& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
struct ShaderBufferResource
|
||||
{
|
||||
uint32_t fields[4] = {0};
|
||||
|
||||
void UpdateAddress(uint64_t gpu_addr)
|
||||
{
|
||||
auto lo = static_cast<uint32_t>(gpu_addr & 0xffffffffu);
|
||||
auto hi = static_cast<uint32_t>(gpu_addr >> 32u);
|
||||
fields[0] = lo;
|
||||
fields[1] = (fields[1] & 0xfffff000u) | (hi & 0xfffu);
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t Base() const { return (fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0xFFFFFFFFFFFu; }
|
||||
[[nodiscard]] uint16_t Stride() const { return (fields[1] >> 16u) & 0x3FFFu; }
|
||||
[[nodiscard]] bool SwizzleEnabled() const { return ((fields[1] >> 31u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint32_t NumRecords() const { return fields[2]; }
|
||||
[[nodiscard]] uint8_t DstSelX() const { return (fields[3] >> 0u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelY() const { return (fields[3] >> 3u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelZ() const { return (fields[3] >> 6u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelW() const { return (fields[3] >> 9u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t Nfmt() const { return (fields[3] >> 12u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t Dfmt() const { return (fields[3] >> 15u) & 0xFu; }
|
||||
[[nodiscard]] bool AddTid() const { return ((fields[3] >> 23u) & 0x1u) == 1; }
|
||||
|
||||
[[nodiscard]] uint8_t MemoryType() const
|
||||
{
|
||||
return ((fields[1] >> 7u) & 0x60u) | ((fields[3] >> 25u) & 0x1cu) | ((fields[1] >> 14u) & 0x3u);
|
||||
}
|
||||
};
|
||||
|
||||
struct ShaderTextureResource
|
||||
{
|
||||
uint32_t fields[8] = {0};
|
||||
|
||||
void UpdateAddress(uint64_t gpu_addr)
|
||||
{
|
||||
auto lo = static_cast<uint32_t>(gpu_addr & 0xffffffffu);
|
||||
auto hi = static_cast<uint32_t>(gpu_addr >> 32u);
|
||||
fields[0] = lo;
|
||||
fields[1] = (fields[1] & 0xffffffc0u) | (hi & 0x3fu);
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t Base() const { return ((fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)) & 0x3FFFFFFFFFu) << 8u; }
|
||||
[[nodiscard]] uint16_t MinLod() const { return (fields[1] >> 8u) & 0xFFFu; }
|
||||
[[nodiscard]] uint8_t Dfmt() const { return (fields[1] >> 20u) & 0x3Fu; }
|
||||
[[nodiscard]] uint8_t Nfmt() const { return (fields[1] >> 26u) & 0xFu; }
|
||||
[[nodiscard]] uint16_t Width() const { return (fields[2] >> 0u) & 0x3FFFu; }
|
||||
[[nodiscard]] uint16_t Height() const { return (fields[2] >> 14u) & 0x3FFFu; }
|
||||
[[nodiscard]] uint8_t PerfMod() const { return (fields[2] >> 28u) & 0x7u; }
|
||||
[[nodiscard]] bool Interlaced() const { return ((fields[2] >> 31u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint8_t DstSelX() const { return (fields[3] >> 0u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelY() const { return (fields[3] >> 3u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelZ() const { return (fields[3] >> 6u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DstSelW() const { return (fields[3] >> 9u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t BaseLevel() const { return (fields[3] >> 12u) & 0xFu; }
|
||||
[[nodiscard]] uint8_t LastLevel() const { return (fields[3] >> 16u) & 0xFu; }
|
||||
[[nodiscard]] uint8_t TilingIdx() const { return (fields[3] >> 20u) & 0x1Fu; }
|
||||
[[nodiscard]] bool Pow2Pad() const { return ((fields[3] >> 25u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint8_t Type() const { return (fields[3] >> 28u) & 0xFu; }
|
||||
|
||||
[[nodiscard]] uint16_t Depth() const { return (fields[4] >> 0u) & 0x1FFFu; }
|
||||
[[nodiscard]] uint16_t Pitch() const { return (fields[4] >> 13u) & 0x3FFFu; }
|
||||
[[nodiscard]] uint16_t BaseArray() const { return (fields[5] >> 0u) & 0x1FFFu; }
|
||||
[[nodiscard]] uint16_t LastArray() const { return (fields[5] >> 13u) & 0x1FFFu; }
|
||||
[[nodiscard]] uint16_t MinLodWarn() const { return (fields[6] >> 0u) & 0xFFFu; }
|
||||
[[nodiscard]] uint8_t CounterBankId() const { return (fields[6] >> 12u) & 0xFFu; }
|
||||
[[nodiscard]] bool LodHdwCntEn() const { return ((fields[6] >> 20u) & 0x1u) == 1; }
|
||||
|
||||
[[nodiscard]] uint8_t MemoryType() const
|
||||
{
|
||||
return ((fields[1] >> 6u) & 0x3u) | ((fields[1] >> 30u) << 2u) | ((fields[3] & 0x04000000u) == 0 ? 0x60u : 0x10u);
|
||||
}
|
||||
};
|
||||
|
||||
struct ShaderSamplerResource
|
||||
{
|
||||
uint32_t fields[4] = {0};
|
||||
|
||||
void UpdateIndex(uint32_t index) { fields[0] = index; }
|
||||
|
||||
[[nodiscard]] uint8_t ClampX() const { return (fields[0] >> 0u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t ClampY() const { return (fields[0] >> 3u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t ClampZ() const { return (fields[0] >> 6u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t MaxAnisoRatio() const { return (fields[0] >> 9u) & 0x7u; }
|
||||
[[nodiscard]] uint8_t DepthCompareFunc() const { return (fields[0] >> 12u) & 0x7u; }
|
||||
[[nodiscard]] bool ForceUnormCoords() const { return ((fields[0] >> 15u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint8_t AnisoThreshold() const { return (fields[0] >> 16u) & 0x7u; }
|
||||
[[nodiscard]] bool McCoordTrunc() const { return ((fields[0] >> 19u) & 0x1u) == 1; }
|
||||
[[nodiscard]] bool ForceDegamma() const { return ((fields[0] >> 20u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint8_t AnisoBias() const { return (fields[0] >> 21u) & 0x3Fu; }
|
||||
[[nodiscard]] bool TruncCoord() const { return ((fields[0] >> 27u) & 0x1u) == 1; }
|
||||
[[nodiscard]] bool DisableCubeWrap() const { return ((fields[0] >> 28u) & 0x1u) == 1; }
|
||||
[[nodiscard]] uint8_t FilterMode() const { return (fields[0] >> 29u) & 0x3u; }
|
||||
[[nodiscard]] uint16_t MinLod() const { return (fields[1] >> 0u) & 0xFFFu; }
|
||||
[[nodiscard]] uint16_t MaxLod() const { return (fields[1] >> 12u) & 0xFFFu; }
|
||||
[[nodiscard]] uint8_t PerfMip() const { return (fields[1] >> 24u) & 0xFu; }
|
||||
[[nodiscard]] uint8_t PerfZ() const { return (fields[1] >> 28u) & 0xFu; }
|
||||
[[nodiscard]] uint16_t LodBias() const { return (fields[2] >> 0u) & 0x3FFFu; }
|
||||
[[nodiscard]] uint8_t LodBiasSec() const { return (fields[2] >> 14u) & 0x3Fu; }
|
||||
[[nodiscard]] uint8_t XyMagFilter() const { return (fields[2] >> 20u) & 0x3u; }
|
||||
[[nodiscard]] uint8_t XyMinFilter() const { return (fields[2] >> 22u) & 0x3u; }
|
||||
[[nodiscard]] uint8_t ZFilter() const { return (fields[2] >> 24u) & 0x3u; }
|
||||
[[nodiscard]] uint8_t MipFilter() const { return (fields[2] >> 26u) & 0x3u; }
|
||||
[[nodiscard]] uint16_t BorderColorPtr() const { return (fields[3] >> 0u) & 0xFFFu; }
|
||||
[[nodiscard]] uint8_t BorderColorType() const { return (fields[3] >> 30u) & 0x3u; }
|
||||
};
|
||||
|
||||
struct ShaderGdsResource
|
||||
{
|
||||
uint32_t field = 0;
|
||||
|
||||
[[nodiscard]] uint16_t Base() const { return (field >> 16u) & 0xFFFFu; }
|
||||
[[nodiscard]] uint16_t Size() const { return field & 0xFFFFu; }
|
||||
};
|
||||
|
||||
struct ShaderExtendedResource
|
||||
{
|
||||
uint32_t fields[2] = {0};
|
||||
|
||||
void UpdateAddress(uint64_t gpu_addr)
|
||||
{
|
||||
auto lo = static_cast<uint32_t>(gpu_addr & 0xffffffffu);
|
||||
auto hi = static_cast<uint32_t>(gpu_addr >> 32u);
|
||||
fields[0] = lo;
|
||||
fields[1] = hi;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t Base() const { return (fields[0] | (static_cast<uint64_t>(fields[1]) << 32u)); }
|
||||
};
|
||||
|
||||
struct ShaderVertexInputBuffer
|
||||
{
|
||||
static constexpr int ATTR_MAX = 16;
|
||||
|
||||
uint64_t addr = 0;
|
||||
uint32_t stride = 0;
|
||||
uint32_t num_records = 0;
|
||||
int attr_num = 0;
|
||||
int attr_indices[ATTR_MAX] = {0};
|
||||
uint32_t attr_offsets[ATTR_MAX] = {0};
|
||||
};
|
||||
|
||||
struct ShaderVertexDestination
|
||||
{
|
||||
int register_start = 0;
|
||||
int registers_num = 0;
|
||||
};
|
||||
|
||||
enum class ShaderStorageUsage
|
||||
{
|
||||
Unknown,
|
||||
Constant,
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
};
|
||||
|
||||
struct ShaderStorageResources
|
||||
{
|
||||
static constexpr int BUFFERS_MAX = 16;
|
||||
|
||||
ShaderBufferResource buffers[BUFFERS_MAX];
|
||||
ShaderStorageUsage usages[BUFFERS_MAX] = {};
|
||||
int slots[BUFFERS_MAX] = {0};
|
||||
int start_register[BUFFERS_MAX] = {0};
|
||||
bool extended[BUFFERS_MAX] = {};
|
||||
// int extended_index[BUFFERS_MAX] = {0};
|
||||
int buffers_num = 0;
|
||||
int binding_index = 0;
|
||||
};
|
||||
|
||||
struct ShaderTextureResources
|
||||
{
|
||||
static constexpr int RES_MAX = 16;
|
||||
|
||||
ShaderTextureResource textures[RES_MAX];
|
||||
int start_register[RES_MAX] = {0};
|
||||
bool extended[RES_MAX] = {};
|
||||
// int extended_index[RES_MAX] = {0};
|
||||
int textures_num = 0;
|
||||
int binding_index = 0;
|
||||
};
|
||||
|
||||
struct ShaderSamplerResources
|
||||
{
|
||||
static constexpr int RES_MAX = 16;
|
||||
|
||||
ShaderSamplerResource samplers[RES_MAX];
|
||||
int start_register[RES_MAX] = {0};
|
||||
bool extended[RES_MAX] = {};
|
||||
// int extended_index[RES_MAX] = {0};
|
||||
int samplers_num = 0;
|
||||
int binding_index = 0;
|
||||
};
|
||||
|
||||
struct ShaderGdsResources
|
||||
{
|
||||
static constexpr int POINTERS_MAX = 1;
|
||||
|
||||
ShaderGdsResource pointers[POINTERS_MAX];
|
||||
int slots[POINTERS_MAX] = {0};
|
||||
int start_register[POINTERS_MAX] = {0};
|
||||
bool extended[POINTERS_MAX] = {};
|
||||
// int extended_index[POINTERS_MAX] = {0};
|
||||
int pointers_num = 0;
|
||||
int binding_index = 0;
|
||||
};
|
||||
|
||||
struct ShaderExtendedResources
|
||||
{
|
||||
bool used = false;
|
||||
int slot = 0;
|
||||
// int dw_num = 0;
|
||||
int start_register = 0;
|
||||
ShaderExtendedResource data;
|
||||
};
|
||||
|
||||
struct ShaderResources
|
||||
{
|
||||
uint32_t push_constant_offset = 0;
|
||||
uint32_t push_constant_size = 0;
|
||||
uint32_t descriptor_set_slot = 0;
|
||||
ShaderStorageResources storage_buffers;
|
||||
ShaderTextureResources textures2D;
|
||||
ShaderSamplerResources samplers;
|
||||
ShaderGdsResources gds_pointers;
|
||||
ShaderExtendedResources extended;
|
||||
};
|
||||
|
||||
struct ShaderVertexInputInfo
|
||||
{
|
||||
static constexpr int RES_MAX = 16;
|
||||
|
||||
ShaderBufferResource resources[RES_MAX];
|
||||
ShaderVertexDestination resources_dst[RES_MAX];
|
||||
int resources_num = 0;
|
||||
bool fetch = false;
|
||||
ShaderVertexInputBuffer buffers[RES_MAX];
|
||||
int buffers_num = 0;
|
||||
int export_count = 0;
|
||||
ShaderResources bind;
|
||||
};
|
||||
|
||||
struct ShaderComputeInputInfo
|
||||
{
|
||||
uint32_t threads_num[3] = {};
|
||||
int workgroup_register = 0;
|
||||
ShaderResources bind;
|
||||
};
|
||||
|
||||
struct ShaderPixelInputInfo
|
||||
{
|
||||
uint32_t interpolator_settings[32] = {0};
|
||||
uint32_t input_num = 0;
|
||||
uint8_t target_output_mode[8] = {};
|
||||
bool ps_pos_xy = false;
|
||||
bool ps_pixel_kill_enable = false;
|
||||
ShaderResources bind;
|
||||
};
|
||||
|
||||
void ShaderGetInputInfoVS(const VertexShaderInfo* regs, ShaderVertexInputInfo* info);
|
||||
void ShaderGetInputInfoPS(const PixelShaderInfo* regs, const ShaderVertexInputInfo* vs_info, ShaderPixelInputInfo* ps_info);
|
||||
void ShaderGetInputInfoCS(const ComputeShaderInfo* regs, ShaderComputeInputInfo* info);
|
||||
void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo* info);
|
||||
void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo* info);
|
||||
void ShaderDbgDumpInputInfo(const ShaderComputeInputInfo* info);
|
||||
ShaderId ShaderGetIdVS(const VertexShaderInfo* regs, const ShaderVertexInputInfo* input_info);
|
||||
ShaderId ShaderGetIdPS(const PixelShaderInfo* regs, const ShaderPixelInputInfo* input_info);
|
||||
ShaderId ShaderGetIdCS(const ComputeShaderInfo* regs, const ShaderComputeInputInfo* input_info);
|
||||
Vector<uint32_t> ShaderRecompileVS(const VertexShaderInfo* regs, const ShaderVertexInputInfo* input_info);
|
||||
Vector<uint32_t> ShaderRecompilePS(const PixelShaderInfo* regs, const ShaderPixelInputInfo* input_info);
|
||||
Vector<uint32_t> ShaderRecompileCS(const ComputeShaderInfo* regs, const ShaderComputeInputInfo* input_info);
|
||||
bool ShaderIsDisabled(uint64_t addr);
|
||||
void ShaderDisable(uint64_t id);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_H_ */
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADERSPIRV_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADERSPIRV_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class ShaderCode;
|
||||
struct ShaderVertexInputInfo;
|
||||
struct ShaderPixelInputInfo;
|
||||
struct ShaderComputeInputInfo;
|
||||
|
||||
String SpirvGenerateSource(const ShaderCode& code, const ShaderVertexInputInfo* vs_input_info, const ShaderPixelInputInfo* ps_input_info,
|
||||
const ShaderComputeInputInfo* cs_input_info);
|
||||
String SpirvGetEmbeddedVs(uint32_t id);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADERSPIRV_H_ */
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_STORAGEBUFFER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_STORAGEBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class StorageBufferGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
StorageBufferGpuObject(uint64_t stride, uint64_t num_records, bool ronly)
|
||||
{
|
||||
params[0] = stride;
|
||||
params[1] = num_records;
|
||||
check_hash = true;
|
||||
read_only = ronly;
|
||||
type = Graphics::GpuMemoryObjectType::StorageBuffer;
|
||||
}
|
||||
|
||||
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;
|
||||
[[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_STORAGEBUFFER_H_ */
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TEXTURE_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TEXTURE_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class TextureObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
static constexpr int PARAM_DFMT = 0;
|
||||
static constexpr int PARAM_NFMT = 1;
|
||||
static constexpr int PARAM_WIDTH = 2;
|
||||
static constexpr int PARAM_HEIGHT = 3;
|
||||
static constexpr int PARAM_LEVELS = 4;
|
||||
static constexpr int PARAM_TILE = 5;
|
||||
static constexpr int PARAM_NEO = 6;
|
||||
static constexpr int PARAM_SWIZZLE = 7;
|
||||
|
||||
TextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t levels, bool htile, bool neo, uint32_t swizzle)
|
||||
{
|
||||
params[PARAM_DFMT] = dfmt;
|
||||
params[PARAM_NFMT] = nfmt;
|
||||
params[PARAM_WIDTH] = width;
|
||||
params[PARAM_HEIGHT] = height;
|
||||
params[PARAM_LEVELS] = levels;
|
||||
params[PARAM_TILE] = htile ? 1 : 0;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
params[PARAM_SWIZZLE] = swizzle;
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::Texture;
|
||||
}
|
||||
|
||||
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_TEXTURE_H_ */
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TILE_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TILE_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
enum class TileMode
|
||||
{
|
||||
VideoOutLinear,
|
||||
VideoOutTiled,
|
||||
TextureLinear,
|
||||
TextureTiled,
|
||||
};
|
||||
|
||||
void TileInit();
|
||||
void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_t width, uint32_t height, bool neo);
|
||||
void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height,
|
||||
uint32_t levels, 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);
|
||||
void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, uint32_t* size);
|
||||
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t levels, bool tile, bool neo,
|
||||
uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_TILE_H_ */
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_UTILS_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_UTILS_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty {
|
||||
template <typename T>
|
||||
class Vector;
|
||||
} // namespace Kyty
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
struct GraphicContext;
|
||||
struct VulkanBuffer;
|
||||
struct VideoOutVulkanImage;
|
||||
struct TextureVulkanImage;
|
||||
struct DepthStencilVulkanImage;
|
||||
struct VulkanSwapchain;
|
||||
|
||||
struct BufferImageCopy
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, VideoOutVulkanImage* dst_image);
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, TextureVulkanImage* dst_image,
|
||||
const Vector<BufferImageCopy>& regions);
|
||||
void UtilBlitImage(CommandBuffer* buffer, VideoOutVulkanImage* src_image, VulkanSwapchain* dst_swapchain);
|
||||
void UtilFillImage(GraphicContext* ctx, VideoOutVulkanImage* 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);
|
||||
void UtilCopyBuffer(VulkanBuffer* src_buffer, VulkanBuffer* dst_buffer, uint64_t size);
|
||||
void UtilSetImageLayoutOptimal(DepthStencilVulkanImage* image);
|
||||
void UtilSetImageLayoutOptimal(VideoOutVulkanImage* image);
|
||||
|
||||
void VulkanCreateBuffer(GraphicContext* gctx, uint64_t size, VulkanBuffer* buffer);
|
||||
void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_UTILS_H_ */
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VERTEXBUFFER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VERTEXBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class VertexBufferGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
VertexBufferGpuObject()
|
||||
{
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::VertexBuffer;
|
||||
}
|
||||
|
||||
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_VERTEXBUFFER_H_ */
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUT_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUT_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
//#include "Kyty/Core/Subsystems.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Kernel/EventQueue.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
// struct VulkanSwapchain;
|
||||
struct VideoOutVulkanImage;
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
namespace Kyty::Libs::VideoOut {
|
||||
|
||||
struct VideoOutResolutionStatus;
|
||||
struct VideoOutBufferAttribute;
|
||||
struct VideoOutFlipStatus;
|
||||
|
||||
struct VideoOutBufferImageInfo
|
||||
{
|
||||
Graphics::VideoOutVulkanImage* image = nullptr;
|
||||
uint32_t index = static_cast<uint32_t>(-1);
|
||||
uint64_t buffer_size = 0;
|
||||
};
|
||||
|
||||
void VideoOutInit(uint32_t width, uint32_t height);
|
||||
VideoOutBufferImageInfo VideoOutGetImage(uint64_t addr);
|
||||
void VideoOutWaitFlipDone(int handle, int index);
|
||||
|
||||
KYTY_SYSV_ABI int VideoOutOpen(int user_id, int bus_type, int index, const void* param);
|
||||
KYTY_SYSV_ABI int VideoOutClose(int handle);
|
||||
KYTY_SYSV_ABI int VideoOutGetResolutionStatus(int handle, VideoOutResolutionStatus* status);
|
||||
KYTY_SYSV_ABI void VideoOutSetBufferAttribute(VideoOutBufferAttribute* attribute, uint32_t pixel_format, uint32_t tiling_mode,
|
||||
uint32_t aspect_ratio, uint32_t width, uint32_t height, uint32_t pitch_in_pixel);
|
||||
KYTY_SYSV_ABI int VideoOutSetFlipRate(int handle, int rate);
|
||||
KYTY_SYSV_ABI int VideoOutAddFlipEvent(LibKernel::EventQueue::KernelEqueue eq, int handle, void* udata);
|
||||
KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* const* addresses, int buffer_num,
|
||||
const VideoOutBufferAttribute* attribute);
|
||||
KYTY_SYSV_ABI int VideoOutSubmitFlip(int handle, int index, int flip_mode, int64_t flip_arg);
|
||||
KYTY_SYSV_ABI int VideoOutGetFlipStatus(int handle, VideoOutFlipStatus* status);
|
||||
|
||||
bool FlipWindow(uint32_t micros);
|
||||
|
||||
} // namespace Kyty::Libs::VideoOut
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUT_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUTBUFFER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_VIDEOOUTBUFFER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/GpuMemory.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
|
||||
class VideoOutBufferObject: 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;
|
||||
|
||||
explicit VideoOutBufferObject(uint32_t pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo)
|
||||
{
|
||||
params[PARAM_FORMAT] = pixel_format;
|
||||
params[PARAM_WIDTH] = width;
|
||||
params[PARAM_HEIGHT] = height;
|
||||
params[PARAM_TILED] = tiled ? 1 : 0;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::VideoOutBuffer;
|
||||
}
|
||||
|
||||
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_VIDEOOUTBUFFER_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_WINDOW_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_WINDOW_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
struct VkSurfaceCapabilitiesKHR;
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
struct VideoOutVulkanImage;
|
||||
|
||||
VkSurfaceCapabilitiesKHR* VulkanGetSurfaceCapabilities();
|
||||
|
||||
GraphicContext* WindowGetGraphicContext();
|
||||
|
||||
void WindowInit(uint32_t width, uint32_t height);
|
||||
void WindowRun();
|
||||
void WindowWaitForGraphicInitialized();
|
||||
void WindowDrawBuffer(VideoOutVulkanImage* image);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_WINDOW_H_ */
|
||||
Reference in New Issue
Block a user