Refactor graphics #1

This commit is contained in:
nmzik
2026-07-19 00:54:31 +02:00
parent 7905f2d12f
commit cbc11d2eaf
71 changed files with 2051 additions and 3399 deletions
@@ -2,19 +2,14 @@
namespace Libs::Graphics {
hw_ctx_parser_func_t g_hw_ctx_func[Pm4::CX_NUM] = {};
hw_ctx_indirect_func_t g_hw_ctx_indirect_func[Pm4::CX_NUM] = {};
hw_sh_parser_func_t g_hw_sh_func[Pm4::SH_NUM] = {};
hw_sh_indirect_func_t g_hw_sh_indirect_func[Pm4::SH_NUM] = {};
hw_uc_parser_func_t g_hw_uc_func[Pm4::UC_NUM] = {};
hw_uc_indirect_func_t g_hw_uc_indirect_func[Pm4::UC_NUM] = {};
cp_op_parser_func_t g_cp_op_func[256] = {};
cp_op_parser_func_t g_cp_op_custom_func[Pm4::R_NUM] = {};
void GraphicsInitJmpTables() {
for (auto& func: g_hw_ctx_func) {
func = nullptr;
}
namespace {
constexpr auto MakeContextDispatchTable() {
std::array<hw_ctx_parser_func_t, Pm4::CX_NUM> g_hw_ctx_func {};
g_hw_ctx_func[Pm4::DB_RENDER_CONTROL] = HwCtxSetRenderControl;
g_hw_ctx_func[Pm4::DB_COUNT_CONTROL] = HwCtxSetDepthMetadataRegisters;
@@ -107,9 +102,11 @@ void GraphicsInitJmpTables() {
}
}
for (auto& func: g_hw_sh_func) {
func = nullptr;
}
return g_hw_ctx_func;
}
constexpr auto MakeShaderDispatchTable() {
std::array<hw_sh_parser_func_t, Pm4::SH_NUM> g_hw_sh_func {};
for (uint32_t slot = 0; slot < 32; slot++) {
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_PS_0 + slot * 1] = HwShSetPsUserSgpr;
@@ -174,9 +171,11 @@ void GraphicsInitJmpTables() {
g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_ADDR_HI_HS] = HwShIgnoreRegisters;
g_hw_sh_func[Pm4::SPI_SHADER_REQ_CTRL_LSHS] = HwShIgnoreRegisters;
for (auto& func: g_hw_uc_func) {
func = nullptr;
}
return g_hw_sh_func;
}
constexpr auto MakeUconfigDispatchTable() {
std::array<hw_uc_parser_func_t, Pm4::UC_NUM> g_hw_uc_func {};
g_hw_uc_func[Pm4::VGT_PRIMITIVE_TYPE] = HwUcSetPrimitiveType;
g_hw_uc_func[Pm4::VGT_INDEX_TYPE] = HwUcSetIndexType;
@@ -191,9 +190,11 @@ void GraphicsInitJmpTables() {
g_hw_uc_func[Pm4::GDS_OA_COUNTER] = HwUcSetGdsOaRegisters;
g_hw_uc_func[Pm4::GDS_OA_ADDRESS] = HwUcSetGdsOaRegisters;
for (auto& func: g_cp_op_func) {
func = nullptr;
}
return g_hw_uc_func;
}
constexpr auto MakeOpcodeDispatchTable() {
std::array<cp_op_parser_func_t, 256> g_cp_op_func {};
g_cp_op_func[Pm4::IT_NOP] = CpOpNop;
g_cp_op_func[Pm4::IT_SET_BASE] = CpOpSetBase;
@@ -238,9 +239,11 @@ void GraphicsInitJmpTables() {
g_cp_op_func[Pm4::IT_WAIT_ON_DE_COUNTER_DIFF] = CpOpWaitOnDeCounterDiff;
g_cp_op_func[Pm4::IT_GET_LOD_STATS] = CpOpGetLodStats;
for (auto& func: g_cp_op_custom_func) {
func = nullptr;
}
return g_cp_op_func;
}
constexpr auto MakeCustomOpcodeDispatchTable() {
std::array<cp_op_parser_func_t, Pm4::R_NUM> g_cp_op_custom_func {};
g_cp_op_custom_func[Pm4::R_DISPATCH_RESET] = CpOpDispatchReset;
g_cp_op_custom_func[Pm4::R_WAIT_MEM_32] = CpOpWaitRegMem32;
@@ -252,6 +255,22 @@ void GraphicsInitJmpTables() {
g_cp_op_custom_func[Pm4::R_FLIP] = CpOpFlip;
g_cp_op_custom_func[Pm4::R_RELEASE_MEM] = CpOpReleaseMem;
return g_cp_op_custom_func;
}
} // namespace
constinit const std::array<hw_ctx_parser_func_t, Pm4::CX_NUM> g_hw_ctx_func =
MakeContextDispatchTable();
constinit const std::array<hw_sh_parser_func_t, Pm4::SH_NUM> g_hw_sh_func =
MakeShaderDispatchTable();
constinit const std::array<hw_uc_parser_func_t, Pm4::UC_NUM> g_hw_uc_func =
MakeUconfigDispatchTable();
constinit const std::array<cp_op_parser_func_t, 256> g_cp_op_func = MakeOpcodeDispatchTable();
constinit const std::array<cp_op_parser_func_t, Pm4::R_NUM> g_cp_op_custom_func =
MakeCustomOpcodeDispatchTable();
void GraphicsInitJmpTables() {
GraphicsInitJmpTablesCxIndirect();
GraphicsInitJmpTablesShIndirect();
GraphicsInitJmpTablesUcIndirect();
@@ -3,6 +3,7 @@
#include "graphics/guest_gpu/pm4.h"
#include <array>
#include <cstdint>
namespace Libs::Graphics {
@@ -21,14 +22,14 @@ using hw_ctx_indirect_func_t = void (*)(CommandProcessor*, uint32_t, uint32_t);
using hw_uc_indirect_func_t = void (*)(CommandProcessor*, uint32_t, uint32_t);
using hw_sh_indirect_func_t = void (*)(CommandProcessor*, uint32_t, uint32_t);
extern hw_ctx_parser_func_t g_hw_ctx_func[Pm4::CX_NUM];
extern hw_ctx_indirect_func_t g_hw_ctx_indirect_func[Pm4::CX_NUM];
extern hw_sh_parser_func_t g_hw_sh_func[Pm4::SH_NUM];
extern hw_sh_indirect_func_t g_hw_sh_indirect_func[Pm4::SH_NUM];
extern hw_uc_parser_func_t g_hw_uc_func[Pm4::UC_NUM];
extern hw_uc_indirect_func_t g_hw_uc_indirect_func[Pm4::UC_NUM];
extern cp_op_parser_func_t g_cp_op_func[256];
extern cp_op_parser_func_t g_cp_op_custom_func[Pm4::R_NUM];
extern const std::array<hw_ctx_parser_func_t, Pm4::CX_NUM> g_hw_ctx_func;
extern hw_ctx_indirect_func_t g_hw_ctx_indirect_func[Pm4::CX_NUM];
extern const std::array<hw_sh_parser_func_t, Pm4::SH_NUM> g_hw_sh_func;
extern hw_sh_indirect_func_t g_hw_sh_indirect_func[Pm4::SH_NUM];
extern const std::array<hw_uc_parser_func_t, Pm4::UC_NUM> g_hw_uc_func;
extern hw_uc_indirect_func_t g_hw_uc_indirect_func[Pm4::UC_NUM];
extern const std::array<cp_op_parser_func_t, 256> g_cp_op_func;
extern const std::array<cp_op_parser_func_t, Pm4::R_NUM> g_cp_op_custom_func;
void GraphicsInitJmpTables();
void GraphicsInitJmpTablesCxIndirect();
+70 -85
View File
@@ -7,82 +7,76 @@
namespace Libs::Graphics::Prospero {
namespace {
struct FormatInfo {
uint32_t format;
uint32_t bytes_per_element;
uint32_t block_compressed_bytes_per_block;
uint32_t render_target_bytes_per_element;
bool supported_sampled_texture_format;
bool unsigned_integer_texture_format;
};
constexpr FormatInfo kFormatInfo[] = {
{GpuEnumValue(BufferFormat::k8UNorm), vk::Format::eR8Unorm, 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::k8SNorm), vk::Format::eUndefined, 0, 0, 1, false, false},
{GpuEnumValue(BufferFormat::k8UInt), vk::Format::eR8Uint, 1, 0, 1, true, true},
{GpuEnumValue(BufferFormat::k16UNorm), vk::Format::eR16Unorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16SNorm), vk::Format::eR16Snorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16UInt), vk::Format::eR16Uint, 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k16SInt), vk::Format::eR16Sint, 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k16Float), vk::Format::eR16Sfloat, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UNorm), vk::Format::eR8G8Unorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8SNorm), vk::Format::eR8G8Snorm, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UInt), vk::Format::eR8G8Uint, 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k8_8SInt), vk::Format::eR8G8Sint, 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k32UInt), vk::Format::eR32Uint, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k32SInt), vk::Format::eR32Sint, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32Float), vk::Format::eR32Sfloat, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UNorm), vk::Format::eR16G16Unorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16SNorm), vk::Format::eR16G16Snorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UInt), vk::Format::eR16G16Uint, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k16_16SInt), vk::Format::eR16G16Sint, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k16_16Float), vk::Format::eR16G16Sfloat, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k11_11_10Float), vk::Format::eB10G11R11UfloatPack32, 4, 0, 4, true,
false},
{GpuEnumValue(BufferFormat::k10_10_10_2UNorm), vk::Format::eA2B10G10R10UnormPack32, 4, 0, 4,
true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8UNorm), vk::Format::eR8G8B8A8Unorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8SNorm), vk::Format::eR8G8B8A8Snorm, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8UInt), vk::Format::eR8G8B8A8Uint, 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k8_8_8_8SInt), vk::Format::eR8G8B8A8Sint, 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32_32UInt), vk::Format::eR32G32Uint, 8, 0, 8, true, true},
{GpuEnumValue(BufferFormat::k32_32SInt), vk::Format::eR32G32Sint, 8, 0, 8, false, false},
{GpuEnumValue(BufferFormat::k32_32Float), vk::Format::eR32G32Sfloat, 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16UNorm), vk::Format::eR16G16B16A16Unorm, 8, 0, 8, true,
false},
{GpuEnumValue(BufferFormat::k16_16_16_16SNorm), vk::Format::eR16G16B16A16Snorm, 8, 0, 8, true,
false},
{GpuEnumValue(BufferFormat::k16_16_16_16UInt), vk::Format::eR16G16B16A16Uint, 8, 0, 8, true,
true},
{GpuEnumValue(BufferFormat::k16_16_16_16SInt), vk::Format::eR16G16B16A16Sint, 8, 0, 8, false,
false},
{GpuEnumValue(BufferFormat::k16_16_16_16Float), vk::Format::eR16G16B16A16Sfloat, 8, 0, 8, true,
false},
{GpuEnumValue(BufferFormat::k32_32_32UInt), vk::Format::eR32G32B32Uint, 12, 0, 12, true, true},
{GpuEnumValue(BufferFormat::k32_32_32SInt), vk::Format::eR32G32B32Sint, 12, 0, 12, false,
false},
{GpuEnumValue(BufferFormat::k32_32_32Float), vk::Format::eR32G32B32Sfloat, 12, 0, 12, true,
false},
{GpuEnumValue(BufferFormat::k32_32_32_32UInt), vk::Format::eR32G32B32A32Uint, 16, 0, 16, true,
true},
{GpuEnumValue(BufferFormat::k32_32_32_32SInt), vk::Format::eR32G32B32A32Sint, 16, 0, 16, false,
false},
{GpuEnumValue(BufferFormat::k32_32_32_32Float), vk::Format::eR32G32B32A32Sfloat, 16, 0, 16,
true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8Srgb), vk::Format::eR8G8B8A8Srgb, 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k9_9_9_5Float), vk::Format::eE5B9G9R9UfloatPack32, 4, 0, 0, true,
false},
{GpuEnumValue(BufferFormat::k5_6_5UNorm), vk::Format::eB5G6R5UnormPack16, 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k5_5_5_1UNorm), vk::Format::eR5G5B5A1UnormPack16, 2, 0, 2, true,
false},
{GpuEnumValue(BufferFormat::k4_4_4_4UNorm), vk::Format::eR4G4B4A4UnormPack16, 2, 0, 2, true,
false},
{GpuEnumValue(BufferFormat::kFmask8_S4_F4), vk::Format::eR32Sfloat, 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::kBc1UNorm), vk::Format::eBc1RgbaUnormBlock, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc1Srgb), vk::Format::eBc1RgbaSrgbBlock, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2UNorm), vk::Format::eBc2UnormBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2Srgb), vk::Format::eBc2SrgbBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3UNorm), vk::Format::eBc3UnormBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3Srgb), vk::Format::eBc3SrgbBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4UNorm), vk::Format::eBc4UnormBlock, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4SNorm), vk::Format::eBc4SnormBlock, 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5UNorm), vk::Format::eBc5UnormBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5SNorm), vk::Format::eBc5SnormBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6UFloat), vk::Format::eBc6HUfloatBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6SFloat), vk::Format::eBc6HSfloatBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7UNorm), vk::Format::eBc7UnormBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7Srgb), vk::Format::eBc7SrgbBlock, 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::k8UNorm), 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::k8SNorm), 0, 0, 1, false, false},
{GpuEnumValue(BufferFormat::k8UInt), 1, 0, 1, true, true},
{GpuEnumValue(BufferFormat::k16UNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16SNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k16UInt), 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k16SInt), 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k16Float), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8SNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k8_8UInt), 2, 0, 2, true, true},
{GpuEnumValue(BufferFormat::k8_8SInt), 2, 0, 2, false, false},
{GpuEnumValue(BufferFormat::k32UInt), 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k32SInt), 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32Float), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UNorm), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16SNorm), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k16_16UInt), 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k16_16SInt), 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k16_16Float), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k11_11_10Float), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k10_10_10_2UNorm), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8UNorm), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8SNorm), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8UInt), 4, 0, 4, true, true},
{GpuEnumValue(BufferFormat::k8_8_8_8SInt), 4, 0, 4, false, false},
{GpuEnumValue(BufferFormat::k32_32UInt), 8, 0, 8, true, true},
{GpuEnumValue(BufferFormat::k32_32SInt), 8, 0, 8, false, false},
{GpuEnumValue(BufferFormat::k32_32Float), 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16UNorm), 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16SNorm), 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k16_16_16_16UInt), 8, 0, 8, true, true},
{GpuEnumValue(BufferFormat::k16_16_16_16SInt), 8, 0, 8, false, false},
{GpuEnumValue(BufferFormat::k16_16_16_16Float), 8, 0, 8, true, false},
{GpuEnumValue(BufferFormat::k32_32_32UInt), 12, 0, 12, true, true},
{GpuEnumValue(BufferFormat::k32_32_32SInt), 12, 0, 12, false, false},
{GpuEnumValue(BufferFormat::k32_32_32Float), 12, 0, 12, true, false},
{GpuEnumValue(BufferFormat::k32_32_32_32UInt), 16, 0, 16, true, true},
{GpuEnumValue(BufferFormat::k32_32_32_32SInt), 16, 0, 16, false, false},
{GpuEnumValue(BufferFormat::k32_32_32_32Float), 16, 0, 16, true, false},
{GpuEnumValue(BufferFormat::k8_8_8_8Srgb), 4, 0, 4, true, false},
{GpuEnumValue(BufferFormat::k9_9_9_5Float), 4, 0, 0, true, false},
{GpuEnumValue(BufferFormat::k5_6_5UNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k5_5_5_1UNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::k4_4_4_4UNorm), 2, 0, 2, true, false},
{GpuEnumValue(BufferFormat::kFmask8_S4_F4), 1, 0, 1, true, false},
{GpuEnumValue(BufferFormat::kBc1UNorm), 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc1Srgb), 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2UNorm), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc2Srgb), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3UNorm), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc3Srgb), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4UNorm), 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc4SNorm), 0, 8, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5UNorm), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc5SNorm), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6UFloat), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc6SFloat), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7UNorm), 0, 16, 0, true, false},
{GpuEnumValue(BufferFormat::kBc7Srgb), 0, 16, 0, true, false},
};
constexpr auto MakeFormatInfoLookup() {
@@ -96,20 +90,11 @@ constexpr auto MakeFormatInfoLookup() {
constexpr auto kFormatInfoLookup = MakeFormatInfoLookup();
} // namespace
std::span<const FormatInfo> Formats() {
return kFormatInfo;
}
const FormatInfo* FindFormatInfo(uint32_t format) {
return format < kFormatInfoLookup.size() ? kFormatInfoLookup[format] : nullptr;
}
vk::Format SurfaceFormat(uint32_t format) {
const auto* info = FindFormatInfo(format);
return info != nullptr ? info->vk_format : vk::Format::eUndefined;
}
} // namespace
uint32_t NumBytesPerElement(uint32_t format) {
const auto* info = FindFormatInfo(format);
+6 -22
View File
@@ -2,31 +2,15 @@
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_GUEST_GPU_GPU_FORMAT_H_
#include "common/common.h"
#include "graphics/host_gpu/vulkanCommon.h"
#include <span>
namespace Libs::Graphics::Prospero {
struct FormatInfo {
uint32_t format = 0;
vk::Format vk_format = vk::Format::eUndefined;
uint32_t bytes_per_element = 0;
uint32_t block_compressed_bytes_per_block = 0;
uint32_t render_target_bytes_per_element = 0;
bool supported_sampled_texture_format = false;
bool unsigned_integer_texture_format = false;
};
std::span<const FormatInfo> Formats();
const FormatInfo* FindFormatInfo(uint32_t format);
vk::Format SurfaceFormat(uint32_t format);
uint32_t NumBytesPerElement(uint32_t format);
uint32_t BlockCompressedBytesPerBlock(uint32_t format);
uint32_t RenderTargetBytesPerElement(uint32_t format);
bool IsSupportedTextureFormat(uint32_t format);
bool IsUintTextureFormat(uint32_t format);
bool IsFmaskTextureFormat(uint32_t format);
uint32_t NumBytesPerElement(uint32_t format);
uint32_t BlockCompressedBytesPerBlock(uint32_t format);
uint32_t RenderTargetBytesPerElement(uint32_t format);
bool IsSupportedTextureFormat(uint32_t format);
bool IsUintTextureFormat(uint32_t format);
bool IsFmaskTextureFormat(uint32_t format);
} // namespace Libs::Graphics::Prospero
+6 -10
View File
@@ -626,8 +626,8 @@ struct GeUserVgprEn {
class Context {
public:
Context() = default;
virtual ~Context() = default;
Context() = default;
~Context() = default;
KYTY_CLASS_DEFAULT_COPY(Context);
@@ -723,10 +723,6 @@ public:
return m_depth_render_target.size;
}
void SetViewportZ(uint32_t viewport_id, float zmin, float zmax) {
m_screen_viewport.viewports[viewport_id].zmin = zmin;
m_screen_viewport.viewports[viewport_id].zmax = zmax;
}
void SetViewportZMin(uint32_t viewport_id, float zmin) {
m_screen_viewport.viewports[viewport_id].zmin = zmin;
}
@@ -942,8 +938,8 @@ private:
class UserConfig {
public:
UserConfig() = default;
virtual ~UserConfig() = default;
UserConfig() = default;
~UserConfig() = default;
KYTY_CLASS_DEFAULT_COPY(UserConfig);
@@ -980,8 +976,8 @@ private:
class Shader {
public:
Shader() = default;
virtual ~Shader() = default;
Shader() = default;
~Shader() = default;
KYTY_CLASS_DEFAULT_COPY(Shader);
+124 -107
View File
@@ -3,97 +3,104 @@
#include "common/assert.h"
#include "common/file.h"
#include <array>
namespace Libs::Graphics::Pm4 {
static const char* g_names[256] = {};
static const char* g_r_names[Pm4::R_NUM] = {};
static bool g_names_initialized = false;
namespace {
static void InitNames() {
if (!g_names_initialized) {
for (auto& n: g_names) {
n = "<unknown>";
}
enum class PacketType : uint32_t { Type0, Type1, Type2, Type3 };
for (auto& n: g_r_names) {
n = "<unknown>";
}
g_r_names[R_ZERO] = "R_ZERO";
g_r_names[R_DRAW_RESET] = "R_DRAW_RESET";
g_r_names[R_WAIT_FLIP_DONE] = "R_WAIT_FLIP_DONE";
g_r_names[R_DISPATCH_RESET] = "R_DISPATCH_RESET";
g_r_names[R_WAIT_MEM_32] = "R_WAIT_MEM_32";
g_r_names[R_PUSH_MARKER] = "R_PUSH_MARKER";
g_r_names[R_POP_MARKER] = "R_POP_MARKER";
g_r_names[R_ACQUIRE_MEM] = "R_ACQUIRE_MEM";
g_r_names[R_WRITE_DATA] = "R_WRITE_DATA";
g_r_names[R_WAIT_MEM_64] = "R_WAIT_MEM_64";
g_r_names[R_FLIP] = "R_FLIP";
g_r_names[R_RELEASE_MEM] = "R_RELEASE_MEM";
g_r_names[R_DMA_DATA] = "R_DMA_DATA";
g_names[IT_NOP] = "IT_NOP";
g_names[IT_SET_BASE] = "IT_SET_BASE";
g_names[IT_CLEAR_STATE] = "IT_CLEAR_STATE";
g_names[IT_INDEX_BUFFER_SIZE] = "IT_INDEX_BUFFER_SIZE";
g_names[IT_DISPATCH_DIRECT] = "IT_DISPATCH_DIRECT";
g_names[IT_DISPATCH_INDIRECT] = "IT_DISPATCH_INDIRECT";
g_names[IT_SET_PREDICATION] = "IT_SET_PREDICATION";
g_names[IT_COND_EXEC] = "IT_COND_EXEC";
g_names[IT_DRAW_INDIRECT] = "IT_DRAW_INDIRECT";
g_names[IT_DRAW_INDEX_INDIRECT] = "IT_DRAW_INDEX_INDIRECT";
g_names[IT_INDEX_BASE] = "IT_INDEX_BASE";
g_names[IT_DRAW_INDEX_2] = "IT_DRAW_INDEX_2";
g_names[IT_CONTEXT_CONTROL] = "IT_CONTEXT_CONTROL";
g_names[IT_INDEX_TYPE] = "IT_INDEX_TYPE";
g_names[IT_DRAW_INDIRECT_MULTI] = "IT_DRAW_INDIRECT_MULTI";
g_names[IT_DRAW_INDEX_AUTO] = "IT_DRAW_INDEX_AUTO";
g_names[IT_NUM_INSTANCES] = "IT_NUM_INSTANCES";
g_names[IT_INDIRECT_BUFFER_CNST] = "IT_INDIRECT_BUFFER_CNST";
g_names[IT_DRAW_INDEX_OFFSET_2] = "IT_DRAW_INDEX_OFFSET_2";
g_names[IT_WRITE_DATA] = "IT_WRITE_DATA";
g_names[IT_MEM_SEMAPHORE] = "IT_MEM_SEMAPHORE";
g_names[IT_DRAW_INDEX_INDIRECT_MULTI] = "IT_DRAW_INDEX_INDIRECT_MULTI";
g_names[IT_INDIRECT_BUFFER] = "IT_INDIRECT_BUFFER";
g_names[IT_COPY_DATA] = "IT_COPY_DATA";
g_names[IT_CP_DMA] = "IT_CP_DMA";
g_names[IT_PFP_SYNC_ME] = "IT_PFP_SYNC_ME";
g_names[IT_SURFACE_SYNC] = "IT_SURFACE_SYNC";
g_names[IT_EVENT_WRITE] = "IT_EVENT_WRITE";
g_names[IT_EVENT_WRITE_EOP] = "IT_EVENT_WRITE_EOP";
g_names[IT_EVENT_WRITE_EOS] = "IT_EVENT_WRITE_EOS";
g_names[IT_RELEASE_MEM] = "IT_RELEASE_MEM";
g_names[IT_DMA_DATA] = "IT_DMA_DATA";
g_names[IT_ACQUIRE_MEM] = "IT_ACQUIRE_MEM";
g_names[IT_REWIND] = "IT_REWIND";
g_names[IT_SET_SH_REG_INDIRECT] = "IT_SET_SH_REG_INDIRECT";
g_names[IT_SET_UCONFIG_REG_INDIRECT] = "IT_SET_UCONFIG_REG_INDIRECT";
g_names[IT_SET_CONFIG_REG] = "IT_SET_CONFIG_REG";
g_names[IT_SET_CONTEXT_REG] = "IT_SET_CONTEXT_REG";
g_names[IT_SET_SH_REG] = "IT_SET_SH_REG";
g_names[IT_SET_QUEUE_REG] = "IT_SET_QUEUE_REG";
g_names[IT_SET_UCONFIG_REG] = "IT_SET_UCONFIG_REG";
g_names[IT_SET_UCONFIG_REG_INDEX] = "IT_SET_UCONFIG_REG_INDEX";
g_names[IT_WRITE_CONST_RAM] = "IT_WRITE_CONST_RAM";
g_names[IT_DUMP_CONST_RAM] = "IT_DUMP_CONST_RAM";
g_names[IT_INCREMENT_CE_COUNTER] = "IT_INCREMENT_CE_COUNTER";
g_names[IT_INCREMENT_DE_COUNTER] = "IT_INCREMENT_DE_COUNTER";
g_names[IT_WAIT_ON_CE_COUNTER] = "IT_WAIT_ON_CE_COUNTER";
g_names[IT_WAIT_ON_DE_COUNTER_DIFF] = "IT_WAIT_ON_DE_COUNTER_DIFF";
g_names[IT_DISPATCH_DRAW_PREAMBLE] = "IT_DISPATCH_DRAW_PREAMBLE";
g_names[IT_DISPATCH_DRAW] = "IT_DISPATCH_DRAW";
g_names[IT_GET_LOD_STATS] = "IT_GET_LOD_STATS";
g_names[IT_SET_CONTEXT_REG_INDIRECT] = "IT_SET_CONTEXT_REG_INDIRECT";
g_names_initialized = true;
constexpr auto MakeRegisterNames() {
std::array<const char*, R_NUM> names {};
for (auto& name: names) {
name = "<unknown>";
}
names[R_ZERO] = "R_ZERO";
names[R_DRAW_RESET] = "R_DRAW_RESET";
names[R_WAIT_FLIP_DONE] = "R_WAIT_FLIP_DONE";
names[R_DISPATCH_RESET] = "R_DISPATCH_RESET";
names[R_WAIT_MEM_32] = "R_WAIT_MEM_32";
names[R_PUSH_MARKER] = "R_PUSH_MARKER";
names[R_POP_MARKER] = "R_POP_MARKER";
names[R_ACQUIRE_MEM] = "R_ACQUIRE_MEM";
names[R_WRITE_DATA] = "R_WRITE_DATA";
names[R_WAIT_MEM_64] = "R_WAIT_MEM_64";
names[R_FLIP] = "R_FLIP";
names[R_RELEASE_MEM] = "R_RELEASE_MEM";
names[R_DMA_DATA] = "R_DMA_DATA";
return names;
}
constexpr auto MakeOpcodeNames() {
std::array<const char*, 256> names {};
for (auto& name: names) {
name = "<unknown>";
}
names[IT_NOP] = "IT_NOP";
names[IT_SET_BASE] = "IT_SET_BASE";
names[IT_CLEAR_STATE] = "IT_CLEAR_STATE";
names[IT_INDEX_BUFFER_SIZE] = "IT_INDEX_BUFFER_SIZE";
names[IT_DISPATCH_DIRECT] = "IT_DISPATCH_DIRECT";
names[IT_DISPATCH_INDIRECT] = "IT_DISPATCH_INDIRECT";
names[IT_SET_PREDICATION] = "IT_SET_PREDICATION";
names[IT_COND_EXEC] = "IT_COND_EXEC";
names[IT_DRAW_INDIRECT] = "IT_DRAW_INDIRECT";
names[IT_DRAW_INDEX_INDIRECT] = "IT_DRAW_INDEX_INDIRECT";
names[IT_INDEX_BASE] = "IT_INDEX_BASE";
names[IT_DRAW_INDEX_2] = "IT_DRAW_INDEX_2";
names[IT_CONTEXT_CONTROL] = "IT_CONTEXT_CONTROL";
names[IT_INDEX_TYPE] = "IT_INDEX_TYPE";
names[IT_DRAW_INDIRECT_MULTI] = "IT_DRAW_INDIRECT_MULTI";
names[IT_DRAW_INDEX_AUTO] = "IT_DRAW_INDEX_AUTO";
names[IT_NUM_INSTANCES] = "IT_NUM_INSTANCES";
names[IT_INDIRECT_BUFFER_CNST] = "IT_INDIRECT_BUFFER_CNST";
names[IT_DRAW_INDEX_OFFSET_2] = "IT_DRAW_INDEX_OFFSET_2";
names[IT_WRITE_DATA] = "IT_WRITE_DATA";
names[IT_MEM_SEMAPHORE] = "IT_MEM_SEMAPHORE";
names[IT_DRAW_INDEX_INDIRECT_MULTI] = "IT_DRAW_INDEX_INDIRECT_MULTI";
names[IT_INDIRECT_BUFFER] = "IT_INDIRECT_BUFFER";
names[IT_COPY_DATA] = "IT_COPY_DATA";
names[IT_CP_DMA] = "IT_CP_DMA";
names[IT_PFP_SYNC_ME] = "IT_PFP_SYNC_ME";
names[IT_SURFACE_SYNC] = "IT_SURFACE_SYNC";
names[IT_EVENT_WRITE] = "IT_EVENT_WRITE";
names[IT_EVENT_WRITE_EOP] = "IT_EVENT_WRITE_EOP";
names[IT_EVENT_WRITE_EOS] = "IT_EVENT_WRITE_EOS";
names[IT_RELEASE_MEM] = "IT_RELEASE_MEM";
names[IT_DMA_DATA] = "IT_DMA_DATA";
names[IT_ACQUIRE_MEM] = "IT_ACQUIRE_MEM";
names[IT_REWIND] = "IT_REWIND";
names[IT_SET_SH_REG_INDIRECT] = "IT_SET_SH_REG_INDIRECT";
names[IT_SET_UCONFIG_REG_INDIRECT] = "IT_SET_UCONFIG_REG_INDIRECT";
names[IT_SET_CONFIG_REG] = "IT_SET_CONFIG_REG";
names[IT_SET_CONTEXT_REG] = "IT_SET_CONTEXT_REG";
names[IT_SET_SH_REG] = "IT_SET_SH_REG";
names[IT_SET_QUEUE_REG] = "IT_SET_QUEUE_REG";
names[IT_SET_UCONFIG_REG] = "IT_SET_UCONFIG_REG";
names[IT_SET_UCONFIG_REG_INDEX] = "IT_SET_UCONFIG_REG_INDEX";
names[IT_WRITE_CONST_RAM] = "IT_WRITE_CONST_RAM";
names[IT_DUMP_CONST_RAM] = "IT_DUMP_CONST_RAM";
names[IT_INCREMENT_CE_COUNTER] = "IT_INCREMENT_CE_COUNTER";
names[IT_INCREMENT_DE_COUNTER] = "IT_INCREMENT_DE_COUNTER";
names[IT_WAIT_ON_CE_COUNTER] = "IT_WAIT_ON_CE_COUNTER";
names[IT_WAIT_ON_DE_COUNTER_DIFF] = "IT_WAIT_ON_DE_COUNTER_DIFF";
names[IT_DISPATCH_DRAW_PREAMBLE] = "IT_DISPATCH_DRAW_PREAMBLE";
names[IT_DISPATCH_DRAW] = "IT_DISPATCH_DRAW";
names[IT_GET_LOD_STATS] = "IT_GET_LOD_STATS";
names[IT_SET_CONTEXT_REG_INDIRECT] = "IT_SET_CONTEXT_REG_INDIRECT";
return names;
}
constexpr auto g_register_names = MakeRegisterNames();
constexpr auto g_opcode_names = MakeOpcodeNames();
} // namespace
void DumpPm4PacketStream(Common::File* file, uint32_t* cmd_buffer, uint32_t start_dw,
uint32_t num_dw) {
InitNames();
// db_dump();
file->Printf("----- Buffer --- dwords: 0x%05" PRIx32 ", offset : %u, addr: %016" PRIx64
@@ -112,36 +119,46 @@ void DumpPm4PacketStream(Common::File* file, uint32_t* cmd_buffer, uint32_t star
uint32_t len = 0;
if ((cmd_id & 0xC0000000u) == 0xC0000000u) {
const bool sh_gx = (cmd_id & 0x2u) == 0;
const uint8_t op = ((cmd_id >> 8u) & 0xffu);
const auto r = KYTY_PM4_R(cmd_id);
len = ((cmd_id >> 16u) & 0x3fffu) + 1;
const auto packet_type = static_cast<PacketType>(cmd_id >> 30u);
switch (packet_type) {
case PacketType::Type3: {
const bool sh_gx = (cmd_id & 0x2u) == 0;
const uint8_t op = ((cmd_id >> 8u) & 0xffu);
const auto r = KYTY_PM4_R(cmd_id);
len = ((cmd_id >> 16u) & 0x3fffu) + 1;
file->Printf("%s %s(OP:0x%02" PRIx8 ") SH:%s CNT:%u\n", g_names[op],
(op == IT_NOP ? g_r_names[r] : ""), op, sh_gx ? "GX" : "CX", len);
EXIT_NOT_IMPLEMENTED(len >= dw);
for (uint32_t i = 0; i < len; i++) {
file->Printf(" | 0x%08" PRIx32 " | \n", cmd[i]);
}
file->Printf("%s %s(OP:0x%02" PRIx8 ") SH:%s CNT:%u\n", g_opcode_names[op],
(op == IT_NOP ? g_register_names[r] : ""), op, sh_gx ? "GX" : "CX",
len);
if ((op == IT_SET_CONTEXT_REG_INDIRECT || op == IT_SET_SH_REG_INDIRECT ||
op == IT_SET_UCONFIG_REG_INDIRECT) &&
len == 4) {
auto* indirect_buffer =
reinterpret_cast<uint32_t*>((static_cast<uint64_t>(cmd[0]) & 0xfffffffcu) |
(static_cast<uint64_t>(cmd[1]) << 32u));
const uint32_t indirect_num_regs = cmd[3] & 0x3fffu;
for (uint32_t i = 0; indirect_buffer != nullptr && i < indirect_num_regs;
i++, indirect_buffer += 2) {
file->Printf(" | | offset = 0x%08" PRIx32
", value = 0x%08" PRIx32 "\n",
indirect_buffer[0], indirect_buffer[1]);
for (uint32_t i = 0; i < len; i++) {
file->Printf(" | 0x%08" PRIx32 " | \n", cmd[i]);
}
if ((op == IT_SET_CONTEXT_REG_INDIRECT || op == IT_SET_SH_REG_INDIRECT ||
op == IT_SET_UCONFIG_REG_INDIRECT) &&
len == 4) {
auto* indirect_buffer =
reinterpret_cast<uint32_t*>((static_cast<uint64_t>(cmd[0]) & 0xfffffffcu) |
(static_cast<uint64_t>(cmd[1]) << 32u));
const uint32_t indirect_num_regs = cmd[3] & 0x3fffu;
for (uint32_t i = 0; indirect_buffer != nullptr && i < indirect_num_regs;
i++, indirect_buffer += 2) {
file->Printf(" | | offset = 0x%08" PRIx32
", value = 0x%08" PRIx32 "\n",
indirect_buffer[0], indirect_buffer[1]);
}
}
break;
}
} else {
file->Printf("?????\n");
case PacketType::Type0:
case PacketType::Type1:
case PacketType::Type2:
file->Printf("<unsupported TYPE%u packet>\n", static_cast<uint32_t>(packet_type));
break;
}
cmd += len;
+71 -361
View File
@@ -1392,81 +1392,82 @@ static const Standard64KB128Tables& GetStandard64KB128Tables() {
return tables;
}
void TileConvertTiledToLinearStandard64KB32(void* dst, const void* src, uint32_t width,
uint32_t height, uint32_t pitch, uint64_t size,
uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
template <typename T, uint32_t BlockWidth, uint32_t BlockHeight, uint32_t CopyBatch,
bool ExactSurfaceRequiresFullWidth, typename Tables>
static void ConvertTiledToLinearStandard64KBElements(void* dst, const void* src, uint32_t width,
uint32_t height, uint32_t pitch, uint64_t size,
uint64_t src_size, uint32_t src_x,
uint32_t src_y, const Tables& tables) {
static_assert(BlockWidth * BlockHeight * sizeof(T) == 64u * 1024u);
static_assert(CopyBatch != 0 && BlockWidth % CopyBatch == 0);
EXIT_IF(dst == nullptr || src == nullptr);
EXIT_NOT_IMPLEMENTED(pitch == 0);
const bool tail_block = (src_size != 0 && (src_x != 0 || src_y != 0 || size < src_size));
EXIT_NOT_IMPLEMENTED(width > pitch);
EXIT_NOT_IMPLEMENTED(tail_block && (src_x + width > 128u || src_y + height > 128u));
EXIT_NOT_IMPLEMENTED(tail_block &&
(src_x + width > BlockWidth || src_y + height > BlockHeight));
auto* dst32 = static_cast<uint32_t*>(dst);
const auto* src32 = static_cast<const uint32_t*>(src);
const auto& tables = GetStandard64KB32Tables();
const auto size_words = size >> 2u;
const auto src_size_words = (src_size != 0 ? src_size : size) >> 2u;
auto* dst_elements = static_cast<T*>(dst);
const auto* src_elements = static_cast<const T*>(src);
const auto element_count = size / sizeof(T);
const auto src_element_count = (src_size != 0 ? src_size : size) / sizeof(T);
const auto blocks_per_row =
(tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch, 128u) >> 7u));
const auto dst_words = static_cast<uint64_t>(pitch) * height;
const bool exact_surface =
(!tail_block && width == pitch && (size & 3u) == 0 && size_words == dst_words);
const auto* x_words = tables.x_words.data();
const auto* y_words = tables.y_words.data();
tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch, BlockWidth) / BlockWidth);
const auto dst_element_count = static_cast<uint64_t>(pitch) * height;
const bool exact_surface = !tail_block && (!ExactSurfaceRequiresFullWidth || width == pitch) &&
size % sizeof(T) == 0 && element_count == dst_element_count;
const auto* x_elements = tables.x_words.data();
const auto* y_elements = tables.y_words.data();
if (!exact_surface) {
std::memset(dst32, 0, static_cast<size_t>(size));
std::memset(dst_elements, 0, static_cast<size_t>(size));
}
for (uint32_t block_y = 0; block_y < height; block_y += 128u) {
const uint32_t block_height = std::min(128u, height - block_y);
constexpr uint64_t ElementsPerBlock = BlockWidth * BlockHeight;
for (uint32_t block_y = 0; block_y < height; block_y += BlockHeight) {
const uint32_t copy_height = std::min(BlockHeight, height - block_y);
for (uint32_t block_x = 0; block_x < width; block_x += 128u) {
const uint32_t block_width = std::min(128u, width - block_x);
for (uint32_t block_x = 0; block_x < width; block_x += BlockWidth) {
const uint32_t copy_width = std::min(BlockWidth, width - block_x);
const uint64_t block_base =
(tail_block
? 0u
: (((static_cast<uint64_t>(block_y) >> 7u) * blocks_per_row) + (block_x >> 7u))
<< 14u);
const bool full_block =
(!tail_block && block_width == 128u && block_height == 128u &&
block_base + 16384u <= src_size_words &&
(static_cast<uint64_t>(block_y + 127u) * pitch) + block_x + 127u < size_words);
tail_block ? 0u
: ((static_cast<uint64_t>(block_y / BlockHeight) * blocks_per_row) +
block_x / BlockWidth) *
ElementsPerBlock;
const bool full_block = !tail_block && copy_width == BlockWidth &&
copy_height == BlockHeight &&
block_base + ElementsPerBlock <= src_element_count &&
static_cast<uint64_t>(block_y + BlockHeight - 1u) * pitch +
block_x + BlockWidth - 1u <
element_count;
if (full_block) {
for (uint32_t local_y = 0; local_y < 128u; local_y++) {
for (uint32_t local_y = 0; local_y < BlockHeight; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
static_cast<uint64_t>(block_y + local_y) * pitch + block_x;
const uint64_t src_row = block_base + y_elements[src_y + local_y];
for (uint32_t local_x = 0; local_x < 128u; local_x += 4u) {
dst32[dst_row + local_x + 0u] =
src32[src_row + x_words[src_x + local_x + 0u]];
dst32[dst_row + local_x + 1u] =
src32[src_row + x_words[src_x + local_x + 1u]];
dst32[dst_row + local_x + 2u] =
src32[src_row + x_words[src_x + local_x + 2u]];
dst32[dst_row + local_x + 3u] =
src32[src_row + x_words[src_x + local_x + 3u]];
for (uint32_t local_x = 0; local_x < BlockWidth; local_x += CopyBatch) {
for (uint32_t i = 0; i < CopyBatch; i++) {
dst_elements[dst_row + local_x + i] =
src_elements[src_row + x_elements[src_x + local_x + i]];
}
}
}
continue;
}
for (uint32_t local_y = 0; local_y < block_height; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_y = 0; local_y < copy_height; local_y++) {
const uint64_t dst_row = static_cast<uint64_t>(block_y + local_y) * pitch + block_x;
const uint64_t src_row = block_base + y_elements[src_y + local_y];
for (uint32_t local_x = 0; local_x < block_width; local_x++) {
for (uint32_t local_x = 0; local_x < copy_width; local_x++) {
const uint64_t dst_index = dst_row + local_x;
const uint64_t src_index = src_row + x_words[src_x + local_x];
const uint64_t src_index = src_row + x_elements[src_x + local_x];
if (src_index < src_size_words && dst_index < size_words) {
dst32[dst_index] = src32[src_index];
if (src_index < src_element_count && dst_index < element_count) {
dst_elements[dst_index] = src_elements[src_index];
}
}
}
@@ -1474,6 +1475,15 @@ void TileConvertTiledToLinearStandard64KB32(void* dst, const void* src, uint32_t
}
}
void TileConvertTiledToLinearStandard64KB32(void* dst, const void* src, uint32_t width,
uint32_t height, uint32_t pitch, uint64_t size,
uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
ConvertTiledToLinearStandard64KBElements<uint32_t, 128u, 128u, 4u, true>(
dst, src, width, height, pitch, size, src_size, src_x, src_y, GetStandard64KB32Tables());
}
void TileConvertLinearToTiledStandard64KB32(void* dst, const void* src, uint32_t width,
uint32_t height, uint32_t pitch, uint64_t size) {
KYTY_PROFILER_FUNCTION();
@@ -1540,81 +1550,8 @@ void TileConvertTiledToLinearStandard64KB16(void* dst, const void* src, uint32_t
uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(dst == nullptr || src == nullptr);
EXIT_NOT_IMPLEMENTED(pitch == 0);
const bool tail_block = (src_size != 0 && (src_x != 0 || src_y != 0 || size < src_size));
EXIT_NOT_IMPLEMENTED(width > pitch);
EXIT_NOT_IMPLEMENTED(tail_block && (src_x + width > 256u || src_y + height > 128u));
auto* dst16 = static_cast<uint16_t*>(dst);
const auto* src16 = static_cast<const uint16_t*>(src);
const auto& tables = GetStandard64KB16Tables();
const auto size_words = size >> 1u;
const auto src_size_words = (src_size != 0 ? src_size : size) >> 1u;
const auto blocks_per_row =
(tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch, 256u) >> 8u));
const auto dst_words = static_cast<uint64_t>(pitch) * height;
const bool exact_surface =
(!tail_block && width == pitch && (size & 1u) == 0 && size_words == dst_words);
const auto* x_words = tables.x_words.data();
const auto* y_words = tables.y_words.data();
if (!exact_surface) {
std::memset(dst16, 0, static_cast<size_t>(size));
}
for (uint32_t block_y = 0; block_y < height; block_y += 128u) {
const uint32_t block_height = std::min(128u, height - block_y);
for (uint32_t block_x = 0; block_x < width; block_x += 256u) {
const uint32_t block_width = std::min(256u, width - block_x);
const uint64_t block_base =
(tail_block
? 0u
: (((static_cast<uint64_t>(block_y) >> 7u) * blocks_per_row) + (block_x >> 8u))
<< 15u);
const bool full_block =
(!tail_block && block_width == 256u && block_height == 128u &&
block_base + 32768u <= src_size_words &&
(static_cast<uint64_t>(block_y + 127u) * pitch) + block_x + 255u < size_words);
if (full_block) {
for (uint32_t local_y = 0; local_y < 128u; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < 256u; local_x += 4u) {
dst16[dst_row + local_x + 0u] =
src16[src_row + x_words[src_x + local_x + 0u]];
dst16[dst_row + local_x + 1u] =
src16[src_row + x_words[src_x + local_x + 1u]];
dst16[dst_row + local_x + 2u] =
src16[src_row + x_words[src_x + local_x + 2u]];
dst16[dst_row + local_x + 3u] =
src16[src_row + x_words[src_x + local_x + 3u]];
}
}
continue;
}
for (uint32_t local_y = 0; local_y < block_height; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < block_width; local_x++) {
const uint64_t dst_index = dst_row + local_x;
const uint64_t src_index = src_row + x_words[src_x + local_x];
if (src_index < src_size_words && dst_index < size_words) {
dst16[dst_index] = src16[src_index];
}
}
}
}
}
ConvertTiledToLinearStandard64KBElements<uint16_t, 256u, 128u, 4u, true>(
dst, src, width, height, pitch, size, src_size, src_x, src_y, GetStandard64KB16Tables());
}
static void TileConvertTiledToLinearStandard64KB8Elements(
@@ -1622,82 +1559,9 @@ static void TileConvertTiledToLinearStandard64KB8Elements(
uint32_t pitch_elements, uint64_t size, uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(dst == nullptr || src == nullptr);
EXIT_NOT_IMPLEMENTED(pitch_elements == 0);
const bool tail_block = (src_size != 0 && (src_x != 0 || src_y != 0 || size < src_size));
EXIT_NOT_IMPLEMENTED(width_elements > pitch_elements);
EXIT_NOT_IMPLEMENTED(tail_block &&
(src_x + width_elements > 256u || src_y + height_elements > 256u));
auto* dst8 = static_cast<uint8_t*>(dst);
const auto* src8 = static_cast<const uint8_t*>(src);
const auto& tables = GetStandard64KB8Tables();
const auto size_words = size;
const auto src_size_words = (src_size != 0 ? src_size : size);
const auto blocks_per_row =
(tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch_elements, 256u) >> 8u));
const auto dst_words = static_cast<uint64_t>(pitch_elements) * height_elements;
const bool exact_surface = (!tail_block && size_words == dst_words);
const auto* x_words = tables.x_words.data();
const auto* y_words = tables.y_words.data();
if (!exact_surface) {
std::memset(dst8, 0, static_cast<size_t>(size));
}
for (uint32_t block_y = 0; block_y < height_elements; block_y += 256u) {
const uint32_t block_height = std::min(256u, height_elements - block_y);
for (uint32_t block_x = 0; block_x < width_elements; block_x += 256u) {
const uint32_t block_width = std::min(256u, width_elements - block_x);
const uint64_t block_base =
(tail_block
? 0u
: (((static_cast<uint64_t>(block_y) >> 8u) * blocks_per_row) + (block_x >> 8u))
<< 16u);
const bool full_block =
(!tail_block && block_width == 256u && block_height == 256u &&
block_base + 65536u <= src_size_words &&
(static_cast<uint64_t>(block_y + 255u) * pitch_elements) + block_x + 255u <
size_words);
if (full_block) {
for (uint32_t local_y = 0; local_y < 256u; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < 256u; local_x += 4u) {
dst8[dst_row + local_x + 0u] =
src8[src_row + x_words[src_x + local_x + 0u]];
dst8[dst_row + local_x + 1u] =
src8[src_row + x_words[src_x + local_x + 1u]];
dst8[dst_row + local_x + 2u] =
src8[src_row + x_words[src_x + local_x + 2u]];
dst8[dst_row + local_x + 3u] =
src8[src_row + x_words[src_x + local_x + 3u]];
}
}
continue;
}
for (uint32_t local_y = 0; local_y < block_height; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < block_width; local_x++) {
const uint64_t dst_index = dst_row + local_x;
const uint64_t src_index = src_row + x_words[src_x + local_x];
if (src_index < src_size_words && dst_index < size_words) {
dst8[dst_index] = src8[src_index];
}
}
}
}
}
ConvertTiledToLinearStandard64KBElements<uint8_t, 256u, 256u, 4u, false>(
dst, src, width_elements, height_elements, pitch_elements, size, src_size, src_x, src_y,
GetStandard64KB8Tables());
}
static void TileConvertTiledToLinearStandard64KB64Elements(
@@ -1705,90 +1569,9 @@ static void TileConvertTiledToLinearStandard64KB64Elements(
uint32_t pitch_elements, uint64_t size, uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(dst == nullptr || src == nullptr);
EXIT_NOT_IMPLEMENTED(pitch_elements == 0);
const bool tail_block = (src_size != 0 && (src_x != 0 || src_y != 0 || size < src_size));
EXIT_NOT_IMPLEMENTED(width_elements > pitch_elements);
EXIT_NOT_IMPLEMENTED(tail_block &&
(src_x + width_elements > 128u || src_y + height_elements > 64u));
auto* dst64 = static_cast<uint64_t*>(dst);
const auto* src64 = static_cast<const uint64_t*>(src);
const auto& tables = GetStandard64KB64Tables();
const auto size_words = size >> 3u;
const auto src_size_words = (src_size != 0 ? src_size : size) >> 3u;
const auto blocks_per_row =
(tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch_elements, 128u) >> 7u));
const auto dst_words = static_cast<uint64_t>(pitch_elements) * height_elements;
const bool exact_surface = (!tail_block && (size & 7u) == 0 && size_words == dst_words);
const auto* x_words = tables.x_words.data();
const auto* y_words = tables.y_words.data();
if (!exact_surface) {
std::memset(dst64, 0, static_cast<size_t>(size));
}
for (uint32_t block_y = 0; block_y < height_elements; block_y += 64u) {
const uint32_t block_height = std::min(64u, height_elements - block_y);
for (uint32_t block_x = 0; block_x < width_elements; block_x += 128u) {
const uint32_t block_width = std::min(128u, width_elements - block_x);
const uint64_t block_base =
(tail_block
? 0u
: (((static_cast<uint64_t>(block_y) >> 6u) * blocks_per_row) + (block_x >> 7u))
<< 13u);
const bool full_block =
(!tail_block && block_width == 128u && block_height == 64u &&
block_base + 8192u <= src_size_words &&
(static_cast<uint64_t>(block_y + 63u) * pitch_elements) + block_x + 127u <
size_words);
if (full_block) {
for (uint32_t local_y = 0; local_y < 64u; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < 128u; local_x += 8u) {
dst64[dst_row + local_x + 0u] =
src64[src_row + x_words[src_x + local_x + 0u]];
dst64[dst_row + local_x + 1u] =
src64[src_row + x_words[src_x + local_x + 1u]];
dst64[dst_row + local_x + 2u] =
src64[src_row + x_words[src_x + local_x + 2u]];
dst64[dst_row + local_x + 3u] =
src64[src_row + x_words[src_x + local_x + 3u]];
dst64[dst_row + local_x + 4u] =
src64[src_row + x_words[src_x + local_x + 4u]];
dst64[dst_row + local_x + 5u] =
src64[src_row + x_words[src_x + local_x + 5u]];
dst64[dst_row + local_x + 6u] =
src64[src_row + x_words[src_x + local_x + 6u]];
dst64[dst_row + local_x + 7u] =
src64[src_row + x_words[src_x + local_x + 7u]];
}
}
continue;
}
for (uint32_t local_y = 0; local_y < block_height; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < block_width; local_x++) {
const uint64_t dst_index = dst_row + local_x;
const uint64_t src_index = src_row + x_words[src_x + local_x];
if (src_index < src_size_words && dst_index < size_words) {
dst64[dst_index] = src64[src_index];
}
}
}
}
}
ConvertTiledToLinearStandard64KBElements<uint64_t, 128u, 64u, 8u, false>(
dst, src, width_elements, height_elements, pitch_elements, size, src_size, src_x, src_y,
GetStandard64KB64Tables());
}
static void TileConvertLinearToTiledStandard64KB64Elements(
@@ -1822,82 +1605,9 @@ static void TileConvertTiledToLinearStandard64KB128Elements(
uint32_t pitch_elements, uint64_t size, uint64_t src_size, uint32_t src_x, uint32_t src_y) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(dst == nullptr || src == nullptr);
EXIT_NOT_IMPLEMENTED(pitch_elements == 0);
const bool tail_block = (src_size != 0 && (src_x != 0 || src_y != 0 || size < src_size));
EXIT_NOT_IMPLEMENTED(width_elements > pitch_elements);
EXIT_NOT_IMPLEMENTED(tail_block &&
(src_x + width_elements > 64u || src_y + height_elements > 64u));
auto* dst128 = static_cast<Uint128*>(dst);
const auto* src128 = static_cast<const Uint128*>(src);
const auto& tables = GetStandard64KB128Tables();
const auto size_words = size >> 4u;
const auto src_size_words = (src_size != 0 ? src_size : size) >> 4u;
const auto blocks_per_row =
(tail_block ? 1u : static_cast<uint64_t>(AlignUp(pitch_elements, 64u) >> 6u));
const auto dst_words = static_cast<uint64_t>(pitch_elements) * height_elements;
const bool exact_surface = (!tail_block && (size & 15u) == 0 && size_words == dst_words);
const auto* x_words = tables.x_words.data();
const auto* y_words = tables.y_words.data();
if (!exact_surface) {
std::memset(dst128, 0, static_cast<size_t>(size));
}
for (uint32_t block_y = 0; block_y < height_elements; block_y += 64u) {
const uint32_t block_height = std::min(64u, height_elements - block_y);
for (uint32_t block_x = 0; block_x < width_elements; block_x += 64u) {
const uint32_t block_width = std::min(64u, width_elements - block_x);
const uint64_t block_base =
(tail_block
? 0u
: (((static_cast<uint64_t>(block_y) >> 6u) * blocks_per_row) + (block_x >> 6u))
<< 12u);
const bool full_block =
(!tail_block && block_width == 64u && block_height == 64u &&
block_base + 4096u <= src_size_words &&
(static_cast<uint64_t>(block_y + 63u) * pitch_elements) + block_x + 63u <
size_words);
if (full_block) {
for (uint32_t local_y = 0; local_y < 64u; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < 64u; local_x += 4u) {
dst128[dst_row + local_x + 0u] =
src128[src_row + x_words[src_x + local_x + 0u]];
dst128[dst_row + local_x + 1u] =
src128[src_row + x_words[src_x + local_x + 1u]];
dst128[dst_row + local_x + 2u] =
src128[src_row + x_words[src_x + local_x + 2u]];
dst128[dst_row + local_x + 3u] =
src128[src_row + x_words[src_x + local_x + 3u]];
}
}
continue;
}
for (uint32_t local_y = 0; local_y < block_height; local_y++) {
const uint64_t dst_row =
(static_cast<uint64_t>(block_y + local_y) * pitch_elements) + block_x;
const uint64_t src_row = block_base + y_words[src_y + local_y];
for (uint32_t local_x = 0; local_x < block_width; local_x++) {
const uint64_t dst_index = dst_row + local_x;
const uint64_t src_index = src_row + x_words[src_x + local_x];
if (src_index < src_size_words && dst_index < size_words) {
dst128[dst_index] = src128[src_index];
}
}
}
}
}
ConvertTiledToLinearStandard64KBElements<Uint128, 64u, 64u, 4u, false>(
dst, src, width_elements, height_elements, pitch_elements, size, src_size, src_x, src_y,
GetStandard64KB128Tables());
}
void TileConvertTiledToLinearStandard64KB(void* dst, const void* src, uint32_t format,