core: libraries: gnmdriver: basic functionality extension (#120)

Also a bit of refactoring in `video_core`
This commit is contained in:
psucien 2024-05-01 18:29:06 +02:00 committed by GitHub
parent 1b9bf924ca
commit 7e8d90d609
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 402 additions and 185 deletions

View file

@ -26,20 +26,20 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) {
break;
case PM4ItOpcode::SetContextReg: {
auto* set_data = reinterpret_cast<PM4CmdSetData*>(header);
std::memcpy(&regs.reg_array[ContextRegWordOffset + set_data->regOffset], header + 2,
(count - 1) * sizeof(u32));
std::memcpy(&regs.reg_array[ContextRegWordOffset + set_data->reg_offset],
header + 2, (count - 1) * sizeof(u32));
break;
}
case PM4ItOpcode::SetShReg: {
auto* set_data = reinterpret_cast<PM4CmdSetData*>(header);
std::memcpy(&regs.reg_array[ShRegWordOffset + set_data->regOffset], header + 2,
std::memcpy(&regs.reg_array[ShRegWordOffset + set_data->reg_offset], header + 2,
(count - 1) * sizeof(u32));
break;
}
case PM4ItOpcode::SetUconfigReg: {
auto* set_data = reinterpret_cast<PM4CmdSetData*>(header);
std::memcpy(&regs.reg_array[UconfigRegWordOffset + set_data->regOffset], header + 2,
(count - 1) * sizeof(u32));
std::memcpy(&regs.reg_array[UconfigRegWordOffset + set_data->reg_offset],
header + 2, (count - 1) * sizeof(u32));
break;
}
case PM4ItOpcode::IndexType: {
@ -49,11 +49,11 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) {
}
case PM4ItOpcode::DrawIndex2: {
auto* draw_index = reinterpret_cast<PM4CmdDrawIndex2*>(header);
regs.max_index_size = draw_index->maxSize;
regs.index_base_address.base_addr_lo = draw_index->indexBaseLo;
regs.index_base_address.base_addr_hi.Assign(draw_index->indexBaseHi);
regs.num_indices = draw_index->indexCount;
regs.draw_initiator = draw_index->drawInitiator;
regs.max_index_size = draw_index->max_size;
regs.index_base_address.base_addr_lo = draw_index->index_base_lo;
regs.index_base_address.base_addr_hi.Assign(draw_index->index_base_hi);
regs.num_indices = draw_index->index_count;
regs.draw_initiator = draw_index->draw_initiator;
// rasterizer->DrawIndex();
break;
}
@ -66,8 +66,8 @@ void Liverpool::ProcessCmdList(u32* cmdbuf, u32 size_in_bytes) {
}
case PM4ItOpcode::EventWriteEop: {
auto* event_write = reinterpret_cast<PM4CmdEventWriteEop*>(header);
const InterruptSelect irq_sel = event_write->intSel;
const DataSelect data_sel = event_write->dataSel;
const InterruptSelect irq_sel = event_write->int_sel;
const DataSelect data_sel = event_write->data_sel;
ASSERT(irq_sel == InterruptSelect::None && data_sel == DataSelect::Data64);
*event_write->Address() = event_write->DataQWord();
break;

View file

@ -39,7 +39,7 @@ union PM4Type3Header {
PM4Predicate pred = PM4Predicate::PredDisable) {
raw = 0;
predicate.Assign(pred);
shaderType.Assign(stype);
shader_type.Assign(stype);
opcode.Assign(code);
count.Assign(num_words_min_one);
type.Assign(3);
@ -50,10 +50,10 @@ union PM4Type3Header {
}
u32 raw;
BitField<0, 1, PM4Predicate> predicate; ///< Predicated version of packet when set
BitField<1, 1, PM4ShaderType> shaderType; ///< 0: Graphics, 1: Compute Shader
BitField<8, 8, PM4ItOpcode> opcode; ///< IT opcode
BitField<16, 14, u32> count; ///< Number of DWORDs - 1 in the information body.
BitField<0, 1, PM4Predicate> predicate; ///< Predicated version of packet when set
BitField<1, 1, PM4ShaderType> shader_type; ///< 0: Graphics, 1: Compute Shader
BitField<8, 8, PM4ItOpcode> opcode; ///< IT opcode
BitField<16, 14, u32> count; ///< Number of DWORDs - 1 in the information body.
BitField<30, 2, u32> type; ///< Packet identifier. It should be 3 for type 3 packets
};
@ -64,42 +64,55 @@ union PM4Header {
BitField<30, 2, u32> type;
};
template <PM4ItOpcode opcode, typename... Args>
constexpr u32* Write(u32* cmdbuf, PM4ShaderType type, Args... data) {
// Write the PM4 header.
PM4Type3Header header{opcode, sizeof...(Args) - 1, type};
// Write the PM4 header
template <PM4ItOpcode opcode>
constexpr u32* WriteHeader(u32* cmdbuf, u32 size,
PM4ShaderType type = PM4ShaderType::ShaderGraphics,
PM4Predicate predicate = PM4Predicate::PredDisable) {
PM4Type3Header header{opcode, size - 1, type, predicate};
std::memcpy(cmdbuf, &header, sizeof(header));
return ++cmdbuf;
}
// Write arguments
// Write arguments
template <typename... Args>
constexpr u32* WriteBody(u32* cmdbuf, Args... data) {
const std::array<u32, sizeof...(Args)> args{data...};
std::memcpy(++cmdbuf, args.data(), sizeof(args));
std::memcpy(cmdbuf, args.data(), sizeof(args));
cmdbuf += args.size();
return cmdbuf;
}
template <PM4ItOpcode opcode, typename... Args>
constexpr u32* WritePacket(u32* cmdbuf, PM4ShaderType type, Args... data) {
cmdbuf = WriteHeader<opcode>(cmdbuf, sizeof...(Args), type);
cmdbuf = WriteBody(cmdbuf, data...);
return cmdbuf;
}
union ContextControlEnable {
u32 raw;
BitField<0, 1, u32> enableSingleCntxConfigReg; ///< single context config reg
BitField<1, 1, u32> enableMultiCntxRenderReg; ///< multi context render state reg
BitField<15, 1, u32> enableUserConfigReg__CI; ///< User Config Reg on CI(reserved for SI)
BitField<16, 1, u32> enableGfxSHReg; ///< Gfx SH Registers
BitField<24, 1, u32> enableCSSHReg; ///< CS SH Registers
BitField<31, 1, u32> enableDw; ///< DW enable
BitField<0, 1, u32> enable_single_cntx_config_reg; ///< single context config reg
BitField<1, 1, u32> enable_multi_cntx_render_reg; ///< multi context render state reg
BitField<15, 1, u32> enable_user_config_reg__CI; ///< User Config Reg on CI(reserved for SI)
BitField<16, 1, u32> enable_gfx_sh_reg; ///< Gfx SH Registers
BitField<24, 1, u32> enable_cs_sh_reg; ///< CS SH Registers
BitField<31, 1, u32> enable_dw; ///< DW enable
};
struct PM4CmdContextControl {
PM4Type3Header header;
ContextControlEnable loadControl; ///< Enable bits for loading
ContextControlEnable shadowEnable; ///< Enable bits for shadowing
ContextControlEnable load_control; ///< Enable bits for loading
ContextControlEnable shadow_enable; ///< Enable bits for shadowing
};
union LoadAddressHigh {
u32 raw;
BitField<0, 16, u32>
addrHi; ///< bits for the block in Memory from where the CP will fetch the state
addr_hi; ///< bits for the block in Memory from where the CP will fetch the state
BitField<31, 1, u32>
waitIdle; ///< if set the CP will wait for the graphics pipe to be idle by writing
///< to the GRBM Wait Until register with "Wait for 3D idle"
wait_idle; ///< if set the CP will wait for the graphics pipe to be idle by writing
///< to the GRBM Wait Until register with "Wait for 3D idle"
};
/**
@ -110,12 +123,12 @@ union LoadAddressHigh {
*/
struct PM4CmdLoadData {
PM4Type3Header header;
u32 addrLo; ///< low 32 address bits for the block in memory from where the CP will fetch the
///< state
LoadAddressHigh addrHi;
u32 regOffset; ///< offset in DWords from the register base address
u32 numDwords; ///< number of DWords that the CP will fetch and write into the chip. A value of
///< zero will fetch nothing
u32 addr_lo; ///< low 32 address bits for the block in memory from where the CP will fetch the
///< state
LoadAddressHigh addr_hi;
u32 reg_offset; ///< offset in DWords from the register base address
u32 num_dwords; ///< number of DWords that the CP will fetch and write into the chip. A value of
///< zero will fetch nothing
};
enum class LoadDataIndex : u32 {
@ -131,8 +144,8 @@ enum class LoadDataFormat : u32 {
union LoadAddressLow {
u32 raw;
BitField<0, 1, LoadDataIndex> index;
BitField<2, 30, u32> addrLo; ///< bits for the block in Memory from where the CP will fetch the
///< state. DWORD aligned
BitField<2, 30, u32> addr_lo; ///< bits for the block in Memory from where the CP will fetch the
///< state. DWORD aligned
};
/**
@ -142,16 +155,16 @@ union LoadAddressLow {
*/
struct PM4CmdLoadDataIndex {
PM4Type3Header header;
LoadAddressLow addrLo; ///< low 32 address bits for the block in memory from where the CP will
///< fetch the state
u32 addrOffset; ///< addrLo.index = 1 Indexed mode
LoadAddressLow addr_lo; ///< low 32 address bits for the block in memory from where the CP will
///< fetch the state
u32 addr_offset; ///< addrLo.index = 1 Indexed mode
union {
BitField<0, 16, u32> regOffset; ///< offset in DWords from the register base address
BitField<31, 1, LoadDataFormat> dataFormat;
BitField<0, 16, u32> reg_offset; ///< offset in DWords from the register base address
BitField<31, 1, LoadDataFormat> data_format;
u32 raw;
};
u32 numDwords; ///< Number of DWords that the CP will fetch and write
///< into the chip. A value of zero will fetch nothing
u32 num_dwords; ///< Number of DWords that the CP will fetch and write
///< into the chip. A value of zero will fetch nothing
};
/**
@ -168,52 +181,62 @@ struct PM4CmdSetData {
PM4Type3Header header;
union {
u32 raw;
BitField<0, 16, u32> regOffset; ///< Offset in DWords from the register base address
BitField<28, 4, u32> index; ///< Index for UCONFIG/CONTEXT on CI+
///< Program to zero for other opcodes and on SI
BitField<0, 16, u32> reg_offset; ///< Offset in DWords from the register base address
BitField<28, 4, u32> index; ///< Index for UCONFIG/CONTEXT on CI+
///< Program to zero for other opcodes and on SI
};
template <PM4ShaderType type = PM4ShaderType::ShaderGraphics, typename... Args>
static constexpr u32* SetContextReg(u32* cmdbuf, Args... data) {
return Write<PM4ItOpcode::SetContextReg>(cmdbuf, type, data...);
return WritePacket<PM4ItOpcode::SetContextReg>(cmdbuf, type, data...);
}
template <PM4ShaderType type = PM4ShaderType::ShaderGraphics, typename... Args>
static constexpr u32* SetShReg(u32* cmdbuf, Args... data) {
return Write<PM4ItOpcode::SetShReg>(cmdbuf, type, data...);
return WritePacket<PM4ItOpcode::SetShReg>(cmdbuf, type, data...);
}
};
struct PM4CmdNop {
PM4Type3Header header;
u32 data_block[0];
enum class PayloadType : u32 {
DebugMarkerPush = 0x68750001, ///< Begin of GPU event scope
DebugMarkerPop = 0x68750002, ///< End of GPU event scope
SetVsharpInUdata = 0x68750004, ///< Indicates that V# will be set in the next packet
SetTsharpInUdata = 0x68750005, ///< Indicates that T# will be set in the next packet
SetSsharpInUdata = 0x68750006, ///< Indicates that S# will be set in the next packet
DebugColorMarkerPush = 0x6875000e, ///< Begin of GPU event scope with color
};
};
struct PM4CmdDrawIndexOffset2 {
PM4Type3Header header;
u32 maxSize; ///< Maximum number of indices
u32 indexOffset; ///< Zero based starting index number in the index buffer
u32 indexCount; ///< number of indices in the Index Buffer
u32 drawInitiator; ///< draw Initiator Register
u32 max_size; ///< Maximum number of indices
u32 index_offset; ///< Zero based starting index number in the index buffer
u32 index_count; ///< number of indices in the Index Buffer
u32 draw_initiator; ///< draw Initiator Register
};
struct PM4CmdDrawIndex2 {
PM4Type3Header header;
u32 maxSize; ///< maximum number of indices
u32 indexBaseLo; ///< base Address Lo [31:1] of Index Buffer
///< (Word-Aligned). Written to the VGT_DMA_BASE register.
u32 indexBaseHi; ///< base Address Hi [39:32] of Index Buffer.
///< Written to the VGT_DMA_BASE_HI register
u32 indexCount; ///< number of indices in the Index Buffer.
///< Written to the VGT_NUM_INDICES register.
u32 drawInitiator; ///< written to the VGT_DRAW_INITIATOR register
u32 max_size; ///< maximum number of indices
u32 index_base_lo; ///< base Address Lo [31:1] of Index Buffer
///< (Word-Aligned). Written to the VGT_DMA_BASE register.
u32 index_base_hi; ///< base Address Hi [39:32] of Index Buffer.
///< Written to the VGT_DMA_BASE_HI register
u32 index_count; ///< number of indices in the Index Buffer.
///< Written to the VGT_NUM_INDICES register.
u32 draw_initiator; ///< written to the VGT_DRAW_INITIATOR register
};
struct PM4CmdDrawIndexType {
PM4Type3Header header;
union {
u32 raw;
BitField<0, 2, u32> indexType; ///< Select 16 Vs 32bit index
BitField<2, 2, u32> swapMode; ///< DMA swap mode
BitField<0, 2, u32> index_type; ///< Select 16 Vs 32bit index
BitField<2, 2, u32> swap_mode; ///< DMA swap mode
};
};
@ -241,25 +264,25 @@ struct PM4CmdEventWriteEop {
PM4Type3Header header;
union {
u32 event_control;
BitField<0, 6, u32> eventType; ///< Event type written to VGT_EVENT_INITIATOR
BitField<8, 4, u32> eventIndex; ///< Event index
BitField<0, 6, u32> event_type; ///< Event type written to VGT_EVENT_INITIATOR
BitField<8, 4, u32> event_index; ///< Event index
};
u32 addressLo;
u32 address_lo;
union {
u32 data_control;
BitField<0, 16, u32> addressHi; ///< High bits of address
BitField<24, 2, InterruptSelect> intSel; ///< Selects interrupt action for end-of-pipe
BitField<29, 3, DataSelect> dataSel; ///< Selects source of data
BitField<0, 16, u32> address_hi; ///< High bits of address
BitField<24, 2, InterruptSelect> int_sel; ///< Selects interrupt action for end-of-pipe
BitField<29, 3, DataSelect> data_sel; ///< Selects source of data
};
u32 dataLo; ///< Value that will be written to memory when event occurs
u32 dataHi; ///< Value that will be written to memory when event occurs
u32 data_lo; ///< Value that will be written to memory when event occurs
u32 data_hi; ///< Value that will be written to memory when event occurs
u64* Address() const {
return reinterpret_cast<u64*>(addressLo | u64(addressHi) << 32);
return reinterpret_cast<u64*>(address_lo | u64(address_hi) << 32);
}
u64 DataQWord() const {
return dataLo | u64(dataHi) << 32;
return data_lo | u64(data_hi) << 32;
}
};
@ -287,4 +310,19 @@ struct PM4DmaData {
u32 command;
};
struct PM4CmdWaitRegMem {
PM4Type3Header header;
union {
BitField<0, 3, u32> function;
BitField<4, 1, u32> mem_space;
BitField<8, 1, u32> engine;
u32 raw;
};
u32 poll_addr_lo;
u32 poll_addr_hi;
u32 ref;
u32 mask;
u32 poll_interval;
};
} // namespace AmdGpu

View file

@ -36,6 +36,7 @@ enum class PM4ItOpcode : u32 {
WriteData = 0x37,
DrawIndexIndirectMulti = 0x38,
MemSemaphore = 0x39,
WaitRegMem = 0x3c,
IndirectBuffer = 0x3F,
CondIndirectBuffer = 0x3F,
CopyData = 0x40,
@ -48,6 +49,7 @@ enum class PM4ItOpcode : u32 {
PremableCntl = 0x4A,
DmaData = 0x50,
ContextRegRmw = 0x51,
Unknown58 = 0x58,
LoadShReg = 0x5F,
LoadConfigReg = 0x60,
LoadContextReg = 0x61,