gpu rewrite initial commit

This commit is contained in:
DH 2024-09-25 16:00:55 +03:00
parent 0d4ed51cd9
commit 4cf808facd
133 changed files with 35491 additions and 4 deletions

View file

@ -0,0 +1,289 @@
#pragma once
#include <cstdint>
namespace gnm {
enum DataFormat : unsigned {
kDataFormatInvalid = 0x00000000,
kDataFormat8 = 0x00000001,
kDataFormat16 = 0x00000002,
kDataFormat8_8 = 0x00000003,
kDataFormat32 = 0x00000004,
kDataFormat16_16 = 0x00000005,
kDataFormat10_11_11 = 0x00000006,
kDataFormat11_11_10 = 0x00000007,
kDataFormat10_10_10_2 = 0x00000008,
kDataFormat2_10_10_10 = 0x00000009,
kDataFormat8_8_8_8 = 0x0000000a,
kDataFormat32_32 = 0x0000000b,
kDataFormat16_16_16_16 = 0x0000000c,
kDataFormat32_32_32 = 0x0000000d,
kDataFormat32_32_32_32 = 0x0000000e,
kDataFormat5_6_5 = 0x00000010,
kDataFormat1_5_5_5 = 0x00000011,
kDataFormat5_5_5_1 = 0x00000012,
kDataFormat4_4_4_4 = 0x00000013,
kDataFormat8_24 = 0x00000014,
kDataFormat24_8 = 0x00000015,
kDataFormatX24_8_32 = 0x00000016,
kDataFormatGB_GR = 0x00000020,
kDataFormatBG_RG = 0x00000021,
kDataFormat5_9_9_9 = 0x00000022,
kDataFormatBc1 = 0x00000023,
kDataFormatBc2 = 0x00000024,
kDataFormatBc3 = 0x00000025,
kDataFormatBc4 = 0x00000026,
kDataFormatBc5 = 0x00000027,
kDataFormatBc6 = 0x00000028,
kDataFormatBc7 = 0x00000029,
kDataFormatFmask8_S2_F1 = 0x0000002C,
kDataFormatFmask8_S4_F1 = 0x0000002D,
kDataFormatFmask8_S8_F1 = 0x0000002E,
kDataFormatFmask8_S2_F2 = 0x0000002F,
kDataFormatFmask8_S4_F2 = 0x00000030,
kDataFormatFmask8_S4_F4 = 0x00000031,
kDataFormatFmask16_S16_F1 = 0x00000032,
kDataFormatFmask16_S8_F2 = 0x00000033,
kDataFormatFmask32_S16_F2 = 0x00000034,
kDataFormatFmask32_S8_F4 = 0x00000035,
kDataFormatFmask32_S8_F8 = 0x00000036,
kDataFormatFmask64_S16_F4 = 0x00000037,
kDataFormatFmask64_S16_F8 = 0x00000038,
kDataFormat4_4 = 0x00000039,
kDataFormat6_5_5 = 0x0000003A,
kDataFormat1 = 0x0000003B,
kDataFormat1Reversed = 0x0000003C,
};
enum NumericFormat : unsigned {
kNumericFormatUNorm = 0x00000000,
kNumericFormatSNorm = 0x00000001,
kNumericFormatUScaled = 0x00000002,
kNumericFormatSScaled = 0x00000003,
kNumericFormatUInt = 0x00000004,
kNumericFormatSInt = 0x00000005,
kNumericFormatSNormNoZero = 0x00000006,
kNumericFormatFloat = 0x00000007,
kNumericFormatSrgb = 0x00000009,
kNumericFormatUBNorm = 0x0000000A,
kNumericFormatUBNormNoZero = 0x0000000B,
kNumericFormatUBInt = 0x0000000C,
kNumericFormatUBScaled = 0x0000000D,
};
enum ZFormat {
kZFormatInvalid = 0,
kZFormat16 = 1,
kZFormat32Float = 3,
};
enum StencilFormat {
kStencilInvalid = 0,
kStencil8 = 1,
};
enum class TextureType : std::uint8_t {
Dim1D = 8,
Dim2D,
Dim3D,
Cube,
Array1D,
Array2D,
Msaa2D,
MsaaArray2D,
};
enum class IndexType : std::uint8_t {
Int16,
Int32,
};
enum class PrimitiveType : std::uint8_t {
None = 0x00,
PointList = 0x01,
LineList = 0x02,
LineStrip = 0x03,
TriList = 0x04,
TriFan = 0x05,
TriStrip = 0x06,
Patch = 0x09,
LineListAdjacency = 0x0a,
LineStripAdjacency = 0x0b,
TriListAdjacency = 0x0c,
TriStripAdjacency = 0x0d,
RectList = 0x11,
LineLoop = 0x12,
QuadList = 0x13,
QuadStrip = 0x14,
Polygon = 0x15,
};
enum class StencilOp : std::uint8_t {
Keep,
Zero,
Ones,
ReplaceTest,
ReplaceOp,
AddClamp,
SubClamp,
Invert,
AddWrap,
SubWrap,
And,
Or,
Xor,
Nand,
Nor,
Xnor,
};
enum class RasterOp : std::uint8_t {
Blackness = 0x00,
Nor = 0x05,
AndInverted = 0x0a,
CopyInverted = 0x0f,
AndReverse = 0x44,
Invert = 0x55,
Xor = 0x5a,
Nand = 0x5f,
And = 0x88,
Equiv = 0x99,
Noop = 0xaa,
OrInverted = 0xaf,
Copy = 0xcc,
OrReverse = 0xdd,
Or = 0xee,
Set = 0xff,
};
enum class CompareFunc : std::uint8_t {
Never,
Less,
Equal,
LessEqual,
Greater,
NotEqual,
GreaterEqual,
Always,
};
enum class BorderColor : std::uint8_t {
OpaqueBlack,
TransparentBlack,
White,
Custom,
};
enum class FilterMode : std::uint8_t {
Blend,
Min,
Max,
};
enum class Filter : std::uint8_t {
Point,
Bilinear,
AnisoPoint,
AnisoLinear,
};
enum class MipFilter : std::uint8_t {
None = 0,
Point = 1,
Linear = 2,
};
enum class CbMode : std::uint8_t {
Disable = 0,
Normal = 1,
EliminateFastClear = 2,
Resolve = 3,
FmaskDecompress = 5,
DccDecompress = 6,
};
enum class Swizzle : std::uint8_t {
Zero = 0,
One = 1,
R = 4,
G = 5,
B = 6,
A = 7,
};
enum class BlendMultiplier : std::uint8_t {
Zero = 0x00,
One = 0x01,
SrcColor = 0x02,
OneMinusSrcColor = 0x03,
SrcAlpha = 0x04,
OneMinusSrcAlpha = 0x05,
DestAlpha = 0x06,
OneMinusDestAlpha = 0x07,
DestColor = 0x08,
OneMinusDestColor = 0x09,
SrcAlphaSaturate = 0x0a,
ConstantColor = 0x0d,
OneMinusConstantColor = 0x0e,
Src1Color = 0x0f,
InverseSrc1Color = 0x10,
Src1Alpha = 0x11,
InverseSrc1Alpha = 0x12,
ConstantAlpha = 0x13,
OneMinusConstantAlpha = 0x14,
};
enum class BlendFunc : std::uint8_t {
Add = 0,
Subtract = 1,
Min = 2,
Max = 3,
ReverseSubtract = 4,
};
enum class Face : std::uint8_t { CCW, CW };
enum class PolyMode : std::uint8_t { Disable, Dual };
enum class PolyModePtype : std::uint8_t {
Points,
Lines,
Triangles,
};
enum class RoundMode : std::uint8_t {
Truncate,
Round,
RoundToEven,
RoundToOdd,
};
enum class QuantMode : std::uint8_t {
Fp16_8_4,
Fp16_8_3,
Fp16_8_2,
Fp16_8_1,
Fp16_8_0,
Fp16_8_8,
Fp14_10,
Fp12_12,
};
enum class ClampMode : std::uint8_t {
Wrap,
Mirror,
ClampLastTexel,
MirrorOnceLastTexel,
ClampHalfBorder,
MirrorOnceHalfBorder,
ClampBorder,
MirrorOnceBorder,
};
enum class AnisoRatio : std::uint8_t {
x1,
x2,
x4,
x8,
x16,
};
} // namespace gnm

View file

@ -0,0 +1,124 @@
#pragma once
#include "constants.hpp"
#include <compare>
#include <cstdint>
namespace gnm {
#pragma pack(push, 1)
struct VBuffer {
std::uint64_t base : 44;
std::uint64_t mtype_L1s : 2;
std::uint64_t mtype_L2 : 2;
std::uint64_t stride : 14;
std::uint64_t cache_swizzle : 1;
std::uint64_t swizzle_en : 1;
std::uint32_t num_records;
Swizzle dst_sel_x : 3;
Swizzle dst_sel_y : 3;
Swizzle dst_sel_z : 3;
Swizzle dst_sel_w : 3;
NumericFormat nfmt : 3;
DataFormat dfmt : 4;
std::uint32_t element_size : 2;
std::uint32_t index_stride : 2;
std::uint32_t addtid_en : 1;
std::uint32_t reserved0 : 1;
std::uint32_t hash_en : 1;
std::uint32_t reserved1 : 1;
std::uint32_t mtype : 3;
std::uint32_t type : 2;
std::uint64_t address() const { return base; }
std::uint64_t size() const { return stride ? num_records * stride : num_records; }
auto operator<=>(const VBuffer &) const = default;
};
static_assert(sizeof(VBuffer) == sizeof(std::uint64_t) * 2);
struct TBuffer {
uint64_t baseaddr256 : 38;
uint64_t mtype_L2 : 2;
uint64_t min_lod : 12;
DataFormat dfmt : 6;
NumericFormat nfmt : 4;
uint64_t mtype01 : 2;
uint64_t width : 14;
uint64_t height : 14;
uint64_t perfMod : 3;
uint64_t interlaced : 1;
Swizzle dst_sel_x : 3;
Swizzle dst_sel_y : 3;
Swizzle dst_sel_z : 3;
Swizzle dst_sel_w : 3;
uint64_t base_level : 4;
uint64_t last_level : 4;
uint64_t tiling_idx : 5;
uint64_t pow2pad : 1;
uint64_t mtype2 : 1;
uint64_t : 1; // reserved
TextureType type : 4;
uint64_t depth : 13;
uint64_t pitch : 14;
uint64_t : 5; // reserved
uint64_t base_array : 13;
uint64_t last_array : 13;
uint64_t : 6; // reserved
uint64_t min_lod_warn : 12; // fixed point 4.8
uint64_t counter_bank_id : 8;
uint64_t LOD_hdw_cnt_en : 1;
uint64_t : 42; // reserved
std::uint64_t address() const {
return static_cast<std::uint64_t>(static_cast<std::uint32_t>(baseaddr256))
<< 8;
}
auto operator<=>(const TBuffer &) const = default;
};
static_assert(sizeof(TBuffer) == sizeof(std::uint64_t) * 4);
struct SSampler {
ClampMode clamp_x : 3;
ClampMode clamp_y : 3;
ClampMode clamp_z : 3;
AnisoRatio max_aniso_ratio : 3;
CompareFunc depth_compare_func : 3;
int32_t force_unorm_coords : 1;
int32_t aniso_threshold : 3;
int32_t mc_coord_trunc : 1;
int32_t force_degamma : 1;
int32_t aniso_bias : 6;
int32_t trunc_coord : 1;
int32_t disable_cube_wrap : 1;
FilterMode filter_mode : 2;
int32_t : 1;
int32_t min_lod : 12;
int32_t max_lod : 12;
int32_t perf_mip : 4;
int32_t perf_z : 4;
int32_t lod_bias : 14;
int32_t lod_bias_sec : 6;
Filter xy_mag_filter : 2;
Filter xy_min_filter : 2;
Filter z_filter : 2;
MipFilter mip_filter : 2;
int32_t : 4;
int32_t border_color_ptr : 12;
int32_t : 18;
BorderColor border_color_type : 2;
auto operator<=>(const SSampler &) const = default;
};
static_assert(sizeof(SSampler) == sizeof(std::uint32_t) * 4);
#pragma pack(pop)
} // namespace gnm

View file

@ -0,0 +1,256 @@
#pragma once
#include "constants.hpp"
#include "descriptors.hpp"
namespace gnm {
constexpr int getTexelsPerElement(gnm::DataFormat dfmt) {
switch (dfmt) {
case kDataFormatBc1:
case kDataFormatBc2:
case kDataFormatBc3:
case kDataFormatBc4:
case kDataFormatBc5:
case kDataFormatBc6:
case kDataFormatBc7:
return 16;
case kDataFormat1:
case kDataFormat1Reversed:
return 8;
case kDataFormatGB_GR:
case kDataFormatBG_RG:
return 2;
default:
return 1;
}
}
inline int getBitsPerElement(DataFormat dfmt) {
switch (dfmt) {
case kDataFormatInvalid:
return 0;
case kDataFormat8:
return 8;
case kDataFormat16:
return 16;
case kDataFormat8_8:
return 16;
case kDataFormat32:
return 32;
case kDataFormat16_16:
return 32;
case kDataFormat10_11_11:
return 32;
case kDataFormat11_11_10:
return 32;
case kDataFormat10_10_10_2:
return 32;
case kDataFormat2_10_10_10:
return 32;
case kDataFormat8_8_8_8:
return 32;
case kDataFormat32_32:
return 64;
case kDataFormat16_16_16_16:
return 64;
case kDataFormat32_32_32:
return 96;
case kDataFormat32_32_32_32:
return 128;
case kDataFormat5_6_5:
return 16;
case kDataFormat1_5_5_5:
return 16;
case kDataFormat5_5_5_1:
return 16;
case kDataFormat4_4_4_4:
return 16;
case kDataFormat8_24:
return 32;
case kDataFormat24_8:
return 32;
case kDataFormatX24_8_32:
return 64;
case kDataFormatGB_GR:
return 16;
case kDataFormatBG_RG:
return 16;
case kDataFormat5_9_9_9:
return 32;
case kDataFormatBc1:
return 4;
case kDataFormatBc2:
return 8;
case kDataFormatBc3:
return 8;
case kDataFormatBc4:
return 4;
case kDataFormatBc5:
return 8;
case kDataFormatBc6:
return 8;
case kDataFormatBc7:
return 8;
case kDataFormatFmask8_S2_F1:
return 8;
case kDataFormatFmask8_S4_F1:
return 8;
case kDataFormatFmask8_S8_F1:
return 8;
case kDataFormatFmask8_S2_F2:
return 8;
case kDataFormatFmask8_S4_F2:
return 8;
case kDataFormatFmask8_S4_F4:
return 8;
case kDataFormatFmask16_S16_F1:
return 16;
case kDataFormatFmask16_S8_F2:
return 16;
case kDataFormatFmask32_S16_F2:
return 32;
case kDataFormatFmask32_S8_F4:
return 32;
case kDataFormatFmask32_S8_F8:
return 32;
case kDataFormatFmask64_S16_F4:
return 64;
case kDataFormatFmask64_S16_F8:
return 64;
case kDataFormat4_4:
return 8;
case kDataFormat6_5_5:
return 16;
case kDataFormat1:
return 1;
case kDataFormat1Reversed:
return 1;
}
return -1;
}
constexpr int getTotalBitsPerElement(DataFormat dfmt) {
return getBitsPerElement(dfmt) * getTexelsPerElement(dfmt);
}
constexpr int getNumComponentsPerElement(DataFormat dfmt) {
switch (dfmt) {
case kDataFormatInvalid:
return 0;
case kDataFormat8:
return 1;
case kDataFormat16:
return 1;
case kDataFormat8_8:
return 2;
case kDataFormat32:
return 1;
case kDataFormat16_16:
return 2;
case kDataFormat10_11_11:
return 3;
case kDataFormat11_11_10:
return 3;
case kDataFormat10_10_10_2:
return 4;
case kDataFormat2_10_10_10:
return 4;
case kDataFormat8_8_8_8:
return 4;
case kDataFormat32_32:
return 2;
case kDataFormat16_16_16_16:
return 4;
case kDataFormat32_32_32:
return 3;
case kDataFormat32_32_32_32:
return 4;
case kDataFormat5_6_5:
return 3;
case kDataFormat1_5_5_5:
return 4;
case kDataFormat5_5_5_1:
return 4;
case kDataFormat4_4_4_4:
return 4;
case kDataFormat8_24:
return 2;
case kDataFormat24_8:
return 2;
case kDataFormatX24_8_32:
return 2;
case kDataFormatGB_GR:
return 3;
case kDataFormatBG_RG:
return 3;
case kDataFormat5_9_9_9:
return 3;
case kDataFormatBc1:
return 4;
case kDataFormatBc2:
return 4;
case kDataFormatBc3:
return 4;
case kDataFormatBc4:
return 1;
case kDataFormatBc5:
return 2;
case kDataFormatBc6:
return 3;
case kDataFormatBc7:
return 4;
case kDataFormatFmask8_S2_F1:
return 2;
case kDataFormatFmask8_S4_F1:
return 2;
case kDataFormatFmask8_S8_F1:
return 2;
case kDataFormatFmask8_S2_F2:
return 2;
case kDataFormatFmask8_S4_F2:
return 2;
case kDataFormatFmask8_S4_F4:
return 2;
case kDataFormatFmask16_S16_F1:
return 2;
case kDataFormatFmask16_S8_F2:
return 2;
case kDataFormatFmask32_S16_F2:
return 2;
case kDataFormatFmask32_S8_F4:
return 2;
case kDataFormatFmask32_S8_F8:
return 2;
case kDataFormatFmask64_S16_F4:
return 2;
case kDataFormatFmask64_S16_F8:
return 2;
case kDataFormat4_4:
return 2;
case kDataFormat6_5_5:
return 3;
case kDataFormat1:
return 1;
case kDataFormat1Reversed:
return 1;
}
return -1;
}
constexpr ZFormat getZFormat(DataFormat dfmt) {
if (dfmt == kDataFormat32) {
return kZFormat32Float;
}
if (dfmt == kDataFormat16) {
return kZFormat16;
}
return kZFormatInvalid;
}
constexpr StencilFormat getStencilFormat(DataFormat dfmt) {
return dfmt == kDataFormat8 ? kStencil8 : kStencilInvalid;
}
} // namespace gnm

View file

@ -0,0 +1,5 @@
#pragma once
namespace gnm::mmio {
const char *registerName(unsigned offset);
} // namespace gnm::mmio

View file

@ -0,0 +1,84 @@
#pragma once
namespace gnm {
enum Pm4Opcode {
IT_NOP = 0x10,
IT_SET_BASE = 0x11,
IT_CLEAR_STATE = 0x12,
IT_INDEX_BUFFER_SIZE = 0x13,
IT_DISPATCH_DIRECT = 0x15,
IT_DISPATCH_INDIRECT = 0x16,
IT_ATOMIC_GDS = 0x1d,
IT_OCCLUSION_QUERY = 0x1f,
IT_SET_PREDICATION = 0x20,
IT_REG_RMW = 0x21,
IT_COND_EXEC = 0x22,
IT_PRED_EXEC = 0x23,
IT_DRAW_INDIRECT = 0x24,
IT_DRAW_INDEX_INDIRECT = 0x25,
IT_INDEX_BASE = 0x26,
IT_DRAW_INDEX_2 = 0x27,
IT_CONTEXT_CONTROL = 0x28,
IT_INDEX_TYPE = 0x2a,
IT_DRAW_INDIRECT_MULTI = 0x2c,
IT_DRAW_INDEX_AUTO = 0x2d,
IT_NUM_INSTANCES = 0x2f,
IT_DRAW_INDEX_MULTI_AUTO = 0x30,
IT_INDIRECT_BUFFER_CNST = 0x33,
IT_STRMOUT_BUFFER_UPDATE = 0x34,
IT_DRAW_INDEX_OFFSET_2 = 0x35,
IT_DRAW_PREAMBLE = 0x36,
IT_WRITE_DATA = 0x37,
IT_DRAW_INDEX_INDIRECT_MULTI = 0x38,
IT_MEM_SEMAPHORE = 0x39,
IT_COPY_DW = 0x3b,
IT_WAIT_REG_MEM = 0x3c,
IT_INDIRECT_BUFFER = 0x3f,
IT_COPY_DATA = 0x40,
IT_PFP_SYNC_ME = 0x42,
IT_SURFACE_SYNC = 0x43,
IT_COND_WRITE = 0x45,
IT_EVENT_WRITE = 0x46,
IT_EVENT_WRITE_EOP = 0x47,
IT_EVENT_WRITE_EOS = 0x48,
IT_RELEASE_MEM = 0x49,
IT_PREAMBLE_CNTL = 0x4a,
IT_DMA_DATA = 0x50,
IT_ACQUIRE_MEM = 0x58,
IT_REWIND = 0x59,
IT_LOAD_UCONFIG_REG = 0x5e,
IT_LOAD_SH_REG = 0x5f,
IT_LOAD_CONFIG_REG = 0x60,
IT_LOAD_CONTEXT_REG = 0x61,
IT_SET_CONFIG_REG = 0x68,
IT_SET_CONTEXT_REG = 0x69,
IT_SET_CONTEXT_REG_INDIRECT = 0x73,
IT_SET_SH_REG = 0x76,
IT_SET_SH_REG_OFFSET = 0x77,
IT_SET_QUEUE_REG = 0x78,
IT_SET_UCONFIG_REG = 0x79,
IT_SCRATCH_RAM_WRITE = 0x7d,
IT_SCRATCH_RAM_READ = 0x7e,
IT_LOAD_CONST_RAM = 0x80,
IT_WRITE_CONST_RAM = 0x81,
IT_DUMP_CONST_RAM = 0x83,
IT_INCREMENT_CE_COUNTER = 0x84,
IT_INCREMENT_DE_COUNTER = 0x85,
IT_WAIT_ON_CE_COUNTER = 0x86,
IT_WAIT_ON_DE_COUNTER_DIFF = 0x88,
IT_SET_CE_DE_COUNTERS = 0x89,
IT_WAIT_ON_AVAIL_BUFFER = 0x8a,
IT_SWITCH_BUFFER = 0x8b,
IT_SET_RESOURCES = 0xa0,
IT_MAP_PROCESS = 0xa1,
IT_MAP_QUEUES = 0xa2,
IT_UNMAP_QUEUES = 0xa3,
IT_QUERY_STATUS = 0xa4,
IT_RUN_LIST = 0xa5,
IT_DISPATCH_DRAW_PREAMBLE = 0x8c,
IT_DISPATCH_DRAW = 0x8d,
};
const char *pm4OpcodeToString(int opcode);
} // namespace gnm