mirror of https://github.com/InoriRus/Kyty.git
add stencil support
This commit is contained in:
parent
02a77aa81a
commit
838a09c810
|
@ -1,4 +1,4 @@
|
|||
version: 0.0.10.build-{build}
|
||||
version: 0.0.11.build-{build}
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
matrix:
|
||||
|
|
|
@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD)
|
|||
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
|
||||
endif()
|
||||
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.10)
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.11)
|
||||
|
||||
include(src_script.cmake)
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
|
||||
struct VulkanSwapchain
|
||||
{
|
||||
VkSwapchainKHR swapchain = nullptr;
|
||||
|
@ -102,6 +104,11 @@ struct VulkanBuffer
|
|||
VkBufferUsageFlags usage = 0;
|
||||
};
|
||||
|
||||
struct StorageVulkanBuffer: public VulkanBuffer
|
||||
{
|
||||
CommandBuffer* cmd_buffer = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
|
|
@ -36,16 +36,16 @@ public:
|
|||
|
||||
[[nodiscard]] bool IsInvalid() const;
|
||||
|
||||
void Allocate();
|
||||
void Free();
|
||||
void Begin() const;
|
||||
void End() const;
|
||||
void Execute();
|
||||
void ExecuteWithSemaphore();
|
||||
VulkanFramebuffer* BeginRenderPass(RenderColorInfo* color, RenderDepthInfo* depth) const;
|
||||
void EndRenderPass() const;
|
||||
void WaitForFence();
|
||||
void WaitForFenceAndReset();
|
||||
void Allocate();
|
||||
void Free();
|
||||
void Begin() const;
|
||||
void End() const;
|
||||
void Execute();
|
||||
void ExecuteWithSemaphore();
|
||||
void BeginRenderPass(VulkanFramebuffer* framebuffer, RenderColorInfo* color, RenderDepthInfo* depth) const;
|
||||
void EndRenderPass() const;
|
||||
void WaitForFence();
|
||||
void WaitForFenceAndReset();
|
||||
|
||||
[[nodiscard]] uint32_t GetIndex() const { return m_index; }
|
||||
VulkanCommandPool* GetPool() { return m_pool; }
|
||||
|
@ -85,6 +85,7 @@ void GraphicsRenderDispatchDirect(CommandBuffer* buffer, HardwareContext* ctx, u
|
|||
uint32_t thread_group_z, uint32_t mode);
|
||||
void GraphicsRenderMemoryBarrier(CommandBuffer* buffer);
|
||||
void GraphicsRenderRenderTextureBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size);
|
||||
void GraphicsRenderMemoryFree(uint64_t vaddr, uint64_t size);
|
||||
|
||||
void DeleteFramebuffer(VideoOutVulkanImage* image);
|
||||
void DeleteFramebuffer(DepthStencilVulkanImage* image);
|
||||
|
|
|
@ -9,24 +9,31 @@
|
|||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct ColorInfo
|
||||
{
|
||||
bool fmask_compression_enable = false;
|
||||
uint32_t fmask_compression_mode = 0;
|
||||
bool cmask_fast_clear_enable = false;
|
||||
bool dcc_compression_enable = false;
|
||||
bool neo_mode = false;
|
||||
uint32_t cmask_tile_mode = 0;
|
||||
uint32_t cmask_tile_mode_neo = 0;
|
||||
uint32_t format = 0;
|
||||
uint32_t channel_type = 0;
|
||||
uint32_t channel_order = 0;
|
||||
};
|
||||
|
||||
struct RenderTarget
|
||||
{
|
||||
uint64_t base_addr = 0;
|
||||
uint32_t pitch_div8_minus1 = 0;
|
||||
uint32_t fmask_pitch_div8_minus1 = 0;
|
||||
uint32_t slice_div64_minus1 = 0;
|
||||
uint32_t base_array_slice_index = 0;
|
||||
uint32_t last_array_slice_index = 0;
|
||||
bool fmask_compression_enable = false;
|
||||
uint32_t fmask_compression_mode = 0;
|
||||
bool cmask_fast_clear_enable = false;
|
||||
bool dcc_compression_enable = false;
|
||||
bool neo_mode = false;
|
||||
uint32_t cmask_tile_mode = 0;
|
||||
uint32_t cmask_tile_mode_neo = 0;
|
||||
uint32_t format = 0;
|
||||
uint32_t channel_type = 0;
|
||||
uint32_t channel_order = 0;
|
||||
uint64_t base_addr = 0;
|
||||
uint32_t pitch_div8_minus1 = 0;
|
||||
uint32_t fmask_pitch_div8_minus1 = 0;
|
||||
uint32_t slice_div64_minus1 = 0;
|
||||
uint32_t base_array_slice_index = 0;
|
||||
uint32_t last_array_slice_index = 0;
|
||||
|
||||
ColorInfo color_info;
|
||||
|
||||
bool force_dest_alpha_to_one = false;
|
||||
uint32_t tile_mode = 0;
|
||||
uint32_t fmask_tile_mode = 0;
|
||||
|
@ -155,6 +162,28 @@ struct DepthControl
|
|||
uint8_t stencilfunc_bf = 0;
|
||||
};
|
||||
|
||||
struct StencilControl
|
||||
{
|
||||
uint8_t stencil_fail = 0;
|
||||
uint8_t stencil_zpass = 0;
|
||||
uint8_t stencil_zfail = 0;
|
||||
uint8_t stencil_fail_bf = 0;
|
||||
uint8_t stencil_zpass_bf = 0;
|
||||
uint8_t stencil_zfail_bf = 0;
|
||||
};
|
||||
|
||||
struct StencilMask
|
||||
{
|
||||
uint8_t stencil_testval = 0;
|
||||
uint8_t stencil_mask = 0;
|
||||
uint8_t stencil_writemask = 0;
|
||||
uint8_t stencil_opval = 0;
|
||||
uint8_t stencil_testval_bf = 0;
|
||||
uint8_t stencil_mask_bf = 0;
|
||||
uint8_t stencil_writemask_bf = 0;
|
||||
uint8_t stencil_opval_bf = 0;
|
||||
};
|
||||
|
||||
struct ModeControl
|
||||
{
|
||||
bool cull_front = false;
|
||||
|
@ -343,7 +372,8 @@ public:
|
|||
|
||||
void Reset() { *this = HardwareContext(); }
|
||||
|
||||
void SetRenderTarget(uint32_t slot, const RenderTarget& target) { m_render_targets[slot] = target; }
|
||||
void SetRenderTarget(uint32_t slot, const RenderTarget& target) { m_render_targets[slot] = target; }
|
||||
void SetColorInfo(uint32_t slot, const ColorInfo& color_info) { m_render_targets[slot].color_info = color_info; }
|
||||
[[nodiscard]] const RenderTarget& GetRenderTargets(uint32_t slot) const { return m_render_targets[slot]; }
|
||||
|
||||
void SetBlendControl(uint32_t slot, const BlendControl& control) { m_blend_control[slot] = control; }
|
||||
|
@ -411,7 +441,16 @@ public:
|
|||
m_vs.vs_embedded = true;
|
||||
}
|
||||
|
||||
void SetPsShader(const PsStageRegisters* ps_regs) { m_ps.ps_regs = *ps_regs; }
|
||||
void SetPsShader(const PsStageRegisters* ps_regs)
|
||||
{
|
||||
m_ps.ps_regs = *ps_regs;
|
||||
m_ps.ps_embedded = false;
|
||||
}
|
||||
void SetPsEmbedded(uint32_t id)
|
||||
{
|
||||
m_ps.ps_embedded_id = id;
|
||||
m_ps.ps_embedded = true;
|
||||
}
|
||||
|
||||
void SetCsShader(const CsStageRegisters* cs_regs, uint32_t shader_modifier)
|
||||
{
|
||||
|
@ -419,18 +458,22 @@ public:
|
|||
m_cs.cs_shader_modifier = shader_modifier;
|
||||
}
|
||||
|
||||
[[nodiscard]] const BlendColor& GetBlendColor() const { return m_blend_color; }
|
||||
void SetBlendColor(const BlendColor& color) { m_blend_color = color; }
|
||||
[[nodiscard]] const ClipControl& GetClipControl() const { return m_clip_control; }
|
||||
void SetClipControl(const ClipControl& control) { m_clip_control = control; }
|
||||
[[nodiscard]] const RenderControl& GetRenderControl() const { return m_render_control; }
|
||||
void SetRenderControl(const RenderControl& control) { m_render_control = control; }
|
||||
[[nodiscard]] const DepthControl& GetDepthControl() const { return m_depth_control; }
|
||||
void SetDepthControl(const DepthControl& control) { m_depth_control = control; }
|
||||
[[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; }
|
||||
void SetModeControl(const ModeControl& control) { m_mode_control = control; }
|
||||
[[nodiscard]] const EqaaControl& GetEqaaControl() const { return m_eqaa_control; }
|
||||
void SetEqaaControl(const EqaaControl& control) { m_eqaa_control = control; }
|
||||
[[nodiscard]] const BlendColor& GetBlendColor() const { return m_blend_color; }
|
||||
void SetBlendColor(const BlendColor& color) { m_blend_color = color; }
|
||||
[[nodiscard]] const ClipControl& GetClipControl() const { return m_clip_control; }
|
||||
void SetClipControl(const ClipControl& control) { m_clip_control = control; }
|
||||
[[nodiscard]] const RenderControl& GetRenderControl() const { return m_render_control; }
|
||||
void SetRenderControl(const RenderControl& control) { m_render_control = control; }
|
||||
[[nodiscard]] const DepthControl& GetDepthControl() const { return m_depth_control; }
|
||||
void SetDepthControl(const DepthControl& control) { m_depth_control = control; }
|
||||
[[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; }
|
||||
void SetModeControl(const ModeControl& control) { m_mode_control = control; }
|
||||
[[nodiscard]] const EqaaControl& GetEqaaControl() const { return m_eqaa_control; }
|
||||
void SetEqaaControl(const EqaaControl& control) { m_eqaa_control = control; }
|
||||
[[nodiscard]] const StencilControl& GetStencilControl() const { return m_stencil_control; }
|
||||
void SetStencilControl(const StencilControl& control) { m_stencil_control = control; }
|
||||
[[nodiscard]] const StencilMask& GetStencilMask() const { return m_stencil_mask; }
|
||||
void SetStencilMask(const StencilMask& mask) { m_stencil_mask = mask; }
|
||||
|
||||
void SetVsUserSgpr(uint32_t id, uint32_t value, UserSgprType type)
|
||||
{
|
||||
|
@ -460,8 +503,10 @@ public:
|
|||
[[nodiscard]] const VertexShaderInfo& GetVs() const { return m_vs; }
|
||||
[[nodiscard]] const ComputeShaderInfo& GetCs() const { return m_cs; }
|
||||
|
||||
[[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; }
|
||||
void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; }
|
||||
[[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; }
|
||||
void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; }
|
||||
[[nodiscard]] uint8_t GetStencilClearValue() const { return m_stencil_clear_value; }
|
||||
void SetStencilClearValue(uint8_t clear_value) { m_stencil_clear_value = clear_value; }
|
||||
|
||||
private:
|
||||
BlendControl m_blend_control[8];
|
||||
|
@ -479,7 +524,10 @@ private:
|
|||
DepthRenderTarget m_depth_render_target;
|
||||
RenderControl m_render_control;
|
||||
DepthControl m_depth_control;
|
||||
float m_depth_clear_value = 0.0f;
|
||||
StencilControl m_stencil_control;
|
||||
StencilMask m_stencil_mask;
|
||||
float m_depth_clear_value = 0.0f;
|
||||
uint8_t m_stencil_clear_value = 0;
|
||||
|
||||
ModeControl m_mode_control;
|
||||
EqaaControl m_eqaa_control;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
class CommandBuffer;
|
||||
struct GraphicContext;
|
||||
struct VulkanMemory;
|
||||
struct VulkanBuffer;
|
||||
|
@ -39,6 +40,12 @@ enum class GpuMemoryObjectType : uint64_t
|
|||
Max
|
||||
};
|
||||
|
||||
enum class GpuMemoryScenario
|
||||
{
|
||||
Common,
|
||||
GenerateMips,
|
||||
};
|
||||
|
||||
struct GpuMemoryObject
|
||||
{
|
||||
GpuMemoryObjectType type = GpuMemoryObjectType::Invalid;
|
||||
|
@ -50,8 +57,8 @@ class GpuObject
|
|||
public:
|
||||
using create_func_t = void* (*)(GraphicContext* ctx, const uint64_t* params, const uint64_t* vaddr, const uint64_t* size, int vaddr_num,
|
||||
VulkanMemory* mem);
|
||||
using create_from_objects_func_t = void* (*)(GraphicContext* ctx, const uint64_t* params, const Vector<GpuMemoryObject>& objects,
|
||||
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,
|
||||
|
@ -81,16 +88,18 @@ public:
|
|||
void GpuMemoryInit();
|
||||
|
||||
void GpuMemorySetAllocatedRange(uint64_t vaddr, uint64_t size);
|
||||
void GpuMemoryFree(GraphicContext* ctx, uint64_t vaddr, uint64_t size);
|
||||
void* GpuMemoryCreateObject(GraphicContext* ctx, uint64_t vaddr, uint64_t size, const GpuObject& info);
|
||||
void* GpuMemoryCreateObject(GraphicContext* ctx, const uint64_t* vaddr, const uint64_t* size, int vaddr_num, const GpuObject& info);
|
||||
void GpuMemoryFree(GraphicContext* ctx, uint64_t vaddr, uint64_t size, bool unmap);
|
||||
void* GpuMemoryCreateObject(GraphicContext* ctx, CommandBuffer* buffer, uint64_t vaddr, uint64_t size, const GpuObject& info);
|
||||
void* GpuMemoryCreateObject(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 GpuMemoryDbgDump();
|
||||
void GpuMemoryFlush(GraphicContext* ctx);
|
||||
void GpuMemoryFrameDone();
|
||||
void GpuMemoryWriteBack(GraphicContext* ctx);
|
||||
bool GpuMemoryCheckAccessViolation(uint64_t vaddr, uint64_t size);
|
||||
|
||||
Vector<GpuMemoryObject> GpuMemoryFindObjects(uint64_t vaddr, uint64_t size);
|
||||
Vector<GpuMemoryObject> GpuMemoryFindObjects(uint64_t vaddr, uint64_t size, bool exact);
|
||||
|
||||
bool VulkanAllocate(GraphicContext* ctx, VulkanMemory* mem);
|
||||
void VulkanFree(GraphicContext* ctx, VulkanMemory* mem);
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
bool Equal(const uint64_t* other) const override;
|
||||
|
||||
[[nodiscard]] create_func_t GetCreateFunc() const override;
|
||||
[[nodiscard]] create_from_objects_func_t GetCreateFromObjectsFunc() const override { return nullptr; };
|
||||
[[nodiscard]] create_from_objects_func_t GetCreateFromObjectsFunc() const override;
|
||||
[[nodiscard]] write_back_func_t GetWriteBackFunc() const override { return nullptr; };
|
||||
[[nodiscard]] delete_func_t GetDeleteFunc() const override;
|
||||
[[nodiscard]] update_func_t GetUpdateFunc() const override;
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
struct StorageVulkanBuffer;
|
||||
class CommandBuffer;
|
||||
|
||||
class StorageBufferGpuObject: public GpuObject
|
||||
{
|
||||
public:
|
||||
|
@ -31,6 +34,8 @@ public:
|
|||
[[nodiscard]] update_func_t GetUpdateFunc() const override;
|
||||
};
|
||||
|
||||
void StorageBufferSet(CommandBuffer* cmd_buffer, StorageVulkanBuffer* buffer);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
|
|
@ -21,13 +21,13 @@ public:
|
|||
static constexpr int PARAM_NEO = 5;
|
||||
static constexpr int PARAM_SWIZZLE = 6;
|
||||
|
||||
StorageTextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
|
||||
bool neo, uint32_t swizzle)
|
||||
StorageTextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t base_level,
|
||||
uint32_t levels, uint32_t tile, bool neo, uint32_t swizzle)
|
||||
{
|
||||
params[PARAM_DFMT_NFMT] = (static_cast<uint64_t>(dfmt) << 32u) | nfmt;
|
||||
params[PARAM_PITCH] = pitch;
|
||||
params[PARAM_WIDTH_HEIGHT] = (static_cast<uint64_t>(width) << 32u) | height;
|
||||
params[PARAM_LEVELS] = levels;
|
||||
params[PARAM_LEVELS] = (static_cast<uint64_t>(base_level) << 32u) | levels;
|
||||
params[PARAM_TILE] = tile;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
params[PARAM_SWIZZLE] = swizzle;
|
||||
|
|
|
@ -21,13 +21,13 @@ public:
|
|||
static constexpr int PARAM_NEO = 5;
|
||||
static constexpr int PARAM_SWIZZLE = 6;
|
||||
|
||||
TextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile, bool neo,
|
||||
uint32_t swizzle)
|
||||
TextureObject(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t base_level, uint32_t levels,
|
||||
uint32_t tile, bool neo, uint32_t swizzle)
|
||||
{
|
||||
params[PARAM_DFMT_NFMT] = (static_cast<uint64_t>(dfmt) << 32u) | nfmt;
|
||||
params[PARAM_PITCH] = pitch;
|
||||
params[PARAM_WIDTH_HEIGHT] = (static_cast<uint64_t>(width) << 32u) | height;
|
||||
params[PARAM_LEVELS] = levels;
|
||||
params[PARAM_LEVELS] = (static_cast<uint64_t>(base_level) << 32u) | levels;
|
||||
params[PARAM_TILE] = tile;
|
||||
params[PARAM_NEO] = neo ? 1 : 0;
|
||||
params[PARAM_SWIZZLE] = swizzle;
|
||||
|
|
|
@ -111,6 +111,10 @@ constexpr uint32_t DB_HTILE_DATA_BASE = 0x5;
|
|||
constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_SHIFT = 0;
|
||||
constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_MASK = 0xFFFFFFFF;
|
||||
|
||||
constexpr uint32_t DB_STENCIL_CLEAR = 0xA;
|
||||
constexpr uint32_t DB_STENCIL_CLEAR_CLEAR_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCIL_CLEAR_CLEAR_MASK = 0xFF;
|
||||
|
||||
constexpr uint32_t DB_DEPTH_CLEAR = 0xB;
|
||||
constexpr uint32_t DB_DEPTH_CLEAR_DEPTH_CLEAR_SHIFT = 0;
|
||||
constexpr uint32_t DB_DEPTH_CLEAR_DEPTH_CLEAR_MASK = 0xFFFFFFFF;
|
||||
|
@ -181,6 +185,40 @@ constexpr uint32_t CB_BLEND_GREEN = 0x106;
|
|||
constexpr uint32_t CB_BLEND_BLUE = 0x107;
|
||||
constexpr uint32_t CB_BLEND_ALPHA = 0x108;
|
||||
|
||||
constexpr uint32_t DB_STENCIL_CONTROL = 0x10B;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILFAIL_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILFAIL_MASK = 0xF;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZPASS_SHIFT = 4;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZPASS_MASK = 0xF;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZFAIL_SHIFT = 8;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZFAIL_MASK = 0xF;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILFAIL_BF_SHIFT = 12;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILFAIL_BF_MASK = 0xF;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZPASS_BF_SHIFT = 16;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZPASS_BF_MASK = 0xF;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZFAIL_BF_SHIFT = 20;
|
||||
constexpr uint32_t DB_STENCIL_CONTROL_STENCILZFAIL_BF_MASK = 0xF;
|
||||
|
||||
constexpr uint32_t DB_STENCILREFMASK = 0x10C;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILTESTVAL_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILTESTVAL_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILMASK_SHIFT = 8;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILMASK_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILWRITEMASK_SHIFT = 16;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILWRITEMASK_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILOPVAL_SHIFT = 24;
|
||||
constexpr uint32_t DB_STENCILREFMASK_STENCILOPVAL_MASK = 0xFF;
|
||||
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF = 0x10D;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILTESTVAL_BF_SHIFT = 0;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILTESTVAL_BF_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILMASK_BF_SHIFT = 8;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILMASK_BF_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILWRITEMASK_BF_SHIFT = 16;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILWRITEMASK_BF_MASK = 0xFF;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILOPVAL_BF_SHIFT = 24;
|
||||
constexpr uint32_t DB_STENCILREFMASK_BF_STENCILOPVAL_BF_MASK = 0xFF;
|
||||
|
||||
constexpr uint32_t PA_CL_VPORT_XSCALE = 0x10F;
|
||||
|
||||
constexpr uint32_t SPI_PS_INPUT_CNTL_0 = 0x191;
|
||||
|
@ -282,6 +320,7 @@ constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_MASK = 0x1;
|
|||
constexpr uint32_t VGT_SHADER_STAGES_EN = 0x2D5;
|
||||
|
||||
constexpr uint32_t CB_COLOR0_BASE = 0x318;
|
||||
constexpr uint32_t CB_COLOR0_INFO = 0x31C;
|
||||
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS = 0xA;
|
||||
constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT = 0;
|
||||
|
|
|
@ -42,6 +42,7 @@ enum class ShaderInstructionType
|
|||
Exp,
|
||||
ImageLoad,
|
||||
ImageSample,
|
||||
ImageStore,
|
||||
ImageStoreMip,
|
||||
SAddcU32,
|
||||
SAddI32,
|
||||
|
@ -137,6 +138,7 @@ enum class ShaderInstructionType
|
|||
VCmpxGeU32,
|
||||
VCmpxGtU32,
|
||||
VCmpxNeU32,
|
||||
VCmpxNeqF32,
|
||||
VCndmaskB32,
|
||||
VCosF32,
|
||||
VCvtF32F16,
|
||||
|
@ -394,18 +396,24 @@ public:
|
|||
{ return m_instructions.Contains(type, [](auto inst, auto type) { return inst.type == type; }); });
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsEmbedded() const { return m_embedded; }
|
||||
void SetEmbedded(bool embedded) { this->m_embedded = embedded; }
|
||||
[[nodiscard]] uint32_t GetEmbeddedId() const { return m_embedded_id; }
|
||||
void SetEmbeddedId(uint32_t embedded_id) { m_embedded_id = embedded_id; }
|
||||
[[nodiscard]] bool IsVsEmbedded() const { return m_vs_embedded; }
|
||||
void SetVsEmbedded(bool embedded) { this->m_vs_embedded = embedded; }
|
||||
[[nodiscard]] uint32_t GetVsEmbeddedId() const { return m_vs_embedded_id; }
|
||||
void SetVsEmbeddedId(uint32_t embedded_id) { m_vs_embedded_id = embedded_id; }
|
||||
[[nodiscard]] bool IsPsEmbedded() const { return m_ps_embedded; }
|
||||
void SetPsEmbedded(bool embedded) { this->m_ps_embedded = embedded; }
|
||||
[[nodiscard]] uint32_t GetPsEmbeddedId() const { return m_ps_embedded_id; }
|
||||
void SetPsEmbeddedId(uint32_t embedded_id) { m_ps_embedded_id = embedded_id; }
|
||||
|
||||
private:
|
||||
Vector<ShaderInstruction> m_instructions;
|
||||
Vector<ShaderLabel> m_labels;
|
||||
ShaderType m_type = ShaderType::Unknown;
|
||||
Vector<ShaderDebugPrintf> m_debug_printfs;
|
||||
uint32_t m_embedded_id = 0;
|
||||
bool m_embedded = false;
|
||||
uint32_t m_vs_embedded_id = 0;
|
||||
uint32_t m_ps_embedded_id = 0;
|
||||
bool m_vs_embedded = false;
|
||||
bool m_ps_embedded = false;
|
||||
};
|
||||
|
||||
struct ShaderId
|
||||
|
|
|
@ -18,6 +18,7 @@ struct ShaderComputeInputInfo;
|
|||
String SpirvGenerateSource(const ShaderCode& code, const ShaderVertexInputInfo* vs_input_info, const ShaderPixelInputInfo* ps_input_info,
|
||||
const ShaderComputeInputInfo* cs_input_info);
|
||||
String SpirvGetEmbeddedVs(uint32_t id);
|
||||
String SpirvGetEmbeddedPs(uint32_t id);
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
ExceptionType type = ExceptionType::Unknown;
|
||||
AccessViolationType access_violation_type = AccessViolationType::Unknown;
|
||||
uint64_t access_violation_vaddr = 0;
|
||||
uint64_t exception_address = 0;
|
||||
};
|
||||
|
||||
using handler_func_t = void (*)(const ExceptionInfo*);
|
||||
|
@ -70,6 +71,8 @@ public:
|
|||
bool Install(uint64_t base_address, uint64_t handler_addr, uint64_t image_size, handler_func_t func);
|
||||
bool Uninstall();
|
||||
|
||||
static bool InstallVectored(handler_func_t func);
|
||||
|
||||
private:
|
||||
ExceptionHandlerPrivate* m_p = nullptr;
|
||||
};
|
||||
|
|
|
@ -191,6 +191,8 @@ int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uin
|
|||
memcpy(&cmd[1], ps_regs, 12 * 4);
|
||||
}
|
||||
|
||||
// printf("ok\n");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@
|
|||
#include "Emulator/Graphics/Graphics.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/HardwareContext.h"
|
||||
#include "Emulator/Graphics/Objects/GpuMemory.h"
|
||||
#include "Emulator/Graphics/Pm4.h"
|
||||
#include "Emulator/Graphics/VideoOut.h"
|
||||
#include "Emulator/Graphics/Window.h"
|
||||
|
@ -610,6 +611,8 @@ void CommandProcessor::DumpConstRam(uint32_t* dst, uint32_t offset, uint32_t dw_
|
|||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
GpuMemoryCheckAccessViolation(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
|
||||
memcpy(dst, m_const_ram + offset / 4, dw_num * 4);
|
||||
}
|
||||
|
||||
|
@ -634,6 +637,8 @@ void CommandProcessor::WriteData(uint32_t* dst, const uint32_t* src, uint32_t dw
|
|||
|
||||
EXIT_NOT_IMPLEMENTED(write_control != 0x04100500);
|
||||
|
||||
GpuMemoryCheckAccessViolation(reinterpret_cast<uint64_t>(dst), dw_num * 4);
|
||||
|
||||
memcpy(dst, src, dw_num * 4);
|
||||
}
|
||||
|
||||
|
@ -912,6 +917,11 @@ void CommandProcessor::Run(uint32_t* data, uint32_t num_dw)
|
|||
{
|
||||
KYTY_PROFILER_BLOCK("CommandProcessor::Run");
|
||||
|
||||
if (num_dw > 0)
|
||||
{
|
||||
GraphicsRenderMemoryFree(reinterpret_cast<uint64_t>(data), num_dw * 4);
|
||||
}
|
||||
|
||||
auto* cmd = data;
|
||||
auto dw = num_dw;
|
||||
for (;;)
|
||||
|
@ -1368,6 +1378,12 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_ps_input)
|
|||
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]);
|
||||
|
@ -1467,6 +1483,46 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_depth_control)
|
|||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_control)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CONTROL);
|
||||
|
||||
StencilControl r;
|
||||
|
||||
r.stencil_fail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL);
|
||||
r.stencil_zpass = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS);
|
||||
r.stencil_zfail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL);
|
||||
r.stencil_fail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL_BF);
|
||||
r.stencil_zpass_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS_BF);
|
||||
r.stencil_zfail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL_BF);
|
||||
|
||||
cp->GetCtx()->SetStencilControl(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_mask)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0026900);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCILREFMASK);
|
||||
|
||||
StencilMask r;
|
||||
|
||||
r.stencil_testval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILTESTVAL);
|
||||
r.stencil_mask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILMASK);
|
||||
r.stencil_writemask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILWRITEMASK);
|
||||
r.stencil_opval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILOPVAL);
|
||||
r.stencil_testval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILTESTVAL_BF);
|
||||
r.stencil_mask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILMASK_BF);
|
||||
r.stencil_writemask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILWRITEMASK_BF);
|
||||
r.stencil_opval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILOPVAL_BF);
|
||||
|
||||
cp->GetCtx()->SetStencilMask(r);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_eqaa_control)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
|
@ -1488,6 +1544,16 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_eqaa_control)
|
|||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_clear)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CLEAR);
|
||||
|
||||
cp->GetCtx()->SetStencilClearValue(KYTY_PM4_GET(buffer[0], DB_STENCIL_CLEAR, CLEAR));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_depth_clear)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
|
@ -1546,22 +1612,24 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_render_target)
|
|||
|
||||
RenderTarget r;
|
||||
|
||||
r.base_addr = static_cast<uint64_t>(buffer[0]) << 8u;
|
||||
r.pitch_div8_minus1 = buffer[1] & 0x7ffu;
|
||||
r.fmask_pitch_div8_minus1 = (buffer[1] >> 20u) & 0x7ffu;
|
||||
r.slice_div64_minus1 = buffer[2] & 0x3fffffu;
|
||||
r.base_array_slice_index = buffer[3] & 0x7ffu;
|
||||
r.last_array_slice_index = (buffer[3] >> 13u) & 0x7ffu;
|
||||
r.fmask_compression_enable = (buffer[4] & 0x4000u) != 0;
|
||||
r.fmask_compression_mode = (buffer[4] >> 26u) & 0x3u;
|
||||
r.cmask_fast_clear_enable = (buffer[4] & 0x2000u) != 0;
|
||||
r.dcc_compression_enable = (buffer[4] & 0x10000000u) != 0;
|
||||
r.neo_mode = (buffer[4] & 0x80000000u) != 0;
|
||||
r.cmask_tile_mode = (buffer[4] >> 19u) & 0x1u;
|
||||
r.cmask_tile_mode_neo = (buffer[4] >> 29u) & 0x3u;
|
||||
r.format = (buffer[4] >> 2u) & 0x1fu;
|
||||
r.channel_type = (buffer[4] >> 8u) & 0x7u;
|
||||
r.channel_order = (buffer[4] >> 11u) & 0x3u;
|
||||
r.base_addr = static_cast<uint64_t>(buffer[0]) << 8u;
|
||||
r.pitch_div8_minus1 = buffer[1] & 0x7ffu;
|
||||
r.fmask_pitch_div8_minus1 = (buffer[1] >> 20u) & 0x7ffu;
|
||||
r.slice_div64_minus1 = buffer[2] & 0x3fffffu;
|
||||
r.base_array_slice_index = buffer[3] & 0x7ffu;
|
||||
r.last_array_slice_index = (buffer[3] >> 13u) & 0x7ffu;
|
||||
|
||||
r.color_info.fmask_compression_enable = (buffer[4] & 0x4000u) != 0;
|
||||
r.color_info.fmask_compression_mode = (buffer[4] >> 26u) & 0x3u;
|
||||
r.color_info.cmask_fast_clear_enable = (buffer[4] & 0x2000u) != 0;
|
||||
r.color_info.dcc_compression_enable = (buffer[4] & 0x10000000u) != 0;
|
||||
r.color_info.neo_mode = (buffer[4] & 0x80000000u) != 0;
|
||||
r.color_info.cmask_tile_mode = (buffer[4] >> 19u) & 0x1u;
|
||||
r.color_info.cmask_tile_mode_neo = (buffer[4] >> 29u) & 0x3u;
|
||||
r.color_info.format = (buffer[4] >> 2u) & 0x1fu;
|
||||
r.color_info.channel_type = (buffer[4] >> 8u) & 0x7u;
|
||||
r.color_info.channel_order = (buffer[4] >> 11u) & 0x3u;
|
||||
|
||||
r.force_dest_alpha_to_one = (buffer[5] & 0x20000u) != 0;
|
||||
r.tile_mode = buffer[5] & 0x1fu;
|
||||
r.fmask_tile_mode = (buffer[5] >> 5u) & 0x1fu;
|
||||
|
@ -1588,6 +1656,30 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_render_target)
|
|||
return count;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_color_info)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900);
|
||||
|
||||
uint32_t param = (cmd_offset - Pm4::CB_COLOR0_INFO) / 15;
|
||||
|
||||
ColorInfo r;
|
||||
|
||||
r.fmask_compression_enable = (buffer[4] & 0x4000u) != 0;
|
||||
r.fmask_compression_mode = (buffer[4] >> 26u) & 0x3u;
|
||||
r.cmask_fast_clear_enable = (buffer[4] & 0x2000u) != 0;
|
||||
r.dcc_compression_enable = (buffer[4] & 0x10000000u) != 0;
|
||||
r.neo_mode = (buffer[4] & 0x80000000u) != 0;
|
||||
r.cmask_tile_mode = (buffer[4] >> 19u) & 0x1u;
|
||||
r.cmask_tile_mode_neo = (buffer[4] >> 29u) & 0x3u;
|
||||
r.format = (buffer[4] >> 2u) & 0x1fu;
|
||||
r.channel_type = (buffer[4] >> 8u) & 0x7u;
|
||||
r.channel_order = (buffer[4] >> 11u) & 0x3u;
|
||||
|
||||
cp->GetCtx()->SetColorInfo(param, r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_render_target_mask)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
|
@ -1744,6 +1836,17 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_vs_embedded)
|
|||
return 28;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_ps_embedded)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0261038);
|
||||
|
||||
auto id = buffer[0];
|
||||
|
||||
cp->GetCtx()->SetPsEmbedded(id);
|
||||
|
||||
return 39;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_ps_shader)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0261008);
|
||||
|
@ -2217,6 +2320,14 @@ KYTY_CP_OP_PARSER(cp_op_acquire_mem)
|
|||
|
||||
switch (cache_action)
|
||||
{
|
||||
case 0x02c40040:
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size_lo == 0);
|
||||
EXIT_NOT_IMPLEMENTED(base_lo == 0);
|
||||
cp->RenderTextureBarrier(base_lo << 8u, size_lo << 8u);
|
||||
cp->WriteBack();
|
||||
}
|
||||
break;
|
||||
case 0x02003fc0:
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size_lo == 0);
|
||||
|
@ -2395,6 +2506,7 @@ KYTY_CP_OP_PARSER(cp_op_nop)
|
|||
case Pm4::R_PUSH_MARKER: return cp_op_push_marker(cp, cmd_id, buffer, dw, num_dw); break;
|
||||
case Pm4::R_POP_MARKER: return cp_op_pop_marker(cp, cmd_id, buffer, dw, num_dw); break;
|
||||
case Pm4::R_VS_EMBEDDED: return hw_ctx_set_vs_embedded(cp, cmd_id, 0, buffer, dw); break;
|
||||
case Pm4::R_PS_EMBEDDED: return hw_ctx_set_ps_embedded(cp, cmd_id, 0, buffer, dw); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -2411,6 +2523,7 @@ static void graphics_init_jmp_tables()
|
|||
}
|
||||
|
||||
g_hw_ctx_func[Pm4::DB_RENDER_CONTROL] = hw_ctx_set_render_control;
|
||||
g_hw_ctx_func[Pm4::DB_STENCIL_CLEAR] = hw_ctx_set_stencil_clear;
|
||||
g_hw_ctx_func[Pm4::DB_DEPTH_CLEAR] = hw_ctx_set_depth_clear;
|
||||
g_hw_ctx_func[0x00c] = hw_ctx_set_screen_scissor;
|
||||
g_hw_ctx_func[Pm4::DB_Z_INFO] = hw_ctx_set_depth_render_target;
|
||||
|
@ -2418,6 +2531,8 @@ static void graphics_init_jmp_tables()
|
|||
g_hw_ctx_func[0x08d] = hw_ctx_hardware_screen_offset;
|
||||
g_hw_ctx_func[0x08e] = hw_ctx_set_render_target_mask;
|
||||
g_hw_ctx_func[Pm4::CB_BLEND_RED] = hw_ctx_set_blend_color;
|
||||
g_hw_ctx_func[Pm4::DB_STENCIL_CONTROL] = hw_ctx_set_stencil_control;
|
||||
g_hw_ctx_func[Pm4::DB_STENCILREFMASK] = hw_ctx_set_stencil_mask;
|
||||
g_hw_ctx_func[Pm4::SPI_PS_INPUT_CNTL_0] = hw_ctx_set_ps_input;
|
||||
g_hw_ctx_func[Pm4::DB_DEPTH_CONTROL] = hw_ctx_set_depth_control;
|
||||
g_hw_ctx_func[Pm4::DB_EQAA] = hw_ctx_set_eqaa_control;
|
||||
|
@ -2430,6 +2545,7 @@ static void graphics_init_jmp_tables()
|
|||
for (uint32_t slot = 0; slot < 8; slot++)
|
||||
{
|
||||
g_hw_ctx_func[Pm4::CB_COLOR0_BASE + slot * 15] = hw_ctx_set_render_target;
|
||||
g_hw_ctx_func[Pm4::CB_COLOR0_INFO + slot * 15] = hw_ctx_set_color_info;
|
||||
|
||||
g_hw_ctx_func[Pm4::CB_BLEND0_CONTROL + slot * 1] = hw_ctx_set_blend_control;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,10 @@
|
|||
#include "Emulator/Graphics/Objects/RenderTexture.h"
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
//#include "Emulator/Graphics/Tile.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
|
@ -66,6 +66,82 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
}
|
||||
}
|
||||
|
||||
static void update2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* params, void* obj, GpuMemoryScenario scenario,
|
||||
const Vector<GpuMemoryObject>& objects)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("RenderTextureObject::update_func");
|
||||
|
||||
EXIT_IF(obj == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
EXIT_IF(objects.IsEmpty());
|
||||
|
||||
auto* vk_obj = static_cast<RenderTextureVulkanImage*>(obj);
|
||||
|
||||
// bool tiled = (params[RenderTextureObject::PARAM_TILED] != 0);
|
||||
// bool neo = (params[RenderTextureObject::PARAM_NEO] != 0);
|
||||
// auto pitch = params[RenderTextureObject::PARAM_PITCH];
|
||||
auto width = params[RenderTextureObject::PARAM_WIDTH];
|
||||
auto height = params[RenderTextureObject::PARAM_HEIGHT];
|
||||
|
||||
vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
if (objects.Size() == 2 && objects.At(0).type == GpuMemoryObjectType::StorageBuffer &&
|
||||
objects.At(1).type == GpuMemoryObjectType::StorageTexture && scenario == GpuMemoryScenario::GenerateMips)
|
||||
{
|
||||
auto* src_obj = static_cast<StorageTextureVulkanImage*>(objects.At(1).obj);
|
||||
|
||||
uint32_t mip_width = src_obj->extent.width;
|
||||
uint32_t mip_height = src_obj->extent.height;
|
||||
|
||||
Vector<ImageImageCopy> regions(1);
|
||||
|
||||
bool updated = false;
|
||||
|
||||
for (uint32_t i = 0; i < 16 && !updated; i++)
|
||||
{
|
||||
if (mip_width == width && mip_height == height)
|
||||
{
|
||||
auto mipmap_offset = UtilCalcMipmapOffset(i, width, height);
|
||||
|
||||
regions[0].src_image = src_obj;
|
||||
regions[0].src_level = 0;
|
||||
regions[0].dst_level = 0;
|
||||
regions[0].width = mip_width;
|
||||
regions[0].height = mip_height;
|
||||
regions[0].src_x = mipmap_offset.first;
|
||||
regions[0].src_y = mipmap_offset.second;
|
||||
regions[0].dst_x = 0;
|
||||
regions[0].dst_y = 0;
|
||||
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
UtilFillImage(ctx, regions, vk_obj, static_cast<uint64_t>(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
} else
|
||||
{
|
||||
UtilImageToImage(buffer, regions, vk_obj, static_cast<uint64_t>(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
}
|
||||
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (mip_width > 1)
|
||||
{
|
||||
mip_width /= 2;
|
||||
}
|
||||
if (mip_height > 1)
|
||||
{
|
||||
mip_height /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!updated);
|
||||
} else
|
||||
{
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint64_t* vaddr, const uint64_t* size, int vaddr_num,
|
||||
VulkanMemory* mem)
|
||||
{
|
||||
|
@ -168,6 +244,108 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
return vk_obj;
|
||||
}
|
||||
|
||||
static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* params, GpuMemoryScenario scenario,
|
||||
const Vector<GpuMemoryObject>& objects, VulkanMemory* mem)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("RenderTextureObject::CreateFromObjects");
|
||||
|
||||
EXIT_IF(objects.IsEmpty());
|
||||
EXIT_IF(mem == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
auto pixel_format = params[RenderTextureObject::PARAM_FORMAT];
|
||||
auto width = params[RenderTextureObject::PARAM_WIDTH];
|
||||
auto height = params[RenderTextureObject::PARAM_HEIGHT];
|
||||
|
||||
VkFormat vk_format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
switch (pixel_format) // NOLINT
|
||||
{
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
|
||||
default: EXIT("unknown format: %" PRIu64 "\n", pixel_format);
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(width == 0);
|
||||
EXIT_NOT_IMPLEMENTED(height == 0);
|
||||
|
||||
auto* vk_obj = new RenderTextureVulkanImage;
|
||||
|
||||
vk_obj->extent.width = width;
|
||||
vk_obj->extent.height = height;
|
||||
vk_obj->format = vk_format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->image_view = nullptr;
|
||||
|
||||
VkImageCreateInfo image_info {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info.pNext = nullptr;
|
||||
image_info.flags = 0;
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_info.extent.width = vk_obj->extent.width;
|
||||
image_info.extent.height = vk_obj->extent.height;
|
||||
image_info.extent.depth = 1;
|
||||
image_info.mipLevels = 1;
|
||||
image_info.arrayLayers = 1;
|
||||
image_info.format = vk_obj->format;
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_info.usage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) |
|
||||
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) |
|
||||
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_DST_BIT) |
|
||||
static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
vkCreateImage(ctx->device, &image_info, nullptr, &vk_obj->image);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image == nullptr);
|
||||
|
||||
vkGetImageMemoryRequirements(ctx->device, vk_obj->image, &mem->requirements);
|
||||
|
||||
mem->property = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
bool allocated = VulkanAllocate(ctx, mem);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!allocated);
|
||||
|
||||
VulkanBindImageMemory(ctx, vk_obj, mem);
|
||||
|
||||
vk_obj->memory = *mem;
|
||||
|
||||
printf("RenderTextureObject::CreateFromObjects()\n");
|
||||
printf("\t mem->requirements.size = %" PRIu64 "\n", mem->requirements.size);
|
||||
printf("\t width = %" PRIu64 "\n", width);
|
||||
printf("\t height = %" PRIu64 "\n", height);
|
||||
// printf("\t size = %" PRIu64 "\n", *size);
|
||||
|
||||
// EXIT_NOT_IMPLEMENTED(mem->requirements.size > *size);
|
||||
|
||||
update2_func(ctx, buffer, params, vk_obj, scenario, objects);
|
||||
|
||||
VkImageViewCreateInfo create_info {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
create_info.pNext = nullptr;
|
||||
create_info.flags = 0;
|
||||
create_info.image = vk_obj->image;
|
||||
create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
create_info.format = vk_obj->format;
|
||||
create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
create_info.subresourceRange.baseArrayLayer = 0;
|
||||
create_info.subresourceRange.baseMipLevel = 0;
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = 1;
|
||||
|
||||
vkCreateImageView(ctx->device, &create_info, nullptr, &vk_obj->image_view);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_obj->image_view == nullptr);
|
||||
|
||||
return vk_obj;
|
||||
}
|
||||
|
||||
static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("RenderTextureObject::delete_func");
|
||||
|
@ -202,6 +380,11 @@ GpuObject::create_func_t RenderTextureObject::GetCreateFunc() const
|
|||
return create_func;
|
||||
}
|
||||
|
||||
GpuObject::create_from_objects_func_t RenderTextureObject::GetCreateFromObjectsFunc() const
|
||||
{
|
||||
return create2_func;
|
||||
}
|
||||
|
||||
GpuObject::delete_func_t RenderTextureObject::GetDeleteFunc() const
|
||||
{
|
||||
return delete_func;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Kyty/Core/DbgAssert.h"
|
||||
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/GraphicsRender.h"
|
||||
#include "Emulator/Graphics/Utils.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
||||
|
@ -21,7 +22,7 @@ static void update_func(GraphicContext* ctx, const uint64_t* /*params*/, void* o
|
|||
EXIT_IF(obj == nullptr);
|
||||
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num != 1);
|
||||
|
||||
auto* vk_obj = reinterpret_cast<VulkanBuffer*>(obj);
|
||||
auto* vk_obj = reinterpret_cast<StorageVulkanBuffer*>(obj);
|
||||
|
||||
void* data = nullptr;
|
||||
// vkMapMemory(ctx->device, vk_obj->memory.memory, vk_obj->memory.offset, *size, 0, &data);
|
||||
|
@ -41,7 +42,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
EXIT_IF(mem == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
auto* vk_obj = new VulkanBuffer;
|
||||
auto* vk_obj = new StorageVulkanBuffer;
|
||||
|
||||
vk_obj->usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
vk_obj->memory.property = static_cast<uint32_t>(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
||||
|
@ -60,12 +61,17 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* /*mem*/)
|
|||
{
|
||||
KYTY_PROFILER_BLOCK("StorageBufferGpuObject::delete_func");
|
||||
|
||||
auto* vk_obj = reinterpret_cast<VulkanBuffer*>(obj);
|
||||
auto* vk_obj = reinterpret_cast<StorageVulkanBuffer*>(obj);
|
||||
|
||||
EXIT_IF(vk_obj == nullptr);
|
||||
EXIT_IF(vk_obj->buffer == nullptr);
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
EXIT_IF(vk_obj->cmd_buffer == nullptr);
|
||||
|
||||
// All submitted commands that refer to any element of pDescriptorSets must have completed execution
|
||||
vk_obj->cmd_buffer->CommandProcessorWait();
|
||||
|
||||
VulkanDeleteBuffer(ctx, vk_obj);
|
||||
|
||||
delete vk_obj;
|
||||
|
@ -79,7 +85,7 @@ static void write_back(GraphicContext* ctx, void* obj, const uint64_t* vaddr, co
|
|||
EXIT_IF(obj == nullptr);
|
||||
EXIT_IF(vaddr == nullptr || size == nullptr || vaddr_num != 1);
|
||||
|
||||
auto* vk_obj = reinterpret_cast<VulkanBuffer*>(obj);
|
||||
auto* vk_obj = reinterpret_cast<StorageVulkanBuffer*>(obj);
|
||||
|
||||
void* data = nullptr;
|
||||
|
||||
|
@ -123,6 +129,13 @@ GpuObject::update_func_t StorageBufferGpuObject::GetUpdateFunc() const
|
|||
return update_func;
|
||||
}
|
||||
|
||||
void StorageBufferSet(CommandBuffer* cmd_buffer, StorageVulkanBuffer* buffer)
|
||||
{
|
||||
// EXIT_IF(buffer->cmd_buffer != nullptr);
|
||||
|
||||
buffer->cmd_buffer = cmd_buffer;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
|
|
@ -133,7 +133,8 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
auto nfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[StorageTextureObject::PARAM_LEVELS];
|
||||
// auto base_level = params[StorageTextureObject::PARAM_LEVELS] >> 32u;
|
||||
auto levels = params[StorageTextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
auto pitch = params[StorageTextureObject::PARAM_PITCH];
|
||||
bool neo = Config::IsNeo();
|
||||
|
||||
|
@ -208,12 +209,15 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[StorageTextureObject::PARAM_LEVELS];
|
||||
auto swizzle = params[StorageTextureObject::PARAM_SWIZZLE];
|
||||
auto dfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[StorageTextureObject::PARAM_LEVELS] >> 32u;
|
||||
auto levels = params[StorageTextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
auto swizzle = params[StorageTextureObject::PARAM_SWIZZLE];
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(base_level != 0);
|
||||
|
||||
VkImageUsageFlags vk_usage = get_usage();
|
||||
|
||||
|
@ -230,10 +234,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
EXIT_NOT_IMPLEMENTED(width == 0);
|
||||
EXIT_NOT_IMPLEMENTED(height == 0);
|
||||
|
||||
if (levels > 1)
|
||||
{
|
||||
height += (height > 1 ? height / 2 : 1);
|
||||
}
|
||||
auto real_height = ((levels > 1) ? height + (height > 1 ? height / 2 : 1) : height);
|
||||
|
||||
auto* vk_obj = new StorageTextureVulkanImage;
|
||||
|
||||
|
@ -243,7 +244,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
image_info.flags = 0;
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_info.extent.width = width;
|
||||
image_info.extent.height = height;
|
||||
image_info.extent.height = real_height;
|
||||
image_info.extent.depth = 1;
|
||||
image_info.mipLevels = 1;
|
||||
image_info.arrayLayers = 1;
|
||||
|
|
|
@ -133,7 +133,7 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS];
|
||||
auto levels = params[TextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
auto pitch = params[TextureObject::PARAM_PITCH];
|
||||
bool neo = Config::IsNeo();
|
||||
|
||||
|
@ -196,7 +196,9 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
}
|
||||
}
|
||||
|
||||
static void update2_func(GraphicContext* ctx, const uint64_t* params, void* obj, const Vector<GpuMemoryObject>& objects)
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
static void update2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* params, void* obj, GpuMemoryScenario scenario,
|
||||
const Vector<GpuMemoryObject>& objects)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("TextureObject::update2_func");
|
||||
|
||||
|
@ -209,7 +211,7 @@ static void update2_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS];
|
||||
auto levels = params[TextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
|
||||
VkImageLayout vk_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
|
@ -220,9 +222,9 @@ static void update2_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
|
||||
Vector<ImageImageCopy> regions(levels);
|
||||
|
||||
if (objects.Size() == 1 && objects.At(0).type == GpuMemoryObjectType::StorageTexture)
|
||||
if (objects.Size() == 1 && objects.At(0).type == GpuMemoryObjectType::StorageTexture && scenario == GpuMemoryScenario::Common)
|
||||
{
|
||||
auto* src_obj = static_cast<TextureVulkanImage*>(objects.At(0).obj);
|
||||
auto* src_obj = static_cast<StorageTextureVulkanImage*>(objects.At(0).obj);
|
||||
|
||||
for (uint32_t i = 0; i < levels; i++)
|
||||
{
|
||||
|
@ -247,10 +249,8 @@ static void update2_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
mip_height /= 2;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else if (levels == objects.Size() && scenario == GpuMemoryScenario::Common)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(levels != objects.Size());
|
||||
|
||||
for (uint32_t i = 0; i < levels; i++)
|
||||
{
|
||||
const auto& object = objects.At(i);
|
||||
|
@ -278,9 +278,87 @@ static void update2_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
|||
mip_height /= 2;
|
||||
}
|
||||
}
|
||||
} else if (objects.Size() >= 2 && objects.At(0).type == GpuMemoryObjectType::StorageBuffer &&
|
||||
objects.At(1).type == GpuMemoryObjectType::StorageTexture && scenario == GpuMemoryScenario::GenerateMips)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < levels; i++)
|
||||
{
|
||||
VulkanImage* src_image = nullptr;
|
||||
bool storage = false;
|
||||
|
||||
for (const auto& o: objects)
|
||||
{
|
||||
if (o.type == GpuMemoryObjectType::StorageTexture)
|
||||
{
|
||||
auto* src_obj = static_cast<StorageTextureVulkanImage*>(o.obj);
|
||||
if (mip_width == src_obj->extent.width && mip_height == src_obj->extent.height)
|
||||
{
|
||||
src_image = src_obj;
|
||||
storage = true;
|
||||
break;
|
||||
}
|
||||
} else if (o.type == GpuMemoryObjectType::RenderTexture)
|
||||
{
|
||||
auto* src_obj = static_cast<RenderTextureVulkanImage*>(o.obj);
|
||||
if (mip_width == src_obj->extent.width && mip_height == src_obj->extent.height)
|
||||
{
|
||||
src_image = src_obj;
|
||||
storage = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(src_image == nullptr);
|
||||
|
||||
if (storage)
|
||||
{
|
||||
auto mipmap_offset = UtilCalcMipmapOffset(i, width, height);
|
||||
|
||||
regions[i].src_image = src_image;
|
||||
regions[i].src_level = 0;
|
||||
regions[i].dst_level = i;
|
||||
regions[i].width = mip_width;
|
||||
regions[i].height = mip_height;
|
||||
regions[i].src_x = mipmap_offset.first;
|
||||
regions[i].src_y = mipmap_offset.second;
|
||||
regions[i].dst_x = 0;
|
||||
regions[i].dst_y = 0;
|
||||
} else
|
||||
{
|
||||
regions[i].src_image = src_image;
|
||||
regions[i].src_level = 0;
|
||||
regions[i].dst_level = i;
|
||||
regions[i].width = mip_width;
|
||||
regions[i].height = mip_height;
|
||||
regions[i].src_x = 0;
|
||||
regions[i].src_y = 0;
|
||||
regions[i].dst_x = 0;
|
||||
regions[i].dst_y = 0;
|
||||
}
|
||||
|
||||
if (mip_width > 1)
|
||||
{
|
||||
mip_width /= 2;
|
||||
}
|
||||
if (mip_height > 1)
|
||||
{
|
||||
mip_height /= 2;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
UtilFillImage(ctx, regions, vk_obj, static_cast<uint64_t>(vk_layout));
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
UtilFillImage(ctx, regions, vk_obj, static_cast<uint64_t>(vk_layout));
|
||||
} else
|
||||
{
|
||||
UtilImageToImage(buffer, regions, vk_obj, static_cast<uint64_t>(vk_layout));
|
||||
}
|
||||
}
|
||||
|
||||
static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint64_t* vaddr, const uint64_t* size, int vaddr_num,
|
||||
|
@ -293,12 +371,13 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS];
|
||||
auto swizzle = params[TextureObject::PARAM_SWIZZLE];
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[TextureObject::PARAM_LEVELS] >> 32u;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
auto swizzle = params[TextureObject::PARAM_SWIZZLE];
|
||||
|
||||
VkImageUsageFlags vk_usage = get_usage();
|
||||
|
||||
|
@ -379,7 +458,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
create_info.components = components;
|
||||
create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
create_info.subresourceRange.baseArrayLayer = 0;
|
||||
create_info.subresourceRange.baseMipLevel = 0;
|
||||
create_info.subresourceRange.baseMipLevel = base_level;
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
|
||||
|
@ -390,7 +469,8 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
return vk_obj;
|
||||
}
|
||||
|
||||
static void* create2_func(GraphicContext* ctx, const uint64_t* params, const Vector<GpuMemoryObject>& objects, VulkanMemory* mem)
|
||||
static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint64_t* params, GpuMemoryScenario scenario,
|
||||
const Vector<GpuMemoryObject>& objects, VulkanMemory* mem)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("TextureObject::CreateFromObjects");
|
||||
|
||||
|
@ -399,12 +479,13 @@ static void* create2_func(GraphicContext* ctx, const uint64_t* params, const Vec
|
|||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS];
|
||||
auto swizzle = params[TextureObject::PARAM_SWIZZLE];
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[TextureObject::PARAM_LEVELS] >> 32u;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
auto swizzle = params[TextureObject::PARAM_SWIZZLE];
|
||||
|
||||
VkImageUsageFlags vk_usage = get_usage();
|
||||
|
||||
|
@ -473,7 +554,7 @@ static void* create2_func(GraphicContext* ctx, const uint64_t* params, const Vec
|
|||
|
||||
vk_obj->memory = *mem;
|
||||
|
||||
update2_func(ctx, params, vk_obj, objects);
|
||||
update2_func(ctx, buffer, params, vk_obj, scenario, objects);
|
||||
|
||||
VkImageViewCreateInfo create_info {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
|
@ -485,7 +566,7 @@ static void* create2_func(GraphicContext* ctx, const uint64_t* params, const Vec
|
|||
create_info.components = components;
|
||||
create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
create_info.subresourceRange.baseArrayLayer = 0;
|
||||
create_info.subresourceRange.baseMipLevel = 0;
|
||||
create_info.subresourceRange.baseMipLevel = base_level;
|
||||
create_info.subresourceRange.layerCount = 1;
|
||||
create_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
|
||||
|
|
|
@ -802,6 +802,7 @@ 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 0x1d: inst.type = ShaderInstructionType::VCmpxNeqF32; break;
|
||||
case 0x80: inst.type = ShaderInstructionType::VCmpFI32; break;
|
||||
case 0x81: inst.type = ShaderInstructionType::VCmpLtI32; break;
|
||||
case 0x82: inst.type = ShaderInstructionType::VCmpEqI32; break;
|
||||
|
@ -1096,6 +1097,7 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||
case 0x0d: inst.type = ShaderInstructionType::VCmpNeqF32; break;
|
||||
case 0x0e: inst.type = ShaderInstructionType::VCmpNltF32; break;
|
||||
case 0x0f: inst.type = ShaderInstructionType::VCmpTruF32; break;
|
||||
case 0x1d: inst.type = ShaderInstructionType::VCmpxNeqF32; break;
|
||||
case 0x80: inst.type = ShaderInstructionType::VCmpFI32; break;
|
||||
case 0x81: inst.type = ShaderInstructionType::VCmpLtI32; break;
|
||||
case 0x82: inst.type = ShaderInstructionType::VCmpEqI32; break;
|
||||
|
@ -1555,6 +1557,17 @@ KYTY_SHADER_PARSER(shader_parse_mimg)
|
|||
inst.dst.size = 4;
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
inst.type = ShaderInstructionType::ImageStore;
|
||||
inst.src[0].size = 3;
|
||||
inst.src[1].size = 8;
|
||||
inst.src_num = 2;
|
||||
if (dmask == 0xf)
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata4Vaddr3StDmaskF;
|
||||
inst.dst.size = 4;
|
||||
}
|
||||
break;
|
||||
case 0x09:
|
||||
inst.type = ShaderInstructionType::ImageStoreMip;
|
||||
inst.src[0].size = 4;
|
||||
|
@ -2046,6 +2059,8 @@ static ShaderUsageInfo GetUsageSlots(const uint32_t* code)
|
|||
|
||||
static void ShaderDetectBuffers(ShaderVertexInputInfo* info)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(info == nullptr);
|
||||
|
||||
info->buffers_num = 0;
|
||||
|
@ -2104,13 +2119,21 @@ static void ShaderDetectBuffers(ShaderVertexInputInfo* info)
|
|||
|
||||
static void ShaderParseFetch(ShaderVertexInputInfo* info, const uint32_t* fetch, const uint32_t* buffer)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(info == nullptr || fetch == nullptr || buffer == nullptr);
|
||||
|
||||
KYTY_PROFILER_BLOCK("ShaderParseFetch::parse_code");
|
||||
|
||||
ShaderCode code;
|
||||
code.SetType(ShaderType::Fetch);
|
||||
shader_parse(0, fetch, nullptr, &code);
|
||||
|
||||
printf("%s", code.DbgDump().C_Str());
|
||||
KYTY_PROFILER_END_BLOCK;
|
||||
|
||||
// printf("%s", code.DbgDump().C_Str());
|
||||
|
||||
KYTY_PROFILER_BLOCK("ShaderParseFetch::check_insts");
|
||||
|
||||
const auto& insts = code.GetInstructions();
|
||||
uint32_t size = insts.Size();
|
||||
|
@ -2178,6 +2201,8 @@ static void ShaderParseFetch(ShaderVertexInputInfo* info, const uint32_t* fetch,
|
|||
}
|
||||
}
|
||||
|
||||
KYTY_PROFILER_END_BLOCK;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(s_num != v_num);
|
||||
}
|
||||
|
||||
|
@ -2358,6 +2383,8 @@ void ShaderCalcBindingIndices(ShaderBindResources* bind)
|
|||
|
||||
void ShaderGetInputInfoVS(const VertexShaderInfo* regs, ShaderVertexInputInfo* info)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(info == nullptr || regs == nullptr);
|
||||
|
||||
info->export_count = static_cast<int>(1 + ((regs->vs_regs.m_spiVsOutConfig >> 1u) & 0x1Fu));
|
||||
|
@ -2379,6 +2406,8 @@ void ShaderGetInputInfoVS(const VertexShaderInfo* regs, ShaderVertexInputInfo* i
|
|||
bool vertex_buffer = false;
|
||||
int vertex_buffer_reg = 0;
|
||||
|
||||
KYTY_PROFILER_BLOCK("ShaderGetInputInfoVS::usages_cycle");
|
||||
|
||||
for (int i = 0; i < usages.slots_num; i++)
|
||||
{
|
||||
const auto& usage = usages.slots[i];
|
||||
|
@ -2405,6 +2434,10 @@ void ShaderGetInputInfoVS(const VertexShaderInfo* regs, ShaderVertexInputInfo* i
|
|||
}
|
||||
}
|
||||
|
||||
KYTY_PROFILER_END_BLOCK;
|
||||
|
||||
KYTY_PROFILER_BLOCK("ShaderGetInputInfoVS::parse_fetch");
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((fetch && !vertex_buffer) || (!fetch && vertex_buffer));
|
||||
|
||||
if (fetch && vertex_buffer)
|
||||
|
@ -2425,16 +2458,29 @@ void ShaderGetInputInfoVS(const VertexShaderInfo* regs, ShaderVertexInputInfo* i
|
|||
ShaderDetectBuffers(info);
|
||||
}
|
||||
|
||||
KYTY_PROFILER_END_BLOCK;
|
||||
|
||||
KYTY_PROFILER_BLOCK("ShaderGetInputInfoVS::calc_binding");
|
||||
|
||||
ShaderCalcBindingIndices(&info->bind);
|
||||
|
||||
KYTY_PROFILER_END_BLOCK;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void ShaderGetInputInfoPS(const PixelShaderInfo* regs, const ShaderVertexInputInfo* vs_info, ShaderPixelInputInfo* ps_info)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(vs_info == nullptr);
|
||||
EXIT_IF(ps_info == nullptr);
|
||||
EXIT_IF(regs == nullptr);
|
||||
|
||||
if (regs->ps_embedded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ps_info->input_num = regs->ps_regs.ps_in_control;
|
||||
ps_info->ps_pos_xy = (regs->ps_regs.ps_input_ena == 0x00000302 && regs->ps_regs.ps_input_addr == 0x00000302);
|
||||
ps_info->ps_pixel_kill_enable = regs->ps_regs.shader_kill_enable;
|
||||
|
@ -2515,6 +2561,7 @@ void ShaderGetInputInfoPS(const PixelShaderInfo* regs, const ShaderVertexInputIn
|
|||
ShaderCalcBindingIndices(&ps_info->bind);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void ShaderGetInputInfoCS(const ComputeShaderInfo* regs, ShaderComputeInputInfo* info)
|
||||
{
|
||||
EXIT_IF(info == nullptr);
|
||||
|
@ -2564,9 +2611,17 @@ void ShaderGetInputInfoCS(const ComputeShaderInfo* regs, ShaderComputeInputInfo*
|
|||
regs->cs_user_sgpr, extended_buffer);
|
||||
break;
|
||||
case 0x04:
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0);
|
||||
ShaderGetStorageBuffer(&info->bind.storage_buffers, usage.start_register, usage.slot, ShaderStorageUsage::ReadWrite,
|
||||
regs->cs_user_sgpr, extended_buffer);
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0 && usage.flags != 3);
|
||||
if (usage.flags == 0)
|
||||
{
|
||||
ShaderGetStorageBuffer(&info->bind.storage_buffers, usage.start_register, usage.slot, ShaderStorageUsage::ReadWrite,
|
||||
regs->cs_user_sgpr, extended_buffer);
|
||||
} else if (usage.flags == 3)
|
||||
{
|
||||
ShaderGetTextureBuffer(&info->bind.textures2D, usage.start_register, usage.slot, ShaderTextureUsage::ReadWrite,
|
||||
regs->cs_user_sgpr, extended_buffer);
|
||||
EXIT_NOT_IMPLEMENTED(info->bind.textures2D.textures[info->bind.textures2D.textures_num - 1].Type() != 9);
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0);
|
||||
|
@ -2730,6 +2785,8 @@ static void ShaderDbgDumpResources(const ShaderBindResources& bind)
|
|||
|
||||
void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo* info)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("ShaderDbgDumpInputInfo(Vs)");
|
||||
|
||||
printf("ShaderDbgDumpInputInfo()\n");
|
||||
|
||||
printf("\t fetch = %s\n", info->fetch ? "true" : "false");
|
||||
|
@ -2781,6 +2838,8 @@ void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo* info)
|
|||
|
||||
void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo* info)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("ShaderDbgDumpInputInfo(Ps)");
|
||||
|
||||
printf("ShaderDbgDumpInputInfo()\n");
|
||||
|
||||
printf("\t input_num = %u\n", info->input_num);
|
||||
|
@ -2967,8 +3026,8 @@ ShaderCode ShaderParseVS(const VertexShaderInfo* regs)
|
|||
|
||||
if (regs->vs_embedded)
|
||||
{
|
||||
code.SetEmbedded(true);
|
||||
code.SetEmbeddedId(regs->vs_embedded_id);
|
||||
code.SetVsEmbedded(true);
|
||||
code.SetVsEmbeddedId(regs->vs_embedded_id);
|
||||
} else
|
||||
{
|
||||
const auto* src = reinterpret_cast<const uint32_t*>(regs->vs_regs.GetGpuAddress());
|
||||
|
@ -3007,9 +3066,9 @@ Vector<uint32_t> ShaderRecompileVS(const ShaderCode& code, const ShaderVertexInp
|
|||
Vector<uint32_t> ret;
|
||||
ShaderLogHelper log("vs");
|
||||
|
||||
if (code.IsEmbedded())
|
||||
if (code.IsVsEmbedded())
|
||||
{
|
||||
source = SpirvGetEmbeddedVs(code.GetEmbeddedId());
|
||||
source = SpirvGetEmbeddedVs(code.GetVsEmbeddedId());
|
||||
} else
|
||||
{
|
||||
for (int i = 0; i < input_info->bind.storage_buffers.buffers_num; i++)
|
||||
|
@ -3039,32 +3098,39 @@ ShaderCode ShaderParsePS(const PixelShaderInfo* regs)
|
|||
{
|
||||
KYTY_PROFILER_FUNCTION(profiler::colors::Blue300);
|
||||
|
||||
const auto* src = reinterpret_cast<const uint32_t*>(regs->ps_regs.data_addr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(src == nullptr);
|
||||
|
||||
ps_print("ShaderParsePS()", regs->ps_regs);
|
||||
ps_check(regs->ps_regs);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(regs->ps_regs.user_sgpr > regs->ps_user_sgpr.count);
|
||||
|
||||
const auto* header = GetBinaryInfo(src);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(header == nullptr);
|
||||
|
||||
bi_print("ShaderParsePS():ShaderBinaryInfo", *header);
|
||||
|
||||
ShaderCode code;
|
||||
code.SetType(ShaderType::Pixel);
|
||||
|
||||
shader_parse(0, src, nullptr, &code);
|
||||
|
||||
if (g_debug_printfs != nullptr)
|
||||
if (regs->ps_embedded)
|
||||
{
|
||||
auto id = (static_cast<uint64_t>(header->hash0) << 32u) | header->crc32;
|
||||
if (auto index = g_debug_printfs->Find(id, [](auto cmd, auto id) { return cmd.id == id; }); g_debug_printfs->IndexValid(index))
|
||||
code.SetPsEmbedded(true);
|
||||
code.SetPsEmbeddedId(regs->ps_embedded_id);
|
||||
} else
|
||||
{
|
||||
const auto* src = reinterpret_cast<const uint32_t*>(regs->ps_regs.data_addr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(src == nullptr);
|
||||
|
||||
ps_print("ShaderParsePS()", regs->ps_regs);
|
||||
ps_check(regs->ps_regs);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(regs->ps_regs.user_sgpr > regs->ps_user_sgpr.count);
|
||||
|
||||
const auto* header = GetBinaryInfo(src);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(header == nullptr);
|
||||
|
||||
bi_print("ShaderParsePS():ShaderBinaryInfo", *header);
|
||||
|
||||
shader_parse(0, src, nullptr, &code);
|
||||
|
||||
if (g_debug_printfs != nullptr)
|
||||
{
|
||||
code.GetDebugPrintfs() = g_debug_printfs->At(index).cmds;
|
||||
auto id = (static_cast<uint64_t>(header->hash0) << 32u) | header->crc32;
|
||||
if (auto index = g_debug_printfs->Find(id, [](auto cmd, auto id) { return cmd.id == id; }); g_debug_printfs->IndexValid(index))
|
||||
{
|
||||
code.GetDebugPrintfs() = g_debug_printfs->At(index).cmds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3075,24 +3141,30 @@ Vector<uint32_t> ShaderRecompilePS(const ShaderCode& code, const ShaderPixelInpu
|
|||
{
|
||||
KYTY_PROFILER_FUNCTION(profiler::colors::Blue300);
|
||||
|
||||
ShaderLogHelper log("ps");
|
||||
|
||||
for (uint32_t i = 0; i < input_info->input_num; i++)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(input_info->interpolator_settings[i] != i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < input_info->bind.storage_buffers.buffers_num; i++)
|
||||
{
|
||||
const auto& r = input_info->bind.storage_buffers.buffers[i];
|
||||
EXIT_NOT_IMPLEMENTED(((r.Stride() * r.NumRecords()) & 0x3u) != 0);
|
||||
}
|
||||
|
||||
String source;
|
||||
Vector<uint32_t> ret;
|
||||
ShaderLogHelper log("ps");
|
||||
|
||||
log.DumpOriginalShader(code);
|
||||
if (code.IsPsEmbedded())
|
||||
{
|
||||
source = SpirvGetEmbeddedPs(code.GetPsEmbeddedId());
|
||||
} else
|
||||
{
|
||||
// for (uint32_t i = 0; i < input_info->input_num; i++)
|
||||
// {
|
||||
// EXIT_NOT_IMPLEMENTED(input_info->interpolator_settings[i] != i);
|
||||
// }
|
||||
|
||||
auto source = SpirvGenerateSource(code, nullptr, input_info, nullptr);
|
||||
for (int i = 0; i < input_info->bind.storage_buffers.buffers_num; i++)
|
||||
{
|
||||
const auto& r = input_info->bind.storage_buffers.buffers[i];
|
||||
EXIT_NOT_IMPLEMENTED(((r.Stride() * r.NumRecords()) & 0x3u) != 0);
|
||||
}
|
||||
|
||||
log.DumpOriginalShader(code);
|
||||
|
||||
source = SpirvGenerateSource(code, nullptr, input_info, nullptr);
|
||||
}
|
||||
|
||||
log.DumpRecompiledShader(source);
|
||||
|
||||
|
@ -3194,7 +3266,8 @@ static ShaderBindParameters ShaderUpdateBindInfo(const ShaderCode& code, const S
|
|||
break;
|
||||
}
|
||||
|
||||
if (inst.type == ShaderInstructionType::ImageStoreMip || inst.type == ShaderInstructionType::ImageLoad)
|
||||
if (inst.type == ShaderInstructionType::ImageStore || inst.type == ShaderInstructionType::ImageStoreMip ||
|
||||
inst.type == ShaderInstructionType::ImageLoad)
|
||||
{
|
||||
if (inst.src[1].register_id == s)
|
||||
{
|
||||
|
@ -3389,6 +3462,8 @@ static void ShaderGetBindIds(ShaderId* ret, const ShaderBindResources& bind)
|
|||
|
||||
ShaderId ShaderGetIdVS(const VertexShaderInfo* regs, const ShaderVertexInputInfo* input_info)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
ShaderId ret;
|
||||
|
||||
if (regs->vs_embedded)
|
||||
|
@ -3453,6 +3528,16 @@ ShaderId ShaderGetIdVS(const VertexShaderInfo* regs, const ShaderVertexInputInfo
|
|||
|
||||
ShaderId ShaderGetIdPS(const PixelShaderInfo* regs, const ShaderPixelInputInfo* input_info)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
ShaderId ret;
|
||||
|
||||
if (regs->ps_embedded)
|
||||
{
|
||||
ret.ids.Add(regs->ps_embedded_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const auto* src = reinterpret_cast<const uint32_t*>(regs->ps_regs.data_addr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(src == nullptr);
|
||||
|
@ -3461,7 +3546,6 @@ ShaderId ShaderGetIdPS(const PixelShaderInfo* regs, const ShaderPixelInputInfo*
|
|||
|
||||
EXIT_NOT_IMPLEMENTED(header == nullptr);
|
||||
|
||||
ShaderId ret;
|
||||
ret.ids.Expand(64);
|
||||
|
||||
ret.ids.Add(header->length);
|
||||
|
|
|
@ -2383,6 +2383,74 @@ KYTY_RECOMPILER_FUNC(Recompile_ImageLoad_Vdata4Vaddr3StDmaskF)
|
|||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageStore_Vdata4Vaddr3StDmaskF)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
const auto& bind_params = spirv->GetBindParams();
|
||||
|
||||
if (bind_info != nullptr && bind_params.textures2d_storage_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 dst_value3 = operand_variable_to_str(inst.dst, 3);
|
||||
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src1_value2 = operand_variable_to_str(inst.src[1], 2);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
// TODO() swizzle channels
|
||||
// TODO() convert SRGB -> LINEAR if SRGB format was replaced with UNORM
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t25_<index> = OpLoad %uint %<src1_value2>
|
||||
%t143_<index> = OpShiftRightLogical %uint %t25_<index> %uint_0
|
||||
%t145_<index> = OpBitwiseAnd %uint %t143_<index> %uint_0x00003fff
|
||||
%t146_<index> = OpIAdd %uint %t145_<index> %uint_1
|
||||
%t149_<index> = OpShiftRightLogical %uint %t25_<index> %uint_14
|
||||
%t150_<index> = OpBitwiseAnd %uint %t149_<index> %uint_0x00003fff
|
||||
%t151_<index> = OpIAdd %uint %t150_<index> %uint_1
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageL %textures2D_L %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageL %t26_<index>
|
||||
%t67_<index> = OpLoad %float %<src0_value0>
|
||||
%t69_<index> = OpBitcast %uint %t67_<index>
|
||||
%t70_<index> = OpLoad %float %<src0_value1>
|
||||
%t71_<index> = OpBitcast %uint %t70_<index>
|
||||
%t73_<index> = OpCompositeConstruct %v2uint %t69_<index> %t71_<index>
|
||||
%t84_<index> = OpLoad %float %<dst_value0>
|
||||
%t85_<index> = OpLoad %float %<dst_value1>
|
||||
%t86_<index> = OpLoad %float %<dst_value2>
|
||||
%t87_<index> = OpLoad %float %<dst_value3>
|
||||
%t88_<index> = OpCompositeConstruct %v4float %t84_<index> %t85_<index> %t86_<index> %t87_<index>
|
||||
OpImageWrite %t27_<index> %t73_<index> %t88_<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"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src1_value2>", src1_value2.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value)
|
||||
.ReplaceStr(U"<dst_value2>", dst_value2.value)
|
||||
.ReplaceStr(U"<dst_value3>", dst_value3.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageStoreMip_Vdata4Vaddr4StDmaskF)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
@ -3807,6 +3875,60 @@ KYTY_RECOMPILER_FUNC(Recompile_VCmpx_XXX_U32_SmaskVsrc0Vsrc1)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* XXX: Neq */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_VCmpx_XXX_F32_SmaskVsrc0Vsrc1)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
||||
String load0;
|
||||
String load1;
|
||||
|
||||
String index_str = String::FromPrintf("%u", index);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_variable(inst.dst));
|
||||
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Uint);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(operand_is_exec(inst.dst));
|
||||
|
||||
if (!operand_load_float(spirv, inst.src[0], U"t0_<index>", index_str, &load0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!operand_load_float(spirv, inst.src[1], U"t1_<index>", index_str, &load1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check EXEC
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
<load0>
|
||||
<load1>
|
||||
%t2_<index> = <param> %bool %t0_<index> %t1_<index>
|
||||
%t3_<index> = OpSelect %uint %t2_<index> %uint_1 %uint_0
|
||||
OpStore %<dst0> %t3_<index>
|
||||
OpStore %<dst1> %uint_0
|
||||
OpStore %exec_lo %t3_<index>
|
||||
OpStore %exec_hi %uint_0
|
||||
<execz>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<dst0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst1>", dst_value1.value)
|
||||
.ReplaceStr(U"<load0>", load0)
|
||||
.ReplaceStr(U"<load1>", load1)
|
||||
.ReplaceStr(U"<param>", param[0])
|
||||
.ReplaceStr(U"<execz>", EXECZ)
|
||||
.ReplaceStr(U"<index>", index_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_VCndmaskB32_VdstVsrc0Vsrc1Smask2)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
@ -3967,8 +4089,8 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2)
|
|||
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);
|
||||
|
||||
|
@ -4000,11 +4122,20 @@ KYTY_RECOMPILER_FUNC(Recompile_V_XXX_F32_VdstVsrc0Vsrc1Vsrc2)
|
|||
%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"<load1>", load1)
|
||||
|
@ -4690,6 +4821,7 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_ImageLoad_Vdata4Vaddr3StDmaskF, ShaderInstructionType::ImageLoad, ShaderInstructionFormat::Vdata4Vaddr3StDmaskF, {U""}},
|
||||
{Recompile_ImageSample_Vdata3Vaddr3StSsDmask7, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7, {U""}},
|
||||
{Recompile_ImageSample_Vdata4Vaddr3StSsDmaskF, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF, {U""}},
|
||||
{Recompile_ImageStore_Vdata4Vaddr3StDmaskF, ShaderInstructionType::ImageStore, ShaderInstructionFormat::Vdata4Vaddr3StDmaskF, {U""}},
|
||||
{Recompile_ImageStoreMip_Vdata4Vaddr4StDmaskF, ShaderInstructionType::ImageStoreMip, ShaderInstructionFormat::Vdata4Vaddr4StDmaskF, {U""}},
|
||||
|
||||
{Recompile_SBufferLoadDword_SdstSvSoffset, ShaderInstructionType::SBufferLoadDword, ShaderInstructionFormat::SdstSvSoffset, {U""}},
|
||||
|
@ -4701,7 +4833,7 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_SCbranchExecz_Label, ShaderInstructionType::SCbranchExecz, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchScc0_Label, ShaderInstructionType::SCbranchScc0, ShaderInstructionFormat::Label, {U""}},
|
||||
|
||||
{Recompile_SEndpgm_Empty, ShaderInstructionType::SEndpgm, ShaderInstructionFormat::Empty, {U""}},
|
||||
{Recompile_SEndpgm_Empty, ShaderInstructionType::SEndpgm, ShaderInstructionFormat::Empty, {U""}},
|
||||
|
||||
{Recompile_SLoadDwordx4_Sdst4SbaseSoffset, ShaderInstructionType::SLoadDwordx4, ShaderInstructionFormat::Sdst4SbaseSoffset, {U""}},
|
||||
{Recompile_SLoadDwordx8_Sdst8SbaseSoffset, ShaderInstructionType::SLoadDwordx8, ShaderInstructionFormat::Sdst8SbaseSoffset, {U""}},
|
||||
|
@ -4744,51 +4876,51 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_S_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SLshrB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %uint %t1_<index> %uint_31", U"%t_<index> = OpShiftRightLogical %uint %t0_<index> %ts_<index>"}, SccCheck::NonZero},
|
||||
{Recompile_S_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SAddI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpIAdd %int %t0_<index> %t1_<index>"}, SccCheck::Overflow},
|
||||
{Recompile_S_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SMulI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpIMul %int %t0_<index> %t1_<index>"}, SccCheck::None},
|
||||
{Recompile_S_XXX_U32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SAddcU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tscc_<index> = OpLoad %uint %scc", U"%ts_<index> = OpFunctionCall %v2uint %addc %t0_<index> %t1_<index> %tscc_<index>", U"%t_<index> = OpCompositeExtract %uint %ts_<index> 0", U"%carry_<index> = OpCompositeExtract %uint %ts_<index> 1"}, SccCheck::CarryOut},
|
||||
{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_S_XXX_U32_SVdstSVsrc0SVsrc1, ShaderInstructionType::SAddcU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%tscc_<index> = OpLoad %uint %scc", U"%ts_<index> = OpFunctionCall %v2uint %addc %t0_<index> %t1_<index> %tscc_<index>", U"%t_<index> = OpCompositeExtract %uint %ts_<index> 0", U"%carry_<index> = OpCompositeExtract %uint %ts_<index> 1"}, SccCheck::CarryOut},
|
||||
{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::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::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::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>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VLshrrevB32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %uint %t0_<index> %uint_31", U"%t_<index> = OpShiftRightLogical %uint %t1_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulHiU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %uint %mul_hi_uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulLoU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %uint %mul_lo_uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulHiU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %uint %mul_hi_uint %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulLoU32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %uint %mul_lo_uint %t0_<index> %t1_<index>"}},
|
||||
{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_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::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>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFMul %float %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VSubF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFSub %float %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VSubrevF32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFSub %float %t1_<index> %t0_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAshrI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %int %t1_<index> %int_31", U"%t_<index> = OpShiftRightArithmetic %int %t0_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAshrrevI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %int %t0_<index> %int_31", U"%t_<index> = OpShiftRightArithmetic %int %t1_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulLoI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %int %mul_lo_int %t0_<index> %t1_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAshrI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %int %t1_<index> %int_31", U"%t_<index> = OpShiftRightArithmetic %int %t0_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VAshrrevI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%ts_<index> = OpBitwiseAnd %int %t0_<index> %int_31", U"%t_<index> = OpShiftRightArithmetic %int %t1_<index> %ts_<index>"}},
|
||||
{Recompile_V_XXX_I32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMulLoI32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U"%t_<index> = OpFunctionCall %int %mul_lo_int %t0_<index> %t1_<index>"}},
|
||||
{Recompile_VCvtPkrtzF16F32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VCvtPkrtzF16F32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U""}},
|
||||
{Recompile_VMbcntHiU32B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMbcntHiU32B32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U""}},
|
||||
{Recompile_VMbcntLoU32B32_SVdstSVsrc0SVsrc1, ShaderInstructionType::VMbcntLoU32B32, ShaderInstructionFormat::SVdstSVsrc0SVsrc1, {U""}},
|
||||
|
||||
|
||||
{Recompile_SMovB32_SVdstSVsrc0, ShaderInstructionType::SMovB32, ShaderInstructionFormat::SVdstSVsrc0, {U""}},
|
||||
{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_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::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_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>"}},
|
||||
{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>"}},
|
||||
{Recompile_VCvtF32_XXX_SVdstSVsrc0, ShaderInstructionType::VCvtF32U32, ShaderInstructionFormat::SVdstSVsrc0, {U"%t_<index> = OpConvertUToF %float %t0_<index>"}},
|
||||
{Recompile_VCvtF32_XXX_SVdstSVsrc0, ShaderInstructionType::VCvtF32Ubyte0, ShaderInstructionFormat::SVdstSVsrc0, {U"%tb_<index> = OpBitFieldUExtract %uint %t0_<index> %uint_0 %uint_8", U"%t_<index> = OpConvertUToF %float %tb_<index>"}},
|
||||
{Recompile_VCvtF32_XXX_SVdstSVsrc0, ShaderInstructionType::VCvtF32Ubyte1, ShaderInstructionFormat::SVdstSVsrc0, {U"%tb_<index> = OpBitFieldUExtract %uint %t0_<index> %uint_8 %uint_8", U"%t_<index> = OpConvertUToF %float %tb_<index>"}},
|
||||
|
@ -4811,54 +4943,55 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_V_XXX_U32_VdstSdst2Vsrc0Vsrc1, ShaderInstructionType::VSubrevI32, ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1, {U"%t_<index> = OpISubBorrow %ResTypeU %t1_<index> %t0_<index>"}},
|
||||
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpEqF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLeF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdLessThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLgF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdNotEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdLessThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLgF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdNotEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFOrdLessThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNeqF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordNotEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNgeF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordLessThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNgtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordLessThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNleF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNlgF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNltF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpOF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFunctionCall %bool %ordered %t0_<index> %t1_<index> ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpTruF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_0 ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpUF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFunctionCall %bool %unordered %t0_<index> %t1_<index> ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNgeF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordLessThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNgtF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordLessThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNleF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNlgF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNltF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFUnordGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpOF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFunctionCall %bool %ordered %t0_<index> %t1_<index> ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpTruF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_0 ; "}},
|
||||
{Recompile_VCmp_XXX_F32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpUF32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpFunctionCall %bool %unordered %t0_<index> %t1_<index> ; "}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpEqI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpEqU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGtI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLeI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSLessThanEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLtI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSLessThan"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLeI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSLessThanEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLtI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpSLessThan"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNeI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpINotEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpNeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpINotEqual"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpTI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_0 ; "}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGtU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_I32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpTI32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_0 ; "}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpFU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpIEqual %bool %uint_0 %uint_1 ; "}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThanEqual"}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpGtU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThan"}},
|
||||
{Recompile_VCmp_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpLeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpULessThanEqual"}},
|
||||
{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_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_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"}},
|
||||
{Recompile_VCmpx_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxGtU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThan"}},
|
||||
{Recompile_VCmpx_XXX_U32_SmaskVsrc0Vsrc1, ShaderInstructionType::VCmpxGeU32, ShaderInstructionFormat::SmaskVsrc0Vsrc1, {U"OpUGreaterThanEqual"}},
|
||||
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpEqI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpIEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGeI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSGreaterThanEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGtI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSGreaterThan"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLgI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpINotEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLtI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSLessThan"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLeI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSLessThanEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpEqI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpIEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGeI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSGreaterThanEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGtI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSGreaterThan"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLgI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpINotEqual"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLtI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSLessThan"}},
|
||||
{Recompile_SCmp_XXX_I32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLeI32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpSLessThanEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpEqU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpIEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGeU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpUGreaterThanEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGtU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpUGreaterThan"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLeU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpULessThanEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLtU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpULessThan"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLgU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpINotEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGeU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpUGreaterThanEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpGtU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpUGreaterThan"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLeU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpULessThanEqual"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLtU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpULessThan"}},
|
||||
{Recompile_SCmp_XXX_U32_Ssrc0Ssrc1, ShaderInstructionType::SCmpLgU32, ShaderInstructionFormat::Ssrc0Ssrc1, {U"OpINotEqual"}},
|
||||
|
||||
{Recompile_VCndmaskB32_VdstVsrc0Vsrc1Smask2, ShaderInstructionType::VCndmaskB32, ShaderInstructionFormat::VdstVsrc0Vsrc1Smask2, {U""}},
|
||||
|
||||
|
@ -5265,7 +5398,7 @@ void Spirv::WriteAnnotations()
|
|||
{
|
||||
for (uint32_t i = 0; i < m_ps_input_info->input_num; i++)
|
||||
{
|
||||
vars.Add(String::FromPrintf("OpDecorate %%attr%d Location %d", i, i));
|
||||
vars.Add(String::FromPrintf("OpDecorate %%attr%d Location %d", i, m_ps_input_info->interpolator_settings[i]));
|
||||
}
|
||||
if (m_ps_input_info->ps_pos_xy)
|
||||
{
|
||||
|
@ -6202,6 +6335,15 @@ String SpirvGetEmbeddedVs(uint32_t id)
|
|||
return EMBEDDED_SHADER_VS_0;
|
||||
}
|
||||
|
||||
String SpirvGetEmbeddedPs(uint32_t id)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(id != 0);
|
||||
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
|
||||
return U"";
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
|
|
@ -614,6 +614,8 @@ void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, u
|
|||
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, uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
struct Padded
|
||||
{
|
||||
uint32_t width;
|
||||
|
@ -661,6 +663,11 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
|
|||
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
{ 10, 0, 512, 512, 10, 13, true, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
|
||||
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 512, 768, kTileModeThin_1dThin
|
||||
{ 10, 0, 512, 768, 10, 13, false, {1572864, 1048576, 131072, 32768, 8192, 2048, 512, 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, 10, 13, true, {1572864, 1048576, 131072, 32768, 8192, 2048, 512, 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, kTileModeThin_2dThin
|
||||
{ 10, 0, 256, 256, 9, 14, false, {262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
|
||||
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
|
||||
|
|
|
@ -846,7 +846,7 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* con
|
|||
ctx->buffers[i + start_index].buffer_size = buffer_size;
|
||||
ctx->buffers[i + start_index].buffer_pitch = buffer_pitch;
|
||||
ctx->buffers[i + start_index].buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(Graphics::GpuMemoryCreateObject(
|
||||
g_video_out_context->GetGraphicCtx(), reinterpret_cast<uint64_t>(addresses[i]), buffer_size, vulkan_buffer_info));
|
||||
g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast<uint64_t>(addresses[i]), buffer_size, vulkan_buffer_info));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(ctx->buffers[i + start_index].buffer_vulkan == nullptr);
|
||||
|
||||
|
|
|
@ -229,6 +229,8 @@ struct WindowContext
|
|||
SurfaceCapabilities* surface_capabilities = nullptr;
|
||||
GameApi* game = nullptr;
|
||||
|
||||
char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {0};
|
||||
|
||||
Core::Mutex mutex;
|
||||
bool graphic_initialized = false;
|
||||
Core::CondVar graphic_initialized_condvar;
|
||||
|
@ -1376,57 +1378,57 @@ static VkPhysicalDevice VulkanFindPhysicalDevice(VkInstance instance, VkSurfaceK
|
|||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_R8G8B8A8_SRGB, false, VK_FORMAT_FEATURE_BLIT_SRC_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB cannot be used as transfer source");
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB cannot be used as transfer source\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_D32_SFLOAT, true, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_D32_SFLOAT cannot be used as depth buffer");
|
||||
printf("Format VK_FORMAT_D32_SFLOAT cannot be used as depth buffer\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_D32_SFLOAT_S8_UINT, true, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_D32_SFLOAT_S8_UINT cannot be used as depth buffer");
|
||||
printf("Format VK_FORMAT_D32_SFLOAT_S8_UINT cannot be used as depth buffer\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_D16_UNORM, true, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_D16_UNORM cannot be used as depth buffer");
|
||||
printf("Format VK_FORMAT_D16_UNORM cannot be used as depth buffer\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_D24_UNORM_S8_UINT, true, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_D24_UNORM_S8_UINT cannot be used as depth buffer");
|
||||
printf("Format VK_FORMAT_D24_UNORM_S8_UINT cannot be used as depth buffer\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device &&
|
||||
!CheckFormat(device, VK_FORMAT_BC3_SRGB_BLOCK, true, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_BC3_SRGB_BLOCK cannot be used as texture");
|
||||
printf("Format VK_FORMAT_BC3_SRGB_BLOCK cannot be used as texture\n");
|
||||
skip_device = true;
|
||||
}
|
||||
|
||||
if (!skip_device &&
|
||||
!CheckFormat(device, VK_FORMAT_R8G8B8A8_SRGB, true, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB cannot be used as texture");
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB 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))
|
||||
{
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB cannot be used as texture");
|
||||
printf("Format VK_FORMAT_R8G8B8A8_SRGB cannot be used as texture\n");
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_R8G8B8A8_UNORM, true,
|
||||
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_R8G8B8A8_UNORM cannot be used as texture");
|
||||
printf("Format VK_FORMAT_R8G8B8A8_UNORM cannot be used as texture\n");
|
||||
skip_device = true;
|
||||
}
|
||||
}
|
||||
|
@ -1434,12 +1436,12 @@ static VkPhysicalDevice VulkanFindPhysicalDevice(VkInstance instance, VkSurfaceK
|
|||
if (!skip_device &&
|
||||
!CheckFormat(device, VK_FORMAT_B8G8R8A8_SRGB, true, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_B8G8R8A8_SRGB cannot be used as texture");
|
||||
printf("Format VK_FORMAT_B8G8R8A8_SRGB cannot be used as texture\n");
|
||||
|
||||
if (!skip_device && !CheckFormat(device, VK_FORMAT_B8G8R8A8_UNORM, true,
|
||||
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
{
|
||||
printf("Format VK_FORMAT_B8G8R8A8_UNORM cannot be used as texture");
|
||||
printf("Format VK_FORMAT_B8G8R8A8_UNORM cannot be used as texture\n");
|
||||
skip_device = true;
|
||||
}
|
||||
}
|
||||
|
@ -1982,6 +1984,13 @@ static void VulkanCreate(WindowContext* ctx)
|
|||
EXIT("Could not find suitable device");
|
||||
}
|
||||
|
||||
VkPhysicalDeviceProperties device_properties {};
|
||||
vkGetPhysicalDeviceProperties(ctx->graphic_ctx.physical_device, &device_properties);
|
||||
|
||||
printf("Select device: %s\n", device_properties.deviceName);
|
||||
|
||||
memcpy(ctx->device_name, device_properties.deviceName, sizeof(ctx->device_name));
|
||||
|
||||
ctx->graphic_ctx.device =
|
||||
VulkanCreateDevice(ctx->graphic_ctx.physical_device, ctx->surface, &r, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT,
|
||||
GraphicContext::QUEUES_NUM, &ctx->graphic_ctx.queue_family_index, device_extensions);
|
||||
|
@ -2074,7 +2083,8 @@ void WindowShowFps()
|
|||
EXIT_IF(g_window_ctx == nullptr);
|
||||
EXIT_IF(g_window_ctx->game == nullptr);
|
||||
|
||||
auto fps = String::FromPrintf("frame: %d, fps: %f", g_window_ctx->game->m_frame_num, g_window_ctx->game->m_current_fps);
|
||||
auto fps = String::FromPrintf("[%s], frame: %d, fps: %f", g_window_ctx->device_name, g_window_ctx->game->m_frame_num,
|
||||
g_window_ctx->game->m_current_fps);
|
||||
|
||||
SDL_SetWindowTitle(g_window_ctx->window, fps.C_Str());
|
||||
}
|
||||
|
|
|
@ -456,7 +456,7 @@ int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len)
|
|||
if (gpu_mode != Graphics::GpuMemoryMode::NoAccess)
|
||||
{
|
||||
Graphics::GraphicsRunWait();
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, len);
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, len, true);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -575,7 +575,7 @@ int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len)
|
|||
if (gpu_mode != Graphics::GpuMemoryMode::NoAccess)
|
||||
{
|
||||
Graphics::GraphicsRunWait();
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, size);
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, size, true);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Kyty/Sys/SysDbg.h"
|
||||
|
||||
#include "Emulator/Elf.h"
|
||||
#include "Emulator/Graphics/Objects/GpuMemory.h"
|
||||
#include "Emulator/Jit.h"
|
||||
#include "Emulator/Kernel/Pthread.h"
|
||||
#include "Emulator/Profiler.h"
|
||||
|
@ -152,10 +153,18 @@ static VirtualMemory::Mode get_mode(Elf64_Word flags)
|
|||
}
|
||||
}
|
||||
|
||||
static void dbg_exception_handler(const VirtualMemory::ExceptionHandler::ExceptionInfo* info)
|
||||
static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::ExceptionInfo* info)
|
||||
{
|
||||
printf("kyty_exception_handler: %016" PRIx64 "\n", info->exception_address);
|
||||
|
||||
if (info->type == VirtualMemory::ExceptionHandler::ExceptionType::AccessViolation)
|
||||
{
|
||||
if (info->access_violation_type == VirtualMemory::ExceptionHandler::AccessViolationType::Write &&
|
||||
Libs::Graphics::GpuMemoryCheckAccessViolation(info->access_violation_vaddr, sizeof(uint64_t)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)" : ""));
|
||||
}
|
||||
|
@ -1041,12 +1050,14 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
|||
if (is_shared)
|
||||
{
|
||||
program->exception_handler->Install(program->base_vaddr, program->base_vaddr + program->base_size_aligned,
|
||||
program->base_size_aligned + exception_handler_size + tls_handler_size, dbg_exception_handler);
|
||||
program->base_size_aligned + exception_handler_size + tls_handler_size, kyty_exception_handler);
|
||||
} else
|
||||
{
|
||||
program->exception_handler->Install(0, program->base_vaddr + program->base_size_aligned,
|
||||
program->base_vaddr + program->base_size_aligned + exception_handler_size + tls_handler_size,
|
||||
dbg_exception_handler);
|
||||
kyty_exception_handler);
|
||||
|
||||
VirtualMemory::ExceptionHandler::InstallVectored(kyty_exception_handler);
|
||||
}
|
||||
|
||||
// program->elf->SetBaseVAddr(program->base_vaddr);
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
{
|
||||
ExceptionHandler::ExceptionInfo info {};
|
||||
|
||||
info.exception_address = reinterpret_cast<uint64_t>(exception_record->ExceptionAddress);
|
||||
|
||||
if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
info.type = ExceptionHandler::ExceptionType::AccessViolation;
|
||||
|
@ -140,8 +142,12 @@ public:
|
|||
PRUNTIME_FUNCTION function_table = nullptr;
|
||||
|
||||
ExceptionHandler::handler_func_t func = nullptr;
|
||||
|
||||
static ExceptionHandler::handler_func_t g_vec_func;
|
||||
};
|
||||
|
||||
ExceptionHandler::handler_func_t ExceptionHandlerPrivate::g_vec_func = nullptr;
|
||||
|
||||
ExceptionHandler::ExceptionHandler(): m_p(new ExceptionHandlerPrivate) {}
|
||||
|
||||
ExceptionHandler::~ExceptionHandler()
|
||||
|
@ -178,6 +184,49 @@ bool ExceptionHandler::Install(uint64_t base_address, uint64_t handler_addr, uin
|
|||
return false;
|
||||
}
|
||||
|
||||
static LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS exception)
|
||||
{
|
||||
PEXCEPTION_RECORD exception_record = exception->ExceptionRecord;
|
||||
|
||||
ExceptionHandler::ExceptionInfo info {};
|
||||
|
||||
info.exception_address = reinterpret_cast<uint64_t>(exception_record->ExceptionAddress);
|
||||
|
||||
if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
info.type = ExceptionHandler::ExceptionType::AccessViolation;
|
||||
switch (exception_record->ExceptionInformation[0])
|
||||
{
|
||||
case 0: info.access_violation_type = ExceptionHandler::AccessViolationType::Read; break;
|
||||
case 1: info.access_violation_type = ExceptionHandler::AccessViolationType::Write; break;
|
||||
case 8: info.access_violation_type = ExceptionHandler::AccessViolationType::Execute; break;
|
||||
default: info.access_violation_type = ExceptionHandler::AccessViolationType::Unknown; break;
|
||||
}
|
||||
info.access_violation_vaddr = exception_record->ExceptionInformation[1];
|
||||
}
|
||||
|
||||
ExceptionHandlerPrivate::g_vec_func(&info);
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
bool ExceptionHandler::InstallVectored(handler_func_t func)
|
||||
{
|
||||
if (ExceptionHandlerPrivate::g_vec_func == nullptr)
|
||||
{
|
||||
ExceptionHandlerPrivate::g_vec_func = func;
|
||||
|
||||
if (AddVectoredExceptionHandler(1, ExceptionFilter) == nullptr)
|
||||
{
|
||||
printf("AddVectoredExceptionHandler() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExceptionHandler::Uninstall()
|
||||
{
|
||||
if (m_p->function_table != nullptr)
|
||||
|
@ -291,6 +340,8 @@ bool Free(uint64_t address)
|
|||
|
||||
bool Protect(uint64_t address, uint64_t size, Mode mode, Mode* old_mode)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
DWORD old_protect = 0;
|
||||
if (VirtualProtect(reinterpret_cast<LPVOID>(static_cast<uintptr_t>(address)), size, get_protection_flag(mode), &old_protect) == 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue