From f1f4302f99645c3559d6a7da9b5ea7d32d4c09ce Mon Sep 17 00:00:00 2001 From: InoriRus Date: Fri, 10 Jun 2022 19:27:34 +1000 Subject: [PATCH] support more texture sizes --- appveyor.yml | 2 +- source/CMakeLists.txt | 2 +- .../include/Emulator/Graphics/Shader.h | 1 + .../emulator/include/Emulator/Graphics/Tile.h | 14 +- .../emulator/src/Graphics/GraphicsRender.cpp | 2 +- .../src/Graphics/Objects/GpuMemory.cpp | 22 +- .../src/Graphics/Objects/StorageTexture.cpp | 11 +- .../emulator/src/Graphics/Objects/Texture.cpp | 11 +- source/emulator/src/Graphics/Shader.cpp | 54 +- source/emulator/src/Graphics/ShaderSpirv.cpp | 36 ++ .../Tables/TileTextureInfo_10_10_0.inc | 263 ++++++++++ .../Tables/TileTextureInfo_13_10_0.inc | 464 +++++++++++++++++ .../Tables/TileTextureInfo_13_10_9.inc | 462 +++++++++++++++++ .../Tables/TileTextureInfo_13_35_0.inc | 464 +++++++++++++++++ .../Tables/TileTextureInfo_13_36_0.inc | 462 +++++++++++++++++ .../Tables/TileTextureInfo_13_37_0.inc | 464 +++++++++++++++++ .../Tables/TileTextureInfo_13_37_9.inc | 462 +++++++++++++++++ .../Tables/TileTextureInfo_14_10_0.inc | 462 +++++++++++++++++ .../Graphics/Tables/TileTextureInfo_2_4_7.inc | 14 + .../Tables/TileTextureInfo_8_10_0.inc | 462 +++++++++++++++++ .../Tables/TileTextureInfo_8_10_9.inc | 462 +++++++++++++++++ .../Graphics/Tables/TileTextureInfo_8_1_0.inc | 462 +++++++++++++++++ source/emulator/src/Graphics/Tile.cpp | 473 ++++++++---------- source/include/Kyty/Core/ArrayWrapper.h | 12 +- 24 files changed, 5240 insertions(+), 303 deletions(-) create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_10_10_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_10_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_10_9.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_35_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_36_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_37_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_13_37_9.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_14_10_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_2_4_7.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_8_10_0.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_8_10_9.inc create mode 100644 source/emulator/src/Graphics/Tables/TileTextureInfo_8_1_0.inc diff --git a/appveyor.yml b/appveyor.yml index f65bbfd..e08fb87 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.1.5.build-{build} +version: 0.1.6.build-{build} image: Visual Studio 2019 environment: matrix: diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 56f68f9..b1388b3 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -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.5) +project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.6) include(src_script.cmake) diff --git a/source/emulator/include/Emulator/Graphics/Shader.h b/source/emulator/include/Emulator/Graphics/Shader.h index 92a7a99..33ad4d4 100644 --- a/source/emulator/include/Emulator/Graphics/Shader.h +++ b/source/emulator/include/Emulator/Graphics/Shader.h @@ -64,6 +64,7 @@ enum class ShaderInstructionType SBufferLoadDwordx8, SCbranchExecz, SCbranchScc0, + SCbranchScc1, SCbranchVccz, SCmpEqI32, SCmpEqU32, diff --git a/source/emulator/include/Emulator/Graphics/Tile.h b/source/emulator/include/Emulator/Graphics/Tile.h index 7c46f75..a6ceacc 100644 --- a/source/emulator/include/Emulator/Graphics/Tile.h +++ b/source/emulator/include/Emulator/Graphics/Tile.h @@ -25,6 +25,18 @@ struct TileSizeAlign uint32_t align = 0; }; +struct TileSizeOffset +{ + uint32_t size = 0; + uint32_t offset = 0; +}; + +struct TilePaddedSize +{ + uint32_t width = 0; + uint32_t height = 0; +}; + void TileInit(); void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_t width, uint32_t height, bool neo); void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, @@ -34,7 +46,7 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t TileSizeAlign* stencil_size, TileSizeAlign* htile_size, TileSizeAlign* depth_size); void TileGetVideoOutSize(uint32_t width, uint32_t height, uint32_t pitch, bool tile, bool neo, TileSizeAlign* size); void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile, - bool neo, TileSizeAlign* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height); + bool neo, TileSizeAlign* total_size, TileSizeOffset* level_sizes, TilePaddedSize* padded_size); } // namespace Kyty::Libs::Graphics diff --git a/source/emulator/src/Graphics/GraphicsRender.cpp b/source/emulator/src/Graphics/GraphicsRender.cpp index 2293e4e..c21c5da 100644 --- a/source/emulator/src/Graphics/GraphicsRender.cpp +++ b/source/emulator/src/Graphics/GraphicsRender.cpp @@ -3995,7 +3995,7 @@ static void PrepareTextures(uint64_t submit_id, CommandBuffer* buffer, const Sha bool check_depth_texture = (tile == 2); - TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, &size, nullptr, nullptr, nullptr); + TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, &size, nullptr, nullptr); EXIT_NOT_IMPLEMENTED(size.size == 0); EXIT_NOT_IMPLEMENTED((addr & (static_cast(size.align) - 1u)) != 0); diff --git a/source/emulator/src/Graphics/Objects/GpuMemory.cpp b/source/emulator/src/Graphics/Objects/GpuMemory.cpp index 402449d..7bf6c53 100644 --- a/source/emulator/src/Graphics/Objects/GpuMemory.cpp +++ b/source/emulator/src/Graphics/Objects/GpuMemory.cpp @@ -812,7 +812,7 @@ bool GpuMemory::create_maybe_deleted(const Vector& others, GpuM { auto& heap = m_heaps[heap_id]; - if (type == GpuMemoryObjectType::IndexBuffer) + if (type == GpuMemoryObjectType::VertexBuffer || type == GpuMemoryObjectType::IndexBuffer) { return std::all_of(others.begin(), others.end(), [heap](auto& r) @@ -821,19 +821,7 @@ bool GpuMemory::create_maybe_deleted(const Vector& others, GpuM 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::IndexBuffer); - }); - } - if (type == GpuMemoryObjectType::VertexBuffer) - { - 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::VertexBuffer); + (o_type == GpuMemoryObjectType::VertexBuffer || o_type == GpuMemoryObjectType::IndexBuffer)); }); } if (type == GpuMemoryObjectType::Texture) @@ -974,9 +962,15 @@ void* GpuMemory::CreateObject(uint64_t submit_id, GraphicContext* ctx, CommandBu case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::Crosses, GpuMemoryObjectType::IndexBuffer): case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::Contains, GpuMemoryObjectType::IndexBuffer): case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::IsContainedWithin, GpuMemoryObjectType::IndexBuffer): + case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::Crosses, GpuMemoryObjectType::VertexBuffer): + case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::Contains, GpuMemoryObjectType::VertexBuffer): + case ObjectsRelation(GpuMemoryObjectType::IndexBuffer, OverlapType::IsContainedWithin, GpuMemoryObjectType::VertexBuffer): case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::Crosses, GpuMemoryObjectType::VertexBuffer): case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::Contains, GpuMemoryObjectType::VertexBuffer): case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::IsContainedWithin, GpuMemoryObjectType::VertexBuffer): + case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::Crosses, GpuMemoryObjectType::IndexBuffer): + case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::Contains, GpuMemoryObjectType::IndexBuffer): + case ObjectsRelation(GpuMemoryObjectType::VertexBuffer, OverlapType::IsContainedWithin, GpuMemoryObjectType::IndexBuffer): case ObjectsRelation(GpuMemoryObjectType::Texture, OverlapType::Crosses, GpuMemoryObjectType::Texture): case ObjectsRelation(GpuMemoryObjectType::Texture, OverlapType::Contains, GpuMemoryObjectType::Texture): case ObjectsRelation(GpuMemoryObjectType::Texture, OverlapType::IsContainedWithin, GpuMemoryObjectType::Texture): diff --git a/source/emulator/src/Graphics/Objects/StorageTexture.cpp b/source/emulator/src/Graphics/Objects/StorageTexture.cpp index 6856ce1..456f513 100644 --- a/source/emulator/src/Graphics/Objects/StorageTexture.cpp +++ b/source/emulator/src/Graphics/Objects/StorageTexture.cpp @@ -145,13 +145,12 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, EXIT_NOT_IMPLEMENTED(tile != 8 && tile != 13); - uint32_t level_sizes[16]; + TileSizeOffset level_sizes[16]; - TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr, nullptr); + TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr); // dbg_test_mipmaps(ctx, VK_FORMAT_BC3_SRGB_BLOCK, 512, 512); - uint32_t offset = 0; uint32_t mip_width = width; uint32_t mip_height = height; uint32_t mip_pitch = pitch; @@ -159,11 +158,11 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, Vector regions(levels); for (uint32_t i = 0; i < levels; i++) { - EXIT_NOT_IMPLEMENTED(level_sizes[i] == 0); + EXIT_NOT_IMPLEMENTED(level_sizes[i].size == 0); auto mipmap_offset = UtilCalcMipmapOffset(i, width, height); - regions[i].offset = offset; + regions[i].offset = level_sizes[i].offset; regions[i].width = mip_width; regions[i].height = mip_height; regions[i].pitch = mip_pitch; @@ -171,8 +170,6 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, regions[i].dst_x = mipmap_offset.first; regions[i].dst_y = mipmap_offset.second; - offset += level_sizes[i]; - if (mip_width > 1) { mip_width /= 2; diff --git a/source/emulator/src/Graphics/Objects/Texture.cpp b/source/emulator/src/Graphics/Objects/Texture.cpp index e9ff6a0..9e92ee4 100644 --- a/source/emulator/src/Graphics/Objects/Texture.cpp +++ b/source/emulator/src/Graphics/Objects/Texture.cpp @@ -164,13 +164,12 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, EXIT_NOT_IMPLEMENTED(tile != 8 && tile != 13); - uint32_t level_sizes[16]; + TileSizeOffset level_sizes[16]; - TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr, nullptr); + TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr); // dbg_test_mipmaps(ctx, VK_FORMAT_BC3_SRGB_BLOCK, 512, 512); - uint32_t offset = 0; uint32_t mip_width = width; uint32_t mip_height = height; uint32_t mip_pitch = pitch; @@ -178,9 +177,9 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, Vector regions(levels); for (uint32_t i = 0; i < levels; i++) { - EXIT_NOT_IMPLEMENTED(level_sizes[i] == 0); + EXIT_NOT_IMPLEMENTED(level_sizes[i].size == 0); - regions[i].offset = offset; + regions[i].offset = level_sizes[i].offset; regions[i].width = mip_width; regions[i].height = mip_height; regions[i].pitch = mip_pitch; @@ -188,8 +187,6 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj, regions[i].dst_x = 0; regions[i].dst_y = 0; - offset += level_sizes[i]; - if (mip_width > 1) { mip_width /= 2; diff --git a/source/emulator/src/Graphics/Shader.cpp b/source/emulator/src/Graphics/Shader.cpp index e93281b..7fecf2d 100644 --- a/source/emulator/src/Graphics/Shader.cpp +++ b/source/emulator/src/Graphics/Shader.cpp @@ -414,7 +414,8 @@ bool ShaderCode::IsDiscardBlock(uint32_t pc) const const auto& inst = m_instructions.At(i); if (inst.type == ShaderInstructionType::SEndpgm || inst.type == ShaderInstructionType::SCbranchExecz || - inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchVccz) + inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchScc1 || + inst.type == ShaderInstructionType::SCbranchVccz) { return false; } @@ -566,7 +567,9 @@ KYTY_SHADER_PARSER(shader_parse_sopc) case 0x0a: inst.type = ShaderInstructionType::SCmpLtU32; break; case 0x0b: inst.type = ShaderInstructionType::SCmpLeU32; break; - default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc); + default: + printf("%s", dst->DbgDump().C_Str()); + EXIT("unknown sopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0()); } dst->GetInstructions().Add(inst); @@ -597,7 +600,9 @@ KYTY_SHADER_PARSER(shader_parse_sopk) inst.src[0].constant.i = imm; inst.src_num = 1; break; - default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopk opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc); + default: + printf("%s", dst->DbgDump().C_Str()); + EXIT("unknown sopk opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0()); } dst->GetInstructions().Add(inst); @@ -630,6 +635,7 @@ KYTY_SHADER_PARSER(shader_parse_sopp) inst.src_num = 0; break; case 0x04: inst.type = ShaderInstructionType::SCbranchScc0; break; + case 0x05: inst.type = ShaderInstructionType::SCbranchScc1; break; case 0x06: inst.type = ShaderInstructionType::SCbranchVccz; break; case 0x08: inst.type = ShaderInstructionType::SCbranchExecz; break; case 0x0c: @@ -639,13 +645,15 @@ KYTY_SHADER_PARSER(shader_parse_sopp) inst.src[0].constant.u = simm; inst.src_num = 1; break; - default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopp opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc); + default: + printf("%s", dst->DbgDump().C_Str()); + EXIT("unknown sopp opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0()); } dst->GetInstructions().Add(inst); - if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchVccz || - inst.type == ShaderInstructionType::SCbranchExecz) + if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchScc1 || + inst.type == ShaderInstructionType::SCbranchVccz || inst.type == ShaderInstructionType::SCbranchExecz) { dst->GetLabels().Add(ShaderLabel(inst)); } @@ -1170,6 +1178,7 @@ KYTY_SHADER_PARSER(shader_parse_vop3) if (opcode >= 0 && opcode <= 0xff) { + /* VOPC using VOP3 encoding */ inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1; inst.src_num = 2; inst.dst = operand_parse(vdst); @@ -1178,12 +1187,21 @@ KYTY_SHADER_PARSER(shader_parse_vop3) if (opcode >= 0x100 && opcode <= 0x13d) { + /* VOP2 using VOP3 encoding */ inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1; inst.src_num = 2; } + if (opcode >= 0x180 && opcode <= 0x1e8) + { + /* VOP1 using VOP3 encoding */ + inst.format = ShaderInstructionFormat::SVdstSVsrc0; + inst.src_num = 1; + } + switch (opcode) { + /* VOPC using VOP3 encoding */ case 0x00: inst.type = ShaderInstructionType::VCmpFF32; break; case 0x01: inst.type = ShaderInstructionType::VCmpLtF32; break; case 0x02: inst.type = ShaderInstructionType::VCmpEqF32; break; @@ -1221,6 +1239,8 @@ KYTY_SHADER_PARSER(shader_parse_vop3) case 0xd4: inst.type = ShaderInstructionType::VCmpxGtU32; break; case 0xd5: inst.type = ShaderInstructionType::VCmpxNeU32; break; case 0xd6: inst.type = ShaderInstructionType::VCmpxGeU32; break; + + /* VOP2 using VOP3 encoding */ case 0x100: inst.type = ShaderInstructionType::VCndmaskB32; inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Smask2; @@ -1267,6 +1287,8 @@ KYTY_SHADER_PARSER(shader_parse_vop3) inst.dst2.size = 2; break; case 0x12f: inst.type = ShaderInstructionType::VCvtPkrtzF16F32; break; + + /* VOP3 instructions */ case 0x141: inst.type = ShaderInstructionType::VMadF32; break; case 0x143: inst.type = ShaderInstructionType::VMadU32U24; break; case 0x148: inst.type = ShaderInstructionType::VBfeU32; break; @@ -1290,11 +1312,21 @@ KYTY_SHADER_PARSER(shader_parse_vop3) inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1; inst.src_num = 2; break; - case 0x1aa: - inst.type = ShaderInstructionType::VRcpF32; - inst.format = ShaderInstructionFormat::SVdstSVsrc0; - inst.src_num = 1; - break; + + /* VOP1 using VOP3 encoding */ + case 0x1a0: inst.type = ShaderInstructionType::VFractF32; break; + case 0x1a1: inst.type = ShaderInstructionType::VTruncF32; break; + case 0x1a2: inst.type = ShaderInstructionType::VCeilF32; break; + case 0x1a3: inst.type = ShaderInstructionType::VRndneF32; break; + case 0x1a4: inst.type = ShaderInstructionType::VFloorF32; break; + case 0x1a5: inst.type = ShaderInstructionType::VExpF32; break; + case 0x1a7: inst.type = ShaderInstructionType::VLogF32; break; + case 0x1aa: inst.type = ShaderInstructionType::VRcpF32; break; + case 0x1ae: inst.type = ShaderInstructionType::VRsqF32; break; + case 0x1b3: inst.type = ShaderInstructionType::VSqrtF32; break; + case 0x1b5: inst.type = ShaderInstructionType::VSinF32; break; + case 0x1b6: inst.type = ShaderInstructionType::VCosF32; break; + default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop3 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 " (hash0 = 0x%08" PRIx32 ")\n", opcode, pc, dst->GetHash0()); diff --git a/source/emulator/src/Graphics/ShaderSpirv.cpp b/source/emulator/src/Graphics/ShaderSpirv.cpp index e4ec7e4..5817f5f 100644 --- a/source/emulator/src/Graphics/ShaderSpirv.cpp +++ b/source/emulator/src/Graphics/ShaderSpirv.cpp @@ -3578,6 +3578,41 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label) 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.IsDiscardBlock(label.GetDst()); + + String label_str = label.ToString(); + + static const char32_t* text_variant_a = UR"( + %scc_u_ = OpLoad %uint %scc + %scc_b_ = OpIEqual %bool %scc_u_ %uint_1 + OpSelectionMerge %