mirror of https://github.com/InoriRus/Kyty.git
fix some issues
This commit is contained in:
parent
f1f4302f99
commit
1aa7cf72ce
|
@ -1,4 +1,4 @@
|
|||
version: 0.1.6.build-{build}
|
||||
version: 0.1.7.build-{build}
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
matrix:
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
doc/** filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
*.inc linguist-language=C++
|
||||
|
|
|
@ -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.1.6)
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.7)
|
||||
|
||||
include(src_script.cmake)
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Kyty::Libs::Graphics {
|
|||
enum class RenderTextureFormat : uint64_t
|
||||
{
|
||||
Unknown,
|
||||
R8Unorm,
|
||||
R8G8B8A8Unorm,
|
||||
R8G8B8A8Srgb,
|
||||
B8G8R8A8Unorm,
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Graphics/Shader.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
@ -57,6 +57,7 @@ enum class ShaderInstructionType
|
|||
SAndn2B64,
|
||||
SAndSaveexecB64,
|
||||
SBfmB32,
|
||||
SBranch,
|
||||
SBufferLoadDword,
|
||||
SBufferLoadDwordx16,
|
||||
SBufferLoadDwordx2,
|
||||
|
@ -66,6 +67,7 @@ enum class ShaderInstructionType
|
|||
SCbranchScc0,
|
||||
SCbranchScc1,
|
||||
SCbranchVccz,
|
||||
SCbranchVccnz,
|
||||
SCmpEqI32,
|
||||
SCmpEqU32,
|
||||
SCmpGeI32,
|
||||
|
@ -260,6 +262,7 @@ enum FormatByte : uint64_t
|
|||
Dmask8, // dmask:0x8
|
||||
Dmask3, // dmask:0x3
|
||||
Dmask5, // dmask:0x5
|
||||
Dmask9, // dmask:0x9
|
||||
Gds, // gds
|
||||
};
|
||||
|
||||
|
@ -308,6 +311,7 @@ enum Format : uint64_t
|
|||
Vdata1VaddrSvSoffsIdxenFloat1 = FormatDefine({D, S0, S1A4, S2, Idxen, Float1}),
|
||||
Vdata2Vaddr3StSsDmask3 = FormatDefine({DA2, S0A3, S1A8, S2A4, Dmask3}),
|
||||
Vdata2Vaddr3StSsDmask5 = FormatDefine({DA2, S0A3, S1A8, S2A4, Dmask5}),
|
||||
Vdata2Vaddr3StSsDmask9 = FormatDefine({DA2, S0A3, S1A8, S2A4, Dmask9}),
|
||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata3Vaddr4StSsDmask7 = FormatDefine({DA3, S0A4, S1A8, S2A4, Dmask7}),
|
||||
|
@ -418,6 +422,14 @@ struct ShaderDebugPrintf
|
|||
Vector<ShaderOperand> args;
|
||||
};
|
||||
|
||||
struct ShaderControlFlowBlock
|
||||
{
|
||||
uint32_t pc = 0;
|
||||
bool is_discard = false;
|
||||
bool is_valid = false;
|
||||
ShaderInstruction last;
|
||||
};
|
||||
|
||||
class ShaderCode
|
||||
{
|
||||
public:
|
||||
|
@ -455,9 +467,11 @@ public:
|
|||
[[nodiscard]] uint32_t GetPsEmbeddedId() const { return m_ps_embedded_id; }
|
||||
void SetPsEmbeddedId(uint32_t embedded_id) { m_ps_embedded_id = embedded_id; }
|
||||
|
||||
[[nodiscard]] bool IsDiscardBlock(uint32_t pc) const;
|
||||
[[nodiscard]] bool IsDiscardInstruction(uint32_t index) const;
|
||||
[[nodiscard]] Vector<ShaderInstruction> GetDiscardBlock(uint32_t pc) const;
|
||||
//[[nodiscard]] bool IsDiscardBlock(uint32_t pc) const;
|
||||
//[[nodiscard]] bool IsDiscardInstruction(uint32_t index) const;
|
||||
//[[nodiscard]] Vector<ShaderInstruction> GetDiscardBlock(uint32_t pc) const;
|
||||
[[nodiscard]] ShaderControlFlowBlock ReadBlock(uint32_t pc) const;
|
||||
[[nodiscard]] Vector<ShaderInstruction> ReadIntructions(const ShaderControlFlowBlock& block) const;
|
||||
|
||||
[[nodiscard]] uint32_t GetCrc32() const { return m_crc32; }
|
||||
void SetCrc32(uint32_t c) { this->m_crc32 = c; }
|
||||
|
|
|
@ -1128,10 +1128,13 @@ static void playback_simulate(void* arg)
|
|||
|
||||
EXIT_IF(play_data == nullptr);
|
||||
|
||||
if (play_data != nullptr)
|
||||
{
|
||||
// TODO(): Audio output is not yet implemented, so simulate audio delay
|
||||
Core::Thread::SleepMicro(port->data_delay);
|
||||
play_data->state = Audio3dData::State::Empty;
|
||||
}
|
||||
}
|
||||
|
||||
port->playback_finished = true;
|
||||
}
|
||||
|
|
|
@ -476,46 +476,50 @@ static void uc_print(const char* func, const HW::UserConfig& uc)
|
|||
// EXIT_NOT_IMPLEMENTED(uc.GetPrimType() != 4);
|
||||
//}
|
||||
|
||||
static void rt_print(const char* func, const HW::RenderTarget& rt)
|
||||
static Core::StringList rt_print(const char* func, const HW::RenderTarget& rt)
|
||||
{
|
||||
printf("%s\n", func);
|
||||
Core::StringList dst;
|
||||
|
||||
printf("\t base.addr = 0x%016" PRIx64 "\n", rt.base.addr);
|
||||
printf("\t pitch.pitch_div8_minus1 = 0x%08" PRIx32 "\n", rt.pitch.pitch_div8_minus1);
|
||||
printf("\t pitch.fmask_pitch_div8_minus1 = 0x%08" PRIx32 "\n", rt.pitch.fmask_pitch_div8_minus1);
|
||||
printf("\t slice.slice_div64_minus1 = 0x%08" PRIx32 "\n", rt.slice.slice_div64_minus1);
|
||||
printf("\t view.base_array_slice_index = 0x%08" PRIx32 "\n", rt.view.base_array_slice_index);
|
||||
printf("\t view.last_array_slice_index = 0x%08" PRIx32 "\n", rt.view.last_array_slice_index);
|
||||
printf("\t info.fmask_compression_enable = %s\n", rt.info.fmask_compression_enable ? "true" : "false");
|
||||
printf("\t info.fmask_compression_mode = 0x%08" PRIx32 "\n", rt.info.fmask_compression_mode);
|
||||
printf("\t info.cmask_fast_clear_enable = %s\n", rt.info.cmask_fast_clear_enable ? "true" : "false");
|
||||
printf("\t info.dcc_compression_enable = %s\n", rt.info.dcc_compression_enable ? "true" : "false");
|
||||
printf("\t info.neo_mode = %s\n", rt.info.neo_mode ? "true" : "false");
|
||||
printf("\t info.cmask_tile_mode = 0x%08" PRIx32 "\n", rt.info.cmask_tile_mode);
|
||||
printf("\t info.cmask_tile_mode_neo = 0x%08" PRIx32 "\n", rt.info.cmask_tile_mode_neo);
|
||||
printf("\t info.format = 0x%08" PRIx32 "\n", rt.info.format);
|
||||
printf("\t info.channel_type = 0x%08" PRIx32 "\n", rt.info.channel_type);
|
||||
printf("\t info.channel_order = 0x%08" PRIx32 "\n", rt.info.channel_order);
|
||||
printf("\t attrib.force_dest_alpha_to_one = %s\n", rt.attrib.force_dest_alpha_to_one ? "true" : "false");
|
||||
printf("\t attrib.tile_mode = 0x%08" PRIx32 "\n", rt.attrib.tile_mode);
|
||||
printf("\t attrib.fmask_tile_mode = 0x%08" PRIx32 "\n", rt.attrib.fmask_tile_mode);
|
||||
printf("\t attrib.num_samples = 0x%08" PRIx32 "\n", rt.attrib.num_samples);
|
||||
printf("\t attrib.num_fragments = 0x%08" PRIx32 "\n", rt.attrib.num_fragments);
|
||||
printf("\t dcc.max_uncompressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.max_uncompressed_block_size);
|
||||
printf("\t dcc.max_compressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.max_compressed_block_size);
|
||||
printf("\t dcc.min_compressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.min_compressed_block_size);
|
||||
printf("\t dcc.color_transform = 0x%08" PRIx32 "\n", rt.dcc.color_transform);
|
||||
printf("\t dcc.enable_overwrite_combiner = %s\n", rt.dcc.enable_overwrite_combiner ? "true" : "false");
|
||||
printf("\t dcc.force_independent_blocks = %s\n", rt.dcc.force_independent_blocks ? "true" : "false");
|
||||
printf("\t cmask.addr = 0x%016" PRIx64 "\n", rt.cmask.addr);
|
||||
printf("\t cmask_slice.slice_minus1 = 0x%08" PRIx32 "\n", rt.cmask_slice.slice_minus1);
|
||||
printf("\t fmask.addr = 0x%016" PRIx64 "\n", rt.fmask.addr);
|
||||
printf("\t fmask_slice.slice_minus1 = 0x%08" PRIx32 "\n", rt.fmask_slice.slice_minus1);
|
||||
printf("\t clear_word0.word0 = 0x%08" PRIx32 "\n", rt.clear_word0.word0);
|
||||
printf("\t clear_word1.word1 = 0x%08" PRIx32 "\n", rt.clear_word1.word1);
|
||||
printf("\t dcc_addr.addr = 0x%016" PRIx64 "\n", rt.dcc_addr.addr);
|
||||
printf("\t size.width = 0x%08" PRIx32 "\n", rt.size.width);
|
||||
printf("\t size.height = 0x%08" PRIx32 "\n", rt.size.height);
|
||||
dst.Add(String::FromPrintf("%s\n", func));
|
||||
|
||||
dst.Add(String::FromPrintf("\t base.addr = 0x%016" PRIx64 "\n", rt.base.addr));
|
||||
dst.Add(String::FromPrintf("\t pitch.pitch_div8_minus1 = 0x%08" PRIx32 "\n", rt.pitch.pitch_div8_minus1));
|
||||
dst.Add(String::FromPrintf("\t pitch.fmask_pitch_div8_minus1 = 0x%08" PRIx32 "\n", rt.pitch.fmask_pitch_div8_minus1));
|
||||
dst.Add(String::FromPrintf("\t slice.slice_div64_minus1 = 0x%08" PRIx32 "\n", rt.slice.slice_div64_minus1));
|
||||
dst.Add(String::FromPrintf("\t view.base_array_slice_index = 0x%08" PRIx32 "\n", rt.view.base_array_slice_index));
|
||||
dst.Add(String::FromPrintf("\t view.last_array_slice_index = 0x%08" PRIx32 "\n", rt.view.last_array_slice_index));
|
||||
dst.Add(String::FromPrintf("\t info.fmask_compression_enable = %s\n", rt.info.fmask_compression_enable ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t info.fmask_compression_mode = 0x%08" PRIx32 "\n", rt.info.fmask_compression_mode));
|
||||
dst.Add(String::FromPrintf("\t info.cmask_fast_clear_enable = %s\n", rt.info.cmask_fast_clear_enable ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t info.dcc_compression_enable = %s\n", rt.info.dcc_compression_enable ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t info.neo_mode = %s\n", rt.info.neo_mode ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t info.cmask_tile_mode = 0x%08" PRIx32 "\n", rt.info.cmask_tile_mode));
|
||||
dst.Add(String::FromPrintf("\t info.cmask_tile_mode_neo = 0x%08" PRIx32 "\n", rt.info.cmask_tile_mode_neo));
|
||||
dst.Add(String::FromPrintf("\t info.format = 0x%08" PRIx32 "\n", rt.info.format));
|
||||
dst.Add(String::FromPrintf("\t info.channel_type = 0x%08" PRIx32 "\n", rt.info.channel_type));
|
||||
dst.Add(String::FromPrintf("\t info.channel_order = 0x%08" PRIx32 "\n", rt.info.channel_order));
|
||||
dst.Add(String::FromPrintf("\t attrib.force_dest_alpha_to_one = %s\n", rt.attrib.force_dest_alpha_to_one ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t attrib.tile_mode = 0x%08" PRIx32 "\n", rt.attrib.tile_mode));
|
||||
dst.Add(String::FromPrintf("\t attrib.fmask_tile_mode = 0x%08" PRIx32 "\n", rt.attrib.fmask_tile_mode));
|
||||
dst.Add(String::FromPrintf("\t attrib.num_samples = 0x%08" PRIx32 "\n", rt.attrib.num_samples));
|
||||
dst.Add(String::FromPrintf("\t attrib.num_fragments = 0x%08" PRIx32 "\n", rt.attrib.num_fragments));
|
||||
dst.Add(String::FromPrintf("\t dcc.max_uncompressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.max_uncompressed_block_size));
|
||||
dst.Add(String::FromPrintf("\t dcc.max_compressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.max_compressed_block_size));
|
||||
dst.Add(String::FromPrintf("\t dcc.min_compressed_block_size = 0x%08" PRIx32 "\n", rt.dcc.min_compressed_block_size));
|
||||
dst.Add(String::FromPrintf("\t dcc.color_transform = 0x%08" PRIx32 "\n", rt.dcc.color_transform));
|
||||
dst.Add(String::FromPrintf("\t dcc.enable_overwrite_combiner = %s\n", rt.dcc.enable_overwrite_combiner ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t dcc.force_independent_blocks = %s\n", rt.dcc.force_independent_blocks ? "true" : "false"));
|
||||
dst.Add(String::FromPrintf("\t cmask.addr = 0x%016" PRIx64 "\n", rt.cmask.addr));
|
||||
dst.Add(String::FromPrintf("\t cmask_slice.slice_minus1 = 0x%08" PRIx32 "\n", rt.cmask_slice.slice_minus1));
|
||||
dst.Add(String::FromPrintf("\t fmask.addr = 0x%016" PRIx64 "\n", rt.fmask.addr));
|
||||
dst.Add(String::FromPrintf("\t fmask_slice.slice_minus1 = 0x%08" PRIx32 "\n", rt.fmask_slice.slice_minus1));
|
||||
dst.Add(String::FromPrintf("\t clear_word0.word0 = 0x%08" PRIx32 "\n", rt.clear_word0.word0));
|
||||
dst.Add(String::FromPrintf("\t clear_word1.word1 = 0x%08" PRIx32 "\n", rt.clear_word1.word1));
|
||||
dst.Add(String::FromPrintf("\t dcc_addr.addr = 0x%016" PRIx64 "\n", rt.dcc_addr.addr));
|
||||
dst.Add(String::FromPrintf("\t size.width = 0x%08" PRIx32 "\n", rt.size.width));
|
||||
dst.Add(String::FromPrintf("\t size.height = 0x%08" PRIx32 "\n", rt.size.height));
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
|
@ -1039,13 +1043,16 @@ static void hw_print(const HW::HardwareContext& hw)
|
|||
const auto& aa = hw.GetAaSampleControl();
|
||||
const auto& ac = hw.GetAaConfig();
|
||||
|
||||
if (Kyty::Log::GetDirection() != Kyty::Log::Direction::Silent)
|
||||
{
|
||||
printf("HardwareContext\n");
|
||||
printf("\t GetRenderTargetMask() = 0x%08" PRIx32 "\n", hw.GetRenderTargetMask());
|
||||
printf("\t GetDepthClearValue() = %f\n", hw.GetDepthClearValue());
|
||||
printf("\t GetStencilClearValue() = %" PRIu8 "\n", hw.GetStencilClearValue());
|
||||
printf("\t GetLineWidth() = %f\n", hw.GetLineWidth());
|
||||
|
||||
rt_print("RenderTraget:", rt);
|
||||
printf("%s", rt_print("RenderTraget:", rt).Concat(U"").C_Str());
|
||||
|
||||
z_print("DepthRenderTraget:", z);
|
||||
vp_print("ScreenViewport:", vp, smc);
|
||||
clip_print("ClipControl:", c);
|
||||
|
@ -1055,6 +1062,7 @@ static void hw_print(const HW::HardwareContext& hw)
|
|||
bc_print("BlendColorControl:", bc, bclr, cc);
|
||||
eqaa_print("EqaaControl:", eqaa);
|
||||
aa_print("AaSampleControl:", aa, ac);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsRenderInit()
|
||||
|
@ -3828,9 +3836,12 @@ static void FindRenderColorInfo(uint64_t submit_id, CommandBuffer* buffer, const
|
|||
} else if (rt.info.format == 0xa && rt.info.channel_type == 0x6 && rt.info.channel_order == 0x1)
|
||||
{
|
||||
rt_format = RenderTextureFormat::B8G8R8A8Srgb;
|
||||
} else if (rt.info.format == 0x1 && rt.info.channel_type == 0x0 && rt.info.channel_order == 0x0)
|
||||
{
|
||||
rt_format = RenderTextureFormat::R8Unorm;
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format");
|
||||
EXIT("%s\n unknown format\n", rt_print("RenderTarget", rt).Concat(U"").C_Str());
|
||||
}
|
||||
|
||||
// Render to texture
|
||||
|
|
|
@ -836,6 +836,18 @@ bool GpuMemory::create_maybe_deleted(const Vector<OverlappedBlock>& others, GpuM
|
|||
o_type == GpuMemoryObjectType::Texture);
|
||||
});
|
||||
}
|
||||
if (type == GpuMemoryObjectType::RenderTexture)
|
||||
{
|
||||
return std::all_of(others.begin(), others.end(),
|
||||
[heap](auto& r)
|
||||
{
|
||||
OverlapType rel = r.relation;
|
||||
const auto& o = heap.objects[r.object_id];
|
||||
GpuMemoryObjectType o_type = o.info.object.type;
|
||||
return ((rel == OverlapType::IsContainedWithin || rel == OverlapType::Crosses) &&
|
||||
(o_type == GpuMemoryObjectType::RenderTexture || o_type == GpuMemoryObjectType::DepthStencilBuffer));
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -163,8 +163,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
|||
|
||||
VkFormat vk_format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
switch (pixel_format) // NOLINT
|
||||
switch (pixel_format)
|
||||
{
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8Unorm): vk_format = VK_FORMAT_R8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Unorm): vk_format = VK_FORMAT_B8G8R8A8_UNORM; break;
|
||||
|
@ -292,8 +293,9 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
|||
|
||||
VkFormat vk_format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
switch (pixel_format) // NOLINT
|
||||
switch (pixel_format)
|
||||
{
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8Unorm): vk_format = VK_FORMAT_R8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Unorm): vk_format = VK_FORMAT_R8G8B8A8_UNORM; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break;
|
||||
case static_cast<uint64_t>(RenderTextureFormat::B8G8R8A8Unorm): vk_format = VK_FORMAT_B8G8R8A8_UNORM; break;
|
||||
|
|
|
@ -229,6 +229,7 @@ static String dbg_fmt_to_str(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Vdata1Vaddr3StSsDmask8: return U"Vdata1Vaddr3StSsDmask8"; break;
|
||||
case ShaderInstructionFormat::Vdata2Vaddr3StSsDmask3: return U"Vdata2Vaddr3StSsDmask3"; break;
|
||||
case ShaderInstructionFormat::Vdata2Vaddr3StSsDmask5: return U"Vdata2Vaddr3StSsDmask5"; break;
|
||||
case ShaderInstructionFormat::Vdata2Vaddr3StSsDmask9: return U"Vdata2Vaddr3StSsDmask9"; break;
|
||||
case ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7: return U"Vdata3Vaddr3StSsDmask7"; break;
|
||||
case ShaderInstructionFormat::Vdata3Vaddr4StSsDmask7: return U"Vdata3Vaddr4StSsDmask7"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF: return U"Vdata4Vaddr3StSsDmaskF"; break;
|
||||
|
@ -311,6 +312,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Dmask3: s = U"dmask:0x3"; break;
|
||||
case ShaderInstructionFormat::Dmask5: s = U"dmask:0x5"; break;
|
||||
case ShaderInstructionFormat::Dmask7: s = U"dmask:0x7"; break;
|
||||
case ShaderInstructionFormat::Dmask9: s = U"dmask:0x9"; break;
|
||||
case ShaderInstructionFormat::DmaskF: s = U"dmask:0xf"; break;
|
||||
case ShaderInstructionFormat::Gds: s = U"gds"; break;
|
||||
default: EXIT("unknown code: %u\n", static_cast<uint32_t>(fu));
|
||||
|
@ -385,13 +387,13 @@ String ShaderCode::DbgDump() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool ShaderCode::IsDiscardInstruction(uint32_t index) const
|
||||
static bool IsDiscardInstruction(const Vector<ShaderInstruction>& code, uint32_t index)
|
||||
{
|
||||
if (!(index == 0 || index + 1 >= m_instructions.Size()))
|
||||
if (!(index == 0 || index + 1 >= code.Size()))
|
||||
{
|
||||
const auto& prev_inst = m_instructions.At(index - 1);
|
||||
const auto& inst = m_instructions.At(index);
|
||||
const auto& next_inst = m_instructions.At(index + 1);
|
||||
const auto& prev_inst = code.At(index - 1);
|
||||
const auto& inst = code.At(index);
|
||||
const auto& next_inst = code.At(index + 1);
|
||||
|
||||
return (inst.type == ShaderInstructionType::Exp && inst.format == ShaderInstructionFormat::Mrt0OffOffComprVmDone &&
|
||||
prev_inst.type == ShaderInstructionType::SMovB64 && prev_inst.format == ShaderInstructionFormat::Sdst2Ssrc02 &&
|
||||
|
@ -401,37 +403,72 @@ bool ShaderCode::IsDiscardInstruction(uint32_t index) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ShaderCode::IsDiscardBlock(uint32_t pc) const
|
||||
// bool ShaderCode::IsDiscardBlock(uint32_t pc) const
|
||||
//{
|
||||
// auto inst_count = m_instructions.Size();
|
||||
// for (uint32_t index = 0; index < inst_count; index++)
|
||||
// {
|
||||
// const auto& inst = m_instructions.At(index);
|
||||
// if (inst.pc == pc)
|
||||
// {
|
||||
// for (uint32_t i = index; i < inst_count; i++)
|
||||
// {
|
||||
// const auto& inst = m_instructions.At(i);
|
||||
//
|
||||
// if (inst.type == ShaderInstructionType::SEndpgm || inst.type == ShaderInstructionType::SCbranchExecz ||
|
||||
// inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchScc1 ||
|
||||
// inst.type == ShaderInstructionType::SCbranchVccz)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (IsDiscardInstruction(i))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
ShaderControlFlowBlock ShaderCode::ReadBlock(uint32_t pc) const
|
||||
{
|
||||
ShaderControlFlowBlock ret;
|
||||
auto inst_count = m_instructions.Size();
|
||||
for (uint32_t index = 0; index < inst_count; index++)
|
||||
{
|
||||
const auto& inst = m_instructions.At(index);
|
||||
if (inst.pc == pc)
|
||||
{
|
||||
ret.pc = pc;
|
||||
ret.is_valid = true;
|
||||
for (uint32_t i = index; i < inst_count; i++)
|
||||
{
|
||||
const auto& inst = m_instructions.At(i);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SEndpgm || inst.type == ShaderInstructionType::SCbranchExecz ||
|
||||
inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchScc1 ||
|
||||
inst.type == ShaderInstructionType::SCbranchVccz)
|
||||
inst.type == ShaderInstructionType::SCbranchVccz || inst.type == ShaderInstructionType::SCbranchVccnz ||
|
||||
inst.type == ShaderInstructionType::SBranch)
|
||||
{
|
||||
return false;
|
||||
ret.last = inst;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsDiscardInstruction(i))
|
||||
if (IsDiscardInstruction(m_instructions, i))
|
||||
{
|
||||
return true;
|
||||
ret.is_discard = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
||||
Vector<ShaderInstruction> ShaderCode::ReadIntructions(const ShaderControlFlowBlock& block) const
|
||||
{
|
||||
Vector<ShaderInstruction> ret;
|
||||
|
||||
|
@ -439,7 +476,7 @@ Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
|||
for (uint32_t index = 0; index < inst_count; index++)
|
||||
{
|
||||
const auto& inst = m_instructions.At(index);
|
||||
if (inst.pc == pc)
|
||||
if (inst.pc == block.pc)
|
||||
{
|
||||
for (uint32_t i = index; i < inst_count; i++)
|
||||
{
|
||||
|
@ -447,9 +484,8 @@ Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
|||
|
||||
ret.Add(inst);
|
||||
|
||||
if (IsDiscardInstruction(i))
|
||||
if (inst.pc == block.last.pc)
|
||||
{
|
||||
ret.Add(m_instructions.At(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -460,6 +496,35 @@ Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Vector<ShaderInstruction> ShaderCode::GetDiscardBlock(uint32_t pc) const
|
||||
//{
|
||||
// Vector<ShaderInstruction> ret;
|
||||
//
|
||||
// auto inst_count = m_instructions.Size();
|
||||
// for (uint32_t index = 0; index < inst_count; index++)
|
||||
// {
|
||||
// const auto& inst = m_instructions.At(index);
|
||||
// if (inst.pc == pc)
|
||||
// {
|
||||
// for (uint32_t i = index; i < inst_count; i++)
|
||||
// {
|
||||
// const auto& inst = m_instructions.At(i);
|
||||
//
|
||||
// ret.Add(inst);
|
||||
//
|
||||
// if (IsDiscardInstruction(i))
|
||||
// {
|
||||
// ret.Add(m_instructions.At(i + 1));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
static ShaderOperand operand_parse(uint32_t code)
|
||||
{
|
||||
ShaderOperand ret;
|
||||
|
@ -634,9 +699,11 @@ KYTY_SHADER_PARSER(shader_parse_sopp)
|
|||
inst.format = ShaderInstructionFormat::Empty;
|
||||
inst.src_num = 0;
|
||||
break;
|
||||
case 0x02: inst.type = ShaderInstructionType::SBranch; break;
|
||||
case 0x04: inst.type = ShaderInstructionType::SCbranchScc0; break;
|
||||
case 0x05: inst.type = ShaderInstructionType::SCbranchScc1; break;
|
||||
case 0x06: inst.type = ShaderInstructionType::SCbranchVccz; break;
|
||||
case 0x07: inst.type = ShaderInstructionType::SCbranchVccnz; break;
|
||||
case 0x08: inst.type = ShaderInstructionType::SCbranchExecz; break;
|
||||
case 0x0c:
|
||||
inst.type = ShaderInstructionType::SWaitcnt;
|
||||
|
@ -653,7 +720,8 @@ KYTY_SHADER_PARSER(shader_parse_sopp)
|
|||
dst->GetInstructions().Add(inst);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchScc1 ||
|
||||
inst.type == ShaderInstructionType::SCbranchVccz || inst.type == ShaderInstructionType::SCbranchExecz)
|
||||
inst.type == ShaderInstructionType::SCbranchVccz || inst.type == ShaderInstructionType::SCbranchVccnz ||
|
||||
inst.type == ShaderInstructionType::SCbranchExecz || inst.type == ShaderInstructionType::SBranch)
|
||||
{
|
||||
dst->GetLabels().Add(ShaderLabel(inst));
|
||||
}
|
||||
|
@ -1777,6 +1845,12 @@ KYTY_SHADER_PARSER(shader_parse_mimg)
|
|||
inst.dst.size = 1;
|
||||
break;
|
||||
}
|
||||
case 0x9:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata2Vaddr3StSsDmask9;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
}
|
||||
case 0xf:
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF;
|
||||
|
|
|
@ -2049,24 +2049,15 @@ KYTY_RECOMPILER_FUNC(Recompile_Exp_Mrt0OffOffComprVmDone)
|
|||
{
|
||||
EXIT_NOT_IMPLEMENTED(index == 0 || index + 1 >= code.GetInstructions().Size());
|
||||
|
||||
if (!code.IsDiscardInstruction(index))
|
||||
const auto& prev_inst = code.GetInstructions().At(index - 1);
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
auto block = code.ReadBlock(prev_inst.pc);
|
||||
|
||||
if (!block.is_discard)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// const auto& prev_inst = code.GetInstructions().At(index - 1);
|
||||
// const auto& inst = code.GetInstructions().At(index);
|
||||
// const auto& next_inst = code.GetInstructions().At(index + 1);
|
||||
//
|
||||
// if (!(prev_inst.type == ShaderInstructionType::SMovB64 && prev_inst.format == ShaderInstructionFormat::Sdst2Ssrc02 &&
|
||||
// prev_inst.dst.type == ShaderOperandType::ExecLo && prev_inst.src[0].type == ShaderOperandType::IntegerInlineConstant &&
|
||||
// prev_inst.src[0].constant.i == 0 && next_inst.type == ShaderInstructionType::SEndpgm))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
||||
const auto* info = spirv->GetPsInputInfo();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(info == nullptr || !info->ps_pixel_kill_enable);
|
||||
|
@ -2463,6 +2454,65 @@ KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata2Vaddr3StSsDmask5)
|
|||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata2Vaddr3StSsDmask9)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto* bind_info = spirv->GetBindInfo();
|
||||
|
||||
if (bind_info != nullptr && bind_info->textures2D.textures2d_sampled_num > 0 && bind_info->samplers.samplers_num > 0)
|
||||
{
|
||||
auto dst_value0 = operand_variable_to_str(inst.dst, 0);
|
||||
auto dst_value1 = operand_variable_to_str(inst.dst, 1);
|
||||
auto src0_value0 = operand_variable_to_str(inst.src[0], 0);
|
||||
auto src0_value1 = operand_variable_to_str(inst.src[0], 1);
|
||||
auto src0_value2 = operand_variable_to_str(inst.src[0], 2);
|
||||
auto src1_value0 = operand_variable_to_str(inst.src[1], 0);
|
||||
auto src2_value0 = operand_variable_to_str(inst.src[2], 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(dst_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src0_value0.type != SpirvType::Float);
|
||||
EXIT_NOT_IMPLEMENTED(src1_value0.type != SpirvType::Uint);
|
||||
EXIT_NOT_IMPLEMENTED(src2_value0.type != SpirvType::Uint);
|
||||
|
||||
// TODO() check VSKIP
|
||||
// TODO() check LOD_CLAMPED
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%t24_<index> = OpLoad %uint %<src1_value0>
|
||||
%t26_<index> = OpAccessChain %_ptr_UniformConstant_ImageS %textures2D_S %t24_<index>
|
||||
%t27_<index> = OpLoad %ImageS %t26_<index>
|
||||
%t33_<index> = OpLoad %uint %<src2_value0>
|
||||
%t35_<index> = OpAccessChain %_ptr_UniformConstant_Sampler %samplers %t33_<index>
|
||||
%t36_<index> = OpLoad %Sampler %t35_<index>
|
||||
%t38_<index> = OpSampledImage %SampledImage %t27_<index> %t36_<index>
|
||||
%t39_<index> = OpLoad %float %<src0_value0>
|
||||
%t40_<index> = OpLoad %float %<src0_value1>
|
||||
%t42_<index> = OpCompositeConstruct %v2float %t39_<index> %t40_<index>
|
||||
%t43_<index> = OpImageSampleImplicitLod %v4float %t38_<index> %t42_<index>
|
||||
OpStore %temp_v4float %t43_<index>
|
||||
%t46_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_0
|
||||
%t47_<index> = OpLoad %float %t46_<index>
|
||||
OpStore %<dst_value0> %t47_<index>
|
||||
%t54_<index> = OpAccessChain %_ptr_Function_float %temp_v4float %uint_3
|
||||
%t55_<index> = OpLoad %float %t54_<index>
|
||||
OpStore %<dst_value1> %t55_<index>
|
||||
)";
|
||||
*dst_source += String(text)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<src0_value0>", src0_value0.value)
|
||||
.ReplaceStr(U"<src0_value1>", src0_value1.value)
|
||||
.ReplaceStr(U"<src0_value2>", src0_value2.value)
|
||||
.ReplaceStr(U"<src1_value0>", src1_value0.value)
|
||||
.ReplaceStr(U"<src2_value0>", src2_value0.value)
|
||||
.ReplaceStr(U"<dst_value0>", dst_value0.value)
|
||||
.ReplaceStr(U"<dst_value1>", dst_value1.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_ImageSample_Vdata3Vaddr3StSsDmask7)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
@ -3520,22 +3570,41 @@ KYTY_RECOMPILER_FUNC(Recompile_SBufferLoadDwordx16_Sdst16SvSoffset)
|
|||
return false;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranchExecz_Label)
|
||||
// KYTY_RECOMPILER_FUNC(Recompile_SCbranchExecz_Label)
|
||||
//{
|
||||
// const auto& inst = code.GetInstructions().At(index);
|
||||
//
|
||||
// EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
//
|
||||
// EXIT_NOT_IMPLEMENTED(code.ReadBlock(ShaderLabel(inst).GetDst()).is_discard);
|
||||
//
|
||||
// String label = ShaderLabel(inst).ToString();
|
||||
//
|
||||
// static const char32_t* text = UR"(
|
||||
// %execz_u_<index> = OpLoad %uint %execz
|
||||
// %execz_b_<index> = OpINotEqual %bool %execz_u_<index> %uint_0
|
||||
// OpSelectionMerge %<label> None
|
||||
// OpBranchConditional %execz_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
//
|
||||
// *dst_source += String(text).ReplaceStr(U"<index>", String::FromPrintf("%u", index)).ReplaceStr(U"<label>", label);
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SBranch_Label)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(code.IsDiscardBlock(ShaderLabel(inst).GetDst()));
|
||||
EXIT_NOT_IMPLEMENTED(code.ReadBlock(ShaderLabel(inst).GetDst()).is_discard);
|
||||
|
||||
String label = ShaderLabel(inst).ToString();
|
||||
|
||||
static const char32_t* text = UR"(
|
||||
%execz_u_<index> = OpLoad %uint %execz
|
||||
%execz_b_<index> = OpINotEqual %bool %execz_u_<index> %uint_0
|
||||
OpSelectionMerge %<label> None
|
||||
OpBranchConditional %execz_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
OpBranch %<label>
|
||||
)";
|
||||
|
||||
*dst_source += String(text).ReplaceStr(U"<index>", String::FromPrintf("%u", index)).ReplaceStr(U"<label>", label);
|
||||
|
@ -3543,110 +3612,197 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchExecz_Label)
|
|||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label)
|
||||
/* XXX: Execz, Scc0, Scc1, Vccz, Vccnz */
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranch_XXX_Label)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(index + 1 >= code.GetInstructions().Size());
|
||||
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
const auto& next_inst = code.GetInstructions().At(index + 1);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
auto label = ShaderLabel(inst);
|
||||
|
||||
// TODO(): analyze control flow graph
|
||||
bool discard = code.IsDiscardBlock(label.GetDst());
|
||||
auto label = ShaderLabel(inst);
|
||||
auto dst_block = code.ReadBlock(label.GetDst());
|
||||
auto next_block = code.ReadBlock(next_inst.pc);
|
||||
bool discard = dst_block.is_discard;
|
||||
auto label_next_block = ShaderLabel(next_block.last);
|
||||
auto label_dst_block = ShaderLabel(dst_block.last);
|
||||
|
||||
bool if_else = next_block.is_valid && !next_block.is_discard && dst_block.is_valid && !dst_block.is_discard &&
|
||||
((next_block.last.type == ShaderInstructionType::SBranch && label_next_block.GetDst() >= dst_block.pc &&
|
||||
label_next_block.GetDst() <= dst_block.last.pc) ||
|
||||
(dst_block.last.type == ShaderInstructionType::SBranch && label_dst_block.GetDst() >= next_block.pc &&
|
||||
label_dst_block.GetDst() <= next_block.last.pc));
|
||||
|
||||
String label_str = label.ToString();
|
||||
String label_merge =
|
||||
if_else ? (dst_block.last.type == ShaderInstructionType::SBranch ? label_dst_block.ToString() : label_next_block.ToString()) : U"";
|
||||
|
||||
// if (condition)
|
||||
// {
|
||||
// L1:
|
||||
// ...
|
||||
// }
|
||||
// L2: /* merge */
|
||||
// ...
|
||||
static const char32_t* text_variant_a = UR"(
|
||||
%scc_u_<index> = OpLoad %uint %scc
|
||||
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
|
||||
<param0>
|
||||
<param1>
|
||||
OpSelectionMerge %<label> None
|
||||
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
static const char32_t* text_variant_b = UR"(
|
||||
%scc_u_<index> = OpLoad %uint %scc
|
||||
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
|
||||
OpSelectionMerge %t230_<index> None
|
||||
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
OpBranchConditional %cc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
*dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
// if (condition)
|
||||
// {
|
||||
// L2:
|
||||
// ...
|
||||
// discard;
|
||||
// }
|
||||
// L1: /* merge */
|
||||
// ...
|
||||
static const char32_t* text_variant_b = UR"(
|
||||
<param0>
|
||||
<param1>
|
||||
OpSelectionMerge %t230_<index> None
|
||||
OpBranchConditional %cc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
// if (condition)
|
||||
// {
|
||||
// L1:
|
||||
// ...
|
||||
// } else
|
||||
// {
|
||||
// L2:
|
||||
// ...
|
||||
// }
|
||||
// /* merge */
|
||||
static const char32_t* text_variant_c = UR"(
|
||||
<param0>
|
||||
<param1>
|
||||
OpSelectionMerge %<merge> None
|
||||
OpBranchConditional %cc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
*dst_source += String(if_else ? text_variant_c : (discard ? text_variant_b : text_variant_a))
|
||||
.ReplaceStr(U"<param0>", param[0])
|
||||
.ReplaceStr(U"<param1>", param[1])
|
||||
.ReplaceStr(U"<merge>", label_merge)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<label>", label_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc1_Label)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
// KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label)
|
||||
//{
|
||||
// const auto& inst = code.GetInstructions().At(index);
|
||||
//
|
||||
// EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
//
|
||||
// auto label = ShaderLabel(inst);
|
||||
//
|
||||
// // TODO(): analyze control flow graph
|
||||
// bool discard = code.ReadBlock(label.GetDst()).is_discard;
|
||||
//
|
||||
// String label_str = label.ToString();
|
||||
//
|
||||
// static const char32_t* text_variant_a = UR"(
|
||||
// %scc_u_<index> = OpLoad %uint %scc
|
||||
// %scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
|
||||
// OpSelectionMerge %<label> None
|
||||
// OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
// static const char32_t* text_variant_b = UR"(
|
||||
// %scc_u_<index> = OpLoad %uint %scc
|
||||
// %scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
|
||||
// OpSelectionMerge %t230_<index> None
|
||||
// OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
//
|
||||
// *dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
// .ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
// .ReplaceStr(U"<label>", label_str);
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
auto label = ShaderLabel(inst);
|
||||
|
||||
// TODO(): analyze control flow graph
|
||||
bool discard = code.IsDiscardBlock(label.GetDst());
|
||||
|
||||
String label_str = label.ToString();
|
||||
|
||||
static const char32_t* text_variant_a = UR"(
|
||||
%scc_u_<index> = OpLoad %uint %scc
|
||||
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_1
|
||||
OpSelectionMerge %<label> None
|
||||
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
static const char32_t* text_variant_b = UR"(
|
||||
%scc_u_<index> = OpLoad %uint %scc
|
||||
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_1
|
||||
OpSelectionMerge %t230_<index> None
|
||||
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
*dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<label>", label_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SCbranchVccz_Label)
|
||||
{
|
||||
const auto& inst = code.GetInstructions().At(index);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
|
||||
auto label = ShaderLabel(inst);
|
||||
|
||||
// TODO(): analyze control flow graph
|
||||
bool discard = code.IsDiscardBlock(label.GetDst());
|
||||
|
||||
String label_str = label.ToString();
|
||||
|
||||
static const char32_t* text_variant_a = UR"(
|
||||
%vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
%vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
OpSelectionMerge %<label> None
|
||||
OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
static const char32_t* text_variant_b = UR"(
|
||||
%vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
%vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
OpSelectionMerge %t230_<index> None
|
||||
OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
%t230_<index> = OpLabel
|
||||
)";
|
||||
|
||||
*dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
.ReplaceStr(U"<label>", label_str);
|
||||
|
||||
return true;
|
||||
}
|
||||
// KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc1_Label)
|
||||
//{
|
||||
// const auto& inst = code.GetInstructions().At(index);
|
||||
//
|
||||
// EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
//
|
||||
// auto label = ShaderLabel(inst);
|
||||
//
|
||||
// // TODO(): analyze control flow graph
|
||||
// bool discard = code.ReadBlock(label.GetDst()).is_discard;
|
||||
//
|
||||
// String label_str = label.ToString();
|
||||
//
|
||||
// static const char32_t* text_variant_a = UR"(
|
||||
// %scc_u_<index> = OpLoad %uint %scc
|
||||
// %scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_1
|
||||
// OpSelectionMerge %<label> None
|
||||
// OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
// static const char32_t* text_variant_b = UR"(
|
||||
// %scc_u_<index> = OpLoad %uint %scc
|
||||
// %scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_1
|
||||
// OpSelectionMerge %t230_<index> None
|
||||
// OpBranchConditional %scc_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
//
|
||||
// *dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
// .ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
// .ReplaceStr(U"<label>", label_str);
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// KYTY_RECOMPILER_FUNC(Recompile_SCbranchVccz_Label)
|
||||
//{
|
||||
// const auto& inst = code.GetInstructions().At(index);
|
||||
//
|
||||
// EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
|
||||
//
|
||||
// auto label = ShaderLabel(inst);
|
||||
//
|
||||
// // TODO(): analyze control flow graph
|
||||
// bool discard = code.ReadBlock(label.GetDst()).is_discard;
|
||||
//
|
||||
// String label_str = label.ToString();
|
||||
//
|
||||
// static const char32_t* text_variant_a = UR"(
|
||||
// %vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
// %vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
// OpSelectionMerge %<label> None
|
||||
// OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
// static const char32_t* text_variant_b = UR"(
|
||||
// %vcc_lo_u_<index> = OpLoad %uint %vcc_lo
|
||||
// %vcc_lo_b_<index> = OpIEqual %bool %vcc_lo_u_<index> %uint_0
|
||||
// OpSelectionMerge %t230_<index> None
|
||||
// OpBranchConditional %vcc_lo_b_<index> %<label> %t230_<index>
|
||||
// %t230_<index> = OpLabel
|
||||
//)";
|
||||
//
|
||||
// *dst_source += String(discard ? text_variant_b : text_variant_a)
|
||||
// .ReplaceStr(U"<index>", String::FromPrintf("%u", index))
|
||||
// .ReplaceStr(U"<label>", label_str);
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
KYTY_RECOMPILER_FUNC(Recompile_SEndpgm_Empty)
|
||||
{
|
||||
|
@ -5407,6 +5563,7 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_ImageSample_Vdata1Vaddr3StSsDmask8, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata1Vaddr3StSsDmask8, {U""}},
|
||||
{Recompile_ImageSample_Vdata2Vaddr3StSsDmask3, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata2Vaddr3StSsDmask3, {U""}},
|
||||
{Recompile_ImageSample_Vdata2Vaddr3StSsDmask5, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata2Vaddr3StSsDmask5, {U""}},
|
||||
{Recompile_ImageSample_Vdata2Vaddr3StSsDmask9, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata2Vaddr3StSsDmask9, {U""}},
|
||||
{Recompile_ImageSample_Vdata3Vaddr3StSsDmask7, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7, {U""}},
|
||||
{Recompile_ImageSample_Vdata4Vaddr3StSsDmaskF, ShaderInstructionType::ImageSample, ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF, {U""}},
|
||||
{Recompile_ImageSampleLz_Vdata3Vaddr3StSsDmask7, ShaderInstructionType::ImageSampleLz, ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7, {U""}},
|
||||
|
@ -5420,10 +5577,12 @@ static RecompilerFunc g_recomp_func[] = {
|
|||
{Recompile_SBufferLoadDwordx8_Sdst8SvSoffset, ShaderInstructionType::SBufferLoadDwordx8, ShaderInstructionFormat::Sdst8SvSoffset, {U""}},
|
||||
{Recompile_SBufferLoadDwordx16_Sdst16SvSoffset, ShaderInstructionType::SBufferLoadDwordx16, ShaderInstructionFormat::Sdst16SvSoffset, {U""}},
|
||||
|
||||
{Recompile_SCbranchExecz_Label, ShaderInstructionType::SCbranchExecz, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchScc0_Label, ShaderInstructionType::SCbranchScc0, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchScc1_Label, ShaderInstructionType::SCbranchScc1, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranchVccz_Label, ShaderInstructionType::SCbranchVccz, ShaderInstructionFormat::Label, {U""}},
|
||||
{Recompile_SCbranch_XXX_Label, ShaderInstructionType::SCbranchExecz, ShaderInstructionFormat::Label, {U"%cc_u_<index> = OpLoad %uint %execz", U"%cc_b_<index> = OpINotEqual %bool %cc_u_<index> %uint_0"}},
|
||||
{Recompile_SCbranch_XXX_Label, ShaderInstructionType::SCbranchScc0, ShaderInstructionFormat::Label, {U"%cc_u_<index> = OpLoad %uint %scc", U"%cc_b_<index> = OpIEqual %bool %cc_u_<index> %uint_0"}},
|
||||
{Recompile_SCbranch_XXX_Label, ShaderInstructionType::SCbranchScc1, ShaderInstructionFormat::Label, {U"%cc_u_<index> = OpLoad %uint %scc", U"%cc_b_<index> = OpIEqual %bool %cc_u_<index> %uint_1"}},
|
||||
{Recompile_SCbranch_XXX_Label, ShaderInstructionType::SCbranchVccz, ShaderInstructionFormat::Label, {U"%cc_u_<index> = OpLoad %uint %vcc_lo", U"%cc_b_<index> = OpIEqual %bool %cc_u_<index> %uint_0"}},
|
||||
{Recompile_SCbranch_XXX_Label, ShaderInstructionType::SCbranchVccnz, ShaderInstructionFormat::Label, {U"%cc_u_<index> = OpLoad %uint %vcc_lo", U"%cc_b_<index> = OpINotEqual %bool %cc_u_<index> %uint_0"}},
|
||||
{Recompile_SBranch_Label, ShaderInstructionType::SBranch, ShaderInstructionFormat::Label, {U""}},
|
||||
|
||||
{Recompile_SEndpgm_Empty, ShaderInstructionType::SEndpgm, ShaderInstructionFormat::Empty, {U""}},
|
||||
|
||||
|
@ -6669,9 +6828,11 @@ void Spirv::WriteLabel(int index)
|
|||
%<label> = OpLabel
|
||||
)";
|
||||
|
||||
bool discard = m_code.IsDiscardBlock(label.GetDst());
|
||||
bool discard = m_code.ReadBlock(label.GetDst()).is_discard;
|
||||
|
||||
bool skip_branch = (discard || (instructions.At(index - 1).type == ShaderInstructionType::SEndpgm && labels_num == 0));
|
||||
bool skip_branch = (discard || ((instructions.At(index - 1).type == ShaderInstructionType::SEndpgm ||
|
||||
instructions.At(index - 1).type == ShaderInstructionType::SBranch) &&
|
||||
labels_num == 0));
|
||||
|
||||
m_source += String(text)
|
||||
.ReplaceStr(U"<branch>", (skip_branch ? U"" : U"OpBranch %<label>"))
|
||||
|
@ -6692,7 +6853,7 @@ void Spirv::ModifyCode()
|
|||
{
|
||||
struct DiscardLabel
|
||||
{
|
||||
uint32_t pc = 0;
|
||||
ShaderControlFlowBlock block;
|
||||
int num = 0;
|
||||
};
|
||||
const auto& labels = m_code.GetLabels();
|
||||
|
@ -6711,18 +6872,21 @@ void Spirv::ModifyCode()
|
|||
}
|
||||
}
|
||||
EXIT_IF(num == 0);
|
||||
if (num > 1 && m_code.IsDiscardBlock(pc))
|
||||
if (num > 1)
|
||||
{
|
||||
if (!dls.Contains(pc, [](auto d, auto pc) { return d.pc == pc; }))
|
||||
if (auto block = m_code.ReadBlock(pc); block.is_discard)
|
||||
{
|
||||
dls.Add(DiscardLabel({pc, num - 1}));
|
||||
if (!dls.Contains(pc, [](auto d, auto pc) { return d.block.pc == pc; }))
|
||||
{
|
||||
dls.Add(DiscardLabel({block, num - 1}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& dl: dls)
|
||||
{
|
||||
auto block = m_code.GetDiscardBlock(dl.pc);
|
||||
auto block = m_code.ReadIntructions(dl.block);
|
||||
for (int i = 0; i < dl.num; i++)
|
||||
{
|
||||
// Duplicate discard block if there are different branches with the same label
|
||||
|
|
|
@ -5,6 +5,9 @@ static const TextureInfo infos_10_10_0[] = {
|
|||
// kDataFormatB8G8R8A8Unorm, 96, 96, 128, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 96, 96, 128, 1, 10, false, {{65536, 32768, 0, 65536}, }, { {0, 0}, } },
|
||||
{ 10, 0, 96, 96, 128, 1, 10, true, {{65536, 65536, 0, 65536}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 288, 216, 384, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 288, 216, 384, 1, 10, false, {{393216, 32768, 0, 393216}, }, { {0, 0}, } },
|
||||
{ 10, 0, 288, 216, 384, 1, 10, true, {{393216, 65536, 0, 393216}, }, { {0, 0}, } },
|
||||
// kDataFormatB8G8R8A8Unorm, 960, 540, 1024, 1, kTileModeDisplay_2dThin
|
||||
{ 10, 0, 960, 540, 1024, 1, 10, false, {{2359296, 32768, 0, 2359296}, }, { {0, 0}, } },
|
||||
{ 10, 0, 960, 540, 1024, 1, 10, true, {{2621440, 65536, 0, 2621440}, }, { {0, 0}, } },
|
||||
|
|
Loading…
Reference in New Issue