mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
release 0.1.0
This commit is contained in:
@@ -20,6 +20,8 @@ int KYTY_SYSV_ABI AudioOutInit();
|
||||
int KYTY_SYSV_ABI AudioOutOpen(int user_id, int type, int index, uint32_t len, uint32_t freq, uint32_t param);
|
||||
int KYTY_SYSV_ABI AudioOutSetVolume(int handle, uint32_t flag, int* vol);
|
||||
int KYTY_SYSV_ABI AudioOutOutputs(AudioOutOutputParam* param, uint32_t num);
|
||||
int KYTY_SYSV_ABI AudioOutOutput(int handle, const void* ptr);
|
||||
int KYTY_SYSV_ABI AudioOutClose(int handle);
|
||||
|
||||
} // namespace AudioOut
|
||||
|
||||
@@ -39,9 +41,29 @@ int KYTY_SYSV_ABI VoiceQoSInit(void* mem_block, uint32_t mem_size, int32_t app_t
|
||||
namespace Ajm {
|
||||
|
||||
int KYTY_SYSV_ABI AjmInitialize(int64_t reserved, uint32_t* context);
|
||||
int KYTY_SYSV_ABI AjmModuleRegister(uint32_t context, uint32_t codec, int64_t reserved);
|
||||
|
||||
} // namespace Ajm
|
||||
|
||||
namespace AvPlayer {
|
||||
|
||||
struct AvPlayerInitData;
|
||||
struct AvPlayerFrameInfoEx;
|
||||
struct AvPlayerFrameInfo;
|
||||
struct AvPlayerInternal;
|
||||
|
||||
using Bool = uint8_t;
|
||||
|
||||
AvPlayerInternal* KYTY_SYSV_ABI AvPlayerInit(AvPlayerInitData* init);
|
||||
int KYTY_SYSV_ABI AvPlayerAddSource(AvPlayerInternal* h, const char* filename);
|
||||
int KYTY_SYSV_ABI AvPlayerSetLooping(AvPlayerInternal* h, Bool loop);
|
||||
Bool KYTY_SYSV_ABI AvPlayerGetVideoDataEx(AvPlayerInternal* h, AvPlayerFrameInfoEx* video_info);
|
||||
Bool KYTY_SYSV_ABI AvPlayerGetAudioData(AvPlayerInternal* h, AvPlayerFrameInfo* audio_info);
|
||||
Bool KYTY_SYSV_ABI AvPlayerIsActive(AvPlayerInternal* h);
|
||||
int KYTY_SYSV_ABI AvPlayerClose(AvPlayerInternal* h);
|
||||
|
||||
} // namespace AvPlayer
|
||||
|
||||
} // namespace Kyty::Libs::Audio
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -56,12 +56,16 @@ String GetCommandBufferDumpFolder();
|
||||
|
||||
Log::Direction GetPrintfDirection();
|
||||
String GetPrintfOutputFile();
|
||||
String GetPrintfOutputFolder();
|
||||
|
||||
ProfilerDirection GetProfilerDirection();
|
||||
String GetProfilerOutputFile();
|
||||
|
||||
bool SpirvDebugPrintfEnabled();
|
||||
|
||||
bool PipelineDumpEnabled();
|
||||
String GetPipelineDumpFolder();
|
||||
|
||||
} // namespace Kyty::Config
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class Axis
|
||||
struct PadControllerInformation;
|
||||
struct PadData;
|
||||
struct PadVibrationParam;
|
||||
struct PadLightBarParam;
|
||||
|
||||
inline int controller_get_axis(int min, int max, int value)
|
||||
{
|
||||
@@ -63,6 +64,8 @@ int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformati
|
||||
int KYTY_SYSV_ABI PadReadState(int handle, PadData* data);
|
||||
int KYTY_SYSV_ABI PadRead(int handle, PadData* data, int num);
|
||||
int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param);
|
||||
int KYTY_SYSV_ABI PadResetLightBar(int handle);
|
||||
int KYTY_SYSV_ABI PadSetLightBar(int handle, const PadLightBarParam* param);
|
||||
|
||||
} // namespace Kyty::Libs::Controller
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <vulkan/vulkan_core.h> // IWYU pragma: export
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
class CommandProcessor;
|
||||
|
||||
struct VulkanSwapchain
|
||||
{
|
||||
@@ -67,36 +67,58 @@ struct VulkanMemory
|
||||
uint64_t unique_id = 0;
|
||||
};
|
||||
|
||||
enum class VulkanImageType
|
||||
{
|
||||
Unknown,
|
||||
VideoOut,
|
||||
DepthStencil,
|
||||
Texture,
|
||||
StorageTexture,
|
||||
RenderTexture
|
||||
};
|
||||
|
||||
struct VulkanImage
|
||||
{
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D extent = {};
|
||||
VkImage image = nullptr;
|
||||
VkImageView image_view = nullptr;
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
static constexpr int VIEW_MAX = 4;
|
||||
static constexpr int VIEW_DEFAULT = 0;
|
||||
static constexpr int VIEW_BGRA = 1;
|
||||
static constexpr int VIEW_DEPTH_TEXTURE = 2;
|
||||
|
||||
explicit VulkanImage(VulkanImageType type): type(type) {}
|
||||
|
||||
VulkanImageType type = VulkanImageType::Unknown;
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkExtent2D extent = {};
|
||||
VkImage image = nullptr;
|
||||
VkImageView image_view[VIEW_MAX] = {};
|
||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
Graphics::VulkanMemory memory;
|
||||
};
|
||||
|
||||
struct VideoOutVulkanImage: public VulkanImage
|
||||
{
|
||||
VideoOutVulkanImage(): VulkanImage(VulkanImageType::VideoOut) {}
|
||||
};
|
||||
|
||||
struct DepthStencilVulkanImage: public VulkanImage
|
||||
{
|
||||
bool compressed = false;
|
||||
VkImageView texture_view = nullptr;
|
||||
DepthStencilVulkanImage(): VulkanImage(VulkanImageType::DepthStencil) {}
|
||||
bool compressed = false;
|
||||
};
|
||||
|
||||
struct TextureVulkanImage: public VulkanImage
|
||||
{
|
||||
TextureVulkanImage(): VulkanImage(VulkanImageType::Texture) {}
|
||||
};
|
||||
|
||||
struct StorageTextureVulkanImage: public VulkanImage
|
||||
{
|
||||
StorageTextureVulkanImage(): VulkanImage(VulkanImageType::StorageTexture) {}
|
||||
};
|
||||
|
||||
struct RenderTextureVulkanImage: public VulkanImage
|
||||
{
|
||||
RenderTextureVulkanImage(): VulkanImage(VulkanImageType::RenderTexture) {}
|
||||
};
|
||||
|
||||
struct VulkanBuffer
|
||||
@@ -108,7 +130,7 @@ struct VulkanBuffer
|
||||
|
||||
struct StorageVulkanBuffer: public VulkanBuffer
|
||||
{
|
||||
CommandBuffer* cmd_buffer = nullptr;
|
||||
CommandProcessor* cp = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
@@ -33,7 +33,8 @@ public:
|
||||
CommandBuffer() { Allocate(); }
|
||||
virtual ~CommandBuffer() { Free(); }
|
||||
|
||||
void SetParent(CommandProcessor* parent) { m_parent = parent; }
|
||||
void SetParent(CommandProcessor* parent) { m_parent = parent; }
|
||||
CommandProcessor* GetParent() { return m_parent; }
|
||||
|
||||
KYTY_CLASS_NO_COPY(CommandBuffer);
|
||||
|
||||
@@ -56,7 +57,7 @@ public:
|
||||
|
||||
void SetQueue(int queue) { m_queue = queue; }
|
||||
|
||||
void CommandProcessorWait();
|
||||
// void CommandProcessorWait();
|
||||
|
||||
private:
|
||||
VulkanCommandPool* m_pool = nullptr;
|
||||
@@ -89,13 +90,15 @@ void GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBack64(uint64_t submit_id,
|
||||
uint64_t value);
|
||||
void GraphicsRenderWriteAtEndOfPipeWithInterrupt64(uint64_t submit_id, CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value);
|
||||
void GraphicsRenderWriteAtEndOfPipeWithInterrupt32(uint64_t submit_id, CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value);
|
||||
void GraphicsRenderWriteBack();
|
||||
void GraphicsRenderWriteBack(CommandProcessor* cp);
|
||||
void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW::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 GraphicsRenderRenderTextureBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size);
|
||||
void GraphicsRenderDepthStencilBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size);
|
||||
void GraphicsRenderMemoryFree(uint64_t vaddr, uint64_t size);
|
||||
void GraphicsRenderDeleteIndexBuffers();
|
||||
void GraphicsRenderMemoryFlush(uint64_t vaddr, uint64_t size);
|
||||
|
||||
void DeleteFramebuffer(VideoOutVulkanImage* image);
|
||||
void DeleteFramebuffer(DepthStencilVulkanImage* image);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandProcessor;
|
||||
|
||||
void GraphicsRunInit();
|
||||
|
||||
void GraphicsRunSubmit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer, uint32_t num_const_dw);
|
||||
@@ -23,6 +25,11 @@ void GraphicsRunDingDong(uint32_t ring_id, uint32_t offset_dw);
|
||||
int GraphicsRunGetFrameNum();
|
||||
bool GraphicsRunAreSubmitsAllowed();
|
||||
|
||||
void GraphicsRunCommandProcessorLock(CommandProcessor* cp);
|
||||
void GraphicsRunCommandProcessorUnlock(CommandProcessor* cp);
|
||||
void GraphicsRunCommandProcessorFlush(CommandProcessor* cp);
|
||||
void GraphicsRunCommandProcessorWait(CommandProcessor* cp);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
class CommandProcessor;
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
struct VulkanBuffer;
|
||||
@@ -60,10 +61,11 @@ public:
|
||||
VulkanMemory* mem);
|
||||
using create_from_objects_func_t = void* (*)(GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* params,
|
||||
GpuMemoryScenario scenario, const Vector<GpuMemoryObject>& objects, VulkanMemory* mem);
|
||||
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);
|
||||
using write_back_func_t = void (*)(GraphicContext* ctx, const uint64_t* params, 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;
|
||||
|
||||
@@ -95,11 +97,12 @@ void* GpuMemoryCreateObject(uint64_t submit_id, GraphicContext* ctx, CommandBuff
|
||||
const GpuObject& info);
|
||||
void* GpuMemoryCreateObject(uint64_t submit_id, GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* vaddr, const uint64_t* size,
|
||||
int vaddr_num, const GpuObject& info);
|
||||
void GpuMemoryResetHash(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, GpuMemoryObjectType type);
|
||||
void GpuMemoryResetHash(const uint64_t* vaddr, const uint64_t* size, int vaddr_num, GpuMemoryObjectType type);
|
||||
void GpuMemoryDbgDump();
|
||||
void GpuMemoryFlush(GraphicContext* ctx);
|
||||
void GpuMemoryFlush(GraphicContext* ctx, uint64_t vaddr, uint64_t size);
|
||||
void GpuMemoryFlushAll(GraphicContext* ctx);
|
||||
void GpuMemoryFrameDone();
|
||||
void GpuMemoryWriteBack(GraphicContext* ctx);
|
||||
void GpuMemoryWriteBack(GraphicContext* ctx, CommandProcessor* cp);
|
||||
bool GpuMemoryCheckAccessViolation(uint64_t vaddr, uint64_t size);
|
||||
bool GpuMemoryWatcherEnabled();
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct GraphicContext;
|
||||
|
||||
void IndexBufferInit();
|
||||
void IndexBufferDeleteAll(GraphicContext* ctx);
|
||||
|
||||
class IndexBufferGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -16,6 +16,8 @@ struct GraphicContext;
|
||||
|
||||
void LabelInit();
|
||||
|
||||
constexpr int LABEL_ARGS_MAX = 5;
|
||||
|
||||
class LabelGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
@@ -28,6 +30,7 @@ public:
|
||||
static constexpr int PARAM_ARG_2 = 4;
|
||||
static constexpr int PARAM_ARG_3 = 5;
|
||||
static constexpr int PARAM_ARG_4 = 6;
|
||||
static constexpr int PARAM_ARG_5 = 7;
|
||||
|
||||
explicit LabelGpuObject(uint64_t value, callback_t callback_1, callback_t callback_2, const uint64_t* args = nullptr)
|
||||
{
|
||||
@@ -40,6 +43,7 @@ public:
|
||||
params[PARAM_ARG_2] = args[1];
|
||||
params[PARAM_ARG_3] = args[2];
|
||||
params[PARAM_ARG_4] = args[3];
|
||||
params[PARAM_ARG_5] = args[4];
|
||||
}
|
||||
check_hash = false;
|
||||
type = Graphics::GpuMemoryObjectType::Label;
|
||||
|
||||
@@ -14,36 +14,41 @@ enum class RenderTextureFormat : uint64_t
|
||||
{
|
||||
Unknown,
|
||||
R8G8B8A8Unorm,
|
||||
B8G8R8A8Unorm
|
||||
R8G8B8A8Srgb,
|
||||
B8G8R8A8Unorm,
|
||||
B8G8R8A8Srgb,
|
||||
};
|
||||
|
||||
class RenderTextureObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
static constexpr int PARAM_FORMAT = 0;
|
||||
static constexpr int PARAM_WIDTH = 1;
|
||||
static constexpr int PARAM_HEIGHT = 2;
|
||||
static constexpr int PARAM_TILED = 3;
|
||||
static constexpr int PARAM_NEO = 4;
|
||||
static constexpr int PARAM_PITCH = 5;
|
||||
static constexpr int PARAM_FORMAT = 0;
|
||||
static constexpr int PARAM_WIDTH = 1;
|
||||
static constexpr int PARAM_HEIGHT = 2;
|
||||
static constexpr int PARAM_TILED = 3;
|
||||
static constexpr int PARAM_NEO = 4;
|
||||
static constexpr int PARAM_PITCH = 5;
|
||||
static constexpr int PARAM_WRITE_BACK = 6;
|
||||
|
||||
explicit RenderTextureObject(RenderTextureFormat pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo, uint32_t pitch)
|
||||
explicit RenderTextureObject(RenderTextureFormat pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo, uint32_t pitch,
|
||||
bool write_back)
|
||||
{
|
||||
params[PARAM_FORMAT] = static_cast<uint64_t>(pixel_format);
|
||||
params[PARAM_WIDTH] = width;
|
||||
params[PARAM_HEIGHT] = height;
|
||||
params[PARAM_TILED] = tiled ? 1 : 0;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
params[PARAM_PITCH] = pitch;
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::RenderTexture;
|
||||
params[PARAM_FORMAT] = static_cast<uint64_t>(pixel_format);
|
||||
params[PARAM_WIDTH] = width;
|
||||
params[PARAM_HEIGHT] = height;
|
||||
params[PARAM_TILED] = tiled ? 1 : 0;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
params[PARAM_PITCH] = pitch;
|
||||
params[PARAM_WRITE_BACK] = write_back ? 1 : 0;
|
||||
check_hash = true;
|
||||
type = Graphics::GpuMemoryObjectType::RenderTexture;
|
||||
}
|
||||
|
||||
bool Equal(const uint64_t* other) const override;
|
||||
|
||||
[[nodiscard]] create_func_t GetCreateFunc() const override;
|
||||
[[nodiscard]] create_from_objects_func_t GetCreateFromObjectsFunc() const override;
|
||||
[[nodiscard]] write_back_func_t GetWriteBackFunc() const override { return nullptr; };
|
||||
[[nodiscard]] write_back_func_t GetWriteBackFunc() const override;
|
||||
[[nodiscard]] delete_func_t GetDeleteFunc() const override;
|
||||
[[nodiscard]] update_func_t GetUpdateFunc() const override;
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ enum class ShaderType
|
||||
enum class ShaderInstructionType
|
||||
{
|
||||
Unknown,
|
||||
|
||||
BufferLoadDword,
|
||||
BufferLoadFormatX,
|
||||
BufferLoadFormatXy,
|
||||
@@ -44,6 +45,8 @@ enum class ShaderInstructionType
|
||||
Exp,
|
||||
ImageLoad,
|
||||
ImageSample,
|
||||
ImageSampleLz,
|
||||
ImageSampleLzO,
|
||||
ImageStore,
|
||||
ImageStoreMip,
|
||||
SAddcU32,
|
||||
@@ -61,6 +64,7 @@ enum class ShaderInstructionType
|
||||
SBufferLoadDwordx8,
|
||||
SCbranchExecz,
|
||||
SCbranchScc0,
|
||||
SCbranchVccz,
|
||||
SCmpEqI32,
|
||||
SCmpEqU32,
|
||||
SCmpGeI32,
|
||||
@@ -94,7 +98,9 @@ enum class ShaderInstructionType
|
||||
SWqmB64,
|
||||
SXnorB64,
|
||||
SXorB64,
|
||||
TBufferLoadFormatX,
|
||||
TBufferLoadFormatXyzw,
|
||||
VAddF32,
|
||||
VAddI32,
|
||||
VAndB32,
|
||||
VAshrI32,
|
||||
@@ -138,9 +144,11 @@ enum class ShaderInstructionType
|
||||
VCmpUF32,
|
||||
VCmpxEqU32,
|
||||
VCmpxGeU32,
|
||||
VCmpxGtF32,
|
||||
VCmpxGtU32,
|
||||
VCmpxNeU32,
|
||||
VCmpxLtF32,
|
||||
VCmpxNeqF32,
|
||||
VCmpxNeU32,
|
||||
VCndmaskB32,
|
||||
VCosF32,
|
||||
VCvtF32F16,
|
||||
@@ -154,9 +162,11 @@ enum class ShaderInstructionType
|
||||
VCvtU32F32,
|
||||
VExpF32,
|
||||
VFloorF32,
|
||||
VFmaF32,
|
||||
VFractF32,
|
||||
VInterpP1F32,
|
||||
VInterpP2F32,
|
||||
VLogF32,
|
||||
VLshlB32,
|
||||
VLshlrevB32,
|
||||
VLshrB32,
|
||||
@@ -166,9 +176,12 @@ enum class ShaderInstructionType
|
||||
VMadF32,
|
||||
VMadmkF32,
|
||||
VMadU32U24,
|
||||
VMax3F32,
|
||||
VMaxF32,
|
||||
VMbcntHiU32B32,
|
||||
VMbcntLoU32B32,
|
||||
VMed3F32,
|
||||
VMin3F32,
|
||||
VMinF32,
|
||||
VMovB32,
|
||||
VMulF32,
|
||||
@@ -182,6 +195,7 @@ enum class ShaderInstructionType
|
||||
VRndneF32,
|
||||
VRsqF32,
|
||||
VSadU32,
|
||||
VSinF32,
|
||||
VSqrtF32,
|
||||
VSubF32,
|
||||
VSubI32,
|
||||
@@ -225,6 +239,7 @@ enum FormatByte : uint64_t
|
||||
Attr, // attr%u.%u <- inst.src[1].constant.u, inst.src[2].constant.u
|
||||
Idxen, // idxen
|
||||
Offen, // offen
|
||||
Float1, // format:float1
|
||||
Float4, // format:float4
|
||||
Pos0, // pos0
|
||||
Done, // done
|
||||
@@ -232,6 +247,7 @@ enum FormatByte : uint64_t
|
||||
Param1, // param1
|
||||
Param2, // param2
|
||||
Param3, // param3
|
||||
Param4, // param4
|
||||
Mrt0, // mrt_color0
|
||||
Off, // off
|
||||
Compr, // compr
|
||||
@@ -240,6 +256,9 @@ enum FormatByte : uint64_t
|
||||
DmaskF, // dmask:0xf
|
||||
Dmask7, // dmask:0x7
|
||||
Dmask1, // dmask:0x1
|
||||
Dmask8, // dmask:0x8
|
||||
Dmask3, // dmask:0x3
|
||||
Dmask5, // dmask:0x5
|
||||
Gds, // gds
|
||||
};
|
||||
|
||||
@@ -266,37 +285,43 @@ enum Format : uint64_t
|
||||
Param1Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param1, S0, S1, S2, S3}),
|
||||
Param2Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param2, S0, S1, S2, S3}),
|
||||
Param3Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param3, S0, S1, S2, S3}),
|
||||
Param4Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param4, 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}),
|
||||
Sdst2SvSoffset = FormatDefine({DA2, 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}),
|
||||
Sdst2SvSoffset = FormatDefine({DA2, S0A4, S1}),
|
||||
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
||||
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
||||
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
||||
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
||||
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
||||
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
||||
Ssrc0Ssrc1 = FormatDefine({S0, S1}),
|
||||
SVdstSVsrc0 = FormatDefine({D, S0}),
|
||||
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
||||
Vdata1Vaddr3StSsDmask1 = FormatDefine({D, S0A3, S1A8, S2A4, Dmask1}),
|
||||
Vdata1Vaddr3StSsDmask8 = FormatDefine({D, S0A3, S1A8, S2A4, Dmask8}),
|
||||
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
||||
Vdata1VaddrSvSoffsIdxenFloat1 = FormatDefine({D, S0, S1A4, S2, Idxen, Float1}),
|
||||
Vdata2Vaddr3StSsDmask3 = FormatDefine({DA2, S0A3, S1A8, S2A4, Dmask3}),
|
||||
Vdata2Vaddr3StSsDmask5 = FormatDefine({DA2, S0A3, S1A8, S2A4, Dmask5}),
|
||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata3Vaddr4StSsDmask7 = FormatDefine({DA3, S0A4, S1A8, S2A4, Dmask7}),
|
||||
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
||||
Vdata4Vaddr2SvSoffsOffenIdxenFloat4 = FormatDefine({DA4, S0A2, S1A4, S2, Offen, Idxen, Float4}),
|
||||
Vdata4Vaddr3StDmaskF = FormatDefine({DA4, S0A3, S1A8, DmaskF}),
|
||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||
Vdata4Vaddr4StDmaskF = FormatDefine({DA4, S0A4, S1A8, DmaskF}),
|
||||
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
||||
Vdata4Vaddr2SvSoffsOffenIdxenFloat4 = FormatDefine({DA4, S0A2, S1A4, S2, Offen, Idxen, Float4}),
|
||||
Vdata1Vaddr3StSsDmask1 = FormatDefine({D, S0A3, S1A8, S2A4, Dmask1}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||
Vdata4Vaddr3StDmaskF = FormatDefine({DA4, S0A3, S1A8, DmaskF}),
|
||||
Vdata4Vaddr4StDmaskF = FormatDefine({DA4, S0A4, S1A8, DmaskF}),
|
||||
VdstGds = FormatDefine({D, Gds}),
|
||||
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
||||
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
|
||||
@@ -332,6 +357,7 @@ struct ShaderOperand
|
||||
int register_id = 0;
|
||||
int size = 0;
|
||||
float multiplier = 1.0f;
|
||||
bool absolute = false;
|
||||
bool negate = false;
|
||||
bool clamp = false;
|
||||
|
||||
@@ -364,6 +390,14 @@ public:
|
||||
|
||||
[[nodiscard]] String ToString() const { return String::FromPrintf("label_%04" PRIx32 "_%04" PRIx32, m_dst, m_src); }
|
||||
|
||||
void Disable()
|
||||
{
|
||||
m_dst = 0;
|
||||
m_src = 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsDisabled() const { return m_dst == 0 && m_src == 0; }
|
||||
|
||||
private:
|
||||
uint32_t m_dst;
|
||||
uint32_t m_src;
|
||||
@@ -420,10 +454,18 @@ public:
|
||||
[[nodiscard]] uint32_t GetPsEmbeddedId() const { return m_ps_embedded_id; }
|
||||
void SetPsEmbeddedId(uint32_t embedded_id) { m_ps_embedded_id = embedded_id; }
|
||||
|
||||
[[nodiscard]] bool IsDiscardBlock(uint32_t pc) const;
|
||||
[[nodiscard]] bool IsDiscardInstruction(uint32_t index) const;
|
||||
[[nodiscard]] bool IsDiscardBlock(uint32_t pc) const;
|
||||
[[nodiscard]] bool IsDiscardInstruction(uint32_t index) const;
|
||||
[[nodiscard]] Vector<ShaderInstruction> GetDiscardBlock(uint32_t pc) const;
|
||||
|
||||
[[nodiscard]] uint32_t GetCrc32() const { return m_crc32; }
|
||||
void SetCrc32(uint32_t c) { this->m_crc32 = c; }
|
||||
[[nodiscard]] uint32_t GetHash0() const { return m_hash0; }
|
||||
void SetHash0(uint32_t h) { this->m_hash0 = h; }
|
||||
|
||||
private:
|
||||
uint32_t m_hash0 = 0;
|
||||
uint32_t m_crc32 = 0;
|
||||
Vector<ShaderInstruction> m_instructions;
|
||||
Vector<ShaderLabel> m_labels;
|
||||
ShaderType m_type = ShaderType::Unknown;
|
||||
@@ -436,12 +478,24 @@ private:
|
||||
|
||||
struct ShaderId
|
||||
{
|
||||
uint32_t hash0 = 0;
|
||||
uint32_t crc32 = 0;
|
||||
Vector<uint32_t> ids;
|
||||
|
||||
bool operator==(const ShaderId& other) const { return ids == other.ids; }
|
||||
bool operator==(const ShaderId& other) const { return hash0 == other.hash0 && crc32 == other.crc32 && ids == other.ids; }
|
||||
bool operator!=(const ShaderId& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
constexpr uint32_t DstSel(uint32_t x, uint32_t y = 0, uint32_t z = 0, uint32_t w = 0)
|
||||
{
|
||||
return x | (y << 3u) | (z << 6u) | (w << 9u);
|
||||
}
|
||||
|
||||
inline uint8_t GetDstSel(uint32_t swizzle, uint32_t channel)
|
||||
{
|
||||
return (swizzle >> (channel * 3u)) & 0x7u;
|
||||
}
|
||||
|
||||
struct ShaderBufferResource
|
||||
{
|
||||
uint32_t fields[4] = {0};
|
||||
@@ -462,6 +516,9 @@ struct ShaderBufferResource
|
||||
[[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]] uint32_t DstSelXY() const { return (fields[3] >> 0u) & 0x3Fu; }
|
||||
[[nodiscard]] uint32_t DstSelXYZ() const { return (fields[3] >> 0u) & 0x1FFu; }
|
||||
[[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; }
|
||||
[[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; }
|
||||
@@ -496,6 +553,9 @@ struct ShaderTextureResource
|
||||
[[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]] uint32_t DstSelXY() const { return (fields[3] >> 0u) & 0x3Fu; }
|
||||
[[nodiscard]] uint32_t DstSelXYZ() const { return (fields[3] >> 0u) & 0x1FFu; }
|
||||
[[nodiscard]] uint32_t DstSelXYZW() const { return (fields[3] >> 0u) & 0xFFFu; }
|
||||
[[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; }
|
||||
|
||||
@@ -28,7 +28,7 @@ struct TileSizeAlign
|
||||
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);
|
||||
uint32_t pitch, uint32_t levels, bool neo);
|
||||
|
||||
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo,
|
||||
TileSizeAlign* stencil_size, TileSizeAlign* htile_size, TileSizeAlign* depth_size);
|
||||
|
||||
@@ -47,15 +47,18 @@ struct ImageImageCopy
|
||||
int dst_y;
|
||||
};
|
||||
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image);
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image, uint64_t dst_layout);
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, VulkanImage* dst_image, const Vector<BufferImageCopy>& regions,
|
||||
uint64_t dst_layout);
|
||||
void UtilImageToBuffer(CommandBuffer* buffer, VulkanImage* src_image, VulkanBuffer* dst_buffer, uint32_t dst_pitch, uint64_t src_layout);
|
||||
void UtilImageToImage(CommandBuffer* buffer, const Vector<ImageImageCopy>& regions, VulkanImage* dst_image, uint64_t dst_layout);
|
||||
void UtilBlitImage(CommandBuffer* buffer, VulkanImage* src_image, VulkanSwapchain* dst_swapchain);
|
||||
void UtilFillImage(GraphicContext* ctx, VulkanImage* dst_image, const void* src_data, uint64_t size, uint32_t src_pitch);
|
||||
void UtilFillImage(GraphicContext* ctx, VulkanImage* dst_image, const void* src_data, uint64_t size, uint32_t src_pitch,
|
||||
uint64_t dst_layout);
|
||||
void UtilFillImage(GraphicContext* ctx, VulkanImage* dst_image, const void* src_data, uint64_t size, const Vector<BufferImageCopy>& regions,
|
||||
uint64_t dst_layout);
|
||||
void UtilFillImage(GraphicContext* ctx, const Vector<ImageImageCopy>& regions, VulkanImage* dst_image, uint64_t dst_layout);
|
||||
void UtilFillBuffer(GraphicContext* ctx, void* dst_data, uint64_t size, uint32_t dst_pitch, VulkanImage* src_image, uint64_t src_layout);
|
||||
void UtilCopyBuffer(VulkanBuffer* src_buffer, VulkanBuffer* dst_buffer, uint64_t size);
|
||||
void UtilSetDepthLayoutOptimal(DepthStencilVulkanImage* image);
|
||||
void UtilSetImageLayoutOptimal(VulkanImage* image);
|
||||
|
||||
@@ -161,21 +161,22 @@ uint64_t KYTY_SYSV_ABI KernelGetProcessTimeCounterFrequency();
|
||||
|
||||
namespace Posix {
|
||||
|
||||
int KYTY_SYSV_ABI pthread_create(LibKernel::Pthread* thread, const LibKernel::PthreadAttr* attr, LibKernel::pthread_entry_func_t entry,
|
||||
void* arg);
|
||||
int KYTY_SYSV_ABI pthread_join(LibKernel::Pthread thread, void** value);
|
||||
int KYTY_SYSV_ABI pthread_cond_broadcast(LibKernel::PthreadCond* cond);
|
||||
int KYTY_SYSV_ABI pthread_cond_wait(LibKernel::PthreadCond* cond, LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_lock(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_unlock(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_rdlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_unlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_wrlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_key_create(LibKernel::PthreadKey* key, LibKernel::pthread_key_destructor_func_t destructor);
|
||||
int KYTY_SYSV_ABI pthread_key_delete(LibKernel::PthreadKey key);
|
||||
int KYTY_SYSV_ABI pthread_setspecific(LibKernel::PthreadKey key, void* value);
|
||||
int KYTY_SYSV_ABI pthread_mutex_destroy(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKernel::PthreadMutexattr* attr);
|
||||
int KYTY_SYSV_ABI pthread_create(LibKernel::Pthread* thread, const LibKernel::PthreadAttr* attr, LibKernel::pthread_entry_func_t entry,
|
||||
void* arg);
|
||||
int KYTY_SYSV_ABI pthread_join(LibKernel::Pthread thread, void** value);
|
||||
int KYTY_SYSV_ABI pthread_cond_broadcast(LibKernel::PthreadCond* cond);
|
||||
int KYTY_SYSV_ABI pthread_cond_wait(LibKernel::PthreadCond* cond, LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_lock(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_unlock(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_rdlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_unlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_rwlock_wrlock(LibKernel::PthreadRwlock* rwlock);
|
||||
int KYTY_SYSV_ABI pthread_key_create(LibKernel::PthreadKey* key, LibKernel::pthread_key_destructor_func_t destructor);
|
||||
int KYTY_SYSV_ABI pthread_key_delete(LibKernel::PthreadKey key);
|
||||
int KYTY_SYSV_ABI pthread_setspecific(LibKernel::PthreadKey key, void* value);
|
||||
void* KYTY_SYSV_ABI pthread_getspecific(LibKernel::PthreadKey key);
|
||||
int KYTY_SYSV_ABI pthread_mutex_destroy(LibKernel::PthreadMutex* mutex);
|
||||
int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKernel::PthreadMutexattr* attr);
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ enum class Direction
|
||||
{
|
||||
Silent,
|
||||
Console,
|
||||
File
|
||||
File,
|
||||
Directory
|
||||
};
|
||||
|
||||
Direction GetDirection();
|
||||
|
||||
@@ -39,7 +39,7 @@ struct HttpEpoll;
|
||||
|
||||
using HttpEpollHandle = HttpEpoll*;
|
||||
|
||||
using HttpsCallback = int (*)(int, unsigned int, void* const*, int, void*);
|
||||
using HttpsCallback = KYTY_SYSV_ABI int (*)(int, unsigned int, void* const*, int, void*);
|
||||
|
||||
int KYTY_SYSV_ABI HttpInit(int memid, int ssl_ctx_id, uint64_t pool_size);
|
||||
int KYTY_SYSV_ABI HttpTerm(int http_ctx_id);
|
||||
@@ -65,7 +65,7 @@ namespace NetCtl {
|
||||
struct NetCtlNatInfo;
|
||||
union NetCtlInfo;
|
||||
|
||||
using NetCtlCallback = void (*)(int, void*);
|
||||
using NetCtlCallback = KYTY_SYSV_ABI void (*)(int, void*);
|
||||
|
||||
int KYTY_SYSV_ABI NetCtlInit();
|
||||
void KYTY_SYSV_ABI NetCtlTerm();
|
||||
@@ -111,10 +111,13 @@ int KYTY_SYSV_ABI NpCheckCallbackForLib();
|
||||
|
||||
namespace NpTrophy {
|
||||
|
||||
struct NpTrophyFlagArray;
|
||||
|
||||
int KYTY_SYSV_ABI NpTrophyCreateHandle(int* handle);
|
||||
int KYTY_SYSV_ABI NpTrophyCreateContext(int* context, int user_id, uint32_t service_label, uint64_t options);
|
||||
int KYTY_SYSV_ABI NpTrophyRegisterContext(int context, int handle, uint64_t options);
|
||||
int KYTY_SYSV_ABI NpTrophyDestroyHandle(int handle);
|
||||
int KYTY_SYSV_ABI NpTrophyGetTrophyUnlockState(int context, int handle, NpTrophyFlagArray* flags, uint32_t* count);
|
||||
|
||||
} // namespace NpTrophy
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ public:
|
||||
static uint8_t* TlsGetAddr(Program* program);
|
||||
static void DeleteTls(Program* program, int thread_id);
|
||||
|
||||
void StackTrace(uint64_t frame_ptr);
|
||||
|
||||
private:
|
||||
static void LoadProgramToMemory(Program* program);
|
||||
static void ParseProgramDynamicInfo(Program* program);
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
AccessViolationType access_violation_type = AccessViolationType::Unknown;
|
||||
uint64_t access_violation_vaddr = 0;
|
||||
uint64_t exception_address = 0;
|
||||
uint64_t rbp = 0;
|
||||
};
|
||||
|
||||
using handler_func_t = void (*)(const ExceptionInfo*);
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
KYTY_CLASS_NO_COPY(Audio);
|
||||
|
||||
Id AudioOutOpen(int type, uint32_t samples_num, uint32_t freq, Format format);
|
||||
bool AudioOutClose(Id handle);
|
||||
bool AudioOutValid(Id handle);
|
||||
bool AudioOutSetVolume(Id handle, uint32_t bitflag, const int* volume);
|
||||
uint32_t AudioOutOutputs(OutputParam* params, uint32_t num);
|
||||
@@ -159,6 +160,19 @@ Audio::Id Audio::AudioOutOpen(int type, uint32_t samples_num, uint32_t freq, For
|
||||
return Id::Invalid();
|
||||
}
|
||||
|
||||
bool Audio::AudioOutClose(Id handle)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (AudioOutValid(handle))
|
||||
{
|
||||
m_out_ports[handle.GetId()].used = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Audio::AudioOutValid(Id handle)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
@@ -211,7 +225,7 @@ uint32_t Audio::AudioOutOutputs(OutputParam* params, uint32_t num)
|
||||
|
||||
const auto& first_port = m_out_ports[params[0].handle.GetId()];
|
||||
|
||||
uint64_t block_time = (1000000 * first_port.samples_num) / first_port.freq;
|
||||
uint64_t block_time = (params->data != nullptr ? (1000000 * first_port.samples_num) / first_port.freq : 0);
|
||||
uint64_t current_time = LibKernel::KernelGetProcessTime();
|
||||
|
||||
uint64_t max_wait_time = 0;
|
||||
@@ -354,6 +368,18 @@ int KYTY_SYSV_ABI AudioOutOpen(int user_id, int type, int index, uint32_t len, u
|
||||
return id.ToInt();
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AudioOutClose(int handle)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (!g_audio->AudioOutClose(Audio::Id(handle)))
|
||||
{
|
||||
return AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AudioOutSetVolume(int handle, uint32_t flag, int* vol)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -401,6 +427,29 @@ int KYTY_SYSV_ABI AudioOutOutputs(AudioOutOutputParam* param, uint32_t num)
|
||||
return static_cast<int>(g_audio->AudioOutOutputs(params, num));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AudioOutOutput(int handle, const void* ptr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t handle = %d\n", handle);
|
||||
|
||||
// EXIT_NOT_IMPLEMENTED(ptr == nullptr);
|
||||
|
||||
Audio::OutputParam params[1];
|
||||
|
||||
EXIT_IF(g_audio == nullptr);
|
||||
|
||||
params[0].handle = Audio::Id(handle);
|
||||
params[0].data = ptr;
|
||||
|
||||
if (!g_audio->AudioOutValid(params[0].handle))
|
||||
{
|
||||
return AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
return static_cast<int>(g_audio->AudioOutOutputs(params, 1));
|
||||
}
|
||||
|
||||
} // namespace AudioOut
|
||||
|
||||
namespace AudioIn {
|
||||
@@ -497,8 +546,428 @@ int KYTY_SYSV_ABI AjmInitialize(int64_t reserved, uint32_t* context)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AjmModuleRegister(uint32_t context, uint32_t codec, int64_t reserved)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(context != 1);
|
||||
EXIT_NOT_IMPLEMENTED(reserved != 0);
|
||||
|
||||
printf("\t codec = %u\n", codec);
|
||||
|
||||
switch (codec)
|
||||
{
|
||||
case 1: printf("\t %s\n", "ATRAC9 decoder"); break;
|
||||
case 2: printf("\t %s\n", "MPEG4-AAC decoder"); break;
|
||||
case 0: printf("\t %s\n", "MP3 decoder"); break;
|
||||
case 4: printf("\t %s\n", "CELP8 encoder"); break;
|
||||
case 3: printf("\t %s\n", "CELP8 decoder"); break;
|
||||
case 13: printf("\t %s\n", "CELP16 encoder"); break;
|
||||
case 12: printf("\t %s\n", "CELP16 decoder"); break;
|
||||
default: EXIT("unknown codec\n");
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace Ajm
|
||||
|
||||
namespace AvPlayer {
|
||||
|
||||
LIB_NAME("AvPlayer", "AvPlayer");
|
||||
|
||||
using AvPlayerAllocate = KYTY_SYSV_ABI void* (*)(void*, uint32_t, uint32_t);
|
||||
using AvPlayerDeallocate = KYTY_SYSV_ABI void (*)(void*, void*);
|
||||
using AvPlayerAllocateTexture = KYTY_SYSV_ABI void* (*)(void*, uint32_t, uint32_t);
|
||||
using AvPlayerDeallocateTexture = KYTY_SYSV_ABI void (*)(void*, void*);
|
||||
using AvPlayerOpenFile = KYTY_SYSV_ABI int (*)(void*, const char*);
|
||||
using AvPlayerCloseFile = KYTY_SYSV_ABI int (*)(void*);
|
||||
using AvPlayerReadOffsetFile = KYTY_SYSV_ABI int (*)(void*, uint8_t*, uint64_t, uint32_t);
|
||||
using AvPlayerSizeFile = KYTY_SYSV_ABI uint64_t (*)(void*);
|
||||
using AvPlayerEventCallback = KYTY_SYSV_ABI void (*)(void*, int32_t, int32_t, void*);
|
||||
|
||||
struct AvPlayerMemAllocator
|
||||
{
|
||||
void* object_pointer = nullptr;
|
||||
AvPlayerAllocate allocate = nullptr;
|
||||
AvPlayerDeallocate deallocate = nullptr;
|
||||
AvPlayerAllocateTexture allocate_texture = nullptr;
|
||||
AvPlayerDeallocateTexture deallocate_texture = nullptr;
|
||||
};
|
||||
|
||||
struct AvPlayerFileReplacement
|
||||
{
|
||||
void* object_pointer = nullptr;
|
||||
AvPlayerOpenFile open = nullptr;
|
||||
AvPlayerCloseFile close = nullptr;
|
||||
AvPlayerReadOffsetFile read_offset = nullptr;
|
||||
AvPlayerSizeFile size = nullptr;
|
||||
};
|
||||
|
||||
struct AvPlayerEventReplacement
|
||||
{
|
||||
void* object_pointer = nullptr;
|
||||
AvPlayerEventCallback event_callback = nullptr;
|
||||
};
|
||||
|
||||
enum AvPlayerDebuglevels
|
||||
{
|
||||
AvplayerDbgNone,
|
||||
AvplayerDbgInfo,
|
||||
AvplayerDbgWarnings,
|
||||
AvplayerDbgAll
|
||||
};
|
||||
|
||||
struct AvPlayerInitData
|
||||
{
|
||||
AvPlayerMemAllocator memory_replacement;
|
||||
AvPlayerFileReplacement file_replacement;
|
||||
AvPlayerEventReplacement event_replacement;
|
||||
AvPlayerDebuglevels debug_level = AvPlayerDebuglevels::AvplayerDbgNone;
|
||||
uint32_t base_priority = 0;
|
||||
int32_t num_output_video_framebuffers = 0;
|
||||
Bool auto_start = 0;
|
||||
uint8_t reserved[3] = {};
|
||||
const char* default_language = nullptr;
|
||||
};
|
||||
|
||||
struct AvPlayerAudioEx
|
||||
{
|
||||
uint16_t channel_count;
|
||||
uint8_t reserved[2];
|
||||
uint32_t sample_rate;
|
||||
uint32_t size;
|
||||
uint8_t language_code[4];
|
||||
uint8_t reserved1[64];
|
||||
};
|
||||
|
||||
struct AvPlayerVideoEx
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
float aspect_ratio;
|
||||
uint8_t language_code[4];
|
||||
uint32_t framerate;
|
||||
uint32_t crop_left_offset;
|
||||
uint32_t crop_right_offset;
|
||||
uint32_t crop_top_offset;
|
||||
uint32_t crop_bottom_offset;
|
||||
uint32_t pitch;
|
||||
uint8_t luma_bit_depth;
|
||||
uint8_t chroma_bit_depth;
|
||||
Bool video_full_tange_flag;
|
||||
uint8_t reserved1[37];
|
||||
};
|
||||
|
||||
struct AvPlayerTimedTextEx
|
||||
{
|
||||
uint8_t language_code[4];
|
||||
uint8_t reserved[12];
|
||||
uint8_t reserved1[64];
|
||||
};
|
||||
|
||||
union AvPlayerStreamDetailsEx
|
||||
{
|
||||
AvPlayerAudioEx audio;
|
||||
AvPlayerVideoEx video;
|
||||
AvPlayerTimedTextEx subs;
|
||||
uint8_t reserved1[80];
|
||||
};
|
||||
|
||||
struct AvPlayerFrameInfoEx
|
||||
{
|
||||
void* data;
|
||||
uint8_t reserved[4];
|
||||
uint64_t time_stamp;
|
||||
AvPlayerStreamDetailsEx details;
|
||||
};
|
||||
|
||||
struct AvPlayerInternal
|
||||
{
|
||||
String filename;
|
||||
bool loop = false;
|
||||
AvPlayerMemAllocator mem;
|
||||
Core::Mutex mutex;
|
||||
void* fake_frame = nullptr;
|
||||
uint32_t fake_width = 0;
|
||||
uint32_t fake_height = 0;
|
||||
float fake_frame_rate = 0.0f;
|
||||
uint32_t fake_frame_num = 0;
|
||||
uint32_t fake_obtained_num = 0;
|
||||
};
|
||||
|
||||
static void rgb_to_yuv(float r, float g, float b, uint8_t* y, uint8_t* u, uint8_t* v)
|
||||
{
|
||||
int yf = static_cast<int>(16.0f + 65.481f * r + 128.553f * g + 24.966f * b);
|
||||
int uf = static_cast<int>(128.0f + -37.797f * r + -74.203f * g + 112.0f * b);
|
||||
int vf = static_cast<int>(128.0f + 112.0f * r + -93.786f * g + -18.214f * b);
|
||||
*y = (yf < 0 ? 0 : (yf > 255 ? 255 : yf));
|
||||
*u = (uf < 0 ? 0 : (uf > 255 ? 255 : uf));
|
||||
*v = (vf < 0 ? 0 : (vf > 255 ? 255 : vf));
|
||||
}
|
||||
|
||||
static void draw_fake_frame(uint32_t width, uint32_t height, void* data, float l)
|
||||
{
|
||||
constexpr int STRIPS_NUM = 5;
|
||||
|
||||
uint32_t luma_width = width;
|
||||
uint32_t luma_height = height;
|
||||
uint32_t chroma_width = luma_width / 2;
|
||||
uint32_t chroma_height = luma_height / 2;
|
||||
auto* buffer = static_cast<uint8_t*>(data);
|
||||
auto* luma = buffer;
|
||||
auto* chroma = buffer + luma_width * luma_height;
|
||||
uint32_t luma_strip_size = luma_height / STRIPS_NUM;
|
||||
uint32_t chroma_strip_size = chroma_height / STRIPS_NUM;
|
||||
|
||||
uint8_t color[STRIPS_NUM][3] = {};
|
||||
|
||||
rgb_to_yuv(l, 0, 0, &color[0][0], &color[0][1], &color[0][2]);
|
||||
rgb_to_yuv(0, l, 0, &color[1][0], &color[1][1], &color[1][2]);
|
||||
rgb_to_yuv(0, 0, l, &color[2][0], &color[2][1], &color[2][2]);
|
||||
rgb_to_yuv(0, 0, 0, &color[3][0], &color[3][1], &color[3][2]);
|
||||
rgb_to_yuv(l, l, l, &color[4][0], &color[4][1], &color[4][2]);
|
||||
|
||||
for (uint32_t y = 0; y < luma_strip_size; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < luma_width; x++)
|
||||
{
|
||||
for (int si = 0; si < STRIPS_NUM; si++)
|
||||
{
|
||||
luma[(y + luma_strip_size * si) * luma_width + x] = color[si][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32_t y = 0; y < chroma_strip_size; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < chroma_width; x++)
|
||||
{
|
||||
for (int si = 0; si < STRIPS_NUM; si++)
|
||||
{
|
||||
chroma[(y + chroma_strip_size * si) * chroma_width * 2 + x * 2 + 0] = color[si][1];
|
||||
chroma[(y + chroma_strip_size * si) * chroma_width * 2 + x * 2 + 1] = color[si][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void create_fake_video(AvPlayerInternal* r)
|
||||
{
|
||||
uint32_t luma_width = 1920;
|
||||
uint32_t luma_height = 1080;
|
||||
uint32_t chroma_width = luma_width / 2;
|
||||
uint32_t chroma_height = luma_height / 2;
|
||||
uint32_t size = luma_width * luma_height + chroma_width * chroma_height * 2;
|
||||
auto* buffer = static_cast<uint8_t*>(r->mem.allocate_texture(r->mem.object_pointer, 256, size));
|
||||
|
||||
r->fake_frame = buffer;
|
||||
r->fake_width = luma_width;
|
||||
r->fake_height = luma_height;
|
||||
r->fake_frame_rate = 59.94f;
|
||||
r->fake_frame_num = 90;
|
||||
r->fake_obtained_num = 0;
|
||||
}
|
||||
|
||||
static void delete_fake_video(AvPlayerInternal* r)
|
||||
{
|
||||
r->mem.deallocate_texture(r->mem.object_pointer, r->fake_frame);
|
||||
r->fake_frame = nullptr;
|
||||
r->fake_width = 0;
|
||||
r->fake_height = 0;
|
||||
r->fake_frame_rate = 0.0f;
|
||||
r->fake_frame_num = 0;
|
||||
r->fake_obtained_num = 0;
|
||||
}
|
||||
|
||||
static bool get_fake_video(AvPlayerInternal* r, AvPlayerFrameInfoEx* info)
|
||||
{
|
||||
if (r->fake_obtained_num < r->fake_frame_num)
|
||||
{
|
||||
info->data = r->fake_frame;
|
||||
info->time_stamp = static_cast<uint64_t>(1000.0f * (static_cast<float>(r->fake_obtained_num) / r->fake_frame_rate));
|
||||
|
||||
info->details.video.width = r->fake_width;
|
||||
info->details.video.height = r->fake_height;
|
||||
info->details.video.aspect_ratio = static_cast<float>(r->fake_width) / static_cast<float>(r->fake_height);
|
||||
info->details.video.language_code[0] = 'e';
|
||||
info->details.video.language_code[1] = 'n';
|
||||
info->details.video.language_code[2] = 'g';
|
||||
info->details.video.language_code[3] = '\0';
|
||||
info->details.video.framerate = 0;
|
||||
info->details.video.crop_left_offset = 0;
|
||||
info->details.video.crop_right_offset = 0;
|
||||
info->details.video.crop_top_offset = 0;
|
||||
info->details.video.crop_bottom_offset = 0;
|
||||
info->details.video.pitch = r->fake_width;
|
||||
info->details.video.luma_bit_depth = 8;
|
||||
info->details.video.chroma_bit_depth = 8;
|
||||
info->details.video.video_full_tange_flag = 0;
|
||||
|
||||
float pos = static_cast<float>(r->fake_obtained_num) / static_cast<float>(r->fake_frame_num);
|
||||
float level = 1.0f;
|
||||
|
||||
if (pos < 0.2f)
|
||||
{
|
||||
level = pos * pos * ((1.0f / 0.2f) * (1.0f / 0.2f));
|
||||
} else if (pos > 0.5f)
|
||||
{
|
||||
level = 1.0f - (1.0f - pos * (1.0f / 0.5f)) * (1.0f - pos * (1.0f / 0.5f));
|
||||
}
|
||||
|
||||
draw_fake_frame(r->fake_width, r->fake_height, r->fake_frame, level * 0.7f);
|
||||
|
||||
r->fake_obtained_num++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool fake_is_playing(AvPlayerInternal* r)
|
||||
{
|
||||
return r->fake_obtained_num < r->fake_frame_num;
|
||||
}
|
||||
|
||||
AvPlayerInternal* KYTY_SYSV_ABI AvPlayerInit(AvPlayerInitData* init)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(init == nullptr);
|
||||
|
||||
printf("\t memory_replacement.object_pointer = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->memory_replacement.object_pointer));
|
||||
printf("\t memory_replacement.allocate = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->memory_replacement.allocate));
|
||||
printf("\t memory_replacement.deallocate = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->memory_replacement.deallocate));
|
||||
printf("\t memory_replacement.allocate_texture = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->memory_replacement.allocate_texture));
|
||||
printf("\t memory_replacement.deallocate_texture = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->memory_replacement.deallocate_texture));
|
||||
printf("\t file_replacement.object_pointer = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->file_replacement.object_pointer));
|
||||
printf("\t file_replacement.open = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->file_replacement.open));
|
||||
printf("\t file_replacement.close = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->file_replacement.close));
|
||||
printf("\t file_replacement.read_offset = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->file_replacement.read_offset));
|
||||
printf("\t file_replacement.size = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(init->file_replacement.size));
|
||||
printf("\t event_replacement.object_pointer = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->event_replacement.object_pointer));
|
||||
printf("\t event_replacement.event_callback = %016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(init->event_replacement.event_callback));
|
||||
printf("\t debug_level = %s\n", Core::EnumName(init->debug_level).C_Str());
|
||||
printf("\t num_output_video_framebuffers = %d\n", init->num_output_video_framebuffers);
|
||||
printf("\t base_priority = %u\n", init->base_priority);
|
||||
printf("\t auto_start = %u\n", init->auto_start);
|
||||
printf("\t default_language = %s\n", init->default_language == nullptr ? "(null)" : init->default_language);
|
||||
|
||||
auto* r = new AvPlayerInternal;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(init->auto_start != 0);
|
||||
EXIT_NOT_IMPLEMENTED(init->file_replacement.object_pointer != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->file_replacement.open != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->file_replacement.close != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->file_replacement.read_offset != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->file_replacement.size != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->event_replacement.object_pointer != nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(init->event_replacement.event_callback != nullptr);
|
||||
|
||||
r->mem = init->memory_replacement;
|
||||
|
||||
create_fake_video(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AvPlayerAddSource(AvPlayerInternal* h, const char* filename)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h == nullptr);
|
||||
|
||||
printf("\t filename = %s\n", filename);
|
||||
|
||||
Core::LockGuard lock(h->mutex);
|
||||
|
||||
h->filename = filename;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AvPlayerSetLooping(AvPlayerInternal* h, Bool loop)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h == nullptr);
|
||||
|
||||
printf("\t loop = %u\n", loop);
|
||||
|
||||
Core::LockGuard lock(h->mutex);
|
||||
|
||||
h->loop = (loop != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bool KYTY_SYSV_ABI AvPlayerGetVideoDataEx(AvPlayerInternal* h, AvPlayerFrameInfoEx* video_info)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(video_info == nullptr);
|
||||
|
||||
Core::LockGuard lock(h->mutex);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h->loop);
|
||||
|
||||
if (get_fake_video(h, video_info))
|
||||
{
|
||||
return 1; // true
|
||||
}
|
||||
|
||||
return 0; // false
|
||||
}
|
||||
|
||||
Bool KYTY_SYSV_ABI AvPlayerGetAudioData(AvPlayerInternal* h, AvPlayerFrameInfo* audio_info)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(audio_info == nullptr);
|
||||
|
||||
return 0; // false
|
||||
}
|
||||
|
||||
Bool KYTY_SYSV_ABI AvPlayerIsActive(AvPlayerInternal* h)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (h != nullptr)
|
||||
{
|
||||
Core::LockGuard lock(h->mutex);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h->loop);
|
||||
|
||||
if (fake_is_playing(h))
|
||||
{
|
||||
return 1; // true
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // false
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AvPlayerClose(AvPlayerInternal* h)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(h == nullptr);
|
||||
|
||||
delete_fake_video(h);
|
||||
|
||||
delete h;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace AvPlayer
|
||||
|
||||
} // namespace Kyty::Libs::Audio
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -22,9 +22,12 @@ struct Config
|
||||
String command_buffer_dump_folder = U"_Buffers";
|
||||
Log::Direction printf_direction = Log::Direction::Console;
|
||||
String printf_output_file = U"_kyty.txt";
|
||||
String printf_output_folder = U"_Logs";
|
||||
ProfilerDirection profiler_direction = ProfilerDirection::None;
|
||||
String profiler_output_file = U"_profile.prof";
|
||||
bool spirv_debug_printf_enabled = false;
|
||||
bool pipeline_dump_enabled = false;
|
||||
String pipeline_dump_folder = U"_Pipelines";
|
||||
};
|
||||
|
||||
static Config* g_config = nullptr;
|
||||
@@ -92,9 +95,12 @@ void Load(const Scripts::ScriptVar& cfg)
|
||||
LoadStr(g_config->command_buffer_dump_folder, cfg, U"CommandBufferDumpFolder");
|
||||
LoadEnum(g_config->printf_direction, cfg, U"PrintfDirection");
|
||||
LoadStr(g_config->printf_output_file, cfg, U"PrintfOutputFile");
|
||||
LoadStr(g_config->printf_output_folder, cfg, U"PrintfOutputFolder");
|
||||
LoadEnum(g_config->profiler_direction, cfg, U"ProfilerDirection");
|
||||
LoadStr(g_config->profiler_output_file, cfg, U"ProfilerOutputFile");
|
||||
LoadBool(g_config->spirv_debug_printf_enabled, cfg, U"SpirvDebugPrintfEnabled");
|
||||
LoadBool(g_config->pipeline_dump_enabled, cfg, U"PipelineDumpEnabled");
|
||||
LoadStr(g_config->pipeline_dump_folder, cfg, U"PipelineDumpFolder");
|
||||
}
|
||||
|
||||
uint32_t GetScreenWidth()
|
||||
@@ -157,6 +163,11 @@ String GetPrintfOutputFile()
|
||||
return g_config->printf_output_file;
|
||||
}
|
||||
|
||||
String GetPrintfOutputFolder()
|
||||
{
|
||||
return g_config->printf_output_folder;
|
||||
}
|
||||
|
||||
ProfilerDirection GetProfilerDirection()
|
||||
{
|
||||
return g_config->profiler_direction;
|
||||
@@ -172,6 +183,16 @@ bool SpirvDebugPrintfEnabled()
|
||||
return g_config->spirv_debug_printf_enabled;
|
||||
}
|
||||
|
||||
bool PipelineDumpEnabled()
|
||||
{
|
||||
return g_config->pipeline_dump_enabled;
|
||||
}
|
||||
|
||||
String GetPipelineDumpFolder()
|
||||
{
|
||||
return g_config->pipeline_dump_folder;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Config
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -560,6 +560,25 @@ int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PadResetLightBar(int handle)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(handle != 1);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PadSetLightBar(int handle, const PadLightBarParam* param)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(handle != 1);
|
||||
EXIT_NOT_IMPLEMENTED(param == nullptr);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Controller
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Emulator/Graphics/GraphicsRun.h"
|
||||
#include "Emulator/Graphics/HardwareContext.h"
|
||||
#include "Emulator/Graphics/Objects/GpuMemory.h"
|
||||
#include "Emulator/Graphics/Objects/IndexBuffer.h"
|
||||
#include "Emulator/Graphics/Objects/Label.h"
|
||||
#include "Emulator/Graphics/Pm4.h"
|
||||
#include "Emulator/Graphics/Tile.h"
|
||||
@@ -38,6 +39,7 @@ KYTY_SUBSYSTEM_INIT(Graphics)
|
||||
GpuMemoryInit();
|
||||
LabelInit();
|
||||
TileInit();
|
||||
IndexBufferInit();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Graphics) {}
|
||||
@@ -519,7 +521,7 @@ void KYTY_SYSV_ABI GraphicsFlushMemory()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
GpuMemoryFlush(WindowGetGraphicContext());
|
||||
GpuMemoryFlushAll(WindowGetGraphicContext());
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,8 +32,6 @@
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandProcessor;
|
||||
|
||||
class CommandProcessor
|
||||
{
|
||||
public:
|
||||
@@ -56,10 +54,14 @@ public:
|
||||
void BufferFlush();
|
||||
void BufferWait();
|
||||
|
||||
void Lock() { m_mutex.Lock(); }
|
||||
void Unlock() { m_mutex.Unlock(); }
|
||||
|
||||
HW::HardwareContext* GetCtx() { return &m_ctx; }
|
||||
HW::UserConfig* GetUcfg() { return &m_ucfg; }
|
||||
|
||||
void SetIndexType(uint32_t index_type_and_size);
|
||||
void SetNumInstances(uint32_t num_instances);
|
||||
void DrawIndex(uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type);
|
||||
void DrawIndexAuto(uint32_t index_count, uint32_t flags);
|
||||
void WriteAtEndOfPipe32(uint32_t cache_policy, uint32_t event_write_dest, uint32_t eop_event_type, uint32_t cache_action,
|
||||
@@ -123,8 +125,9 @@ private:
|
||||
|
||||
HW::HardwareContext m_ctx;
|
||||
HW::UserConfig m_ucfg;
|
||||
uint32_t m_index_type_and_size = 0;
|
||||
HW::UserSgprType m_user_data_marker = HW::UserSgprType::Unknown;
|
||||
uint32_t m_index_type_and_size = 0;
|
||||
uint32_t m_num_instances = 1;
|
||||
|
||||
Core::Mutex m_mutex;
|
||||
|
||||
@@ -488,6 +491,8 @@ void CommandProcessor::Reset()
|
||||
|
||||
BufferWait();
|
||||
|
||||
GraphicsRenderDeleteIndexBuffers();
|
||||
|
||||
m_ucfg.Reset();
|
||||
m_ctx.Reset();
|
||||
m_index_type_and_size = 0;
|
||||
@@ -621,6 +626,8 @@ void CommandProcessor::DumpConstRam(uint32_t* dst, uint32_t offset, uint32_t dw_
|
||||
GpuMemoryCheckAccessViolation(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
|
||||
memcpy(dst, m_const_ram + offset / 4, dw_num * 4);
|
||||
|
||||
GraphicsRenderMemoryFlush(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
}
|
||||
|
||||
void CommandProcessor::WaitRegMem(uint32_t func, bool me, bool mem, const uint32_t* addr, uint32_t ref, uint32_t mask, uint32_t poll)
|
||||
@@ -647,6 +654,8 @@ void CommandProcessor::WriteData(uint32_t* dst, const uint32_t* src, uint32_t dw
|
||||
GpuMemoryCheckAccessViolation(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
|
||||
memcpy(dst, src, dw_num * 4);
|
||||
|
||||
GraphicsRenderMemoryFlush(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
}
|
||||
|
||||
void GraphicsRing::Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer, uint32_t num_const_dw, int handle,
|
||||
@@ -973,6 +982,20 @@ void CommandProcessor::SetIndexType(uint32_t index_type_and_size)
|
||||
m_index_type_and_size = index_type_and_size;
|
||||
}
|
||||
|
||||
void CommandProcessor::SetNumInstances(uint32_t num_instances)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (num_instances == 0)
|
||||
{
|
||||
num_instances = 1;
|
||||
}
|
||||
|
||||
m_num_instances = num_instances;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(m_num_instances != 1);
|
||||
}
|
||||
|
||||
void CommandProcessor::DrawIndex(uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
@@ -1225,15 +1248,15 @@ void CommandProcessor::WriteBack()
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
GraphicsRenderWriteBack();
|
||||
GraphicsRenderWriteBack(this);
|
||||
}
|
||||
|
||||
void CommandBuffer::CommandProcessorWait()
|
||||
{
|
||||
EXIT_IF(m_parent == nullptr);
|
||||
|
||||
m_parent->BufferWait();
|
||||
}
|
||||
// void CommandBuffer::CommandProcessorWait()
|
||||
//{
|
||||
// EXIT_IF(m_parent == nullptr);
|
||||
//
|
||||
// m_parent->BufferWait();
|
||||
//}
|
||||
|
||||
void GraphicsRunSubmit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint32_t* cmd_const_buffer, uint32_t num_const_dw)
|
||||
{
|
||||
@@ -1304,6 +1327,34 @@ int GraphicsRunGetFrameNum()
|
||||
return g_gpu->GetFrameNum();
|
||||
}
|
||||
|
||||
void GraphicsRunCommandProcessorFlush(CommandProcessor* cp)
|
||||
{
|
||||
EXIT_IF(cp == nullptr);
|
||||
|
||||
cp->BufferFlush();
|
||||
}
|
||||
|
||||
void GraphicsRunCommandProcessorWait(CommandProcessor* cp)
|
||||
{
|
||||
EXIT_IF(cp == nullptr);
|
||||
|
||||
cp->BufferWait();
|
||||
}
|
||||
|
||||
void GraphicsRunCommandProcessorLock(CommandProcessor* cp)
|
||||
{
|
||||
EXIT_IF(cp == nullptr);
|
||||
|
||||
cp->Lock();
|
||||
}
|
||||
|
||||
void GraphicsRunCommandProcessorUnlock(CommandProcessor* cp)
|
||||
{
|
||||
EXIT_IF(cp == nullptr);
|
||||
|
||||
cp->Unlock();
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_depth_render_target)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_Z_INFO);
|
||||
@@ -1404,33 +1455,15 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_ps_input)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::SPI_PS_INPUT_CNTL_0);
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
if (cmd_id == 0xC0016900)
|
||||
{
|
||||
cp->GetCtx()->SetPsInputSettings(0, buffer[0]);
|
||||
count = 1;
|
||||
} else if (cmd_id == 0xC0026900)
|
||||
{
|
||||
cp->GetCtx()->SetPsInputSettings(0, buffer[0]);
|
||||
cp->GetCtx()->SetPsInputSettings(1, buffer[1]);
|
||||
count = 2;
|
||||
} else if (cmd_id == 0xC0036900)
|
||||
{
|
||||
cp->GetCtx()->SetPsInputSettings(0, buffer[0]);
|
||||
cp->GetCtx()->SetPsInputSettings(1, buffer[1]);
|
||||
cp->GetCtx()->SetPsInputSettings(2, buffer[2]);
|
||||
count = 3;
|
||||
} else if (cmd_id == 0xc0046900)
|
||||
{
|
||||
cp->GetCtx()->SetPsInputSettings(0, buffer[0]);
|
||||
cp->GetCtx()->SetPsInputSettings(1, buffer[1]);
|
||||
cp->GetCtx()->SetPsInputSettings(2, buffer[2]);
|
||||
cp->GetCtx()->SetPsInputSettings(3, buffer[3]);
|
||||
count = 4;
|
||||
}
|
||||
uint32_t count = (cmd_id >> 16u) & 0x3fffu;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(count == 0);
|
||||
EXIT_NOT_IMPLEMENTED(count > 32);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
cp->GetCtx()->SetPsInputSettings(i, buffer[i]);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -2179,6 +2212,17 @@ KYTY_CP_OP_PARSER(cp_op_index_type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_CP_OP_PARSER(cp_op_num_instances)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0002f00);
|
||||
|
||||
cp->SetNumInstances(buffer[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_CP_OP_PARSER(cp_op_push_marker)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
@@ -2211,16 +2255,50 @@ KYTY_CP_OP_PARSER(cp_op_draw_index)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC008100C);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC008100C && cmd_id != 0xc0042700);
|
||||
|
||||
uint32_t index_count = buffer[0];
|
||||
auto* index_addr = reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
|
||||
uint32_t flags = buffer[3];
|
||||
uint32_t type = buffer[4];
|
||||
if (cmd_id == 0xC008100C)
|
||||
{
|
||||
uint32_t index_count = buffer[0];
|
||||
auto* index_addr = reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
|
||||
uint32_t flags = buffer[3];
|
||||
uint32_t type = buffer[4];
|
||||
|
||||
cp->DrawIndex(index_count, index_addr, flags, type);
|
||||
cp->DrawIndex(index_count, index_addr, flags, type);
|
||||
|
||||
return 9;
|
||||
return 9;
|
||||
}
|
||||
|
||||
if (cmd_id == 0xc0042700)
|
||||
{
|
||||
uint32_t index_count = buffer[0];
|
||||
auto* index_addr = reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(buffer[3] != index_count);
|
||||
EXIT_NOT_IMPLEMENTED(buffer[4] != 0);
|
||||
|
||||
cp->DrawIndex(index_count, index_addr, 0, 1);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!(dw >= 7));
|
||||
|
||||
if (buffer[5] == 0xc0001000)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(buffer[6] != 0);
|
||||
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (buffer[5] == 0xc0021000)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(buffer[6] != 0);
|
||||
|
||||
return 9;
|
||||
}
|
||||
|
||||
EXIT("invalid draw_index\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_CP_OP_PARSER(cp_op_indirect_buffer)
|
||||
@@ -2879,7 +2957,9 @@ static void graphics_init_jmp_tables()
|
||||
}
|
||||
|
||||
g_cp_op_func[Pm4::IT_NOP] = cp_op_nop;
|
||||
g_cp_op_func[Pm4::IT_DRAW_INDEX_2] = cp_op_draw_index;
|
||||
g_cp_op_func[Pm4::IT_INDEX_TYPE] = cp_op_index_type;
|
||||
g_cp_op_func[Pm4::IT_NUM_INSTANCES] = cp_op_num_instances;
|
||||
g_cp_op_func[Pm4::IT_DRAW_INDEX_AUTO] = cp_op_draw_index_auto;
|
||||
g_cp_op_func[Pm4::IT_WAIT_REG_MEM] = cp_op_wait_reg_mem;
|
||||
g_cp_op_func[Pm4::IT_WRITE_DATA] = cp_op_write_data;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
// IWYU pragma: no_forward_declare VkImageView_T
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
@@ -43,9 +43,13 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = pixel_format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
vk_obj->compressed = htile;
|
||||
|
||||
VkImageCreateInfo image_info {};
|
||||
@@ -103,7 +107,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
VkImageViewCreateInfo create_info2 {};
|
||||
create_info2.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
@@ -122,10 +126,10 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info2.subresourceRange.layerCount = 1;
|
||||
create_info2.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info2, nullptr, &vk_obj->texture_view);
|
||||
vkCreateImageView(ctx->device, &create_info2, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEPTH_TEXTURE]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->texture_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEPTH_TEXTURE] == nullptr);
|
||||
|
||||
UtilSetDepthLayoutOptimal(vk_obj);
|
||||
|
||||
@@ -143,8 +147,8 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
DeleteFramebuffer(vk_obj);
|
||||
|
||||
vkDestroyImageView(ctx->device, vk_obj->texture_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEPTH_TEXTURE], nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEFAULT], nullptr);
|
||||
|
||||
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,73 @@
|
||||
#include "Emulator/Graphics/Objects/IndexBuffer.h"
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class IndexBufferManager
|
||||
{
|
||||
public:
|
||||
IndexBufferManager() { EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); }
|
||||
virtual ~IndexBufferManager() { KYTY_NOT_IMPLEMENTED; }
|
||||
KYTY_CLASS_NO_COPY(IndexBufferManager);
|
||||
|
||||
void RegisterForDelete(VulkanBuffer* buf)
|
||||
{
|
||||
Core::Mutex m_mutex;
|
||||
|
||||
m_buffers.Add(buf);
|
||||
}
|
||||
|
||||
void DeleteAll(GraphicContext* ctx)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("IndexBufferManager::DeleteAll");
|
||||
|
||||
Core::Mutex m_mutex;
|
||||
|
||||
for (auto* vk_obj: m_buffers)
|
||||
{
|
||||
EXIT_IF(vk_obj == nullptr);
|
||||
EXIT_IF(vk_obj->buffer == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
VulkanDeleteBuffer(ctx, vk_obj);
|
||||
|
||||
delete vk_obj;
|
||||
}
|
||||
|
||||
m_buffers.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
Core::Mutex m_mutex;
|
||||
|
||||
Vector<VulkanBuffer*> m_buffers;
|
||||
};
|
||||
|
||||
static IndexBufferManager* g_index_buffer_manager = nullptr;
|
||||
|
||||
void IndexBufferInit()
|
||||
{
|
||||
EXIT_IF(g_index_buffer_manager != nullptr);
|
||||
|
||||
g_index_buffer_manager = new IndexBufferManager;
|
||||
}
|
||||
|
||||
void IndexBufferDeleteAll(GraphicContext* ctx)
|
||||
{
|
||||
EXIT_IF(g_index_buffer_manager == nullptr);
|
||||
|
||||
g_index_buffer_manager->DeleteAll(ctx);
|
||||
}
|
||||
|
||||
static void* create_func(GraphicContext* ctx, const uint64_t* /*params*/, const uint64_t* vaddr, const uint64_t* size, int vaddr_num,
|
||||
VulkanMemory* mem)
|
||||
{
|
||||
@@ -60,19 +116,15 @@ static void update_func(GraphicContext* /*ctx*/, const uint64_t* /*params*/, voi
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* /*mem*/)
|
||||
static void delete_func(GraphicContext* /*ctx*/, void* obj, VulkanMemory* /*mem*/)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("IndexBufferGpuObject::delete_func");
|
||||
|
||||
EXIT_IF(g_index_buffer_manager == nullptr);
|
||||
|
||||
auto* vk_obj = reinterpret_cast<VulkanBuffer*>(obj);
|
||||
|
||||
EXIT_IF(vk_obj == nullptr);
|
||||
EXIT_IF(vk_obj->buffer == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
VulkanDeleteBuffer(ctx, vk_obj);
|
||||
|
||||
delete vk_obj;
|
||||
g_index_buffer_manager->RegisterForDelete(vk_obj);
|
||||
}
|
||||
|
||||
bool IndexBufferGpuObject::Equal(const uint64_t* /*other*/) const
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/GraphicsRun.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandProcessor;
|
||||
|
||||
enum LabelStatus
|
||||
{
|
||||
New,
|
||||
@@ -24,22 +25,22 @@ enum LabelStatus
|
||||
|
||||
struct LabelCallbacks
|
||||
{
|
||||
uint64_t* dst_gpu_addr64 = nullptr;
|
||||
uint64_t value64 = 0;
|
||||
uint32_t* dst_gpu_addr32 = nullptr;
|
||||
uint32_t value32 = 0;
|
||||
LabelGpuObject::callback_t callback_1 = nullptr;
|
||||
LabelGpuObject::callback_t callback_2 = nullptr;
|
||||
uint64_t args[4] = {};
|
||||
uint64_t* dst_gpu_addr64 = nullptr;
|
||||
uint64_t value64 = 0;
|
||||
uint32_t* dst_gpu_addr32 = nullptr;
|
||||
uint32_t value32 = 0;
|
||||
LabelGpuObject::callback_t callback_1 = nullptr;
|
||||
LabelGpuObject::callback_t callback_2 = nullptr;
|
||||
uint64_t args[LABEL_ARGS_MAX] = {};
|
||||
};
|
||||
|
||||
struct Label
|
||||
{
|
||||
VkDevice device = nullptr;
|
||||
VkEvent event = nullptr;
|
||||
LabelStatus status = LabelStatus::New;
|
||||
LabelCallbacks callbacks;
|
||||
CommandBuffer* buffer = nullptr;
|
||||
VkDevice device = nullptr;
|
||||
VkEvent event = nullptr;
|
||||
LabelStatus status = LabelStatus::New;
|
||||
LabelCallbacks callbacks;
|
||||
CommandProcessor* cp = nullptr;
|
||||
};
|
||||
|
||||
class LabelManager
|
||||
@@ -179,11 +180,12 @@ Label* LabelManager::Create64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint6
|
||||
label->device = ctx->device;
|
||||
label->callbacks.callback_1 = callback_1;
|
||||
label->callbacks.callback_2 = callback_2;
|
||||
label->callbacks.args[0] = args[0];
|
||||
label->callbacks.args[1] = args[1];
|
||||
label->callbacks.args[2] = args[2];
|
||||
label->callbacks.args[3] = args[3];
|
||||
label->buffer = nullptr;
|
||||
label->cp = nullptr;
|
||||
|
||||
for (int i = 0; i < LABEL_ARGS_MAX; i++)
|
||||
{
|
||||
label->callbacks.args[i] = args[i];
|
||||
}
|
||||
|
||||
VkEventCreateInfo create_info {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
|
||||
@@ -218,10 +220,12 @@ Label* LabelManager::Create32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint3
|
||||
label->device = ctx->device;
|
||||
label->callbacks.callback_1 = callback_1;
|
||||
label->callbacks.callback_2 = callback_2;
|
||||
label->callbacks.args[0] = args[0];
|
||||
label->callbacks.args[1] = args[1];
|
||||
label->callbacks.args[2] = args[2];
|
||||
label->callbacks.args[3] = args[3];
|
||||
label->cp = nullptr;
|
||||
|
||||
for (int i = 0; i < LABEL_ARGS_MAX; i++)
|
||||
{
|
||||
label->callbacks.args[i] = args[i];
|
||||
}
|
||||
|
||||
VkEventCreateInfo create_info {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
|
||||
@@ -268,10 +272,10 @@ void LabelManager::Destroy(Label* label)
|
||||
EXIT_IF(label == nullptr);
|
||||
EXIT_IF(label->event == nullptr);
|
||||
EXIT_IF(label->device == nullptr);
|
||||
EXIT_IF(label->buffer == nullptr);
|
||||
EXIT_IF(label->cp == nullptr);
|
||||
|
||||
// All submitted commands that refer to event must have completed execution
|
||||
label->buffer->CommandProcessorWait();
|
||||
GraphicsRunCommandProcessorWait(label->cp);
|
||||
|
||||
vkDestroyEvent(label->device, label->event, nullptr);
|
||||
|
||||
@@ -306,7 +310,7 @@ void LabelManager::Set(CommandBuffer* buffer, Label* label)
|
||||
|
||||
EXIT_IF(label->event == nullptr);
|
||||
|
||||
label->buffer = buffer;
|
||||
label->cp = buffer->GetParent();
|
||||
|
||||
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
// IWYU pragma: no_forward_declare VkImageView_T
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
@@ -62,7 +62,8 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
delete[] temp_buf;
|
||||
} else
|
||||
{
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, pitch);
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, pitch,
|
||||
static_cast<uint64_t>(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +166,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
switch (pixel_format) // NOLINT
|
||||
{
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Unorm): vk_format = VK_FORMAT_B8G8R8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Srgb): vk_format = VK_FORMAT_B8G8R8A8_SRGB; break;
|
||||
default: EXIT("unknown format: %" PRIu64 "\n", pixel_format);
|
||||
}
|
||||
|
||||
@@ -178,7 +181,11 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = vk_format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
VkImageCreateInfo image_info {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
@@ -243,9 +250,29 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
VkImageViewCreateInfo create_info2 {};
|
||||
create_info2.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
create_info2.pNext = nullptr;
|
||||
create_info2.flags = 0;
|
||||
create_info2.image = vk_obj->image;
|
||||
create_info2.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
create_info2.format = vk_obj->format;
|
||||
create_info2.components.r = VK_COMPONENT_SWIZZLE_B;
|
||||
create_info2.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
create_info2.components.b = VK_COMPONENT_SWIZZLE_R;
|
||||
create_info2.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
create_info2.subresourceRange.baseArrayLayer = 0;
|
||||
create_info2.subresourceRange.baseMipLevel = 0;
|
||||
create_info2.subresourceRange.layerCount = 1;
|
||||
create_info2.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info2, nullptr, &vk_obj->image_view[VulkanImage::VIEW_BGRA]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_BGRA] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -268,7 +295,9 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
switch (pixel_format) // NOLINT
|
||||
{
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Unorm): vk_format = VK_FORMAT_B8G8R8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Srgb): vk_format = VK_FORMAT_B8G8R8A8_SRGB; break;
|
||||
default: EXIT("unknown format: %" PRIu64 "\n", pixel_format);
|
||||
}
|
||||
|
||||
@@ -281,7 +310,11 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = vk_format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
VkImageCreateInfo image_info {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
@@ -346,9 +379,29 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
VkImageViewCreateInfo create_info2 {};
|
||||
create_info2.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
create_info2.pNext = nullptr;
|
||||
create_info2.flags = 0;
|
||||
create_info2.image = vk_obj->image;
|
||||
create_info2.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
create_info2.format = vk_obj->format;
|
||||
create_info2.components.r = VK_COMPONENT_SWIZZLE_B;
|
||||
create_info2.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
create_info2.components.b = VK_COMPONENT_SWIZZLE_R;
|
||||
create_info2.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
create_info2.subresourceRange.baseArrayLayer = 0;
|
||||
create_info2.subresourceRange.baseMipLevel = 0;
|
||||
create_info2.subresourceRange.layerCount = 1;
|
||||
create_info2.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info2, nullptr, &vk_obj->image_view[VulkanImage::VIEW_BGRA]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_BGRA] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -366,7 +419,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
DeleteFramebuffer(vk_obj);
|
||||
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEFAULT], nullptr);
|
||||
|
||||
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
|
||||
|
||||
@@ -375,11 +428,35 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
delete vk_obj;
|
||||
}
|
||||
|
||||
static void write_back(GraphicContext* ctx, const uint64_t* params, void* obj, const uint64_t* vaddr, const uint64_t* size, int vaddr_num)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("RenderTextureObject::write_back");
|
||||
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(obj == nullptr);
|
||||
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num != 1);
|
||||
|
||||
bool tiled = (params[RenderTextureObject::PARAM_TILED] != 0);
|
||||
auto pitch = params[RenderTextureObject::PARAM_PITCH];
|
||||
auto width = params[RenderTextureObject::PARAM_WIDTH];
|
||||
|
||||
EXIT_IF(!(params[RenderTextureObject::PARAM_WRITE_BACK] != 0));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(tiled);
|
||||
EXIT_NOT_IMPLEMENTED(width != pitch);
|
||||
|
||||
auto* vk_obj = reinterpret_cast<RenderTextureVulkanImage*>(obj);
|
||||
|
||||
UtilFillBuffer(ctx, reinterpret_cast<void*>(*vaddr), *size, pitch, vk_obj,
|
||||
static_cast<uint64_t>(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
||||
}
|
||||
|
||||
bool RenderTextureObject::Equal(const uint64_t* other) const
|
||||
{
|
||||
return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_WIDTH] == other[PARAM_WIDTH] &&
|
||||
params[PARAM_HEIGHT] == other[PARAM_HEIGHT] && params[PARAM_TILED] == other[PARAM_TILED] &&
|
||||
params[PARAM_PITCH] == other[PARAM_PITCH] && params[PARAM_PITCH] == other[PARAM_PITCH]);
|
||||
params[PARAM_PITCH] == other[PARAM_PITCH] && params[PARAM_PITCH] == other[PARAM_PITCH] &&
|
||||
params[PARAM_WRITE_BACK] == other[PARAM_WRITE_BACK]);
|
||||
}
|
||||
|
||||
GpuObject::create_func_t RenderTextureObject::GetCreateFunc() const
|
||||
@@ -402,6 +479,12 @@ GpuObject::update_func_t RenderTextureObject::GetUpdateFunc() const
|
||||
return update_func;
|
||||
}
|
||||
|
||||
GpuObject::write_back_func_t RenderTextureObject::GetWriteBackFunc() const
|
||||
{
|
||||
bool wb = (params[RenderTextureObject::PARAM_WRITE_BACK] != 0);
|
||||
return (wb ? write_back : nullptr);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/GraphicsRun.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
@@ -67,17 +66,18 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* /*mem*/)
|
||||
EXIT_IF(vk_obj->buffer == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
EXIT_IF(vk_obj->cmd_buffer == nullptr);
|
||||
EXIT_IF(vk_obj->cp == nullptr);
|
||||
|
||||
// All submitted commands that refer to any element of pDescriptorSets must have completed execution
|
||||
vk_obj->cmd_buffer->CommandProcessorWait();
|
||||
GraphicsRunCommandProcessorWait(vk_obj->cp);
|
||||
|
||||
VulkanDeleteBuffer(ctx, vk_obj);
|
||||
|
||||
delete vk_obj;
|
||||
}
|
||||
|
||||
static void write_back(GraphicContext* ctx, void* obj, const uint64_t* vaddr, const uint64_t* size, int vaddr_num)
|
||||
static void write_back(GraphicContext* ctx, const uint64_t* /*params*/, void* obj, const uint64_t* vaddr, const uint64_t* size,
|
||||
int vaddr_num)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("StorageBufferGpuObject::write_back");
|
||||
|
||||
@@ -131,9 +131,7 @@ GpuObject::update_func_t StorageBufferGpuObject::GetUpdateFunc() const
|
||||
|
||||
void StorageBufferSet(CommandBuffer* cmd_buffer, StorageVulkanBuffer* buffer)
|
||||
{
|
||||
// EXIT_IF(buffer->cmd_buffer != nullptr);
|
||||
|
||||
buffer->cmd_buffer = cmd_buffer;
|
||||
buffer->cp = cmd_buffer->GetParent();
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
#include "Emulator/Config.h"
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/Shader.h"
|
||||
#include "Emulator/Graphics/Tile.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
// IWYU pragma: no_forward_declare VkImageView_T
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
@@ -188,9 +189,10 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
|
||||
if (tile == 13)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
// EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, levels, neo);
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, pitch,
|
||||
levels, neo);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
delete[] temp_buf;
|
||||
} else if (tile == 8)
|
||||
@@ -223,10 +225,10 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
|
||||
VkComponentMapping components {};
|
||||
|
||||
components.r = get_swizzle(swizzle & 0xffu);
|
||||
components.g = get_swizzle((swizzle >> 8u) & 0xffu);
|
||||
components.b = get_swizzle((swizzle >> 16u) & 0xffu);
|
||||
components.a = get_swizzle((swizzle >> 24u) & 0xffu);
|
||||
components.r = get_swizzle(GetDstSel(swizzle, 0));
|
||||
components.g = get_swizzle(GetDstSel(swizzle, 1));
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
|
||||
@@ -269,9 +271,13 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = image_info.format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
vk_obj->layout = image_info.initialLayout;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image == nullptr);
|
||||
@@ -304,9 +310,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -322,7 +328,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
DeleteDescriptor(vk_obj);
|
||||
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEFAULT], nullptr);
|
||||
|
||||
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
#include "Emulator/Config.h"
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/Shader.h"
|
||||
#include "Emulator/Graphics/Tile.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
// IWYU pragma: no_forward_declare VkImageView_T
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
@@ -30,10 +31,26 @@ static VkFormat get_texture_format(uint32_t dfmt, uint32_t nfmt)
|
||||
{
|
||||
return VK_FORMAT_R8_UNORM;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 3)
|
||||
{
|
||||
return VK_FORMAT_R8G8_UNORM;
|
||||
}
|
||||
if (nfmt == 9 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 36)
|
||||
{
|
||||
return VK_FORMAT_BC2_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 35)
|
||||
{
|
||||
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
}
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
@@ -189,9 +206,10 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
|
||||
if (tile == 13)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
// EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, levels, neo);
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, pitch,
|
||||
levels, neo);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
delete[] temp_buf;
|
||||
} else if (tile == 8)
|
||||
@@ -389,10 +407,10 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
|
||||
VkComponentMapping components {};
|
||||
|
||||
components.r = get_swizzle(swizzle & 0xffu);
|
||||
components.g = get_swizzle((swizzle >> 8u) & 0xffu);
|
||||
components.b = get_swizzle((swizzle >> 16u) & 0xffu);
|
||||
components.a = get_swizzle((swizzle >> 24u) & 0xffu);
|
||||
components.r = get_swizzle(GetDstSel(swizzle, 0));
|
||||
components.g = get_swizzle(GetDstSel(swizzle, 1));
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
|
||||
@@ -433,9 +451,13 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = image_info.format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
vk_obj->layout = image_info.initialLayout;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image == nullptr);
|
||||
@@ -468,9 +490,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -497,10 +519,10 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
|
||||
VkComponentMapping components {};
|
||||
|
||||
components.r = get_swizzle(swizzle & 0xffu);
|
||||
components.g = get_swizzle((swizzle >> 8u) & 0xffu);
|
||||
components.b = get_swizzle((swizzle >> 16u) & 0xffu);
|
||||
components.a = get_swizzle((swizzle >> 24u) & 0xffu);
|
||||
components.r = get_swizzle(GetDstSel(swizzle, 0));
|
||||
components.g = get_swizzle(GetDstSel(swizzle, 1));
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
|
||||
@@ -541,9 +563,13 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = image_info.format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
vk_obj->layout = image_info.initialLayout;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image == nullptr);
|
||||
@@ -576,9 +602,9 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -594,7 +620,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
DeleteDescriptor(vk_obj);
|
||||
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEFAULT], nullptr);
|
||||
|
||||
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
// IWYU pragma: no_forward_declare VkImageView_T
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
@@ -56,11 +56,12 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
EXIT_NOT_IMPLEMENTED(width != pitch);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::VideoOutTiled, width, height, neo);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, pitch);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, pitch, static_cast<uint64_t>(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
delete[] temp_buf;
|
||||
} else
|
||||
{
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, pitch);
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, pitch,
|
||||
static_cast<uint64_t>(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,9 +88,13 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
for (auto& view: vk_obj->image_view)
|
||||
{
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
VkImageCreateInfo image_info {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info.pNext = nullptr;
|
||||
@@ -151,9 +156,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view[VulkanImage::VIEW_DEFAULT]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view[VulkanImage::VIEW_DEFAULT] == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
@@ -172,7 +177,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
DeleteFramebuffer(vk_obj);
|
||||
}
|
||||
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view, nullptr);
|
||||
vkDestroyImageView(ctx->device, vk_obj->image_view[VulkanImage::VIEW_DEFAULT], nullptr);
|
||||
|
||||
vkDestroyImage(ctx->device, vk_obj->image, nullptr);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -91,17 +92,17 @@ static String operand_to_str(ShaderOperand op)
|
||||
{
|
||||
case ShaderOperandType::LiteralConstant:
|
||||
EXIT_IF(op.size != 0);
|
||||
EXIT_IF(op.negate);
|
||||
EXIT_IF(op.negate || op.absolute);
|
||||
return String::FromPrintf("%f (%u)", op.constant.f, op.constant.u);
|
||||
break;
|
||||
case ShaderOperandType::IntegerInlineConstant:
|
||||
EXIT_IF(op.size != 0);
|
||||
EXIT_IF(op.negate);
|
||||
EXIT_IF(op.negate || op.absolute);
|
||||
return String::FromPrintf("%d", op.constant.i);
|
||||
break;
|
||||
case ShaderOperandType::FloatInlineConstant:
|
||||
EXIT_IF(op.size != 0);
|
||||
EXIT_IF(op.negate);
|
||||
EXIT_IF(op.negate || op.absolute);
|
||||
return String::FromPrintf("%f", op.constant.f);
|
||||
break;
|
||||
default: break;
|
||||
@@ -123,6 +124,11 @@ static String operand_to_str(ShaderOperand op)
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (op.absolute)
|
||||
{
|
||||
ret = U"abs(" + ret + U")";
|
||||
}
|
||||
|
||||
if (op.negate)
|
||||
{
|
||||
return U"-" + ret;
|
||||
@@ -170,6 +176,11 @@ static String operand_array_to_str(ShaderOperand op, int n)
|
||||
|
||||
EXIT_IF(ret == U"???");
|
||||
|
||||
if (op.absolute)
|
||||
{
|
||||
ret = U"abs(" + ret + U")";
|
||||
}
|
||||
|
||||
if (op.negate)
|
||||
{
|
||||
return U"-" + ret;
|
||||
@@ -192,6 +203,7 @@ static String dbg_fmt_to_str(const ShaderInstruction& inst)
|
||||
case ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param1Vsrc0Vsrc1Vsrc2Vsrc3"; break;
|
||||
case ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param2Vsrc0Vsrc1Vsrc2Vsrc3"; break;
|
||||
case ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param3Vsrc0Vsrc1Vsrc2Vsrc3"; break;
|
||||
case ShaderInstructionFormat::Param4Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param4Vsrc0Vsrc1Vsrc2Vsrc3"; break;
|
||||
case ShaderInstructionFormat::Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done: return U"Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done"; break;
|
||||
case ShaderInstructionFormat::Saddr: return U"Saddr"; break;
|
||||
case ShaderInstructionFormat::Sdst4SbaseSoffset: return U"Sdst4SbaseSoffset"; break;
|
||||
@@ -207,13 +219,18 @@ static String dbg_fmt_to_str(const ShaderInstruction& inst)
|
||||
case ShaderInstructionFormat::SmaskVsrc0Vsrc1: return U"SmaskVsrc0Vsrc1"; break;
|
||||
case ShaderInstructionFormat::Ssrc0Ssrc1: return U"Ssrc0Ssrc1"; break;
|
||||
case ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen: return U"Vdata1VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxenFloat1: return U"Vdata1VaddrSvSoffsIdxenFloat1"; break;
|
||||
case ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen: return U"Vdata2VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata3VaddrSvSoffsIdxen: return U"Vdata3VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxen: return U"Vdata4VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4: return U"Vdata4VaddrSvSoffsIdxenFloat4"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4: return U"Vdata4Vaddr2SvSoffsOffenIdxenFloat4"; break;
|
||||
case ShaderInstructionFormat::Vdata1Vaddr3StSsDmask1: return U"Vdata1Vaddr3StSsDmask1"; break;
|
||||
case ShaderInstructionFormat::Vdata1Vaddr3StSsDmask8: return U"Vdata1Vaddr3StSsDmask8"; break;
|
||||
case ShaderInstructionFormat::Vdata2Vaddr3StSsDmask3: return U"Vdata2Vaddr3StSsDmask3"; break;
|
||||
case ShaderInstructionFormat::Vdata2Vaddr3StSsDmask5: return U"Vdata2Vaddr3StSsDmask5"; break;
|
||||
case ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7: return U"Vdata3Vaddr3StSsDmask7"; break;
|
||||
case ShaderInstructionFormat::Vdata3Vaddr4StSsDmask7: return U"Vdata3Vaddr4StSsDmask7"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF: return U"Vdata4Vaddr3StSsDmaskF"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr3StDmaskF: return U"Vdata4Vaddr3StDmaskF"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr4StDmaskF: return U"Vdata4Vaddr4StDmaskF"; break;
|
||||
@@ -275,6 +292,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
||||
case ShaderInstructionFormat::Attr: s = String::FromPrintf("attr%u.%u", inst.src[1].constant.u, inst.src[2].constant.u); break;
|
||||
case ShaderInstructionFormat::Idxen: s = U"idxen"; break;
|
||||
case ShaderInstructionFormat::Offen: s = U"offen"; break;
|
||||
case ShaderInstructionFormat::Float1: s = U"format:float1"; break;
|
||||
case ShaderInstructionFormat::Float4: s = U"format:float4"; break;
|
||||
case ShaderInstructionFormat::Pos0: s = U"pos0"; break;
|
||||
case ShaderInstructionFormat::Done: s = U"done"; break;
|
||||
@@ -282,12 +300,16 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
||||
case ShaderInstructionFormat::Param1: s = U"param1"; break;
|
||||
case ShaderInstructionFormat::Param2: s = U"param2"; break;
|
||||
case ShaderInstructionFormat::Param3: s = U"param3"; break;
|
||||
case ShaderInstructionFormat::Param4: s = U"param4"; break;
|
||||
case ShaderInstructionFormat::Mrt0: s = U"mrt_color0"; break;
|
||||
case ShaderInstructionFormat::Off: s = U"off"; break;
|
||||
case ShaderInstructionFormat::Compr: s = U"compr"; break;
|
||||
case ShaderInstructionFormat::Vm: s = U"vm"; break;
|
||||
case ShaderInstructionFormat::L: s = String::FromPrintf("label_%04" PRIx32, inst.pc + 4 + inst.src[0].constant.i); break;
|
||||
case ShaderInstructionFormat::Dmask1: s = U"dmask:0x1"; break;
|
||||
case ShaderInstructionFormat::Dmask8: s = U"dmask:0x8"; break;
|
||||
case ShaderInstructionFormat::Dmask3: s = U"dmask:0x3"; break;
|
||||
case ShaderInstructionFormat::Dmask5: s = U"dmask:0x5"; break;
|
||||
case ShaderInstructionFormat::Dmask7: s = U"dmask:0x7"; break;
|
||||
case ShaderInstructionFormat::DmaskF: s = U"dmask:0xf"; break;
|
||||
case ShaderInstructionFormat::Gds: s = U"gds"; break;
|
||||
@@ -354,7 +376,7 @@ String ShaderCode::DbgDump() const
|
||||
String ret;
|
||||
for (const auto& inst: m_instructions)
|
||||
{
|
||||
if (m_labels.Contains(inst.pc, [](auto label, auto pc) { return label.GetDst() == pc; }))
|
||||
if (m_labels.Contains(inst.pc, [](auto label, auto pc) { return (!label.IsDisabled() && label.GetDst() == pc); }))
|
||||
{
|
||||
ret += String::FromPrintf("label_%04" PRIx32 ":\n", inst.pc);
|
||||
}
|
||||
@@ -392,7 +414,7 @@ bool ShaderCode::IsDiscardBlock(uint32_t pc) const
|
||||
const auto& inst = m_instructions.At(i);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SEndpgm || inst.type == ShaderInstructionType::SCbranchExecz ||
|
||||
inst.type == ShaderInstructionType::SCbranchScc0)
|
||||
inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchVccz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -408,6 +430,35 @@ bool ShaderCode::IsDiscardBlock(uint32_t pc) const
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
||||
{
|
||||
Vector<ShaderInstruction> ret;
|
||||
|
||||
auto inst_count = m_instructions.Size();
|
||||
for (uint32_t index = 0; index < inst_count; index++)
|
||||
{
|
||||
const auto& inst = m_instructions.At(index);
|
||||
if (inst.pc == pc)
|
||||
{
|
||||
for (uint32_t i = index; i < inst_count; i++)
|
||||
{
|
||||
const auto& inst = m_instructions.At(i);
|
||||
|
||||
ret.Add(inst);
|
||||
|
||||
if (IsDiscardInstruction(i))
|
||||
{
|
||||
ret.Add(m_instructions.At(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ShaderOperand operand_parse(uint32_t code)
|
||||
{
|
||||
ShaderOperand ret;
|
||||
@@ -566,26 +617,21 @@ KYTY_SHADER_PARSER(shader_parse_sopp)
|
||||
ShaderInstruction inst;
|
||||
inst.pc = pc;
|
||||
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x01:
|
||||
inst.type = ShaderInstructionType::SEndpgm;
|
||||
inst.format = ShaderInstructionFormat::Empty;
|
||||
break;
|
||||
case 0x04:
|
||||
inst.type = ShaderInstructionType::SCbranchScc0;
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
case 0x08:
|
||||
inst.type = ShaderInstructionType::SCbranchExecz;
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
inst.type = ShaderInstructionType::SEndpgm;
|
||||
inst.format = ShaderInstructionFormat::Empty;
|
||||
inst.src_num = 0;
|
||||
break;
|
||||
case 0x04: inst.type = ShaderInstructionType::SCbranchScc0; break;
|
||||
case 0x06: inst.type = ShaderInstructionType::SCbranchVccz; break;
|
||||
case 0x08: inst.type = ShaderInstructionType::SCbranchExecz; break;
|
||||
case 0x0c:
|
||||
inst.type = ShaderInstructionType::SWaitcnt;
|
||||
inst.format = ShaderInstructionFormat::Imm;
|
||||
@@ -598,7 +644,8 @@ KYTY_SHADER_PARSER(shader_parse_sopp)
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchExecz)
|
||||
if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchVccz ||
|
||||
inst.type == ShaderInstructionType::SCbranchExecz)
|
||||
{
|
||||
dst->GetLabels().Add(ShaderLabel(inst));
|
||||
}
|
||||
@@ -849,6 +896,8 @@ KYTY_SHADER_PARSER(shader_parse_vopc)
|
||||
case 0x0d: inst.type = ShaderInstructionType::VCmpNeqF32; break;
|
||||
case 0x0e: inst.type = ShaderInstructionType::VCmpNltF32; break;
|
||||
case 0x0f: inst.type = ShaderInstructionType::VCmpTruF32; break;
|
||||
case 0x11: inst.type = ShaderInstructionType::VCmpxLtF32; break;
|
||||
case 0x14: inst.type = ShaderInstructionType::VCmpxGtF32; break;
|
||||
case 0x1d: inst.type = ShaderInstructionType::VCmpxNeqF32; break;
|
||||
case 0x80: inst.type = ShaderInstructionType::VCmpFI32; break;
|
||||
case 0x81: inst.type = ShaderInstructionType::VCmpLtI32; break;
|
||||
@@ -870,7 +919,9 @@ KYTY_SHADER_PARSER(shader_parse_vopc)
|
||||
case 0xd4: inst.type = ShaderInstructionType::VCmpxGtU32; break;
|
||||
case 0xd5: inst.type = ShaderInstructionType::VCmpxNeU32; break;
|
||||
case 0xd6: inst.type = ShaderInstructionType::VCmpxGeU32; break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
default:
|
||||
printf("%s", dst->DbgDump().C_Str());
|
||||
EXIT("unknown vopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0());
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
@@ -921,13 +972,17 @@ KYTY_SHADER_PARSER(shader_parse_vop1)
|
||||
case 0x23: inst.type = ShaderInstructionType::VRndneF32; break;
|
||||
case 0x24: inst.type = ShaderInstructionType::VFloorF32; break;
|
||||
case 0x25: inst.type = ShaderInstructionType::VExpF32; break;
|
||||
case 0x27: inst.type = ShaderInstructionType::VLogF32; break;
|
||||
case 0x2a: inst.type = ShaderInstructionType::VRcpF32; break;
|
||||
case 0x2e: inst.type = ShaderInstructionType::VRsqF32; break;
|
||||
case 0x33: inst.type = ShaderInstructionType::VSqrtF32; break;
|
||||
case 0x35: inst.type = ShaderInstructionType::VSinF32; break;
|
||||
case 0x36: inst.type = ShaderInstructionType::VCosF32; break;
|
||||
case 0x37: inst.type = ShaderInstructionType::VNotB32; break;
|
||||
case 0x38: inst.type = ShaderInstructionType::VBfrevB32; break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop1 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
default:
|
||||
printf("%s", dst->DbgDump().C_Str());
|
||||
EXIT("unknown vop1 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0());
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
@@ -972,6 +1027,7 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
||||
inst.src[2].size = 2;
|
||||
inst.src_num = 3;
|
||||
break;
|
||||
case 0x03: inst.type = ShaderInstructionType::VAddF32; break;
|
||||
case 0x04: inst.type = ShaderInstructionType::VSubF32; break;
|
||||
case 0x05: inst.type = ShaderInstructionType::VSubrevF32; break;
|
||||
case 0x08: inst.type = ShaderInstructionType::VMulF32; break;
|
||||
@@ -1171,6 +1227,7 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
||||
inst.src_num = 3;
|
||||
inst.src[2].size = 2;
|
||||
break;
|
||||
case 0x103: inst.type = ShaderInstructionType::VAddF32; break;
|
||||
case 0x104: inst.type = ShaderInstructionType::VSubF32; break;
|
||||
case 0x105: inst.type = ShaderInstructionType::VSubrevF32; break;
|
||||
case 0x108: inst.type = ShaderInstructionType::VMulF32; break;
|
||||
@@ -1213,6 +1270,10 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
||||
case 0x141: inst.type = ShaderInstructionType::VMadF32; break;
|
||||
case 0x143: inst.type = ShaderInstructionType::VMadU32U24; break;
|
||||
case 0x148: inst.type = ShaderInstructionType::VBfeU32; break;
|
||||
case 0x14b: inst.type = ShaderInstructionType::VFmaF32; break;
|
||||
case 0x151: inst.type = ShaderInstructionType::VMin3F32; break;
|
||||
case 0x154: inst.type = ShaderInstructionType::VMax3F32; break;
|
||||
case 0x157: inst.type = ShaderInstructionType::VMed3F32; break;
|
||||
case 0x15d: inst.type = ShaderInstructionType::VSadU32; break;
|
||||
case 0x169:
|
||||
inst.type = ShaderInstructionType::VMulLoU32;
|
||||
@@ -1229,12 +1290,30 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.src_num = 2;
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop3 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
case 0x1aa:
|
||||
inst.type = ShaderInstructionType::VRcpF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
default:
|
||||
printf("%s", dst->DbgDump().C_Str());
|
||||
EXIT("unknown vop3 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0());
|
||||
}
|
||||
|
||||
if (inst.dst2.type == ShaderOperandType::Unknown)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(abs != 0);
|
||||
if ((abs & 0x1u) != 0)
|
||||
{
|
||||
inst.src[0].absolute = true;
|
||||
}
|
||||
if ((abs & 0x2u) != 0)
|
||||
{
|
||||
inst.src[1].absolute = true;
|
||||
}
|
||||
if ((abs & 0x4u) != 0)
|
||||
{
|
||||
inst.src[2].absolute = true;
|
||||
}
|
||||
|
||||
inst.dst.clamp = (clamp != 0);
|
||||
}
|
||||
@@ -1304,6 +1383,7 @@ KYTY_SHADER_PARSER(shader_parse_exp)
|
||||
case 0x21: inst.format = ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x22: inst.format = ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x23: inst.format = ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x24: inst.format = ShaderInstructionFormat::Param4Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -1311,7 +1391,9 @@ KYTY_SHADER_PARSER(shader_parse_exp)
|
||||
if (inst.format == ShaderInstructionFormat::Unknown)
|
||||
{
|
||||
printf("%s", dst->DbgDump().C_Str());
|
||||
EXIT("unknown exp target: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", target, pc);
|
||||
EXIT("%s\n"
|
||||
"unknown exp target: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n",
|
||||
dst->DbgDump().C_Str(), target, pc, dst->GetHash0());
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
@@ -1639,12 +1721,30 @@ KYTY_SHADER_PARSER(shader_parse_mimg)
|
||||
inst.dst.size = 1;
|
||||
break;
|
||||
}
|
||||
case 0x3:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata2Vaddr3StSsDmask3;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
}
|
||||
case 0x5:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata2Vaddr3StSsDmask5;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
}
|
||||
case 0x7:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7;
|
||||
inst.dst.size = 3;
|
||||
break;
|
||||
}
|
||||
case 0x8:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata1Vaddr3StSsDmask8;
|
||||
inst.dst.size = 1;
|
||||
break;
|
||||
}
|
||||
case 0xf:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF;
|
||||
@@ -1654,6 +1754,38 @@ KYTY_SHADER_PARSER(shader_parse_mimg)
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
case 0x27:
|
||||
inst.type = ShaderInstructionType::ImageSampleLz;
|
||||
inst.src[0].size = 3;
|
||||
inst.src[1].size = 8;
|
||||
inst.src[2].size = 4;
|
||||
switch (dmask) // NOLINT
|
||||
{
|
||||
case 0x7:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7;
|
||||
inst.dst.size = 3;
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
case 0x37:
|
||||
inst.type = ShaderInstructionType::ImageSampleLzO;
|
||||
inst.src[0].size = 4;
|
||||
inst.src[1].size = 8;
|
||||
inst.src[2].size = 4;
|
||||
switch (dmask) // NOLINT
|
||||
{
|
||||
case 0x7:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata3Vaddr4StSsDmask7;
|
||||
inst.dst.size = 3;
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown mimg opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
@@ -1695,8 +1827,13 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
||||
EXIT_NOT_IMPLEMENTED(glc == 1);
|
||||
EXIT_NOT_IMPLEMENTED(slc == 1);
|
||||
EXIT_NOT_IMPLEMENTED(tfe == 1);
|
||||
EXIT_NOT_IMPLEMENTED(dfmt != 14);
|
||||
EXIT_NOT_IMPLEMENTED(nfmt != 7);
|
||||
// EXIT_NOT_IMPLEMENTED(dfmt != 14);
|
||||
// EXIT_NOT_IMPLEMENTED(nfmt != 7);
|
||||
|
||||
if ((dfmt != 14 && dfmt != 4) || nfmt != 7)
|
||||
{
|
||||
EXIT("unknown format: dfmt = %d, nfmt = %d at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", dfmt, nfmt, pc, dst->GetHash0());
|
||||
}
|
||||
|
||||
uint32_t size = 2;
|
||||
|
||||
@@ -1716,14 +1853,22 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
||||
|
||||
inst.src[1].size = 4;
|
||||
|
||||
switch (opcode) // NOLINT
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00:
|
||||
inst.type = ShaderInstructionType::TBufferLoadFormatX;
|
||||
inst.format = ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxenFloat1;
|
||||
EXIT_NOT_IMPLEMENTED(offen == 1);
|
||||
EXIT_NOT_IMPLEMENTED(!(dfmt == 4 && nfmt == 7));
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
inst.type = ShaderInstructionType::TBufferLoadFormatXyzw;
|
||||
inst.format = (offen == 1 ? ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4
|
||||
: ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4);
|
||||
inst.src[0].size += static_cast<int>(offen);
|
||||
inst.dst.size = 4;
|
||||
EXIT_NOT_IMPLEMENTED(!(dfmt == 14 && nfmt == 7));
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown mtbuf opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
@@ -2026,21 +2171,24 @@ static bool SpirvToGlsl(const uint32_t* /*src_binary*/, size_t /*src_binary_size
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SpirvRun(const String& src, Vector<uint32_t>* dst)
|
||||
static bool SpirvRun(const String& src, Vector<uint32_t>* dst, String* err_msg)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
EXIT_IF(err_msg == nullptr);
|
||||
|
||||
spvtools::SpirvTools core(SPV_ENV_VULKAN_1_2);
|
||||
spvtools::Optimizer opt(SPV_ENV_VULKAN_1_2);
|
||||
|
||||
spv_position_t error_position {};
|
||||
String error_msg;
|
||||
|
||||
auto print_msg_to_stderr = [&error_position](spv_message_level_t /* level */, const char* /*source*/,
|
||||
[[maybe_unused]] const spv_position_t& position, const char* m)
|
||||
auto print_msg_to_stderr = [&error_position, &error_msg](spv_message_level_t /* level */, const char* /*source*/,
|
||||
[[maybe_unused]] const spv_position_t& position, const char* m)
|
||||
{
|
||||
// printf("%s\n", source);
|
||||
printf(FG_BRIGHT_RED "error: %d: %d (%d) %s\n" FG_DEFAULT, static_cast<int>(position.line), static_cast<int>(position.column),
|
||||
static_cast<int>(position.index), m);
|
||||
error_msg = String::FromPrintf("%d: %d (%d) %s", static_cast<int>(position.line), static_cast<int>(position.column),
|
||||
static_cast<int>(position.index), m);
|
||||
printf(FG_BRIGHT_RED "error: %s\n" FG_DEFAULT, error_msg.C_Str());
|
||||
error_position = position;
|
||||
};
|
||||
core.SetMessageConsumer(print_msg_to_stderr);
|
||||
@@ -2054,6 +2202,7 @@ static bool SpirvRun(const String& src, Vector<uint32_t>* dst)
|
||||
if (!core.Assemble(src_utf8.GetDataConst(), src_utf8.Size(), &spirv))
|
||||
{
|
||||
printf("Assemble failed at:\n%s\n", src.Mid(src.FindIndex(U'\n', error_position.index - 100), 200).C_Str());
|
||||
*err_msg = String::FromPrintf("Assemble failed at:\n%s\n", src.Mid(src.FindIndex(U'\n', error_position.index - 100), 200).C_Str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2063,6 +2212,7 @@ static bool SpirvRun(const String& src, Vector<uint32_t>* dst)
|
||||
SpirvDisassemble(spirv.data(), spirv.size(), &disassembly);
|
||||
printf("%s\n", disassembly.C_Str());
|
||||
printf("Validate failed\n");
|
||||
*err_msg = String::FromPrintf("%s\n\nValidate failed:\n%s\n", Log::RemoveColors(disassembly).C_Str(), error_msg.C_Str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2077,6 +2227,7 @@ static bool SpirvRun(const String& src, Vector<uint32_t>* dst)
|
||||
if (optimize && !opt.Run(spirv.data(), spirv.size(), &spirv))
|
||||
{
|
||||
printf("Optimize failed\n");
|
||||
*err_msg = String::FromPrintf("Optimize failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2946,7 +3097,7 @@ class ShaderLogHelper
|
||||
public:
|
||||
explicit ShaderLogHelper(const char* type)
|
||||
{
|
||||
static int id = 0;
|
||||
static std::atomic_int id = 0;
|
||||
|
||||
switch (Config::GetShaderLogDirection())
|
||||
{
|
||||
@@ -2989,11 +3140,17 @@ public:
|
||||
if (m_console)
|
||||
{
|
||||
printf("--------- Original Shader ---------\n");
|
||||
printf("crc32 = %08" PRIx32 "\n", code.GetCrc32());
|
||||
printf("hash0 = %08" PRIx32 "\n", code.GetHash0());
|
||||
printf("---------\n");
|
||||
printf("%s", code.DbgDump().C_Str());
|
||||
printf("---------\n");
|
||||
} else if (!m_file.IsInvalid())
|
||||
{
|
||||
m_file.Printf("--------- Original Shader ---------\n");
|
||||
m_file.Printf("crc32 = %08" PRIx32 "\n", code.GetCrc32());
|
||||
m_file.Printf("hash0 = %08" PRIx32 "\n", code.GetHash0());
|
||||
m_file.Printf("---------\n");
|
||||
m_file.Printf("%s", code.DbgDump().C_Str());
|
||||
m_file.Printf("---------\n");
|
||||
}
|
||||
@@ -3115,6 +3272,8 @@ ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs)
|
||||
|
||||
bi_print("ShaderParseVS():ShaderBinaryInfo", *header);
|
||||
|
||||
code.SetCrc32(header->crc32);
|
||||
code.SetHash0(header->hash0);
|
||||
shader_parse(0, src, nullptr, &code);
|
||||
|
||||
if (g_debug_printfs != nullptr)
|
||||
@@ -3156,9 +3315,9 @@ Vector<uint32_t> ShaderRecompileVS(const ShaderCode& code, const ShaderVertexInp
|
||||
|
||||
log.DumpRecompiledShader(source);
|
||||
|
||||
if (!SpirvRun(source, &ret))
|
||||
if (String err_msg; !SpirvRun(source, &ret, &err_msg))
|
||||
{
|
||||
EXIT("SpirvRun() failed\n");
|
||||
EXIT("SpirvRun() failed:\n%s\n", err_msg.C_Str());
|
||||
}
|
||||
|
||||
log.DumpOptimizedShader(ret);
|
||||
@@ -3194,6 +3353,8 @@ ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs)
|
||||
|
||||
bi_print("ShaderParsePS():ShaderBinaryInfo", *header);
|
||||
|
||||
code.SetCrc32(header->crc32);
|
||||
code.SetHash0(header->hash0);
|
||||
shader_parse(0, src, nullptr, &code);
|
||||
|
||||
if (g_debug_printfs != nullptr)
|
||||
@@ -3240,9 +3401,9 @@ Vector<uint32_t> ShaderRecompilePS(const ShaderCode& code, const ShaderPixelInpu
|
||||
|
||||
log.DumpRecompiledShader(source);
|
||||
|
||||
if (!SpirvRun(source, &ret))
|
||||
if (String err_msg; !SpirvRun(source, &ret, &err_msg))
|
||||
{
|
||||
EXIT("SpirvRun() failed\n");
|
||||
EXIT("SpirvRun() failed:\n%s\n", err_msg.C_Str());
|
||||
}
|
||||
|
||||
log.DumpOptimizedShader(ret);
|
||||
@@ -3272,6 +3433,8 @@ ShaderCode ShaderParseCS(const HW::ComputeShaderInfo* regs)
|
||||
ShaderCode code;
|
||||
code.SetType(ShaderType::Compute);
|
||||
|
||||
code.SetCrc32(header->crc32);
|
||||
code.SetHash0(header->hash0);
|
||||
shader_parse(0, src, nullptr, &code);
|
||||
|
||||
if (g_debug_printfs != nullptr)
|
||||
@@ -3306,9 +3469,9 @@ Vector<uint32_t> ShaderRecompileCS(const ShaderCode& code, const ShaderComputeIn
|
||||
|
||||
log.DumpRecompiledShader(source);
|
||||
|
||||
if (!SpirvRun(source, &ret))
|
||||
if (String err_msg; !SpirvRun(source, &ret, &err_msg))
|
||||
{
|
||||
EXIT("SpirvRun() failed\n");
|
||||
EXIT("SpirvRun() failed:\n%s\n", err_msg.C_Str());
|
||||
}
|
||||
|
||||
log.DumpOptimizedShader(ret);
|
||||
@@ -3553,9 +3716,10 @@ ShaderId ShaderGetIdVS(const HW::VertexShaderInfo* regs, const ShaderVertexInput
|
||||
|
||||
ret.ids.Expand(64);
|
||||
|
||||
ret.hash0 = header->hash0;
|
||||
ret.crc32 = header->crc32;
|
||||
|
||||
ret.ids.Add(header->length);
|
||||
ret.ids.Add(header->hash0);
|
||||
ret.ids.Add(header->crc32);
|
||||
ret.ids.Add(static_cast<uint32_t>(input_info->fetch));
|
||||
ret.ids.Add(input_info->resources_num);
|
||||
ret.ids.Add(input_info->export_count);
|
||||
@@ -3619,9 +3783,10 @@ ShaderId ShaderGetIdPS(const HW::PixelShaderInfo* regs, const ShaderPixelInputIn
|
||||
|
||||
ret.ids.Expand(64);
|
||||
|
||||
ret.hash0 = header->hash0;
|
||||
ret.crc32 = header->crc32;
|
||||
|
||||
ret.ids.Add(header->length);
|
||||
ret.ids.Add(header->hash0);
|
||||
ret.ids.Add(header->crc32);
|
||||
ret.ids.Add(input_info->input_num);
|
||||
ret.ids.Add(static_cast<uint32_t>(input_info->ps_pos_xy));
|
||||
ret.ids.Add(static_cast<uint32_t>(input_info->ps_pixel_kill_enable));
|
||||
@@ -3651,9 +3816,10 @@ ShaderId ShaderGetIdCS(const HW::ComputeShaderInfo* regs, const ShaderComputeInp
|
||||
ShaderId ret;
|
||||
ret.ids.Expand(64);
|
||||
|
||||
ret.hash0 = header->hash0;
|
||||
ret.crc32 = header->crc32;
|
||||
|
||||
ret.ids.Add(header->length);
|
||||
ret.ids.Add(header->hash0);
|
||||
ret.ids.Add(header->crc32);
|
||||
|
||||
ret.ids.Add(input_info->workgroup_register);
|
||||
ret.ids.Add(input_info->thread_ids_num);
|
||||
|
||||
@@ -1304,10 +1304,13 @@ private:
|
||||
void WriteInstructions();
|
||||
void WriteMainEpilog();
|
||||
void WriteFunctions();
|
||||
void WriteLabel(int index);
|
||||
|
||||
void FindConstants();
|
||||
void FindVariables();
|
||||
|
||||
void ModifyCode();
|
||||
|
||||
String m_source;
|
||||
ShaderCode m_code;
|
||||
Vector<Constant> m_constants;
|
||||
@@ -1454,7 +1457,7 @@ static bool operand_load_int(Spirv* spirv, ShaderOperand op, const String& resul
|
||||
{
|
||||
EXIT_IF(load == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(op.negate);
|
||||
EXIT_NOT_IMPLEMENTED(op.negate || op.absolute);
|
||||
|
||||
if (operand_is_constant(op))
|
||||
{
|
||||
@@ -1494,7 +1497,7 @@ static bool operand_load_uint(Spirv* spirv, ShaderOperand op, const String& resu
|
||||
{
|
||||
EXIT_IF(load == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(op.negate);
|
||||
EXIT_NOT_IMPLEMENTED(op.negate || op.absolute);
|
||||
|
||||
if (operand_is_constant(op))
|
||||
{
|
||||
@@ -1593,7 +1596,17 @@ static bool operand_load_float(Spirv* spirv, ShaderOperand op, const String& res
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op.negate)
|
||||
if (op.negate && op.absolute)
|
||||
{
|
||||
// TODO(): negated absolute value
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op.absolute)
|
||||
{
|
||||
l += String(U' ', 10) + String(U"%<result> = OpExtInst %float %GLSL_std_450 FAbs %<result_id>\n");
|
||||
*load = l.ReplaceStr(U"<index>", index).ReplaceStr(U"<result_id>", U"a" + result_id).ReplaceStr(U"<result>", result_id);
|
||||
} else if (op.negate)
|
||||
{
|
||||
l += String(U' ', 10) + String(U"%<result> = OpFNegate %float %<result_id>\n");
|
||||
*load = l.ReplaceStr(U"<index>", index).ReplaceStr(U"<result_id>", U"n" + result_id).ReplaceStr(U"<result>", result_id);
|
||||
@@ -2149,7 +2162,7 @@ KYTY_RECOMPILER_FUNC(Recompile_Exp_Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: 0, 1, 2, 3*/
|
||||
/* XXX: 0, 1, 2, 3, 4 */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_Exp_Param_XXX_Vsrc0Vsrc1Vsrc2Vsrc3)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -2228,11 +2241,10 @@ KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata1Vaddr3StSsDmask1)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
// const auto& bind_params = spirv->GetBindParams();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
@@ -2279,6 +2291,178 @@ KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata1Vaddr3StSsDmask1)
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata1Vaddr3StSsDmask8)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
%t39_<index> = OpLoad %float %<src0_value0>
|
||||
%t40_<index> = OpLoad %float %<src0_value1>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
%t43_<index> = OpImageSampleImplicitLod %v4float %t38_<index> %t42_<index>
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_3
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata2Vaddr3StSsDmask3)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
%t39_<index> = OpLoad %float %<src0_value0>
|
||||
%t40_<index> = OpLoad %float %<src0_value1>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
%t43_<index> = OpImageSampleImplicitLod %v4float %t38_<index> %t42_<index>
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_0
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
%t54_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_1
|
||||
%t55_<index> = OpLoad %float %t54_<index>
|
||||
OpStore %<dst_value1> %t55_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata2Vaddr3StSsDmask5)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
%t39_<index> = OpLoad %float %<src0_value0>
|
||||
%t40_<index> = OpLoad %float %<src0_value1>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
%t43_<index> = OpImageSampleImplicitLod %v4float %t38_<index> %t42_<index>
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_0
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
%t54_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_2
|
||||
%t55_<index> = OpLoad %float %t54_<index>
|
||||
OpStore %<dst_value1> %t55_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata3Vaddr3StSsDmask7)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -2344,6 +2528,153 @@ KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata3Vaddr3StSsDmask7)
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSampleLz_Vdata3Vaddr3StSsDmask7)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
auto dst_value2 = operand_variable_to_str(inst.dst, 2);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
|
||||
%t39_<index> = OpLoad %float %<src0_value0>
|
||||
%t40_<index> = OpLoad %float %<src0_value1>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
|
||||
%t43_<index> = OpImageSampleExplicitLod %v4float %t38_<index> %t42_<index> Lod %float_0_000000
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_0
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
%t50_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_1
|
||||
%t51_<index> = OpLoad %float %t50_<index>
|
||||
OpStore %<dst_value1> %t51_<index>
|
||||
%t54_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_2
|
||||
%t55_<index> = OpLoad %float %t54_<index>
|
||||
OpStore %<dst_value2> %t55_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value)
|
||||
.ReplaceStr(U"<dst_value2>", dst_value2.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSampleLzO_Vdata3Vaddr4StSsDmask7)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
auto dst_value2 = operand_variable_to_str(inst.dst, 2);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src0_value3 = operand_variable_to_str(inst.src[0], 3);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
|
||||
%t39_<index> = OpLoad %float %<src0_value1>
|
||||
%t40_<index> = OpLoad %float %<src0_value2>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
|
||||
%90_<index> = OpLoad %float %<src0_value0>
|
||||
%91_<index> = OpBitcast %int %90_<index>
|
||||
%98_<index> = OpBitFieldSExtract %int %91_<index> %int_0 %int_6
|
||||
%101_<index> = OpBitFieldSExtract %int %91_<index> %int_8 %int_6
|
||||
%102_<index> = OpCompositeConstruct %v2int %98_<index> %101_<index>
|
||||
|
||||
%130_<index> = OpConvertSToF %v2float %102_<index>
|
||||
%138_<index> = OpImage %ImageS %t38_<index>
|
||||
%139_<index> = OpImageQuerySizeLod %v2int %138_<index> %int_0
|
||||
%140_<index> = OpConvertSToF %v2float %139_<index>
|
||||
%141_<index> = OpFDiv %v2float %130_<index> %140_<index>
|
||||
%142_<index> = OpFAdd %v2float %t42_<index> %141_<index>
|
||||
|
||||
%t43_<index> = OpImageSampleExplicitLod %v4float %t38_<index> %142_<index> Lod %float_0_000000
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_0
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
%t50_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_1
|
||||
%t51_<index> = OpLoad %float %t50_<index>
|
||||
OpStore %<dst_value1> %t51_<index>
|
||||
%t54_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_2
|
||||
%t55_<index> = OpLoad %float %t54_<index>
|
||||
OpStore %<dst_value2> %t55_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src0_value3>", src0_value3.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value)
|
||||
.ReplaceStr(U"<dst_value2>", dst_value2.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata4Vaddr3StSsDmaskF)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -3195,6 +3526,8 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchExecz_Label)
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(code.IsDiscardBlock(ShaderLabel(inst).GetDst()));
|
||||
|
||||
String label = ShaderLabel(inst).ToString();
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
@@ -3216,12 +3549,13 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label)
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
auto label = ShaderLabel(inst);
|
||||
String label_str = label.ToString();
|
||||
auto label = ShaderLabel(inst);
|
||||
|
||||
// TODO(): analyze control flow graph
|
||||
bool discard = code.IsDiscardBlock(label.GetDst());
|
||||
|
||||
String label_str = label.ToString();
|
||||
|
||||
static const char32_t* text_variant_a = UR"(
|
||||
%scc_u_<index> = OpLoad %uint %scc
|
||||
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
|
||||
@@ -3244,6 +3578,41 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label)
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranchVccz_Label)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
auto label = ShaderLabel(inst);
|
||||
|
||||
// TODO(): analyze control flow graph
|
||||
bool discard = code.IsDiscardBlock(label.GetDst());
|
||||
|
||||
String label_str = label.ToString();
|
||||
|
||||
static const char32_t* text_variant_a = UR"(
|
||||
%vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
%vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
OpSelectionMerge %<label> None
|
||||
OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
static const char32_t* text_variant_b = UR"(
|
||||
%vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
%vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
OpSelectionMerge %t230_<index> None
|
||||
OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
*dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<label>", label_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SEndpgm_Empty)
|
||||
{
|
||||
// const auto* info = spirv->GetPsInputInfo();
|
||||
@@ -3532,7 +3901,7 @@ KYTY_RECOMPILER_FUNC(Recompile_SWqmB64_Sdst2Ssrc02)
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Uint);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(operand_is_exec(inst.dst));
|
||||
// EXIT_NOT_IMPLEMENTED(operand_is_exec(inst.dst));
|
||||
|
||||
String load0;
|
||||
String load1;
|
||||
@@ -3604,6 +3973,59 @@ KYTY_RECOMPILER_FUNC(Recompile_SWaitcnt_Imm)
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_TBufferLoadFormatX_Vdata1VaddrSvSoffsIdxenFloat1)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->storage_buffers.buffers_num > 0)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[2]));
|
||||
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst);
|
||||
auto src0_value = operand_variable_to_str(inst.src[0]);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src1_value1 = operand_variable_to_str(inst.src[1], 1);
|
||||
String offset = spirv->GetConstant(inst.src[2]);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value1.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check EXEC
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t100_<index> = OpLoad %float %<src0>
|
||||
%t101_<index> = OpBitcast %int %t100_<index>
|
||||
OpStore %temp_int_1 %t101_<index>
|
||||
%t148_<index> = OpLoad %uint %<src1_value1>
|
||||
%t150_<index> = OpShiftRightLogical %uint %t148_<index> %int_16
|
||||
%t152_<index> = OpBitwiseAnd %uint %t150_<index> %uint_0x00003fff
|
||||
%t153_<index> = OpBitcast %int %t152_<index>
|
||||
OpStore %temp_int_3 %t153_<index>
|
||||
%t155_<index> = OpLoad %uint %<src1_value0>
|
||||
%t156_<index> = OpBitcast %int %t155_<index>
|
||||
OpStore %temp_int_4 %t156_<index>
|
||||
OpStore %temp_int_2 %<offset>
|
||||
OpStore %temp_int_5 %int_36
|
||||
%t110_<index> = OpFunctionCall %void %tbuffer_load_format_x %<p0> %temp_int_1 %temp_int_2 %temp_int_3 %temp_int_4 %temp_int_5
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0>", src0_value.value)
|
||||
.ReplaceStr(U"<offset>", offset)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src1_value1>", src1_value1.value)
|
||||
.ReplaceStr(U"<p0>", dst_value0.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_TBufferLoadFormatXyzw_Vdata4VaddrSvSoffsIdxenFloat4)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -3986,7 +4408,7 @@ KYTY_RECOMPILER_FUNC(Recompile_VCmpx_XXX_U32_SmaskVsrc0Vsrc1)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: Neq */
|
||||
/* XXX: Neq, Gt, Lt */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_VCmpx_XXX_F32_SmaskVsrc0Vsrc1)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -4188,7 +4610,7 @@ KYTY_RECOMPILER_FUNC(Recompile_VInterpP2F32_VdstVsrcAttrChan)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: Mad, Madak, Madmk */
|
||||
/* XXX: Mad, Madak, Madmk, Max3, Min3, Med3, Fma */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -4229,7 +4651,10 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2)
|
||||
<load0>
|
||||
<load1>
|
||||
<load2>
|
||||
<param>
|
||||
<param0>
|
||||
<param1>
|
||||
<param2>
|
||||
<param3>
|
||||
%exec_lo_u_<index> = OpLoad %uint %exec_lo
|
||||
%exec_hi_u_<index> = OpLoad %uint %exec_hi ; unused
|
||||
%exec_lo_b_<index> = OpINotEqual %bool %exec_lo_u_<index> %uint_0
|
||||
@@ -4251,7 +4676,10 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2)
|
||||
.ReplaceStr(U"<load0>", load0)
|
||||
.ReplaceStr(U"<load1>", load1)
|
||||
.ReplaceStr(U"<load2>", load2)
|
||||
.ReplaceStr(U"<param>", param[0])
|
||||
.ReplaceStr(U"<param0>", param[0])
|
||||
.ReplaceStr(U"<param1>", (param[1] == nullptr ? U"" : param[1]))
|
||||
.ReplaceStr(U"<param2>", (param[2] == nullptr ? U"" : param[2]))
|
||||
.ReplaceStr(U"<param3>", (param[3] == nullptr ? U"" : param[3]))
|
||||
.ReplaceStr(U"<index>", index_str);
|
||||
|
||||
return true;
|
||||
@@ -4416,7 +4844,7 @@ KYTY_RECOMPILER_FUNC(Recompile_VMovB32_SVdstSVsrc0)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: Mac, Max, Min, Mul, Sub, Subrev */
|
||||
/* XXX: Mac, Max, Min, Mul, Sub, Subrev, Add */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -4485,7 +4913,7 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: Rcp, Rsq, Sqrt, Ceil, Floor, Fract, Rndne, Trunc */
|
||||
/* XXX: Rcp, Rsq, Sqrt, Ceil, Floor, Fract, Rndne, Trunc, Exp, Log, Cos, Sin */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_SVdstSVsrc0)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
@@ -4493,8 +4921,8 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_SVdstSVsrc0)
|
||||
String index_str = String::FromPrintf("%u", index);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_variable(inst.dst));
|
||||
EXIT_NOT_IMPLEMENTED(inst.dst.clamp);
|
||||
EXIT_NOT_IMPLEMENTED(inst.dst.multiplier != 1.0f);
|
||||
// EXIT_NOT_IMPLEMENTED(inst.dst.clamp);
|
||||
// EXIT_NOT_IMPLEMENTED(inst.dst.multiplier != 1.0f);
|
||||
|
||||
auto dst_value = operand_variable_to_str(inst.dst);
|
||||
|
||||
@@ -4518,11 +4946,20 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_SVdstSVsrc0)
|
||||
%exec_lo_u_<index> = OpLoad %uint %exec_lo
|
||||
%exec_hi_u_<index> = OpLoad %uint %exec_hi ; unused
|
||||
%exec_lo_b_<index> = OpINotEqual %bool %exec_lo_u_<index> %uint_0
|
||||
%tdst_<index> = OpLoad %float %<dst>
|
||||
%tval_<index> = OpSelect %float %exec_lo_b_<index> %t_<index> %tdst_<index>
|
||||
OpStore %<dst> %tval_<index>
|
||||
OpSelectionMerge %tl2_<index> None
|
||||
OpBranchConditional %exec_lo_b_<index> %tl1_<index> %tl2_<index>
|
||||
%tl1_<index> = OpLabel
|
||||
OpStore %<dst> %t_<index>
|
||||
<multiply>
|
||||
<clamp>
|
||||
OpBranch %tl2_<index>
|
||||
%tl2_<index> = OpLabel
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<multiply>", (inst.dst.multiplier != 1.0f
|
||||
? String(MULTIPLY).ReplaceStr(U"<mul>", spirv->GetConstantFloat(inst.dst.multiplier))
|
||||
: U""))
|
||||
.ReplaceStr(U"<clamp>", (inst.dst.clamp ? CLAMP : U""))
|
||||
.ReplaceStr(U"<dst>", dst_value.value)
|
||||
.ReplaceStr(U"<load0>", load0)
|
||||
.ReplaceStr(U"<param0>", param[0])
|
||||
@@ -4915,7 +5352,7 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_BufferLoadFormatX_Vdata1VaddrSvSoffsIdxen, ShaderInstructionType::BufferLoadFormatX, ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen, {U""}},
|
||||
{Recompile_BufferStoreDword_Vdata1VaddrSvSoffsIdxen, ShaderInstructionType::BufferStoreDword, ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen, {U""}},
|
||||
{Recompile_BufferStoreFormatX_Vdata1VaddrSvSoffsIdxen, ShaderInstructionType::BufferStoreFormatX, ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen, {U""}},
|
||||
{Recompile_BufferStoreFormatXy_Vdata2VaddrSvSoffsIdxen, ShaderInstructionType::BufferStoreFormatXy, ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen, {U""}},
|
||||
{Recompile_BufferStoreFormatXy_Vdata2VaddrSvSoffsIdxen, ShaderInstructionType::BufferStoreFormatXy, ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen, {U""}},
|
||||
|
||||
{Recompile_DsAppend_VdstGds, ShaderInstructionType::DsAppend, ShaderInstructionFormat::VdstGds, {U""}},
|
||||
{Recompile_DsConsume_VdstGds, ShaderInstructionType::DsConsume, ShaderInstructionFormat::VdstGds, {U""}},
|
||||
@@ -4927,12 +5364,18 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_Exp_Param_XXX_Vsrc0Vsrc1Vsrc2Vsrc3, ShaderInstructionType::Exp, ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3, {U"param1"}},
|
||||
{Recompile_Exp_Param_XXX_Vsrc0Vsrc1Vsrc2Vsrc3, ShaderInstructionType::Exp, ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3, {U"param2"}},
|
||||
{Recompile_Exp_Param_XXX_Vsrc0Vsrc1Vsrc2Vsrc3, ShaderInstructionType::Exp, ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3, {U"param3"}},
|
||||
{Recompile_Exp_Param_XXX_Vsrc0Vsrc1Vsrc2Vsrc3, ShaderInstructionType::Exp, ShaderInstructionFormat::Param4Vsrc0Vsrc1Vsrc2Vsrc3, {U"param4"}},
|
||||
{Recompile_Exp_Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done, ShaderInstructionType::Exp, ShaderInstructionFormat::Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done, {U""}},
|
||||
|
||||
{Recompile_ImageLoad_Vdata4Vaddr3StDmaskF, ShaderInstructionType::ImageLoad, ShaderInstructionFormat::Vdata4Vaddr3StDmaskF, {U""}},
|
||||
{Recompile_ImageSample_Vdata1Vaddr3StSsDmask1, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata1Vaddr3StSsDmask1, {U""}},
|
||||
{Recompile_ImageSample_Vdata1Vaddr3StSsDmask1, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata1Vaddr3StSsDmask1, {U""}},
|
||||
{Recompile_ImageSample_Vdata1Vaddr3StSsDmask8, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata1Vaddr3StSsDmask8, {U""}},
|
||||
{Recompile_ImageSample_Vdata2Vaddr3StSsDmask3, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata2Vaddr3StSsDmask3, {U""}},
|
||||
{Recompile_ImageSample_Vdata2Vaddr3StSsDmask5, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata2Vaddr3StSsDmask5, {U""}},
|
||||
{Recompile_ImageSample_Vdata3Vaddr3StSsDmask7, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7, {U""}},
|
||||
{Recompile_ImageSample_Vdata4Vaddr3StSsDmaskF, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF, {U""}},
|
||||
{Recompile_ImageSampleLz_Vdata3Vaddr3StSsDmask7, ShaderInstructionType::ImageSampleLz, ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7, {U""}},
|
||||
{Recompile_ImageSampleLzO_Vdata3Vaddr4StSsDmask7, ShaderInstructionType::ImageSampleLzO, ShaderInstructionFormat::Vdata3Vaddr4StSsDmask7, {U""}},
|
||||
{Recompile_ImageStore_Vdata4Vaddr3StDmaskF, ShaderInstructionType::ImageStore, ShaderInstructionFormat::Vdata4Vaddr3StDmaskF, {U""}},
|
||||
{Recompile_ImageStoreMip_Vdata4Vaddr4StDmaskF, ShaderInstructionType::ImageStoreMip, ShaderInstructionFormat::Vdata4Vaddr4StDmaskF, {U""}},
|
||||
|
||||
@@ -4940,10 +5383,11 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_SBufferLoadDwordx2_Sdst2SvSoffset, ShaderInstructionType::SBufferLoadDwordx2, ShaderInstructionFormat::Sdst2SvSoffset, {U""}},
|
||||
{Recompile_SBufferLoadDwordx4_Sdst4SvSoffset, ShaderInstructionType::SBufferLoadDwordx4, ShaderInstructionFormat::Sdst4SvSoffset, {U""}},
|
||||
{Recompile_SBufferLoadDwordx8_Sdst8SvSoffset, ShaderInstructionType::SBufferLoadDwordx8, ShaderInstructionFormat::Sdst8SvSoffset, {U""}},
|
||||
{Recompile_SBufferLoadDwordx16_Sdst16SvSoffset, ShaderInstructionType::SBufferLoadDwordx16, ShaderInstructionFormat::Sdst16SvSoffset, {U""}},
|
||||
{Recompile_SBufferLoadDwordx16_Sdst16SvSoffset, ShaderInstructionType::SBufferLoadDwordx16, ShaderInstructionFormat::Sdst16SvSoffset, {U""}},
|
||||
|
||||
{Recompile_SCbranchExecz_Label, ShaderInstructionType::SCbranchExecz, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchScc0_Label, ShaderInstructionType::SCbranchScc0, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchVccz_Label, ShaderInstructionType::SCbranchVccz, ShaderInstructionFormat::Label, {U""}},
|
||||
|
||||
{Recompile_SEndpgm_Empty, ShaderInstructionType::SEndpgm, ShaderInstructionFormat::Empty, {U""}},
|
||||
|
||||
@@ -4992,6 +5436,7 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_S_XXX_U32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SAddU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpIAddCarry %ResTypeU %t0_<index> %t1_<index>", U"%t_<index> = OpCompositeExtract %uint %ts_<index> 0", U"%carry_<index> = OpCompositeExtract %uint %ts_<index> 1"}, SccCheck::CarryOut},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAndB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpBitwiseAnd %uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VBcntU32B32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tb_<index> = OpBitCount %int %t0_<index>", U"%tbu_<index> = OpBitcast %uint %tb_<index>", U"%t_<index> = OpIAdd %uint %tbu_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VBfmB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tcount_<index> = OpBitwiseAnd %uint %t0_<index> %uint_31", U"%toffset_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31", U"%t_<index> = OpBitFieldInsert %uint %uint_0 %uint_0xffffffff %toffset_<index> %tcount_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VLshlB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31", U"%t_<index> = OpShiftLeftLogical %uint %t0_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VLshlrevB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %uint %t0_<index> %uint_31", U"%t_<index> = OpShiftLeftLogical %uint %t1_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VLshrB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31", U"%t_<index> = OpShiftRightLogical %uint %t0_<index> %ts_<index>"}},
|
||||
@@ -5001,7 +5446,7 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulU32U24, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tu0_<index> = OpBitwiseAnd %uint %t0_<index> %uint_0x00ffffff", U"%tu1_<index> = OpBitwiseAnd %uint %t1_<index> %uint_0x00ffffff", U"%t_<index> = OpFunctionCall %uint %mul_lo_uint %tu0_<index> %tu1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VOrB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpBitwiseOr %uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VXorB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpBitwiseXor %uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VBfmB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tcount_<index> = OpBitwiseAnd %uint %t0_<index> %uint_31", U"%toffset_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31", U"%t_<index> = OpBitFieldInsert %uint %uint_0 %uint_0xffffffff %toffset_<index> %tcount_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAddF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFAdd %float %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMacF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fma %t0_<index> %t1_<index> %tdst_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMaxF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpExtInst %float %GLSL_std_450 FMax %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMinF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpExtInst %float %GLSL_std_450 FMin %t0_<index> %t1_<index>"}},
|
||||
@@ -5020,16 +5465,18 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_SMovB32_SVdstSVsrc0, ShaderInstructionType::SMovkI32, ShaderInstructionFormat::SVdstSVsrc0, {U""}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0, ShaderInstructionType::VBfrevB32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpBitReverse %uint %t0_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0, ShaderInstructionType::VNotB32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpNot %uint %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRcpF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpFDiv %float %float_1_000000 %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRsqF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 InverseSqrt %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VSqrtF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Sqrt %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VCeilF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Ceil %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VFloorF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Floor %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VFractF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fract %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRndneF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 RoundEven %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VTruncF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Trunc %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VCosF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%tr_<index> = OpFMul %float %t0_<index> %float_2pi", U"%t_<index> = OpExtInst %float %GLSL_std_450 Cos %tr_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VExpF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Exp2 %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VFloorF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Floor %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VFractF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fract %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VLogF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Log2 %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRcpF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpFDiv %float %float_1_000000 %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRndneF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 RoundEven %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VRsqF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 InverseSqrt %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VSinF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%tr_<index> = OpFMul %float %t0_<index> %float_2pi", U"%t_<index> = OpExtInst %float %GLSL_std_450 Sin %tr_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VSqrtF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Sqrt %t0_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VTruncF32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Trunc %t0_<index>"}},
|
||||
{Recompile_VCvt_XXX_F32_SVdstSVsrc0, ShaderInstructionType::VCvtU32F32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t1_<index> = OpExtInst %float %GLSL_std_450 Trunc %t0_<index>", U"%t2_<index> = OpConvertFToU %uint %t1_<index>"}},
|
||||
{Recompile_VCvtF32_XXX_SVdstSVsrc0, ShaderInstructionType::VCvtF32F16, ShaderInstructionFormat::SVdstSVsrc0, {U"%ts_<index> = OpExtInst %v2float %GLSL_std_450 UnpackHalf2x16 %t0_<index>", U"%t_<index> = OpCompositeExtract %float %ts_<index> 0"}},
|
||||
{Recompile_VCvtF32_XXX_SVdstSVsrc0, ShaderInstructionType::VCvtF32I32, ShaderInstructionFormat::SVdstSVsrc0, {U"%ti_<index> = OpBitcast %int %t0_<index>", U"%t_<index> = OpConvertSToF %float %ti_<index>"}},
|
||||
@@ -5047,8 +5494,9 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
|
||||
{Recompile_SWaitcnt_Imm, ShaderInstructionType::SWaitcnt, ShaderInstructionFormat::Imm, {U""}},
|
||||
|
||||
{Recompile_TBufferLoadFormatX_Vdata1VaddrSvSoffsIdxenFloat1, ShaderInstructionType::TBufferLoadFormatX, ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxenFloat1, {U""}},
|
||||
{Recompile_TBufferLoadFormatXyzw_Vdata4Vaddr2SvSoffsOffenIdxenFloat4, ShaderInstructionType::TBufferLoadFormatXyzw, ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4, {U""}},
|
||||
{Recompile_TBufferLoadFormatXyzw_Vdata4VaddrSvSoffsIdxenFloat4, ShaderInstructionType::TBufferLoadFormatXyzw, ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4, {U""}},
|
||||
{Recompile_TBufferLoadFormatXyzw_Vdata4Vaddr2SvSoffsOffenIdxenFloat4, ShaderInstructionType::TBufferLoadFormatXyzw, ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4, {U""}},
|
||||
|
||||
{Recompile_V_XXX_U32_VdstSdst2Vsrc0Vsrc1, ShaderInstructionType::VAddI32, ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1, {U"%t_<index> = OpIAddCarry %ResTypeU %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_U32_VdstSdst2Vsrc0Vsrc1, ShaderInstructionType::VSubI32, ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1, {U"%t_<index> = OpISubBorrow %ResTypeU %t0_<index> %t1_<index>"}},
|
||||
@@ -5087,6 +5535,8 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLtU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpULessThan"}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpTU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_0 ; "}},
|
||||
{Recompile_VCmpx_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxNeqF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordNotEqual"}},
|
||||
{Recompile_VCmpx_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxGtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdGreaterThan"}},
|
||||
{Recompile_VCmpx_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxLtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdLessThan"}},
|
||||
{Recompile_VCmpx_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxEqU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual"}},
|
||||
{Recompile_VCmpx_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxNeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpINotEqual"}},
|
||||
{Recompile_VCmpx_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxGeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThanEqual"}},
|
||||
@@ -5111,8 +5561,17 @@ static RecompilerFunc g_recomp_func[] = {
|
||||
{Recompile_VInterpP2F32_VdstVsrcAttrChan, ShaderInstructionType::VInterpP2F32, ShaderInstructionFormat::VdstVsrcAttrChan, {U""}},
|
||||
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMadF32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fma %t0_<index> %t1_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VFmaF32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fma %t0_<index> %t1_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMadakF32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fma %t0_<index> %t1_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMadmkF32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%t_<index> = OpExtInst %float %GLSL_std_450 Fma %t0_<index> %t1_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMax3F32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%tm_<index> = OpExtInst %float %GLSL_std_450 FMax %t0_<index> %t1_<index>",
|
||||
U"%t_<index> = OpExtInst %float %GLSL_std_450 FMax %tm_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMin3F32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%tm_<index> = OpExtInst %float %GLSL_std_450 FMin %t0_<index> %t1_<index>",
|
||||
U"%t_<index> = OpExtInst %float %GLSL_std_450 FMin %tm_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VMed3F32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%t3_<index> = OpExtInst %float %GLSL_std_450 FMin %t0_<index> %t1_<index>",
|
||||
U"%t4_<index> = OpExtInst %float %GLSL_std_450 FMax %t0_<index> %t1_<index>",
|
||||
U"%t5_<index> = OpExtInst %float %GLSL_std_450 FMin %t4_<index> %t2_<index>",
|
||||
U"%t_<index> = OpExtInst %float %GLSL_std_450 FMax %t3_<index> %t5_<index>"}},
|
||||
{Recompile_V_XXX_U32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VSadU32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%td_<index> = OpFunctionCall %uint %abs_diff %t0_<index> %t1_<index>",
|
||||
U"%t_<index> = OpIAdd %uint %td_<index> %t2_<index>"}},
|
||||
{Recompile_V_XXX_U32_VdstVsrc0Vsrc1Vsrc2, ShaderInstructionType::VBfeU32, ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2, {U"%to_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31",
|
||||
@@ -5317,22 +5776,10 @@ void Spirv::GenerateSource()
|
||||
|
||||
switch (m_code.GetType())
|
||||
{
|
||||
case ShaderType::Pixel:
|
||||
m_bind = (m_ps_input_info != nullptr ? &m_ps_input_info->bind : nullptr);
|
||||
// m_bind_params = (m_ps_input_info != nullptr ? ShaderGetBindParametersPS(m_code, m_ps_input_info) : ShaderBindParameters());
|
||||
break;
|
||||
case ShaderType::Vertex:
|
||||
m_bind = (m_vs_input_info != nullptr ? &m_vs_input_info->bind : nullptr);
|
||||
// m_bind_params = (m_vs_input_info != nullptr ? ShaderGetBindParametersVS(m_code, m_vs_input_info) : ShaderBindParameters());
|
||||
break;
|
||||
case ShaderType::Compute:
|
||||
m_bind = (m_cs_input_info != nullptr ? &m_cs_input_info->bind : nullptr);
|
||||
// m_bind_params = (m_cs_input_info != nullptr ? ShaderGetBindParametersCS(m_code, m_cs_input_info) : ShaderBindParameters());
|
||||
break;
|
||||
default:
|
||||
m_bind = nullptr;
|
||||
// m_bind_params = ShaderBindParameters();
|
||||
break;
|
||||
case ShaderType::Pixel: m_bind = (m_ps_input_info != nullptr ? &m_ps_input_info->bind : nullptr); break;
|
||||
case ShaderType::Vertex: m_bind = (m_vs_input_info != nullptr ? &m_vs_input_info->bind : nullptr); break;
|
||||
case ShaderType::Compute: m_bind = (m_cs_input_info != nullptr ? &m_cs_input_info->bind : nullptr); break;
|
||||
default: m_bind = nullptr; break;
|
||||
}
|
||||
|
||||
WriteHeader();
|
||||
@@ -5352,7 +5799,8 @@ void Spirv::WriteHeader()
|
||||
{
|
||||
static const char32_t* header = UR"(
|
||||
; Header
|
||||
OpCapability Shader
|
||||
OpCapability Shader
|
||||
OpCapability ImageQuery
|
||||
<Extensions>
|
||||
<Imports>
|
||||
OpMemoryModel Logical GLSL450
|
||||
@@ -5633,6 +6081,7 @@ void Spirv::WriteTypes()
|
||||
%v2uint = OpTypeVector %uint 2
|
||||
%v3uint = OpTypeVector %uint 3
|
||||
%v4uint = OpTypeVector %uint 4
|
||||
%v2int = OpTypeVector %int 2
|
||||
%undef_v2uint = OpUndef %v2uint
|
||||
%_ptr_Input_int = OpTypePointer Input %int
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
@@ -6165,8 +6614,91 @@ void Spirv::WriteLocalVariables()
|
||||
m_source += U"\n";
|
||||
}
|
||||
|
||||
void Spirv::WriteLabel(int index)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
const auto& instructions = m_code.GetInstructions();
|
||||
const auto& inst = instructions.At(index);
|
||||
|
||||
auto& labels = m_code.GetLabels();
|
||||
int labels_num = 0;
|
||||
for (uint32_t i = labels.Size(); i > 0; i--)
|
||||
{
|
||||
auto& label = labels[i - 1];
|
||||
if (!label.IsDisabled() && label.GetDst() == inst.pc)
|
||||
{
|
||||
static const char32_t* text = UR"(
|
||||
<branch>
|
||||
%<label> = OpLabel
|
||||
)";
|
||||
|
||||
bool discard = m_code.IsDiscardBlock(label.GetDst());
|
||||
|
||||
bool skip_branch = (discard || (instructions.At(index - 1).type == ShaderInstructionType::SEndpgm && labels_num == 0));
|
||||
|
||||
m_source += String(text)
|
||||
.ReplaceStr(U"<branch>", (skip_branch ? U"" : U"OpBranch %<label>"))
|
||||
.ReplaceStr(U"<label>", label.ToString());
|
||||
labels_num++;
|
||||
|
||||
if (discard)
|
||||
{
|
||||
label.Disable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spirv::ModifyCode()
|
||||
{
|
||||
struct DiscardLabel
|
||||
{
|
||||
uint32_t pc = 0;
|
||||
int num = 0;
|
||||
};
|
||||
const auto& labels = m_code.GetLabels();
|
||||
Vector<DiscardLabel> dls;
|
||||
for (const auto& l: labels)
|
||||
{
|
||||
if (!l.IsDisabled())
|
||||
{
|
||||
int num = 0;
|
||||
auto pc = l.GetDst();
|
||||
for (const auto& l2: labels)
|
||||
{
|
||||
if (l2.GetDst() == pc)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
EXIT_IF(num == 0);
|
||||
if (num > 1 && m_code.IsDiscardBlock(pc))
|
||||
{
|
||||
if (!dls.Contains(pc, [](auto d, auto pc) { return d.pc == pc; }))
|
||||
{
|
||||
dls.Add(DiscardLabel({pc, num - 1}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& dl: dls)
|
||||
{
|
||||
auto block = m_code.GetDiscardBlock(dl.pc);
|
||||
for (int i = 0; i < dl.num; i++)
|
||||
{
|
||||
// Duplicate discard block if there are different branches with the same label
|
||||
m_code.GetInstructions().Add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spirv::WriteInstructions()
|
||||
{
|
||||
ModifyCode();
|
||||
|
||||
int index = -1;
|
||||
const auto& instructions = m_code.GetInstructions();
|
||||
bool need_debug = (Config::SpirvDebugPrintfEnabled() && !m_code.GetDebugPrintfs().IsEmpty());
|
||||
@@ -6174,25 +6706,7 @@ void Spirv::WriteInstructions()
|
||||
{
|
||||
index++;
|
||||
|
||||
const auto& labels = m_code.GetLabels();
|
||||
for (uint32_t i = labels.Size(); i > 0; i--)
|
||||
{
|
||||
auto label = labels.At(i - 1);
|
||||
if (index > 0 && label.GetDst() == inst.pc)
|
||||
{
|
||||
static const char32_t* text = UR"(
|
||||
<branch>
|
||||
%<label> = OpLabel
|
||||
)";
|
||||
|
||||
auto prev_type = instructions.At(index - 1).type;
|
||||
bool skip_branch = (prev_type == ShaderInstructionType::SEndpgm);
|
||||
|
||||
m_source += String(text)
|
||||
.ReplaceStr(U"<branch>", (skip_branch ? U"" : U"OpBranch %<label>"))
|
||||
.ReplaceStr(U"<label>", label.ToString());
|
||||
}
|
||||
}
|
||||
WriteLabel(index);
|
||||
|
||||
String src = ShaderCode::DbgInstructionToStr(inst);
|
||||
String dst;
|
||||
@@ -6277,7 +6791,8 @@ void Spirv::WriteFunctions()
|
||||
|
||||
if (m_code.HasAnyOf({ShaderInstructionType::BufferLoadDword, ShaderInstructionType::BufferLoadFormatX,
|
||||
ShaderInstructionType::BufferLoadFormatXy, ShaderInstructionType::BufferLoadFormatXyz,
|
||||
ShaderInstructionType::BufferLoadFormatXyzw, ShaderInstructionType::TBufferLoadFormatXyzw}))
|
||||
ShaderInstructionType::BufferLoadFormatXyzw, ShaderInstructionType::TBufferLoadFormatX,
|
||||
ShaderInstructionType::TBufferLoadFormatXyzw}))
|
||||
{
|
||||
m_source += BUFFER_LOAD_FLOAT1;
|
||||
m_source += BUFFER_LOAD_FLOAT4;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "Emulator/Graphics/Tile.h"
|
||||
|
||||
#include "Kyty/Core/ArrayWrapper.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
|
||||
#include "Emulator/Graphics/AsyncJob.h"
|
||||
@@ -200,26 +202,36 @@ class Tiler1d
|
||||
public:
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
uint32_t m_pitch = 0;
|
||||
uint32_t m_bits_per_element = 0;
|
||||
uint32_t m_tile_bytes = 0;
|
||||
uint32_t m_tiles_per_row = 0;
|
||||
|
||||
void Init(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t padded_width, uint32_t /*padded_height*/,
|
||||
bool /*neo*/)
|
||||
void Init(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t padded_width,
|
||||
uint32_t /*padded_height*/, bool /*neo*/)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_pitch = pitch;
|
||||
|
||||
if ((nfmt == 9 && dfmt == 10) || (nfmt == 0 && dfmt == 10))
|
||||
{
|
||||
// VK_FORMAT_R8G8B8A8_SRGB;
|
||||
// R8G8B8A8
|
||||
m_bits_per_element = 32;
|
||||
} else if (nfmt == 9 && dfmt == 37)
|
||||
} else if ((nfmt == 9 && dfmt == 37) || (nfmt == 0 && dfmt == 37) || (nfmt == 0 && dfmt == 36))
|
||||
{
|
||||
// VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
// BC2 or BC3
|
||||
m_bits_per_element = 128;
|
||||
m_width = std::max((m_width + 3) / 4, 1U);
|
||||
m_height = std::max((m_height + 3) / 4, 1U);
|
||||
m_pitch = std::max((m_pitch + 3) / 4, 1U);
|
||||
} else if ((nfmt == 0 && dfmt == 35))
|
||||
{
|
||||
// BC1
|
||||
m_bits_per_element = 64;
|
||||
m_width = std::max((m_width + 3) / 4, 1U);
|
||||
m_height = std::max((m_height + 3) / 4, 1U);
|
||||
m_pitch = std::max((m_pitch + 3) / 4, 1U);
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
@@ -365,6 +377,29 @@ static void Detile32(const Tiler1d* t, uint32_t width, uint32_t height, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
static void Detile64(const Tiler1d* t, uint32_t width, uint32_t height, uint32_t dst_pitch, uint8_t* dst, const uint8_t* src, bool neo)
|
||||
{
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
{
|
||||
uint32_t x = 0;
|
||||
uint64_t linear_offset = y * dst_pitch * 8;
|
||||
|
||||
for (; x + 1 < width; x += 2)
|
||||
{
|
||||
auto tiled_offset = t->GetTiledOffset(x, y, neo);
|
||||
|
||||
*reinterpret_cast<Uint128*>(dst + linear_offset) = *reinterpret_cast<const Uint128*>(src + tiled_offset);
|
||||
linear_offset += 16;
|
||||
}
|
||||
if (x < width)
|
||||
{
|
||||
auto tiled_offset = t->GetTiledOffset(x, y, neo);
|
||||
|
||||
*reinterpret_cast<uint64_t*>(dst + linear_offset) = *reinterpret_cast<const uint64_t*>(src + tiled_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Detile128(const Tiler1d* t, uint32_t width, uint32_t height, uint32_t dst_pitch, uint8_t* dst, const uint8_t* src, bool neo)
|
||||
{
|
||||
for (uint32_t y = 0; y < height; y++)
|
||||
@@ -392,10 +427,13 @@ static void Detile1d(const Tiler1d* t, uint8_t* dst, const uint8_t* src, bool ne
|
||||
{
|
||||
if (t->m_bits_per_element == 32)
|
||||
{
|
||||
Detile32(t, t->m_width, t->m_height, t->m_width, dst, src, neo);
|
||||
Detile32(t, t->m_width, t->m_height, t->m_pitch, dst, src, neo);
|
||||
} else if (t->m_bits_per_element == 64)
|
||||
{
|
||||
Detile64(t, t->m_width, t->m_height, t->m_pitch, dst, src, neo);
|
||||
} else if (t->m_bits_per_element == 128)
|
||||
{
|
||||
Detile128(t, t->m_width, t->m_height, t->m_width, dst, src, neo);
|
||||
Detile128(t, t->m_width, t->m_height, t->m_pitch, dst, src, neo);
|
||||
} else
|
||||
{
|
||||
EXIT("Unknown size");
|
||||
@@ -415,7 +453,7 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
|
||||
}
|
||||
|
||||
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)
|
||||
uint32_t pitch, uint32_t levels, bool neo)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(mode != TileMode::TextureTiled);
|
||||
|
||||
@@ -423,10 +461,11 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
|
||||
uint32_t padded_height[16] = {0};
|
||||
uint32_t level_sizes[16] = {0};
|
||||
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, width, levels, 13, neo, nullptr, level_sizes, padded_width, padded_height);
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, 13, neo, nullptr, level_sizes, padded_width, padded_height);
|
||||
|
||||
uint32_t mip_width = width;
|
||||
uint32_t mip_height = height;
|
||||
uint32_t mip_pitch = pitch;
|
||||
|
||||
auto* dstptr = static_cast<uint8_t*>(dst);
|
||||
const auto* srcptr = static_cast<const uint8_t*>(src);
|
||||
@@ -434,7 +473,7 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
|
||||
for (uint32_t l = 0; l < levels; l++)
|
||||
{
|
||||
Tiler1d t;
|
||||
t.Init(dfmt, nfmt, mip_width, mip_height, padded_width[l], padded_height[l], neo);
|
||||
t.Init(dfmt, nfmt, mip_width, mip_height, mip_pitch, padded_width[l], padded_height[l], neo);
|
||||
|
||||
Detile1d(&t, dstptr, srcptr, neo);
|
||||
|
||||
@@ -449,6 +488,10 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
|
||||
{
|
||||
mip_height /= 2;
|
||||
}
|
||||
if (mip_pitch > 1)
|
||||
{
|
||||
mip_pitch /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,75 +700,277 @@ void TileGetVideoOutSize(uint32_t width, uint32_t height, uint32_t pitch, bool t
|
||||
size->align = ret_align;
|
||||
}
|
||||
|
||||
struct TilePadded
|
||||
{
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
};
|
||||
|
||||
struct TextureInfo
|
||||
{
|
||||
uint32_t dfmt = 0;
|
||||
uint32_t nfmt = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t pitch = 0;
|
||||
uint32_t levels = 0;
|
||||
uint32_t tile = 0;
|
||||
bool neo = false;
|
||||
TileSizeAlign size[16];
|
||||
TilePadded padded[16];
|
||||
};
|
||||
|
||||
static void FindTextureInfo(uint32_t tile, uint32_t dfmt, uint32_t nfmt, const TextureInfo** info, int* num)
|
||||
{
|
||||
EXIT_IF(info == nullptr);
|
||||
EXIT_IF(num == nullptr);
|
||||
|
||||
static const TextureInfo infos_8[] = {
|
||||
// clang-format off
|
||||
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeDisplay_LinearAligned
|
||||
{ 10, 9, 512, 512, 512, 10, 8, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 10, 9, 512, 512, 512, 10, 8, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// kDataFormatR8Unorm, 2048, 2048, 0, 0, kTileModeDisplay_LinearAligned
|
||||
{ 1, 0, 2048, 2048, 2048, 12, 8, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 1, 0, 2048, 2048, 2048, 12, 8, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 1, 1, 64, 0, kTileModeDisplay_LinearAligned
|
||||
{ 10, 0, 1, 1, 64, 1, 8, false, {{256, 256}, }, { {0, 0}, } },
|
||||
{ 10, 0, 1, 1, 64, 1, 8, true, {{256, 256}, }, { {0, 0}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_10_0[] = {
|
||||
// clang-format off
|
||||
// kDataFormatB8G8R8A8Unorm, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 1024, 1024, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 1024, 1024, 1024, 11, 13, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 1024, 1024, 1024, 11, 13, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 2048, 2048, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 2048, 2048, 2048, 12, 13, false, {{16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {2048, 2048}, {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 2048, 2048, 2048, 12, 13, true, {{16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {2048, 2048}, {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 512, 768, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 512, 768, 512, 10, 13, false, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 512, 768, 512, 10, 13, true, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_10_9[] = {
|
||||
// clang-format off
|
||||
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 9, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 9, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_35_0[] = {
|
||||
// clang-format off
|
||||
// kDataFormatBc1Unorm, 256, 64, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 256, 64, 256, 9, 13, false, {{8192, 256}, {2048, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 256, 64, 256, 9, 13, true, {{8192, 256}, {2048, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 256, 256, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 256, 256, 256, 9, 13, false, {{32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 256, 256, 256, 9, 13, true, {{32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 512, 512, 512, 10, 13, false, {{131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 512, 512, 512, 10, 13, true, {{131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 1024, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 1024, 512, 1024, 11, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 1024, 512, 1024, 11, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 1024, 1024, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 1024, 1024, 1024, 11, 13, false, {{524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 1024, 1024, 1024, 11, 13, true, {{524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 2048, 1024, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 2048, 1024, 2048, 12, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {512, 256}, {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 2048, 1024, 2048, 12, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {512, 256}, {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 2048, 2048, 0, 0, kTileModeThin_1dThin
|
||||
{ 35, 0, 2048, 2048, 2048, 12, 13, false, {{2097152, 256}, {524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 35, 0, 2048, 2048, 2048, 12, 13, true, {{2097152, 256}, {524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, {512, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc1Unorm, 1920, 1080, 1920, 1, kTileModeThin_1dThin
|
||||
{ 35, 0, 1920, 1080, 1920, 1, 13, false, {{1044480, 256}, }, { {480, 272}, } },
|
||||
{ 35, 0, 1920, 1080, 1920, 1, 13, true, {{1044480, 256}, }, { {480, 272}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_36_0[] = {
|
||||
// clang-format off
|
||||
// kDataFormatBc2Unorm, 1, 32, 0, 0, kTileModeThin_1dThin
|
||||
{ 36, 0, 1, 32, 32, 6, 13, false, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 36, 0, 1, 32, 32, 6, 13, true, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc2Unorm, 8, 32, 0, 0, kTileModeThin_1dThin
|
||||
{ 36, 0, 8, 32, 32, 6, 13, false, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 36, 0, 8, 32, 32, 6, 13, true, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc2Unorm, 2048, 2048, 0, 0, kTileModeThin_1dThin
|
||||
{ 36, 0, 2048, 2048, 2048, 12, 13, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 36, 0, 2048, 2048, 2048, 12, 13, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc2Unorm, 4096, 4096, 0, 0, kTileModeThin_1dThin
|
||||
{ 36, 0, 4096, 4096, 4096, 13, 13, false, {{16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 36, 0, 4096, 4096, 4096, 13, 13, true, {{16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc2Unorm, 8192, 8192, 0, 0, kTileModeThin_1dThin
|
||||
{ 36, 0, 8192, 8192, 8192, 14, 13, false, {{67108864, 256}, {16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {2048, 2048}, {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 36, 0, 8192, 8192, 8192, 14, 13, true, {{67108864, 256}, {16777216, 256}, {4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {2048, 2048}, {1024, 1024}, {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_37_0[] = {
|
||||
// clang-format off
|
||||
// kDataFormatBc3Unorm, 16, 32, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 16, 32, 32, 6, 13, false, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 16, 32, 32, 6, 13, true, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 32, 32, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 32, 32, 32, 6, 13, false, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 32, 32, 32, 6, 13, true, {{1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 64, 64, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 64, 64, 64, 7, 13, false, {{4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 64, 64, 64, 7, 13, true, {{4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 128, 128, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 128, 128, 128, 8, 13, false, {{16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 128, 128, 128, 8, 13, true, {{16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 256, 256, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 256, 256, 256, 9, 13, false, {{65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 256, 256, 256, 9, 13, true, {{65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 512, 512, 512, 10, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 512, 512, 512, 10, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 1024, 256, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 1024, 256, 1024, 11, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 64}, {128, 32}, {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 1024, 256, 1024, 11, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 64}, {128, 32}, {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 1024, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 1024, 512, 1024, 11, 13, false, {{524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 1024, 512, 1024, 11, 13, true, {{524288, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 128}, {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 1024, 1024, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 1024, 1024, 1024, 11, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 1024, 1024, 1024, 11, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 2048, 128, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 2048, 128, 2048, 12, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {8192, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 32}, {256, 16}, {128, 8}, {64, 8}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 2048, 128, 2048, 12, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {8192, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 32}, {256, 16}, {128, 8}, {64, 8}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 2048, 2048, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 2048, 2048, 2048, 12, 13, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 2048, 2048, 2048, 12, 13, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 256, 32, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 256, 32, 256, 9, 13, false, {{8192, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 8}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 256, 32, 256, 9, 13, true, {{8192, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 8}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 256, 64, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 256, 64, 256, 9, 13, false, {{16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 256, 64, 256, 9, 13, true, {{16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 16}, {32, 8}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 256, 128, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 256, 128, 256, 9, 13, false, {{32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 256, 128, 256, 9, 13, true, {{32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 512, 256, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 0, 512, 256, 512, 10, 13, false, {{131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 0, 512, 256, 512, 10, 13, true, {{131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 64}, {64, 32}, {32, 16}, {16, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3Unorm, 1920, 1080, 1920, 1, kTileModeThin_1dThin
|
||||
{ 37, 0, 1920, 1080, 1920, 1, 13, false, {{2088960, 256}, }, { {480, 272}, } },
|
||||
{ 37, 0, 1920, 1080, 1920, 1, 13, true, {{2088960, 256}, }, { {480, 272}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_13_37_9[] = {
|
||||
// clang-format off
|
||||
// kDataFormatBc3UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 9, 512, 512, 512, 10, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 9, 512, 512, 512, 10, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_14[] = {
|
||||
// clang-format off
|
||||
// kDataFormatB8G8R8A8Unorm, 256, 256, 0, 0, kTileModeThin_2dThin
|
||||
{ 10, 0, 256, 256, 256, 9, 14, false, {{262144, 32768}, {65536, 32768}, {16384, 32768}, {4096, 32768}, {1024, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 10, 0, 256, 256, 256, 9, 14, true, {{262144, 65536}, {65536, 65536}, {16384, 65536}, {4096, 65536}, {1024, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_10[] = {
|
||||
// clang-format off
|
||||
// kDataFormatB8G8R8A8Unorm, 96, 96, 128, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 96, 96, 128, 1, 10, false, {{65536, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 96, 96, 128, 1, 10, true, {{65536, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 128, 128, 128, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 128, 128, 128, 1, 10, false, {{65536, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 128, 128, 128, 1, 10, true, {{65536, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 960, 540, 1024, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 960, 540, 1024, 1, 10, false, {{2359296, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 960, 540, 1024, 1, 10, true, {{2621440, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 1920, 1080, 1920, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 1920, 1080, 1920, 1, 10, false, {{8355840, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 1920, 1080, 1920, 1, 10, true, {{8847360, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 3840, 2160, 3840, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 3840, 2160, 3840, 1, 10, false, {{33423360, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 3840, 2160, 3840, 1, 10, true, {{33423360, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 4096, 4096, 4096, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 4096, 4096, 4096, 1, 10, false, {{67108864, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 4096, 4096, 4096, 1, 10, true, {{67108864, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 8192, 4096, 8192, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 8192, 4096, 8192, 1, 10, false, {{134217728, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 8192, 4096, 8192, 1, 10, true, {{134217728, 65536}, }, { {0, 0}, } },
|
||||
// clang-format on
|
||||
};
|
||||
static const TextureInfo infos_2[] = {
|
||||
// clang-format off
|
||||
// kDataFormatR32Float, 1920, 1080, 1920, 1, kTileModeDepth_2dThin_256
|
||||
{ 4, 7, 1920, 1080, 1920, 1, 2, false, {{8355840, 32768}, }, { {0, 0}, } },
|
||||
{ 4, 7, 1920, 1080, 1920, 1, 2, true, {{8847360, 65536}, }, { {0, 0}, } },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
switch (tile)
|
||||
{
|
||||
case 8:
|
||||
*info = infos_8;
|
||||
*num = KYTY_ARRAY_NUM(infos_8);
|
||||
break;
|
||||
case 13:
|
||||
if (dfmt == 10 && nfmt == 0)
|
||||
{
|
||||
*info = infos_13_10_0;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_10_0);
|
||||
} else if (dfmt == 10 && nfmt == 9)
|
||||
{
|
||||
*info = infos_13_10_9;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_10_9);
|
||||
} else if (dfmt == 35 && nfmt == 0)
|
||||
{
|
||||
*info = infos_13_35_0;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_35_0);
|
||||
} else if (dfmt == 36 && nfmt == 0)
|
||||
{
|
||||
*info = infos_13_36_0;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_36_0);
|
||||
} else if (dfmt == 37 && nfmt == 0)
|
||||
{
|
||||
*info = infos_13_37_0;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_37_0);
|
||||
} else if (dfmt == 37 && nfmt == 9)
|
||||
{
|
||||
*info = infos_13_37_9;
|
||||
*num = KYTY_ARRAY_NUM(infos_13_37_9);
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
*info = infos_14;
|
||||
*num = KYTY_ARRAY_NUM(infos_14);
|
||||
break;
|
||||
case 10:
|
||||
*info = infos_10;
|
||||
*num = KYTY_ARRAY_NUM(infos_10);
|
||||
break;
|
||||
case 2:
|
||||
*info = infos_2;
|
||||
*num = KYTY_ARRAY_NUM(infos_2);
|
||||
break;
|
||||
default: *info = nullptr; *num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
|
||||
bool neo, TileSizeAlign* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
struct Padded
|
||||
{
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
};
|
||||
|
||||
struct TextureInfo
|
||||
{
|
||||
uint32_t dfmt = 0;
|
||||
uint32_t nfmt = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t pitch = 0;
|
||||
uint32_t levels = 0;
|
||||
uint32_t tile = 0;
|
||||
bool neo = false;
|
||||
TileSizeAlign size[16];
|
||||
Padded padded[16];
|
||||
};
|
||||
|
||||
static const TextureInfo infos[] = {
|
||||
// clang-format off
|
||||
|
||||
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeDisplay_LinearAligned
|
||||
{ 10, 9, 512, 512, 512, 10, 8, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 10, 9, 512, 512, 512, 10, 8, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 9, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 9, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatBc3UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 37, 9, 512, 512, 512, 10, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 37, 9, 512, 512, 512, 10, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 512, 512, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 512, 768, 0, 0, kTileModeThin_1dThin
|
||||
{ 10, 0, 512, 768, 512, 10, 13, false, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 512, 768, 512, 10, 13, true, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 256, 256, 0, 0, kTileModeThin_2dThin
|
||||
{ 10, 0, 256, 256, 256, 9, 14, false, {{262144, 32768}, {65536, 32768}, {16384, 32768}, {4096, 32768}, {1024, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 10, 0, 256, 256, 256, 9, 14, true, {{262144, 65536}, {65536, 65536}, {16384, 65536}, {4096, 65536}, {1024, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 1920, 1080, 1920, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 1920, 1080, 1920, 1, 10, false, {{8355840, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 1920, 1080, 1920, 1, 10, true, {{8847360, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 3840, 2160, 3840, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 3840, 2160, 3840, 1, 10, false, {{33423360, 32768}, }, { {0, 0}, } },
|
||||
{ 10, 0, 3840, 2160, 3840, 1, 10, true, {{33423360, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatR32Float, 1920, 1080, 1920, 1, kTileModeDepth_2dThin_256
|
||||
{ 4, 7, 1920, 1080, 1920, 1, 2, false, {{8355840, 32768}, }, { {0, 0}, } },
|
||||
{ 4, 7, 1920, 1080, 1920, 1, 2, true, {{8847360, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatR8Unorm, 2048, 2048, 0, 0, kTileModeDisplay_LinearAligned
|
||||
{ 1, 0, 2048, 2048, 2048, 12, 8, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
{ 1, 0, 2048, 2048, 2048, 12, 8, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 1, 1, 64, 0, kTileModeDisplay_LinearAligned
|
||||
{ 10, 0, 1, 1, 64, 1, 8, false, {{256, 256}, }, { {0, 0}, } },
|
||||
{ 10, 0, 1, 1, 64, 1, 8, true, {{256, 256}, }, { {0, 0}, } },
|
||||
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
// EXIT_IF(total_size == nullptr);
|
||||
|
||||
for (const auto& i: infos)
|
||||
const TextureInfo* infos = nullptr;
|
||||
int num = 0;
|
||||
|
||||
FindTextureInfo(tile, dfmt, nfmt, &infos, &num);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(tile != 31 && infos == nullptr);
|
||||
|
||||
for (int index = 0; index < num; index++)
|
||||
{
|
||||
const auto& i = infos[index];
|
||||
if (i.dfmt == dfmt && i.nfmt == nfmt && i.width == width && i.pitch == pitch && i.height == height && i.levels >= levels &&
|
||||
i.tile == tile && i.neo == neo)
|
||||
{
|
||||
@@ -753,9 +998,21 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
|
||||
}
|
||||
}
|
||||
|
||||
if (tile == 8 && levels == 1 && ((dfmt == 10 && nfmt == 9) || (dfmt == 10 && nfmt == 0)))
|
||||
if ((tile == 8 || tile == 31) && levels == 1)
|
||||
{
|
||||
uint32_t size = pitch * height * 4;
|
||||
uint32_t size = 0;
|
||||
|
||||
if ((dfmt == 10 && nfmt == 9) || (dfmt == 10 && nfmt == 0))
|
||||
{
|
||||
size = pitch * height * 4;
|
||||
} else if ((dfmt == 3 && nfmt == 0))
|
||||
{
|
||||
size = pitch * height * 2;
|
||||
} else if ((dfmt == 1 && nfmt == 0))
|
||||
{
|
||||
size = pitch * height;
|
||||
}
|
||||
|
||||
if (total_size != nullptr)
|
||||
{
|
||||
total_size->size = size;
|
||||
@@ -766,6 +1023,20 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
|
||||
level_sizes[0] = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_size != nullptr && total_size->size == 0)
|
||||
{
|
||||
Core::StringList list;
|
||||
list.Add(String::FromPrintf("dfmt = %u", dfmt));
|
||||
list.Add(String::FromPrintf("nfmt = %u", nfmt));
|
||||
list.Add(String::FromPrintf("width = %u", width));
|
||||
list.Add(String::FromPrintf("height = %u", height));
|
||||
list.Add(String::FromPrintf("pitch = %u", pitch));
|
||||
list.Add(String::FromPrintf("levels = %u", levels));
|
||||
list.Add(String::FromPrintf("tile = %u", tile));
|
||||
list.Add(String::FromPrintf("neo = %s", neo ? "true" : "false"));
|
||||
EXIT("unknown format:\n%s\n", list.Concat(U'\n').C_Str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "Emulator/Graphics/Objects/GpuMemory.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
@@ -19,7 +17,7 @@ static void set_image_layout(VkCommandBuffer buffer, VulkanImage* dst_image, uin
|
||||
{
|
||||
EXIT_IF(buffer == nullptr);
|
||||
|
||||
EXIT_IF(dst_image->layout != old_image_layout);
|
||||
EXIT_IF(old_image_layout != VK_IMAGE_LAYOUT_UNDEFINED && dst_image->layout != old_image_layout);
|
||||
|
||||
VkImageMemoryBarrier image_memory_barrier {};
|
||||
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
@@ -86,7 +84,7 @@ static void set_image_layout(VkCommandBuffer buffer, VulkanImage* dst_image, uin
|
||||
dst_image->layout = new_image_layout;
|
||||
}
|
||||
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image)
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t src_pitch, VulkanImage* dst_image, uint64_t dst_layout)
|
||||
{
|
||||
EXIT_IF(src_buffer == nullptr);
|
||||
EXIT_IF(src_buffer->buffer == nullptr);
|
||||
@@ -114,7 +112,37 @@ void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, uint32_t
|
||||
vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
set_image_layout(vk_buffer, dst_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
static_cast<VkImageLayout>(dst_layout));
|
||||
}
|
||||
|
||||
void UtilImageToBuffer(CommandBuffer* buffer, VulkanImage* src_image, VulkanBuffer* dst_buffer, uint32_t dst_pitch, uint64_t src_layout)
|
||||
{
|
||||
EXIT_IF(dst_buffer == nullptr);
|
||||
EXIT_IF(dst_buffer->buffer == nullptr);
|
||||
EXIT_IF(src_image == nullptr);
|
||||
EXIT_IF(src_image->image == nullptr);
|
||||
|
||||
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
|
||||
|
||||
set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, src_image->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
|
||||
VkBufferImageCopy region {};
|
||||
region.bufferOffset = 0;
|
||||
region.bufferRowLength = (dst_pitch != src_image->extent.width ? dst_pitch : 0);
|
||||
region.bufferImageHeight = 0;
|
||||
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
region.imageOffset = {0, 0, 0};
|
||||
region.imageExtent = {src_image->extent.width, src_image->extent.height, 1};
|
||||
|
||||
vkCmdCopyImageToBuffer(vk_buffer, src_image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_buffer->buffer, 1, ®ion);
|
||||
|
||||
set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
static_cast<VkImageLayout>(src_layout));
|
||||
}
|
||||
|
||||
void UtilBufferToImage(CommandBuffer* buffer, VulkanBuffer* src_buffer, VulkanImage* dst_image, const Vector<BufferImageCopy>& regions,
|
||||
@@ -207,7 +235,7 @@ void UtilBlitImage(CommandBuffer* buffer, VulkanImage* src_image, VulkanSwapchai
|
||||
|
||||
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
|
||||
|
||||
VulkanImage swapchain_image {};
|
||||
VulkanImage swapchain_image(VulkanImageType::Unknown);
|
||||
|
||||
swapchain_image.image = dst_swapchain->swapchain_images[dst_swapchain->current_index];
|
||||
swapchain_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
@@ -286,12 +314,14 @@ void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer)
|
||||
buffer->buffer = nullptr;
|
||||
}
|
||||
|
||||
void UtilFillImage(GraphicContext* ctx, VulkanImage* image, const void* src_data, uint64_t size, uint32_t src_pitch)
|
||||
void UtilFillImage(GraphicContext* ctx, VulkanImage* dst_image, const void* src_data, uint64_t size, uint32_t src_pitch,
|
||||
uint64_t dst_layout)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(image == nullptr);
|
||||
EXIT_IF(dst_image == nullptr);
|
||||
EXIT_IF(src_data == nullptr);
|
||||
|
||||
VulkanBuffer staging_buffer {};
|
||||
staging_buffer.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
@@ -309,7 +339,7 @@ void UtilFillImage(GraphicContext* ctx, VulkanImage* image, const void* src_data
|
||||
EXIT_NOT_IMPLEMENTED(buffer.IsInvalid());
|
||||
|
||||
buffer.Begin();
|
||||
UtilBufferToImage(&buffer, &staging_buffer, src_pitch, image);
|
||||
UtilBufferToImage(&buffer, &staging_buffer, src_pitch, dst_image, dst_layout);
|
||||
buffer.End();
|
||||
buffer.Execute();
|
||||
buffer.WaitForFence();
|
||||
@@ -317,6 +347,38 @@ void UtilFillImage(GraphicContext* ctx, VulkanImage* image, const void* src_data
|
||||
VulkanDeleteBuffer(ctx, &staging_buffer);
|
||||
}
|
||||
|
||||
void UtilFillBuffer(GraphicContext* ctx, void* dst_data, uint64_t size, uint32_t dst_pitch, VulkanImage* src_image, uint64_t src_layout)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(src_image == nullptr);
|
||||
EXIT_IF(dst_data == nullptr);
|
||||
|
||||
VulkanBuffer staging_buffer {};
|
||||
staging_buffer.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
staging_buffer.memory.property = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
VulkanCreateBuffer(ctx, size, &staging_buffer);
|
||||
|
||||
CommandBuffer buffer;
|
||||
buffer.SetQueue(GraphicContext::QUEUE_UTIL);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(buffer.IsInvalid());
|
||||
|
||||
buffer.Begin();
|
||||
UtilImageToBuffer(&buffer, src_image, &staging_buffer, dst_pitch, src_layout);
|
||||
buffer.End();
|
||||
buffer.Execute();
|
||||
buffer.WaitForFence();
|
||||
|
||||
void* data = nullptr;
|
||||
VulkanMapMemory(ctx, &staging_buffer.memory, &data);
|
||||
std::memcpy(dst_data, data, size);
|
||||
VulkanUnmapMemory(ctx, &staging_buffer.memory);
|
||||
|
||||
VulkanDeleteBuffer(ctx, &staging_buffer);
|
||||
}
|
||||
|
||||
void UtilSetDepthLayoutOptimal(DepthStencilVulkanImage* image)
|
||||
{
|
||||
CommandBuffer buffer;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <string>
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
#include <vulkan/vk_platform.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
// IWYU pragma: no_include <intrin.h>
|
||||
|
||||
@@ -1370,6 +1369,18 @@ static VkPhysicalDevice VulkanFindPhysicalDevice(VkInstance instance, VkSurfaceK
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (device_features2.features.samplerAnisotropy != VK_TRUE)
|
||||
{
|
||||
printf("samplerAnisotropy is not supported\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
// if (device_features2.features.shaderImageGatherExtended != VK_TRUE)
|
||||
// {
|
||||
// printf("shaderImageGatherExtended is not supported\n");
|
||||
// skip_device = true;
|
||||
// }
|
||||
|
||||
if (!skip_device)
|
||||
{
|
||||
uint32_t extensions_count = 0;
|
||||
@@ -1460,6 +1471,13 @@ static VkPhysicalDevice VulkanFindPhysicalDevice(VkInstance instance, VkSurfaceK
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device &&
|
||||
!CheckFormat(device, VK_FORMAT_R8G8_UNORM, true, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_R8G8_UNORM cannot be used as texture\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device &&
|
||||
!CheckFormat(device, VK_FORMAT_R8G8B8A8_SRGB, true, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
@@ -1568,6 +1586,8 @@ static VkDevice VulkanCreateDevice(VkPhysicalDevice physical_device, VkSurfaceKH
|
||||
|
||||
VkPhysicalDeviceFeatures device_features {};
|
||||
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
device_features.samplerAnisotropy = VK_TRUE;
|
||||
// device_features.shaderImageGatherExtended = VK_TRUE;
|
||||
|
||||
VkPhysicalDeviceColorWriteEnableFeaturesEXT color_write_ext {};
|
||||
color_write_ext.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT;
|
||||
|
||||
@@ -589,8 +589,6 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f
|
||||
|
||||
EXIT_IF(g_physical_memory == nullptr);
|
||||
|
||||
// EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread());
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(addr == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(flags != 0);
|
||||
|
||||
@@ -619,12 +617,14 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f
|
||||
auto out_addr = VirtualMemory::AllocAligned(in_addr, len, mode, alignment);
|
||||
*addr = reinterpret_cast<void*>(out_addr);
|
||||
|
||||
printf("\tin_addr = 0x%016" PRIx64 "\n", in_addr);
|
||||
printf("\tout_addr = 0x%016" PRIx64 "\n", out_addr);
|
||||
printf("\tsize = 0x%016" PRIx64 "\n", len);
|
||||
printf("\tmode = %s\n", Core::EnumName(mode).C_Str());
|
||||
printf("\talign = 0x%016" PRIx64 "\n", alignment);
|
||||
printf("\tgpu_mode = %s\n", Core::EnumName(gpu_mode).C_Str());
|
||||
printf("\t in_addr = 0x%016" PRIx64 "\n", in_addr);
|
||||
printf("\t out_addr = 0x%016" PRIx64 "\n", out_addr);
|
||||
printf("\t size = 0x%016" PRIx64 "\n", len);
|
||||
printf("\t mode = %s\n", Core::EnumName(mode).C_Str());
|
||||
printf("\t align = 0x%016" PRIx64 "\n", alignment);
|
||||
printf("\t gpu_mode = %s\n", Core::EnumName(gpu_mode).C_Str());
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(out_addr == 0);
|
||||
|
||||
if (out_addr == 0)
|
||||
{
|
||||
@@ -633,8 +633,11 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f
|
||||
|
||||
if (!g_physical_memory->Map(out_addr, direct_memory_start, len, prot, mode, gpu_mode))
|
||||
{
|
||||
printf(FG_RED "\t[Fail]\n" FG_DEFAULT);
|
||||
printf(FG_RED "\t [Fail]\n" FG_DEFAULT);
|
||||
VirtualMemory::Free(out_addr);
|
||||
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
|
||||
return KERNEL_ERROR_EBUSY;
|
||||
}
|
||||
|
||||
@@ -643,7 +646,7 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f
|
||||
Graphics::GpuMemorySetAllocatedRange(out_addr, len);
|
||||
}
|
||||
|
||||
printf(FG_GREEN "\t[Ok]\n" FG_DEFAULT);
|
||||
printf(FG_GREEN "\t [Ok]\n" FG_DEFAULT);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -650,6 +650,8 @@ int KYTY_SYSV_ABI PthreadMutexattrDestroy(PthreadMutexattr* attr)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||
|
||||
int result = pthread_mutexattr_destroy(&(*attr)->p);
|
||||
|
||||
delete *attr;
|
||||
@@ -757,13 +759,11 @@ int KYTY_SYSV_ABI PthreadMutexDestroy(PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (mutex == nullptr)
|
||||
if (mutex == nullptr || *mutex == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(*mutex == nullptr);
|
||||
|
||||
int result = pthread_mutex_destroy(&(*mutex)->p);
|
||||
|
||||
printf("\tmutex destroy: %s, %d\n", (*mutex)->name.C_Str(), result);
|
||||
@@ -907,6 +907,8 @@ int KYTY_SYSV_ABI PthreadAttrDestroy(PthreadAttr* attr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(attr == nullptr || *attr == nullptr);
|
||||
|
||||
int result = pthread_attr_destroy(&(*attr)->p);
|
||||
|
||||
delete *attr;
|
||||
@@ -1584,6 +1586,8 @@ int KYTY_SYSV_ABI PthreadRwlockattrDestroy(PthreadRwlockattr* attr)
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(*attr == nullptr);
|
||||
|
||||
int result = pthread_rwlockattr_destroy(&(*attr)->p);
|
||||
|
||||
delete *attr;
|
||||
@@ -1651,6 +1655,8 @@ int KYTY_SYSV_ABI PthreadCondattrDestroy(PthreadCondattr* attr)
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(*attr == nullptr);
|
||||
|
||||
int result = pthread_condattr_destroy(&(*attr)->p);
|
||||
|
||||
delete *attr;
|
||||
@@ -2629,6 +2635,13 @@ int KYTY_SYSV_ABI pthread_setspecific(LibKernel::PthreadKey key, void* value)
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadSetspecific(key, value));
|
||||
}
|
||||
|
||||
void* KYTY_SYSV_ABI pthread_getspecific(LibKernel::PthreadKey key)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return (LibKernel::PthreadGetspecific(key));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_destroy(LibKernel::PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Libs/Errno.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/SymbolDatabase.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs {
|
||||
|
||||
LIB_VERSION("AppContent", 1, "AppContentUtil", 1, 1);
|
||||
|
||||
namespace AppContent {
|
||||
|
||||
struct AppContentInitParam
|
||||
{
|
||||
char reserved[32];
|
||||
};
|
||||
|
||||
struct AppContentBootParam
|
||||
{
|
||||
char reserved1[4];
|
||||
uint32_t attr;
|
||||
char reserved2[32];
|
||||
};
|
||||
|
||||
struct NpUnifiedEntitlementLabel
|
||||
{
|
||||
char data[17];
|
||||
char padding[3];
|
||||
};
|
||||
|
||||
struct AppContentAddcontInfo
|
||||
{
|
||||
NpUnifiedEntitlementLabel entitlement_label;
|
||||
uint32_t status;
|
||||
};
|
||||
|
||||
int KYTY_SYSV_ABI AppContentInitialize(const AppContentInitParam* init_param, AppContentBootParam* boot_param)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(init_param == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(boot_param == nullptr);
|
||||
|
||||
boot_param->attr = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI AppContentGetAddcontInfoList(uint32_t service_label, AppContentAddcontInfo* /*list*/, uint32_t list_num,
|
||||
uint32_t* hit_num)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(hit_num == nullptr);
|
||||
|
||||
printf("\t service_label = %u\n", service_label);
|
||||
printf("\t list_num = %u\n", list_num);
|
||||
|
||||
*hit_num = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace AppContent
|
||||
|
||||
LIB_DEFINE(InitAppContent_1)
|
||||
{
|
||||
LIB_FUNC("R9lA82OraNs", AppContent::AppContentInitialize);
|
||||
LIB_FUNC("xnd8BJzAxmk", AppContent::AppContentGetAddcontInfoList);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
@@ -19,6 +19,8 @@ LIB_DEFINE(InitAudio_1_AudioOut)
|
||||
LIB_FUNC("ekNvsT22rsY", AudioOut::AudioOutOpen);
|
||||
LIB_FUNC("b+uAV89IlxE", AudioOut::AudioOutSetVolume);
|
||||
LIB_FUNC("w3PdaSTSwGE", AudioOut::AudioOutOutputs);
|
||||
LIB_FUNC("QOQtbeDqsT4", AudioOut::AudioOutOutput);
|
||||
LIB_FUNC("s1--uE9mBFw", AudioOut::AudioOutClose);
|
||||
}
|
||||
|
||||
} // namespace LibAudioOut
|
||||
@@ -59,16 +61,37 @@ namespace Ajm = Audio::Ajm;
|
||||
LIB_DEFINE(InitAudio_1_Ajm)
|
||||
{
|
||||
LIB_FUNC("dl+4eHSzUu4", Ajm::AjmInitialize);
|
||||
LIB_FUNC("Q3dyFuwGn64", Ajm::AjmModuleRegister);
|
||||
}
|
||||
|
||||
} // namespace LibAjm
|
||||
|
||||
namespace LibAvPlayer {
|
||||
|
||||
LIB_VERSION("AvPlayer", 1, "AvPlayer", 1, 0);
|
||||
|
||||
namespace AvPlayer = Audio::AvPlayer;
|
||||
|
||||
LIB_DEFINE(InitAudio_1_AvPlayer)
|
||||
{
|
||||
LIB_FUNC("aS66RI0gGgo", AvPlayer::AvPlayerInit);
|
||||
LIB_FUNC("KMcEa+rHsIo", AvPlayer::AvPlayerAddSource);
|
||||
LIB_FUNC("OVths0xGfho", AvPlayer::AvPlayerSetLooping);
|
||||
LIB_FUNC("JdksQu8pNdQ", AvPlayer::AvPlayerGetVideoDataEx);
|
||||
LIB_FUNC("Wnp1OVcrZgk", AvPlayer::AvPlayerGetAudioData);
|
||||
LIB_FUNC("UbQoYawOsfY", AvPlayer::AvPlayerIsActive);
|
||||
LIB_FUNC("NkJwDzKmIlw", AvPlayer::AvPlayerClose);
|
||||
}
|
||||
|
||||
} // namespace LibAvPlayer
|
||||
|
||||
LIB_DEFINE(InitAudio_1)
|
||||
{
|
||||
LibAudioOut::InitAudio_1_AudioOut(s);
|
||||
LibAudioIn::InitAudio_1_AudioIn(s);
|
||||
LibVoiceQoS::InitAudio_1_VoiceQoS(s);
|
||||
LibAjm::InitAudio_1_Ajm(s);
|
||||
LibAvPlayer::InitAudio_1_AvPlayer(s);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
@@ -224,7 +224,7 @@ static void* KYTY_SYSV_ABI KernelGetProcParam()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
auto* rt = Core::Singleton<Loader::RuntimeLinker>::Instance();
|
||||
auto* rt = Core::Singleton<Loader::RuntimeLinker>::Instance(); // NOLINT
|
||||
|
||||
return reinterpret_cast<void*>(rt->GetProcParam());
|
||||
}
|
||||
@@ -461,6 +461,7 @@ LIB_DEFINE(InitLibKernel_1_Posix)
|
||||
LIB_FUNC("mqULNdimTn0", Posix::pthread_key_create);
|
||||
LIB_FUNC("6BpEZuDT7YI", Posix::pthread_key_delete);
|
||||
LIB_FUNC("WrOLvHU0yQM", Posix::pthread_setspecific);
|
||||
LIB_FUNC("0-KXaS70xy4", Posix::pthread_getspecific);
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
@@ -183,6 +183,7 @@ LIB_DEFINE(InitNet_1_NpTrophy)
|
||||
LIB_FUNC("XbkjbobZlCY", NpTrophy::NpTrophyCreateContext);
|
||||
LIB_FUNC("TJCAxto9SEU", NpTrophy::NpTrophyRegisterContext);
|
||||
LIB_FUNC("GNcF4oidY0Y", NpTrophy::NpTrophyDestroyHandle);
|
||||
LIB_FUNC("LHuSmO3SLd8", NpTrophy::NpTrophyGetTrophyUnlockState);
|
||||
}
|
||||
|
||||
} // namespace LibNpTrophy
|
||||
|
||||
@@ -20,6 +20,8 @@ LIB_DEFINE(InitPad_1)
|
||||
LIB_FUNC("YndgXqQVV7c", Controller::PadReadState);
|
||||
LIB_FUNC("q1cHNfGycLI", Controller::PadRead);
|
||||
LIB_FUNC("yFVnOdGxvZY", Controller::PadSetVibration);
|
||||
LIB_FUNC("DscD1i9HX1w", Controller::PadResetLightBar);
|
||||
LIB_FUNC("RR4novUEENY", Controller::PadSetLightBar);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
@@ -31,6 +31,18 @@ struct SaveDataMountPoint
|
||||
char data[16];
|
||||
};
|
||||
|
||||
struct SaveDataMount
|
||||
{
|
||||
int user_id;
|
||||
int pad;
|
||||
const char* title_id;
|
||||
const char* dir_name;
|
||||
const char* fingerprint;
|
||||
uint64_t blocks;
|
||||
uint32_t mount_mode;
|
||||
uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataMount2
|
||||
{
|
||||
int user_id;
|
||||
@@ -63,6 +75,21 @@ struct SaveDataParam
|
||||
uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataMountInfo
|
||||
{
|
||||
uint64_t blocks;
|
||||
uint64_t free_blocks;
|
||||
uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataIcon
|
||||
{
|
||||
void* buf;
|
||||
size_t buf_size;
|
||||
size_t data_size;
|
||||
uint8_t reserved[32];
|
||||
};
|
||||
|
||||
int KYTY_SYSV_ABI SaveDataInitialize(const void* /*init*/)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -90,6 +117,69 @@ int KYTY_SYSV_ABI SaveDataInitialize3(const void* /*init*/)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SaveDataMount(const SaveDataMount* mount, SaveDataMountResult* mount_result)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(mount == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(mount_result == nullptr);
|
||||
|
||||
printf("\t user_id = %d\n", mount->user_id);
|
||||
printf("\t title_id = %s\n", mount->title_id);
|
||||
printf("\t dir_name = %s\n", mount->dir_name);
|
||||
printf("\t fingerprint = %s\n", mount->fingerprint);
|
||||
printf("\t blocks = %" PRIu64 "\n", mount->blocks);
|
||||
printf("\t mount_mode = %" PRIu32 "\n", mount->mount_mode);
|
||||
|
||||
String mount_dir = String(SAVE_DATA_DIR) + U"/" + String::FromUtf8(mount->dir_name);
|
||||
String mount_point = SAVE_DATA_POINT;
|
||||
bool create = (mount->mount_mode == 6 || mount->mount_mode == 22);
|
||||
bool open = (mount->mount_mode == 1 || mount->mount_mode == 2);
|
||||
|
||||
if (!create && !open)
|
||||
{
|
||||
EXIT("unknown mount mode: %u", mount->mount_mode);
|
||||
}
|
||||
|
||||
if (open)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(create);
|
||||
|
||||
if (!Core::File::IsDirectoryExisting(mount_dir))
|
||||
{
|
||||
return SAVE_DATA_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
LibKernel::FileSystem::Mount(mount_dir, mount_point);
|
||||
|
||||
mount_result->mount_status = 0;
|
||||
}
|
||||
|
||||
if (create)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(open);
|
||||
|
||||
if (Core::File::IsDirectoryExisting(mount_dir))
|
||||
{
|
||||
return SAVE_DATA_ERROR_EXISTS;
|
||||
}
|
||||
|
||||
Core::File::CreateDirectories(mount_dir);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((!Core::File::IsDirectoryExisting(mount_dir)));
|
||||
|
||||
LibKernel::FileSystem::Mount(mount_dir, mount_point);
|
||||
|
||||
mount_result->mount_status = 1;
|
||||
}
|
||||
|
||||
snprintf(mount_result->mount_point.data, 16, "%s", mount_point.C_Str());
|
||||
|
||||
mount_result->required_blocks = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SaveDataMount2(const SaveDataMount2* mount, SaveDataMountResult* mount_result)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -104,7 +194,7 @@ int KYTY_SYSV_ABI SaveDataMount2(const SaveDataMount2* mount, SaveDataMountResul
|
||||
|
||||
String mount_dir = String(SAVE_DATA_DIR) + U"/" + String::FromUtf8(mount->dir_name->data);
|
||||
String mount_point = SAVE_DATA_POINT;
|
||||
bool create = (mount->mount_mode == 22);
|
||||
bool create = (mount->mount_mode == 6 || mount->mount_mode == 22);
|
||||
bool open = (mount->mount_mode == 1 || mount->mount_mode == 2);
|
||||
|
||||
if (!create && !open)
|
||||
@@ -190,6 +280,31 @@ int KYTY_SYSV_ABI SaveDataSetParam(const SaveDataMountPoint* mount_point, uint32
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SaveDataGetMountInfo(const SaveDataMountPoint* mount_point, SaveDataMountInfo* info)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(mount_point == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(info == nullptr);
|
||||
|
||||
info->blocks = 100000;
|
||||
info->free_blocks = 100000;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SaveDataSaveIcon(const SaveDataMountPoint* mount_point, const SaveDataIcon* icon)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(mount_point == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(icon == nullptr);
|
||||
|
||||
printf("\t buf = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(icon->buf));
|
||||
printf("\t buf_size = %" PRIu64 "\n", icon->buf_size);
|
||||
printf("\t data_size = %" PRIu64 "\n", icon->data_size);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace SaveData
|
||||
|
||||
LIB_DEFINE(InitSaveData_1)
|
||||
@@ -197,9 +312,12 @@ LIB_DEFINE(InitSaveData_1)
|
||||
LIB_FUNC("ZkZhskCPXFw", SaveData::SaveDataInitialize);
|
||||
LIB_FUNC("l1NmDeDpNGU", SaveData::SaveDataInitialize2);
|
||||
LIB_FUNC("TywrFKCoLGY", SaveData::SaveDataInitialize3);
|
||||
LIB_FUNC("32HQAQdwM2o", SaveData::SaveDataMount);
|
||||
LIB_FUNC("0z45PIH+SNI", SaveData::SaveDataMount2);
|
||||
LIB_FUNC("BMR4F-Uek3E", SaveData::SaveDataUmount);
|
||||
LIB_FUNC("85zul--eGXs", SaveData::SaveDataSetParam);
|
||||
LIB_FUNC("65VH0Qaaz6s", SaveData::SaveDataGetMountInfo);
|
||||
LIB_FUNC("c88Yy54Mx0w", SaveData::SaveDataSaveIcon);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
@@ -116,7 +116,7 @@ static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value)
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PARAM_ID_LANG: v = PARAM_LANG_RUSSIAN; break;
|
||||
case PARAM_ID_LANG: v = PARAM_LANG_ENGLISH_US; break;
|
||||
case PARAM_ID_DATE_FORMAT: v = PARAM_DATE_FORMAT_DDMMYYYY; break;
|
||||
case PARAM_ID_TIME_FORMAT: v = PARAM_TIME_FORMAT_24HOUR; break;
|
||||
case PARAM_ID_TIME_ZONE: v = +180; break;
|
||||
|
||||
@@ -21,6 +21,18 @@ struct UserServiceLoginUserIdList
|
||||
int user_id[4];
|
||||
};
|
||||
|
||||
enum UserServiceEventType
|
||||
{
|
||||
UserServiceEventTypeLogin,
|
||||
UserServiceEventTypeLogout
|
||||
};
|
||||
|
||||
struct SceUserServiceEvent
|
||||
{
|
||||
UserServiceEventType event_type;
|
||||
int user_id;
|
||||
};
|
||||
|
||||
static KYTY_SYSV_ABI int UserServiceInitialize(const void* /*params*/)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -39,12 +51,22 @@ static KYTY_SYSV_ABI int UserServiceGetInitialUser(int* user_id)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static KYTY_SYSV_ABI int UserServiceGetEvent(void* event)
|
||||
static KYTY_SYSV_ABI int UserServiceGetEvent(SceUserServiceEvent* event)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(event == nullptr);
|
||||
|
||||
static bool logged_in = false;
|
||||
|
||||
if (!logged_in)
|
||||
{
|
||||
logged_in = true;
|
||||
event->event_type = UserServiceEventTypeLogin;
|
||||
event->user_id = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
return USER_SERVICE_ERROR_NO_EVENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace LibcInternal {
|
||||
LIB_DEFINE(InitLibcInternal_1);
|
||||
} // namespace LibcInternal
|
||||
|
||||
LIB_DEFINE(InitAppContent_1);
|
||||
LIB_DEFINE(InitAudio_1);
|
||||
LIB_DEFINE(InitDebug_1);
|
||||
LIB_DEFINE(InitDialog_1);
|
||||
LIB_DEFINE(InitDiscMap_1);
|
||||
LIB_DEFINE(InitGraphicsDriver_1);
|
||||
// LIB_DEFINE(InitLibC_1);
|
||||
LIB_DEFINE(InitLibKernel_1);
|
||||
LIB_DEFINE(InitNet_1);
|
||||
LIB_DEFINE(InitPad_1);
|
||||
@@ -27,7 +27,7 @@ LIB_DEFINE(InitVideoOut_1);
|
||||
bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
{
|
||||
LIB_CHECK(U"libAudio_1", InitAudio_1);
|
||||
// LIB_CHECK(U"libc_1", InitLibC_1);
|
||||
LIB_CHECK(U"libAppContent_1", InitAppContent_1);
|
||||
LIB_CHECK(U"libc_internal_1", LibcInternal::InitLibcInternal_1);
|
||||
LIB_CHECK(U"libDebug_1", InitDebug_1);
|
||||
LIB_CHECK(U"libDialog_1", InitDialog_1);
|
||||
|
||||
+79
-20
@@ -5,6 +5,7 @@
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Subsystems.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Config.h"
|
||||
@@ -22,11 +23,13 @@ namespace Kyty {
|
||||
|
||||
namespace Log {
|
||||
|
||||
static bool g_log_initialized = false;
|
||||
static Core::Mutex* g_mutex = nullptr;
|
||||
static Direction g_dir = Direction::Console;
|
||||
static Core::File* g_file = nullptr;
|
||||
static bool g_colored_printf = false;
|
||||
static bool g_log_initialized = false;
|
||||
static Core::Mutex* g_mutex = nullptr;
|
||||
static Direction g_dir = Direction::Console;
|
||||
static Core::File* g_file = nullptr;
|
||||
static bool g_colored_printf = false;
|
||||
static thread_local Core::File* g_thread_local_file = nullptr;
|
||||
static Vector<Core::File*>* g_thread_local_files = nullptr;
|
||||
|
||||
static bool EnableVTMode()
|
||||
{
|
||||
@@ -92,6 +95,16 @@ static void Close()
|
||||
delete g_file;
|
||||
g_file = nullptr;
|
||||
}
|
||||
if (g_dir == Direction::Directory && !g_thread_local_files->IsEmpty())
|
||||
{
|
||||
for (auto* file: *g_thread_local_files)
|
||||
{
|
||||
file->Flush();
|
||||
file->Close();
|
||||
delete file;
|
||||
}
|
||||
g_thread_local_files->Clear();
|
||||
}
|
||||
g_mutex->Unlock();
|
||||
}
|
||||
}
|
||||
@@ -110,6 +123,8 @@ KYTY_SUBSYSTEM_INIT(Log)
|
||||
{
|
||||
SetOutputFile(Config::GetPrintfOutputFile());
|
||||
}
|
||||
|
||||
g_thread_local_files = new Vector<Core::File*>;
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Log)
|
||||
@@ -172,6 +187,40 @@ void SetOutputFile(const String& file_name, Core::File::Encoding enc)
|
||||
}
|
||||
}
|
||||
|
||||
void SetOutputThreadLocalFile(const String& file_name, Core::File::Encoding enc)
|
||||
{
|
||||
EXIT_IF(!Log::g_log_initialized);
|
||||
EXIT_IF(Log::g_dir != Log::Direction::Directory);
|
||||
EXIT_IF(Log::g_thread_local_file != nullptr);
|
||||
EXIT_IF(g_thread_local_files == nullptr);
|
||||
|
||||
Core::File::CreateDirectories(file_name.DirectoryWithoutFilename());
|
||||
|
||||
g_thread_local_file = new Core::File;
|
||||
g_thread_local_file->Create(file_name);
|
||||
|
||||
if (g_thread_local_file->IsInvalid())
|
||||
{
|
||||
::printf("Can't create log file: %s\n", file_name.C_Str());
|
||||
delete g_thread_local_file;
|
||||
g_thread_local_file = nullptr;
|
||||
} else
|
||||
{
|
||||
g_thread_local_file->SetEncoding(enc);
|
||||
g_thread_local_file->WriteBOM();
|
||||
}
|
||||
|
||||
g_mutex->Lock();
|
||||
g_thread_local_files->Add(g_thread_local_file);
|
||||
g_mutex->Unlock();
|
||||
}
|
||||
|
||||
void CreateThreadLocalFile()
|
||||
{
|
||||
auto file_name = String::FromPrintf("%s/%d.txt", Config::GetPrintfOutputFolder().C_Str(), Core::Thread::GetThreadIdUnique());
|
||||
SetOutputThreadLocalFile(file_name, Core::File::Encoding::Utf8);
|
||||
}
|
||||
|
||||
} // namespace Log
|
||||
|
||||
void emu_printf(const char* format, ...)
|
||||
@@ -214,28 +263,38 @@ void printf(const char* format, ...)
|
||||
|
||||
EXIT_IF(Log::g_mutex == nullptr);
|
||||
|
||||
Log::g_mutex->Lock();
|
||||
va_list args {};
|
||||
va_start(args, format);
|
||||
String s;
|
||||
s.Printf(format, args);
|
||||
va_end(args);
|
||||
|
||||
if (!Log::g_colored_printf)
|
||||
{
|
||||
va_list args {};
|
||||
va_start(args, format);
|
||||
String s;
|
||||
s.Printf(format, args);
|
||||
va_end(args);
|
||||
s = Log::RemoveColors(s);
|
||||
}
|
||||
|
||||
if (!Log::g_colored_printf)
|
||||
if (Log::g_dir == Log::Direction::Console)
|
||||
{
|
||||
Log::g_mutex->Lock();
|
||||
::printf("%s", s.C_Str());
|
||||
Log::g_mutex->Unlock();
|
||||
} else if (Log::g_dir == Log::Direction::File && Log::g_file != nullptr)
|
||||
{
|
||||
Log::g_mutex->Lock();
|
||||
Log::g_file->Write(s);
|
||||
Log::g_mutex->Unlock();
|
||||
} else if (Log::g_dir == Log::Direction::Directory)
|
||||
{
|
||||
if (Log::g_thread_local_file == nullptr)
|
||||
{
|
||||
s = Log::RemoveColors(s);
|
||||
Log::CreateThreadLocalFile();
|
||||
}
|
||||
|
||||
if (Log::g_dir == Log::Direction::Console)
|
||||
if (Log::g_thread_local_file != nullptr)
|
||||
{
|
||||
::printf("%s", s.C_Str());
|
||||
} else if (Log::g_dir == Log::Direction::File && Log::g_file != nullptr)
|
||||
{
|
||||
Log::g_file->Write(s);
|
||||
Log::g_thread_local_file->Write(s);
|
||||
}
|
||||
}
|
||||
Log::g_mutex->Unlock();
|
||||
}
|
||||
|
||||
} // namespace Kyty
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
uint32_t m_type = static_cast<uint32_t>(Type::Invalid);
|
||||
};
|
||||
|
||||
using HttpsCallback = int (*)(int, unsigned int, void* const*, int, void*);
|
||||
using HttpsCallback = KYTY_SYSV_ABI int (*)(int, unsigned int, void* const*, int, void*);
|
||||
|
||||
Network() = default;
|
||||
virtual ~Network() = default;
|
||||
@@ -1341,6 +1341,11 @@ namespace NpTrophy {
|
||||
|
||||
LIB_NAME("NpTrophy", "NpTrophy");
|
||||
|
||||
struct NpTrophyFlagArray
|
||||
{
|
||||
uint32_t flag_bits[4];
|
||||
};
|
||||
|
||||
int KYTY_SYSV_ABI NpTrophyCreateHandle(int* handle)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -1392,6 +1397,28 @@ int KYTY_SYSV_ABI NpTrophyDestroyHandle(int handle)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI NpTrophyGetTrophyUnlockState(int context, int handle, NpTrophyFlagArray* flags, uint32_t* count)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(flags == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(count == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(context != 1);
|
||||
EXIT_NOT_IMPLEMENTED(handle != 1);
|
||||
|
||||
printf("\t context = %d\n", context);
|
||||
printf("\t handle = %d\n", handle);
|
||||
|
||||
flags->flag_bits[0] = 0;
|
||||
flags->flag_bits[1] = 0;
|
||||
flags->flag_bits[2] = 0;
|
||||
flags->flag_bits[3] = 0;
|
||||
|
||||
*count = 0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace NpTrophy
|
||||
|
||||
namespace NpWebApi {
|
||||
|
||||
@@ -74,6 +74,8 @@ constexpr uint64_t DESIRED_BASE_ADDR = 0x010000000;
|
||||
constexpr size_t XSAVE_BUFFER_SIZE = 2688;
|
||||
constexpr uint64_t XSAVE_CHK_GUARD = 0xDeadBeef5533CCAA;
|
||||
|
||||
static uint64_t g_desired_base_addr = DESIRED_BASE_ADDR;
|
||||
|
||||
static Program* g_tls_main_program = nullptr;
|
||||
alignas(64) static uint8_t g_tls_reg_save_area[XSAVE_BUFFER_SIZE + sizeof(XSAVE_CHK_GUARD)];
|
||||
static uint8_t g_tls_spinlock = 0;
|
||||
@@ -153,6 +155,45 @@ static VirtualMemory::Mode get_mode(Elf64_Word flags)
|
||||
}
|
||||
}
|
||||
|
||||
struct FrameS
|
||||
{
|
||||
FrameS* next;
|
||||
uintptr_t ret_addr;
|
||||
};
|
||||
|
||||
static void KYTY_SYSV_ABI stackwalk_x86(uint64_t rbp, void** stack, int* depth, uintptr_t stack_addr, size_t stack_size,
|
||||
uintptr_t code_addr, size_t code_size)
|
||||
{
|
||||
auto* frame = reinterpret_cast<FrameS*>(rbp);
|
||||
|
||||
int d = *depth;
|
||||
int i = 0;
|
||||
|
||||
for (; i < d; i++)
|
||||
{
|
||||
if (!(uintptr_t(frame) >= stack_addr && uintptr_t(frame) < stack_addr + stack_size))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(frame->ret_addr >= code_addr && frame->ret_addr < code_addr + code_size))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
stack[i] = reinterpret_cast<void*>(frame->ret_addr);
|
||||
|
||||
frame = frame->next;
|
||||
}
|
||||
|
||||
*depth = i;
|
||||
}
|
||||
|
||||
void KYTY_SYSV_ABI sys_stack_walk_x86(uint64_t rbp, void** stack, int* depth)
|
||||
{
|
||||
stackwalk_x86(rbp, stack, depth, 0, UINT64_MAX, DESIRED_BASE_ADDR, g_desired_base_addr - DESIRED_BASE_ADDR);
|
||||
}
|
||||
|
||||
static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::ExceptionInfo* info)
|
||||
{
|
||||
printf("kyty_exception_handler: %016" PRIx64 "\n", info->exception_address);
|
||||
@@ -165,6 +206,8 @@ static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::Except
|
||||
return;
|
||||
}
|
||||
|
||||
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(info->rbp);
|
||||
|
||||
EXIT("Access violation: %s [%016" PRIx64 "] %s\n", Core::EnumName(info->access_violation_type).C_Str(),
|
||||
info->access_violation_vaddr, (info->access_violation_vaddr == INVALID_MEMORY ? "(Unpatched object)" : ""));
|
||||
}
|
||||
@@ -453,8 +496,11 @@ static KYTY_SYSV_ABI void RelocateHandler(RelocateHandlerStack s)
|
||||
name = String::FromPrintf(FG_BRIGHT_RED "%s" DEFAULT, ri.name.C_Str());
|
||||
}
|
||||
|
||||
// Restore return address (for debug)
|
||||
// Restore return address (for stack trace)
|
||||
stack[-1] = stack[1];
|
||||
|
||||
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(reinterpret_cast<uint64_t>(s.stack - 2));
|
||||
|
||||
EXIT("=== Unpatched function!!! ===\n[%d]\t%s\n", Core::Thread::GetThreadIdUnique(),
|
||||
(Log::IsColoredPrintf() ? name : Log::RemoveColors(name)).C_Str());
|
||||
}
|
||||
@@ -920,6 +966,23 @@ Program* RuntimeLinker::FindProgramByAddr(uint64_t vaddr)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RuntimeLinker::StackTrace(uint64_t frame_ptr)
|
||||
{
|
||||
void* stack[20];
|
||||
int depth = 20;
|
||||
|
||||
sys_stack_walk_x86(frame_ptr, stack, &depth);
|
||||
|
||||
std::printf("Stack trace [thread = %d]:\n", Core::Thread::GetThreadIdUnique());
|
||||
|
||||
for (int i = 0; i < depth; i++)
|
||||
{
|
||||
auto vaddr = reinterpret_cast<uint64_t>(stack[i]);
|
||||
auto* p = FindProgramByAddr(vaddr);
|
||||
std::printf("[%d] %016" PRIx64 ", %s\n", i, vaddr, (p == nullptr ? "???" : p->file_name.FilenameWithoutDirectory().C_Str()));
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeLinker::StartAllModules()
|
||||
{
|
||||
// EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread());
|
||||
@@ -1043,7 +1106,7 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
||||
EXIT_IF(program == nullptr || program->base_vaddr != 0 || program->base_size != 0 || program->elf == nullptr ||
|
||||
program->exception_handler != nullptr);
|
||||
|
||||
static uint64_t desired_base_addr = DESIRED_BASE_ADDR;
|
||||
// static uint64_t desired_base_addr = DESIRED_BASE_ADDR;
|
||||
|
||||
bool is_shared = program->elf->IsShared();
|
||||
bool is_next_gen = program->elf->IsNextGen();
|
||||
@@ -1060,14 +1123,14 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
||||
uint64_t tls_handler_size = is_shared ? 0 : Jit::SafeCall::GetSize();
|
||||
uint64_t alloc_size = program->base_size_aligned + exception_handler_size + tls_handler_size;
|
||||
|
||||
program->base_vaddr = VirtualMemory::Alloc(desired_base_addr, alloc_size, VirtualMemory::Mode::ExecuteReadWrite);
|
||||
program->base_vaddr = VirtualMemory::Alloc(g_desired_base_addr, alloc_size, VirtualMemory::Mode::ExecuteReadWrite);
|
||||
|
||||
if (!is_shared)
|
||||
{
|
||||
program->tls.handler_vaddr = program->base_vaddr + program->base_size_aligned + exception_handler_size;
|
||||
}
|
||||
|
||||
desired_base_addr += DESIRED_BASE_ADDR * (1 + alloc_size / DESIRED_BASE_ADDR);
|
||||
g_desired_base_addr += DESIRED_BASE_ADDR * (1 + alloc_size / DESIRED_BASE_ADDR);
|
||||
|
||||
EXIT_IF(program->base_vaddr == 0);
|
||||
EXIT_IF(program->base_size_aligned < program->base_size);
|
||||
|
||||
@@ -113,6 +113,8 @@ public:
|
||||
info.access_violation_vaddr = exception_record->ExceptionInformation[1];
|
||||
}
|
||||
|
||||
info.rbp = dispatcher_context->ContextRecord->Rbp;
|
||||
|
||||
auto* p = *static_cast<ExceptionHandlerPrivate**>(dispatcher_context->HandlerData);
|
||||
p->func(&info);
|
||||
|
||||
@@ -318,8 +320,13 @@ static VirtualAlloc2_func_t ResolveVirtualAlloc2()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t AllocAligned(uint64_t /*address*/, uint64_t size, Mode mode, uint64_t alignment)
|
||||
uint64_t AllocAligned(uint64_t address, uint64_t size, Mode mode, uint64_t alignment)
|
||||
{
|
||||
if (alignment == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MEM_ADDRESS_REQUIREMENTS req2 {};
|
||||
MEM_EXTENDED_PARAMETER param {};
|
||||
req2.LowestStartingAddress = nullptr;
|
||||
@@ -337,7 +344,9 @@ uint64_t AllocAligned(uint64_t /*address*/, uint64_t size, Mode mode, uint64_t a
|
||||
get_protection_flag(mode), ¶m, 1));
|
||||
if (ptr == 0)
|
||||
{
|
||||
printf("VirtualAlloc2() failed: 0x%08" PRIx32 "\n", static_cast<uint32_t>(GetLastError()));
|
||||
printf("VirtualAlloc2(alignment = 0x%016" PRIx64 ") failed: 0x%08" PRIx32 "\n", alignment, static_cast<uint32_t>(GetLastError()));
|
||||
|
||||
return AllocAligned(address, size, mode, alignment << 1u);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user