1070 lines
41 KiB
C++
1070 lines
41 KiB
C++
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_
|
|
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_
|
|
|
|
#include "common/abi.h"
|
|
#include "common/common.h"
|
|
#include "graphics/guest_gpu/gpu_defs.h"
|
|
|
|
namespace Libs::Graphics::HW {
|
|
|
|
struct ColorBase {
|
|
uint64_t addr = 0;
|
|
};
|
|
|
|
struct ColorView {
|
|
uint32_t base_array_slice_index = 0;
|
|
uint32_t last_array_slice_index = 0;
|
|
uint32_t current_mip_level = 0;
|
|
};
|
|
|
|
struct ColorInfo {
|
|
bool fmask_compression_enable = false;
|
|
// uint32_t fmask_compression_mode = 0;
|
|
bool fmask_data_compression_disable = false;
|
|
bool fmask_one_frag_mode = false;
|
|
bool cmask_fast_clear_enable = false;
|
|
bool dcc_compression_enable = false;
|
|
bool blend_clamp = false;
|
|
bool blend_bypass = false;
|
|
bool round_mode = false;
|
|
Prospero::ChannelLayout format = Prospero::ChannelLayout::kInvalid;
|
|
Prospero::ChannelType channel_type = Prospero::ChannelType::kUNorm;
|
|
Prospero::ChannelOrder channel_order = Prospero::ChannelOrder::kStandard;
|
|
};
|
|
|
|
struct ColorAttrib {
|
|
bool force_dest_alpha_to_one = false;
|
|
uint32_t num_samples = 0;
|
|
uint32_t num_fragments = 0;
|
|
};
|
|
|
|
struct ColorAttrib2 {
|
|
uint32_t height = 0;
|
|
uint32_t width = 0;
|
|
uint32_t num_mip_levels = 0;
|
|
};
|
|
|
|
struct ColorAttrib3 {
|
|
uint32_t depth = 0;
|
|
Prospero::TileMode tile_mode = Prospero::TileMode::kRenderTarget;
|
|
uint32_t dimension = 0;
|
|
bool metadata_pipe_aligned = false;
|
|
bool write_vrs_rate_hint_to_cmask = false;
|
|
};
|
|
|
|
struct ColorDccControl {
|
|
enum class IndependentBlockSize : uint8_t { Disabled, Bytes64, Bytes128 };
|
|
|
|
uint32_t max_uncompressed_block_size = 2;
|
|
uint32_t max_compressed_block_size = 2;
|
|
uint32_t color_transform = 0;
|
|
bool dcc_clear_key_enable = false;
|
|
bool overwrite_combiner_disable = false;
|
|
IndependentBlockSize independent_block_size = IndependentBlockSize::Disabled;
|
|
bool data_write_on_dcc_clear_to_reg = false;
|
|
};
|
|
|
|
struct ColorCmask {
|
|
uint64_t addr = 0;
|
|
};
|
|
|
|
struct ColorFmask {
|
|
uint64_t addr = 0;
|
|
};
|
|
|
|
struct ColorClearWord0 {
|
|
uint32_t word0 = 0;
|
|
};
|
|
|
|
struct ColorClearWord1 {
|
|
uint32_t word1 = 0;
|
|
};
|
|
|
|
struct ColorDccAddr {
|
|
uint64_t addr = 0;
|
|
};
|
|
|
|
struct RenderTarget {
|
|
ColorBase base;
|
|
ColorView view;
|
|
ColorInfo info;
|
|
ColorAttrib attrib;
|
|
ColorAttrib2 attrib2;
|
|
ColorAttrib3 attrib3;
|
|
ColorDccControl dcc;
|
|
ColorCmask cmask;
|
|
ColorFmask fmask;
|
|
ColorClearWord0 clear_word0;
|
|
ColorClearWord1 clear_word1;
|
|
ColorDccAddr dcc_addr;
|
|
};
|
|
|
|
struct DepthZInfo {
|
|
Prospero::DepthFormat format = Prospero::DepthFormat::kInvalid;
|
|
uint32_t num_samples = 0;
|
|
Prospero::TextureCompatiblePlaneCompression texture_compatibility =
|
|
Prospero::TextureCompatiblePlaneCompression::kDisable;
|
|
Prospero::ZCompareBase z_compare_base = Prospero::ZCompareBase::kZMax;
|
|
bool htile_acceleration = false;
|
|
bool expclear_enabled = false;
|
|
bool partially_resident = false;
|
|
uint8_t max_mip_level = 0;
|
|
|
|
[[nodiscard]] static DepthZInfo Decode(uint32_t value) {
|
|
DepthZInfo info;
|
|
info.format = static_cast<Prospero::DepthFormat>(value & 0x3u);
|
|
info.num_samples = (value >> 2u) & 0x3u;
|
|
info.texture_compatibility = static_cast<Prospero::TextureCompatiblePlaneCompression>(
|
|
value & static_cast<uint32_t>(Prospero::TextureCompatiblePlaneCompression::kBitMask));
|
|
info.partially_resident = (value & 0x00001000u) != 0;
|
|
info.max_mip_level = static_cast<uint8_t>((value >> 16u) & 0x0fu);
|
|
info.expclear_enabled = (value & 0x08000000u) != 0;
|
|
info.htile_acceleration = (value & 0x20000000u) != 0;
|
|
info.z_compare_base = static_cast<Prospero::ZCompareBase>(
|
|
value & static_cast<uint32_t>(Prospero::ZCompareBase::kBitMask));
|
|
return info;
|
|
}
|
|
|
|
[[nodiscard]] bool HasValidTextureCompatibility() const {
|
|
switch (texture_compatibility) {
|
|
case Prospero::TextureCompatiblePlaneCompression::kDisable:
|
|
case Prospero::TextureCompatiblePlaneCompression::kEnable: return true;
|
|
default: return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
struct DepthStencilInfo {
|
|
Prospero::StencilFormat format = Prospero::StencilFormat::kInvalid;
|
|
Prospero::TextureCompatibleStencil texture_compatibility =
|
|
Prospero::TextureCompatibleStencil::kDisable;
|
|
bool expclear_enabled = false;
|
|
bool htile_stencil_disabled = true;
|
|
bool partially_resident = false;
|
|
|
|
[[nodiscard]] static DepthStencilInfo Decode(uint32_t value) {
|
|
DepthStencilInfo info;
|
|
info.format = static_cast<Prospero::StencilFormat>(value & 0x1u);
|
|
info.texture_compatibility = static_cast<Prospero::TextureCompatibleStencil>(
|
|
value & static_cast<uint32_t>(Prospero::TextureCompatibleStencil::kBitMask));
|
|
info.partially_resident = (value & 0x00001000u) != 0;
|
|
info.expclear_enabled = (value & 0x08000000u) != 0;
|
|
info.htile_stencil_disabled = (value & 0x20000000u) != 0;
|
|
return info;
|
|
}
|
|
|
|
[[nodiscard]] bool HasValidTextureCompatibility() const {
|
|
switch (texture_compatibility) {
|
|
case Prospero::TextureCompatibleStencil::kDisable:
|
|
case Prospero::TextureCompatibleStencil::kEnable: return true;
|
|
default: return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
struct DepthDepthView {
|
|
uint32_t slice_start = 0;
|
|
uint32_t slice_max = 0;
|
|
uint8_t current_mip_level = 0;
|
|
bool depth_write_disable = false;
|
|
bool stencil_write_disable = false;
|
|
};
|
|
|
|
struct DepthDepthSizeXY {
|
|
uint16_t x_max = 0;
|
|
uint16_t y_max = 0;
|
|
bool valid = false;
|
|
};
|
|
|
|
struct DepthRenderTarget {
|
|
DepthZInfo z_info;
|
|
DepthStencilInfo stencil_info;
|
|
DepthDepthView depth_view;
|
|
DepthDepthSizeXY size;
|
|
|
|
uint64_t z_read_base_addr = 0;
|
|
uint64_t stencil_read_base_addr = 0;
|
|
uint64_t z_write_base_addr = 0;
|
|
uint64_t stencil_write_base_addr = 0;
|
|
uint64_t htile_data_base_addr = 0;
|
|
uint8_t shading_rate_encoding = 0;
|
|
};
|
|
|
|
struct RenderControl {
|
|
bool depth_clear_enable = false;
|
|
bool stencil_clear_enable = false;
|
|
bool resummarize_enable = false;
|
|
bool stencil_compress_disable = false;
|
|
bool depth_compress_disable = false;
|
|
bool copy_depth_to_color = false;
|
|
bool copy_stencil_to_color = false;
|
|
bool copy_centroid = false;
|
|
uint8_t copy_sample = 0;
|
|
};
|
|
|
|
struct DepthRenderOverride {
|
|
bool force_z_valid = false;
|
|
bool force_z_dirty = false;
|
|
bool force_stencil_valid = false;
|
|
bool force_stencil_dirty = false;
|
|
};
|
|
|
|
struct GdsOaCounter {
|
|
uint32_t counter = 0;
|
|
uint32_t address = 0;
|
|
|
|
[[nodiscard]] uint32_t GetSpaceAvailable() const { return counter; }
|
|
[[nodiscard]] uint32_t GetAddressBytes() const { return address & 0x0000ffffu; }
|
|
[[nodiscard]] uint32_t GetCrawlerType() const { return (address >> 16u) & 0x3u; }
|
|
[[nodiscard]] uint32_t GetCrawlerId() const { return (address >> 20u) & 0xfu; }
|
|
[[nodiscard]] bool IsCounterEnabled() const { return (address & 0x80000000u) != 0; }
|
|
[[nodiscard]] bool IsAllocationCrawlerDisabled() const { return (address & 0x40000000u) != 0; }
|
|
};
|
|
|
|
struct GdsOaState {
|
|
static constexpr uint32_t COUNTERS_NUM = 8;
|
|
|
|
uint32_t cntl = 0;
|
|
GdsOaCounter counters[COUNTERS_NUM];
|
|
|
|
[[nodiscard]] uint32_t GetIndex() const { return cntl & (COUNTERS_NUM - 1u); }
|
|
};
|
|
|
|
struct ClipControl {
|
|
uint8_t user_clip_planes = 0;
|
|
uint8_t user_clip_plane_mode = 0;
|
|
bool dx_clip_space = false;
|
|
bool vertex_kill_any = false;
|
|
bool min_z_clip_disable = false;
|
|
bool max_z_clip_disable = false;
|
|
bool user_clip_plane_negate_y = false;
|
|
bool clip_disable = false;
|
|
bool user_clip_plane_cull_only = false;
|
|
bool cull_on_clipping_error_disable = false;
|
|
bool linear_attribute_clip_enable = false;
|
|
bool force_viewport_index_from_vs_enable = false;
|
|
|
|
[[nodiscard]] bool IsZClipEnabled() const { return !min_z_clip_disable && !max_z_clip_disable; }
|
|
};
|
|
|
|
struct DepthControl {
|
|
bool stencil_enable = false;
|
|
bool z_enable = false;
|
|
bool z_write_enable = false;
|
|
bool depth_bounds_enable = false;
|
|
uint8_t zfunc = 0;
|
|
bool backface_enable = false;
|
|
uint8_t stencilfunc = 0;
|
|
uint8_t stencilfunc_bf = 0;
|
|
};
|
|
|
|
struct StencilControl {
|
|
uint8_t stencil_fail = 0;
|
|
uint8_t stencil_zpass = 0;
|
|
uint8_t stencil_zfail = 0;
|
|
uint8_t stencil_fail_bf = 0;
|
|
uint8_t stencil_zpass_bf = 0;
|
|
uint8_t stencil_zfail_bf = 0;
|
|
};
|
|
|
|
struct StencilMask {
|
|
uint8_t stencil_testval = 0;
|
|
uint8_t stencil_mask = 0;
|
|
uint8_t stencil_writemask = 0;
|
|
uint8_t stencil_opval = 0;
|
|
uint8_t stencil_testval_bf = 0;
|
|
uint8_t stencil_mask_bf = 0;
|
|
uint8_t stencil_writemask_bf = 0;
|
|
uint8_t stencil_opval_bf = 0;
|
|
};
|
|
|
|
struct ModeControl {
|
|
bool cull_front = false;
|
|
bool cull_back = false;
|
|
bool face = false;
|
|
uint8_t poly_mode = 0;
|
|
uint8_t polymode_front_ptype = 0;
|
|
uint8_t polymode_back_ptype = 0;
|
|
bool poly_offset_front_enable = false;
|
|
bool poly_offset_back_enable = false;
|
|
bool vtx_window_offset_enable = false;
|
|
bool provoking_vtx_last = false;
|
|
bool persp_corr_dis = false;
|
|
};
|
|
|
|
struct PolyOffset {
|
|
int8_t neg_num_db_bits = -23;
|
|
bool db_is_float_fmt = true;
|
|
float clamp = 0.0f;
|
|
float front_scale = 0.0f;
|
|
float front_offset = 0.0f;
|
|
float back_scale = 0.0f;
|
|
float back_offset = 0.0f;
|
|
};
|
|
|
|
struct BlendControl {
|
|
uint8_t color_srcblend = 1;
|
|
uint8_t color_comb_fcn = 0;
|
|
uint8_t color_destblend = 0;
|
|
uint8_t alpha_srcblend = 1;
|
|
uint8_t alpha_comb_fcn = 0;
|
|
uint8_t alpha_destblend = 0;
|
|
bool separate_alpha_blend = true;
|
|
bool enable = false;
|
|
};
|
|
|
|
struct BlendColor {
|
|
float red = 0.0f;
|
|
float green = 0.0f;
|
|
float blue = 0.0f;
|
|
float alpha = 0.0f;
|
|
};
|
|
|
|
struct EqaaControl {
|
|
uint8_t max_anchor_samples = 0;
|
|
uint8_t ps_iter_samples = 0;
|
|
uint8_t mask_export_num_samples = 0;
|
|
uint8_t alpha_to_mask_num_samples = 0;
|
|
bool high_quality_intersections = false;
|
|
bool incoherent_eqaa_reads = false;
|
|
bool interpolate_comp_z = false;
|
|
bool static_anchor_associations = false;
|
|
};
|
|
|
|
struct ColorControl {
|
|
uint8_t mode = 1;
|
|
uint8_t op = 0xCC;
|
|
};
|
|
|
|
struct ScanModeControl {
|
|
bool msaa_enable = false;
|
|
bool vport_scissor_enable = true;
|
|
bool line_stipple_enable = false;
|
|
};
|
|
|
|
struct AaSampleControl {
|
|
uint64_t centroid_priority = 0;
|
|
uint32_t locations[16] = {};
|
|
};
|
|
|
|
struct DepthShaderControl {
|
|
uint32_t other_bits = 0;
|
|
uint8_t conservative_z_export_value = 0;
|
|
uint8_t shader_z_behavior = 0;
|
|
bool shader_kill_enable = false;
|
|
bool shader_z_export_enable = false;
|
|
bool shader_mask_export_enable = false;
|
|
bool shader_dual_export_enable = false;
|
|
bool shader_execute_on_noop = false;
|
|
bool alpha_to_mask_disable = false;
|
|
};
|
|
|
|
struct AaConfig {
|
|
uint8_t msaa_num_samples = 0;
|
|
bool aa_mask_centroid_dtmn = false;
|
|
uint8_t max_sample_dist = 0;
|
|
uint8_t msaa_exposed_samples = 0;
|
|
};
|
|
|
|
struct Viewport {
|
|
float zmin = 0.0f;
|
|
float zmax = 0.0f;
|
|
float xscale = 1.0f;
|
|
float xoffset = 0.0f;
|
|
float yscale = 1.0f;
|
|
float yoffset = 0.0f;
|
|
float zscale = 1.0f;
|
|
float zoffset = 0.0f;
|
|
int viewport_scissor_left = 0;
|
|
int viewport_scissor_top = 0;
|
|
int viewport_scissor_right = 16384;
|
|
int viewport_scissor_bottom = 16384;
|
|
bool viewport_scissor_window_offset_enable = false;
|
|
};
|
|
|
|
struct ScreenViewport {
|
|
Viewport viewports[16];
|
|
uint32_t transform_control = 1087;
|
|
int screen_scissor_left = 0;
|
|
int screen_scissor_top = 0;
|
|
int screen_scissor_right = 16384;
|
|
int screen_scissor_bottom = 16384;
|
|
int window_scissor_left = 0;
|
|
int window_scissor_top = 0;
|
|
int window_scissor_right = 16384;
|
|
int window_scissor_bottom = 16384;
|
|
bool window_scissor_window_offset_enable = false;
|
|
int generic_scissor_left = 0;
|
|
int generic_scissor_top = 0;
|
|
int generic_scissor_right = 16384;
|
|
int generic_scissor_bottom = 16384;
|
|
bool generic_scissor_window_offset_enable = false;
|
|
int window_offset_x = 0;
|
|
int window_offset_y = 0;
|
|
uint32_t hw_offset_x = 0;
|
|
uint32_t hw_offset_y = 0;
|
|
float guard_band_horz_clip = 1.0f;
|
|
float guard_band_vert_clip = 1.0f;
|
|
float guard_band_horz_discard = 1.0f;
|
|
float guard_band_vert_discard = 1.0f;
|
|
uint16_t clip_rect_rule = 0xffffu;
|
|
int clip_rect_left[4] = {};
|
|
int clip_rect_top[4] = {};
|
|
int clip_rect_right[4] = {};
|
|
int clip_rect_bottom[4] = {};
|
|
bool clip_rect_window_offset_enable[4] = {};
|
|
};
|
|
|
|
struct HsShaderResource1 {
|
|
uint8_t vgprs = 0;
|
|
uint8_t priority = 0;
|
|
uint8_t float_mode = 0;
|
|
bool dx10_clamp = false;
|
|
bool debug_mode = false;
|
|
bool ieee_mode = false;
|
|
bool require_forward_progress = false;
|
|
bool threadgroup_configuration = false;
|
|
uint8_t ls_vgpr_component_count = 0;
|
|
bool fp16_overflow = false;
|
|
};
|
|
|
|
struct HsShaderResource2 {
|
|
bool scratch_en = false;
|
|
uint8_t user_sgpr = 0;
|
|
uint16_t lds_size = 0;
|
|
uint8_t shared_vgprs = 0;
|
|
};
|
|
|
|
struct PsShaderResource1 {
|
|
uint8_t vgprs = 0;
|
|
uint8_t priority = 0;
|
|
uint8_t float_mode = 0;
|
|
bool dx10_clamp = false;
|
|
bool debug_mode = false;
|
|
bool ieee_mode = false;
|
|
bool cu_group_disable = false;
|
|
bool require_forward_progress = false;
|
|
bool fp16_overflow = false;
|
|
};
|
|
|
|
struct PsShaderResource2 {
|
|
bool scratch_en = false;
|
|
uint8_t user_sgpr = 0;
|
|
bool wave_cnt_en = false;
|
|
uint8_t extra_lds_size = 0;
|
|
uint8_t raster_ordered_shading = 0;
|
|
uint8_t shared_vgprs = 0;
|
|
};
|
|
|
|
struct PsStageRegisters {
|
|
uint64_t data_addr = 0;
|
|
PsShaderResource1 rsrc1;
|
|
PsShaderResource2 rsrc2;
|
|
};
|
|
|
|
struct CsStageRegisters {
|
|
|
|
uint64_t data_addr = 0;
|
|
uint32_t num_thread_x = 0;
|
|
uint32_t num_thread_y = 0;
|
|
uint32_t num_thread_z = 0;
|
|
uint8_t vgprs = 0;
|
|
uint8_t priority = 0;
|
|
uint8_t float_mode = 0;
|
|
bool dx10_clamp = false;
|
|
bool debug_mode = false;
|
|
bool ieee_mode = false;
|
|
bool require_forward_progress = false;
|
|
bool fp16_overflow = false;
|
|
bool threadgroup_configuration = false;
|
|
uint8_t wave_size = 64;
|
|
bool scratch_en = false;
|
|
uint8_t user_sgpr = 0;
|
|
bool tgid_x_en = false;
|
|
bool tgid_y_en = false;
|
|
bool tgid_z_en = false;
|
|
bool tg_size_en = false;
|
|
uint8_t tidig_comp_cnt = 0;
|
|
uint16_t lds_size = 0;
|
|
uint8_t shared_vgprs = 0;
|
|
};
|
|
|
|
struct EsStageRegisters {
|
|
uint64_t data_addr = 0;
|
|
};
|
|
|
|
struct LsStageRegisters {
|
|
uint64_t data_addr = 0;
|
|
};
|
|
|
|
struct HsStageRegisters {
|
|
uint64_t data_addr = 0;
|
|
uint64_t user_data_addr = 0;
|
|
HsShaderResource1 rsrc1;
|
|
HsShaderResource2 rsrc2;
|
|
};
|
|
|
|
struct GsShaderResource1 {
|
|
uint8_t vgprs = 0;
|
|
uint8_t priority = 0;
|
|
uint8_t float_mode = 0;
|
|
bool dx10_clamp = false;
|
|
bool debug_mode = false;
|
|
bool ieee_mode = false;
|
|
bool cu_group_enable = false;
|
|
bool require_forward_progress = false;
|
|
bool threadgroup_configuration = false;
|
|
uint8_t gs_vgpr_component_count = 0;
|
|
bool fp16_overflow = false;
|
|
};
|
|
|
|
struct GsShaderResource2 {
|
|
bool scratch_en = false;
|
|
uint8_t user_sgpr = 0;
|
|
uint8_t es_vgpr_component_count = 0;
|
|
bool offchip_lds = false;
|
|
uint8_t lds_size = 0;
|
|
uint8_t shared_vgprs = 0;
|
|
};
|
|
|
|
struct GsStageRegisters {
|
|
uint64_t data_addr = 0;
|
|
uint64_t user_data_addr = 0;
|
|
GsShaderResource1 rsrc1;
|
|
GsShaderResource2 rsrc2;
|
|
};
|
|
|
|
struct ShaderRegisters {
|
|
uint32_t m_spiVsOutConfig = 0;
|
|
uint32_t m_spiShaderPosFormat = 0;
|
|
uint32_t m_paClVsOutCntl = 0;
|
|
|
|
uint32_t ps_interpolator_settings[32] = {0};
|
|
// uint32_t ps_input_num = 0;
|
|
|
|
uint32_t m_spiShaderIdxFormat = 0;
|
|
uint32_t m_geNggSubgrpCntl = 0;
|
|
uint32_t m_vgtGsInstanceCnt = 0;
|
|
uint32_t m_vgtGsOnchipCntl = 0;
|
|
uint32_t m_vgtHosMaxTessLevel = 0;
|
|
uint32_t m_vgtHosMinTessLevel = 0;
|
|
uint32_t m_geMaxOutputPerSubgroup = 0;
|
|
uint32_t m_vgtEsgsRingItemsize = 0;
|
|
uint32_t m_vgtGsMaxVertOut = 0;
|
|
uint32_t m_vgtGsOutPrimType = 0;
|
|
uint32_t m_vgtPrimitiveIdEn = 0;
|
|
uint32_t m_vgtReuseOff = 0;
|
|
uint32_t m_vgtTessDistribution = 0;
|
|
uint32_t m_vgtLsHsConfig = 0;
|
|
uint32_t m_vgtTfParam = 0;
|
|
|
|
uint32_t shader_z_format = 0;
|
|
uint8_t target_output_mode[8] = {};
|
|
uint32_t ps_input_ena = 0;
|
|
uint32_t ps_input_addr = 0;
|
|
uint32_t ps_in_control = 0;
|
|
uint32_t baryc_cntl = 0;
|
|
uint32_t m_cbShaderMask = 0;
|
|
|
|
uint32_t m_paScShaderControl = 0;
|
|
|
|
DepthShaderControl db_shader_control;
|
|
|
|
[[nodiscard]] uint32_t GetExportCount() const {
|
|
return 1u + ((m_spiVsOutConfig >> 1u) & 0x1Fu);
|
|
}
|
|
[[nodiscard]] uint32_t GetEsVertsPerSubgrp() const {
|
|
return (m_vgtGsOnchipCntl >> 0u) & 0x7FFu;
|
|
}
|
|
[[nodiscard]] uint32_t GetGsPrimsPerSubgrp() const {
|
|
return (m_vgtGsOnchipCntl >> 11u) & 0x7FFu;
|
|
}
|
|
[[nodiscard]] uint32_t GetGsInstPrimsInSubgrp() const {
|
|
return (m_vgtGsOnchipCntl >> 22u) & 0x3FFu;
|
|
}
|
|
};
|
|
|
|
enum class UserSgprType { Unknown, Region, Vsharp };
|
|
|
|
struct UserSgprInfo {
|
|
static constexpr int SGPRS_MAX = 32;
|
|
|
|
uint32_t value[SGPRS_MAX] = {0};
|
|
UserSgprType type[SGPRS_MAX] = {};
|
|
uint32_t count = 0;
|
|
};
|
|
|
|
struct VertexShaderInfo {
|
|
EsStageRegisters es_regs;
|
|
LsStageRegisters ls_regs;
|
|
HsStageRegisters hs_regs;
|
|
GsStageRegisters gs_regs;
|
|
UserSgprInfo hs_user_sgpr;
|
|
UserSgprInfo gs_user_sgpr;
|
|
};
|
|
|
|
struct PixelShaderInfo {
|
|
PsStageRegisters ps_regs;
|
|
UserSgprInfo ps_user_sgpr;
|
|
};
|
|
|
|
struct ComputeShaderInfo {
|
|
CsStageRegisters cs_regs;
|
|
UserSgprInfo cs_user_sgpr;
|
|
};
|
|
|
|
struct GeControl {
|
|
uint16_t primitive_group_size = 0;
|
|
uint16_t vertex_group_size = 0;
|
|
};
|
|
|
|
struct GeUserVgprEn {
|
|
bool vgpr1 = false;
|
|
bool vgpr2 = false;
|
|
bool vgpr3 = false;
|
|
};
|
|
|
|
class Context {
|
|
public:
|
|
Context() = default;
|
|
~Context() = default;
|
|
|
|
KYTY_CLASS_DEFAULT_COPY(Context);
|
|
|
|
void Reset() { *this = Context(); }
|
|
|
|
void SetColorBase(uint32_t slot, const ColorBase& base) { m_render_targets[slot].base = base; }
|
|
void SetColorView(uint32_t slot, const ColorView& view) { m_render_targets[slot].view = view; }
|
|
void SetColorInfo(uint32_t slot, const ColorInfo& info) { m_render_targets[slot].info = info; }
|
|
void SetColorAttrib(uint32_t slot, const ColorAttrib& attrib) {
|
|
m_render_targets[slot].attrib = attrib;
|
|
}
|
|
void SetColorAttrib2(uint32_t slot, const ColorAttrib2& attrib2) {
|
|
m_render_targets[slot].attrib2 = attrib2;
|
|
}
|
|
void SetColorAttrib3(uint32_t slot, const ColorAttrib3& attrib3) {
|
|
m_render_targets[slot].attrib3 = attrib3;
|
|
}
|
|
void SetColorDccControl(uint32_t slot, const ColorDccControl& dcc) {
|
|
m_render_targets[slot].dcc = dcc;
|
|
}
|
|
void SetColorCmask(uint32_t slot, const ColorCmask& cmask) {
|
|
m_render_targets[slot].cmask = cmask;
|
|
}
|
|
void SetColorFmask(uint32_t slot, const ColorFmask& fmask) {
|
|
m_render_targets[slot].fmask = fmask;
|
|
}
|
|
void SetColorClearWord0(uint32_t slot, const ColorClearWord0& clear_word0) {
|
|
m_render_targets[slot].clear_word0 = clear_word0;
|
|
}
|
|
void SetColorClearWord1(uint32_t slot, const ColorClearWord1& clear_word1) {
|
|
m_render_targets[slot].clear_word1 = clear_word1;
|
|
}
|
|
void SetColorDccAddr(uint32_t slot, const ColorDccAddr& dcc_addr) {
|
|
m_render_targets[slot].dcc_addr = dcc_addr;
|
|
}
|
|
[[nodiscard]] const RenderTarget& GetRenderTarget(uint32_t slot) const {
|
|
return m_render_targets[slot];
|
|
}
|
|
|
|
void SetBlendControl(uint32_t slot, const BlendControl& control) {
|
|
m_blend_control[slot] = control;
|
|
}
|
|
[[nodiscard]] const BlendControl& GetBlendControl(uint32_t slot) const {
|
|
return m_blend_control[slot];
|
|
}
|
|
|
|
void SetRenderTargetMask(uint32_t mask) { m_render_target_mask = mask; }
|
|
[[nodiscard]] uint32_t GetRenderTargetMask() const { return m_render_target_mask; }
|
|
|
|
void SetShaderStages(uint32_t flags) { m_shader_stages = flags; }
|
|
[[nodiscard]] uint32_t GetShaderStages() const { return m_shader_stages; }
|
|
|
|
void SetDepthRenderTarget(const DepthRenderTarget& target) { m_depth_render_target = target; }
|
|
[[nodiscard]] const DepthRenderTarget& GetDepthRenderTarget() const {
|
|
return m_depth_render_target;
|
|
}
|
|
void SetDepthZInfo(const DepthZInfo& info) { m_depth_render_target.z_info = info; }
|
|
[[nodiscard]] const DepthZInfo& GetDepthZInfo() const { return m_depth_render_target.z_info; }
|
|
void SetDepthStencilInfo(const DepthStencilInfo& info) {
|
|
m_depth_render_target.stencil_info = info;
|
|
}
|
|
[[nodiscard]] const DepthStencilInfo& GetDepthStencilInfo() const {
|
|
return m_depth_render_target.stencil_info;
|
|
}
|
|
void SetDepthZReadBase(uint64_t addr) { m_depth_render_target.z_read_base_addr = addr; }
|
|
void SetDepthStencilReadBase(uint64_t addr) {
|
|
m_depth_render_target.stencil_read_base_addr = addr;
|
|
}
|
|
void SetDepthZWriteBase(uint64_t addr) { m_depth_render_target.z_write_base_addr = addr; }
|
|
void SetDepthStencilWriteBase(uint64_t addr) {
|
|
m_depth_render_target.stencil_write_base_addr = addr;
|
|
}
|
|
void SetDepthHTileDataBase(uint64_t addr) { m_depth_render_target.htile_data_base_addr = addr; }
|
|
void SetDepthDepthView(const DepthDepthView& view) { m_depth_render_target.depth_view = view; }
|
|
[[nodiscard]] const DepthDepthView& GetDepthDepthView() const {
|
|
return m_depth_render_target.depth_view;
|
|
}
|
|
void SetDepthDepthSizeXY(const DepthDepthSizeXY& size) { m_depth_render_target.size = size; }
|
|
[[nodiscard]] const DepthDepthSizeXY& GetDepthDepthSizeXY() const {
|
|
return m_depth_render_target.size;
|
|
}
|
|
|
|
void SetViewportZMin(uint32_t viewport_id, float zmin) {
|
|
m_screen_viewport.viewports[viewport_id].zmin = zmin;
|
|
}
|
|
void SetViewportZMax(uint32_t viewport_id, float zmax) {
|
|
m_screen_viewport.viewports[viewport_id].zmax = zmax;
|
|
}
|
|
void SetViewportScaleOffset(uint32_t viewport_id, float xscale, float xoffset, float yscale,
|
|
float yoffset, float zscale, float zoffset) {
|
|
m_screen_viewport.viewports[viewport_id].xscale = xscale;
|
|
m_screen_viewport.viewports[viewport_id].xoffset = xoffset;
|
|
m_screen_viewport.viewports[viewport_id].yscale = yscale;
|
|
m_screen_viewport.viewports[viewport_id].yoffset = yoffset;
|
|
m_screen_viewport.viewports[viewport_id].zscale = zscale;
|
|
m_screen_viewport.viewports[viewport_id].zoffset = zoffset;
|
|
}
|
|
void SetViewportXScale(uint32_t viewport_id, float xscale) {
|
|
m_screen_viewport.viewports[viewport_id].xscale = xscale;
|
|
}
|
|
void SetViewportXOffset(uint32_t viewport_id, float xoffset) {
|
|
m_screen_viewport.viewports[viewport_id].xoffset = xoffset;
|
|
}
|
|
void SetViewportYScale(uint32_t viewport_id, float yscale) {
|
|
m_screen_viewport.viewports[viewport_id].yscale = yscale;
|
|
}
|
|
void SetViewportYOffset(uint32_t viewport_id, float yoffset) {
|
|
m_screen_viewport.viewports[viewport_id].yoffset = yoffset;
|
|
}
|
|
void SetViewportZScale(uint32_t viewport_id, float zscale) {
|
|
m_screen_viewport.viewports[viewport_id].zscale = zscale;
|
|
}
|
|
void SetViewportZOffset(uint32_t viewport_id, float zoffset) {
|
|
m_screen_viewport.viewports[viewport_id].zoffset = zoffset;
|
|
}
|
|
void SetViewportScissor(uint32_t viewport_id, int left, int top, int right, int bottom,
|
|
bool window_offset_enable) {
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_left = left;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_top = top;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_right = right;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_bottom = bottom;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_window_offset_enable =
|
|
window_offset_enable;
|
|
}
|
|
void SetViewportScissorTL(uint32_t viewport_id, int left, int top, bool window_offset_enable) {
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_left = left;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_top = top;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_window_offset_enable =
|
|
window_offset_enable;
|
|
}
|
|
void SetViewportScissorBR(uint32_t viewport_id, int right, int bottom) {
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_right = right;
|
|
m_screen_viewport.viewports[viewport_id].viewport_scissor_bottom = bottom;
|
|
}
|
|
void SetViewportTransformControl(uint32_t control) {
|
|
m_screen_viewport.transform_control = control;
|
|
}
|
|
void SetScreenScissor(int left, int top, int right, int bottom) {
|
|
m_screen_viewport.screen_scissor_left = left;
|
|
m_screen_viewport.screen_scissor_top = top;
|
|
m_screen_viewport.screen_scissor_right = right;
|
|
m_screen_viewport.screen_scissor_bottom = bottom;
|
|
}
|
|
void SetWindowScissor(int left, int top, int right, int bottom, bool window_offset_enable) {
|
|
m_screen_viewport.window_scissor_left = left;
|
|
m_screen_viewport.window_scissor_top = top;
|
|
m_screen_viewport.window_scissor_right = right;
|
|
m_screen_viewport.window_scissor_bottom = bottom;
|
|
m_screen_viewport.window_scissor_window_offset_enable = window_offset_enable;
|
|
}
|
|
void SetGenericScissor(int left, int top, int right, int bottom, bool window_offset_enable) {
|
|
m_screen_viewport.generic_scissor_left = left;
|
|
m_screen_viewport.generic_scissor_top = top;
|
|
m_screen_viewport.generic_scissor_right = right;
|
|
m_screen_viewport.generic_scissor_bottom = bottom;
|
|
m_screen_viewport.generic_scissor_window_offset_enable = window_offset_enable;
|
|
}
|
|
void SetWindowOffset(int offset_x, int offset_y) {
|
|
m_screen_viewport.window_offset_x = offset_x;
|
|
m_screen_viewport.window_offset_y = offset_y;
|
|
}
|
|
void SetHardwareScreenOffset(uint32_t offset_x, uint32_t offset_y) {
|
|
m_screen_viewport.hw_offset_x = offset_x;
|
|
m_screen_viewport.hw_offset_y = offset_y;
|
|
}
|
|
void SetGuardBands(float horz_clip, float vert_clip, float horz_discard, float vert_discard) {
|
|
m_screen_viewport.guard_band_horz_clip = horz_clip;
|
|
m_screen_viewport.guard_band_vert_clip = vert_clip;
|
|
m_screen_viewport.guard_band_horz_discard = horz_discard;
|
|
m_screen_viewport.guard_band_vert_discard = vert_discard;
|
|
}
|
|
void SetClipRectRule(uint16_t rule) { m_screen_viewport.clip_rect_rule = rule; }
|
|
void SetClipRectTL(uint32_t rect_id, int left, int top, bool window_offset_enable) {
|
|
m_screen_viewport.clip_rect_left[rect_id] = left;
|
|
m_screen_viewport.clip_rect_top[rect_id] = top;
|
|
m_screen_viewport.clip_rect_window_offset_enable[rect_id] = window_offset_enable;
|
|
}
|
|
void SetClipRectBR(uint32_t rect_id, int right, int bottom) {
|
|
m_screen_viewport.clip_rect_right[rect_id] = right;
|
|
m_screen_viewport.clip_rect_bottom[rect_id] = bottom;
|
|
}
|
|
[[nodiscard]] const ScreenViewport& GetScreenViewport() const { return m_screen_viewport; }
|
|
|
|
[[nodiscard]] const BlendColor& GetBlendColor() const { return m_blend_color; }
|
|
void SetBlendColor(const BlendColor& color) { m_blend_color = color; }
|
|
[[nodiscard]] const ClipControl& GetClipControl() const { return m_clip_control; }
|
|
void SetClipControl(const ClipControl& control) { m_clip_control = control; }
|
|
[[nodiscard]] const RenderControl& GetRenderControl() const { return m_render_control; }
|
|
void SetRenderControl(const RenderControl& control) { m_render_control = control; }
|
|
[[nodiscard]] const DepthRenderOverride& GetDepthRenderOverride() const {
|
|
return m_depth_render_override;
|
|
}
|
|
void SetDepthRenderOverride(const DepthRenderOverride& control) {
|
|
m_depth_render_override = control;
|
|
}
|
|
[[nodiscard]] const DepthControl& GetDepthControl() const { return m_depth_control; }
|
|
void SetDepthControl(const DepthControl& control) { m_depth_control = control; }
|
|
[[nodiscard]] const ModeControl& GetModeControl() const { return m_mode_control; }
|
|
void SetModeControl(const ModeControl& control) { m_mode_control = control; }
|
|
[[nodiscard]] const PolyOffset& GetPolyOffset() const { return m_poly_offset; }
|
|
void SetPolyOffset(const PolyOffset& offset) { m_poly_offset = offset; }
|
|
[[nodiscard]] const EqaaControl& GetEqaaControl() const { return m_eqaa_control; }
|
|
void SetEqaaControl(const EqaaControl& control) { m_eqaa_control = control; }
|
|
[[nodiscard]] const StencilControl& GetStencilControl() const { return m_stencil_control; }
|
|
void SetStencilControl(const StencilControl& control) { m_stencil_control = control; }
|
|
[[nodiscard]] const StencilMask& GetStencilMask() const { return m_stencil_mask; }
|
|
void SetStencilMask(const StencilMask& mask) { m_stencil_mask = mask; }
|
|
[[nodiscard]] const ColorControl& GetColorControl() const { return m_color_control; }
|
|
void SetColorControl(const ColorControl& control) { m_color_control = control; }
|
|
[[nodiscard]] const ScanModeControl& GetScanModeControl() const { return m_scan_mode_control; }
|
|
void SetScanModeControl(const ScanModeControl& control) { m_scan_mode_control = control; }
|
|
[[nodiscard]] const AaSampleControl& GetAaSampleControl() const { return m_aa_sample_control; }
|
|
void SetAaSampleControl(const AaSampleControl& control) { m_aa_sample_control = control; }
|
|
[[nodiscard]] const AaConfig& GetAaConfig() const { return m_aa_config; }
|
|
void SetAaConfig(const AaConfig& config) { m_aa_config = config; }
|
|
|
|
[[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; }
|
|
void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; }
|
|
[[nodiscard]] float GetDepthBoundsMin() const { return m_depth_bounds_min; }
|
|
[[nodiscard]] float GetDepthBoundsMax() const { return m_depth_bounds_max; }
|
|
void SetDepthBoundsMin(float value) { m_depth_bounds_min = value; }
|
|
void SetDepthBoundsMax(float value) { m_depth_bounds_max = value; }
|
|
[[nodiscard]] uint8_t GetStencilClearValue() const { return m_stencil_clear_value; }
|
|
void SetStencilClearValue(uint8_t clear_value) { m_stencil_clear_value = clear_value; }
|
|
|
|
[[nodiscard]] float GetLineWidth() const { return m_line_width; }
|
|
void SetLineWidth(float width) { m_line_width = width; }
|
|
[[nodiscard]] uint32_t GetPrimitiveResetIndex() const { return m_primitive_reset_index; }
|
|
void SetPrimitiveResetIndex(uint32_t index) { m_primitive_reset_index = index; }
|
|
|
|
[[nodiscard]] const ShaderRegisters& GetShaderRegisters() const { return m_sh_regs; }
|
|
|
|
void SetVsOutConfig(uint32_t value) { m_sh_regs.m_spiVsOutConfig = value; }
|
|
void SetShaderPosFormat(uint32_t value) { m_sh_regs.m_spiShaderPosFormat = value; }
|
|
void SetClVsOutCntl(uint32_t value) { m_sh_regs.m_paClVsOutCntl = value; }
|
|
void SetShaderIdxFormat(uint32_t value) { m_sh_regs.m_spiShaderIdxFormat = value; }
|
|
void SetNggSubgrpCntl(uint32_t value) { m_sh_regs.m_geNggSubgrpCntl = value; }
|
|
void SetGsInstanceCnt(uint32_t value) { m_sh_regs.m_vgtGsInstanceCnt = value; }
|
|
void SetGsOnchipCntl(uint32_t value) { m_sh_regs.m_vgtGsOnchipCntl = value; }
|
|
void SetHosMaxTessLevel(uint32_t value) { m_sh_regs.m_vgtHosMaxTessLevel = value; }
|
|
void SetHosMinTessLevel(uint32_t value) { m_sh_regs.m_vgtHosMinTessLevel = value; }
|
|
void SetMaxOutputPerSubgroup(uint32_t value) { m_sh_regs.m_geMaxOutputPerSubgroup = value; }
|
|
void SetEsgsRingItemsize(uint32_t value) { m_sh_regs.m_vgtEsgsRingItemsize = value; }
|
|
void SetGsMaxVertOut(uint32_t value) { m_sh_regs.m_vgtGsMaxVertOut = value; }
|
|
void SetGsOutPrimType(uint32_t value) { m_sh_regs.m_vgtGsOutPrimType = value; }
|
|
void SetPrimitiveIdEn(uint32_t value) { m_sh_regs.m_vgtPrimitiveIdEn = value; }
|
|
void SetReuseOff(uint32_t value) { m_sh_regs.m_vgtReuseOff = value; }
|
|
void SetTessDistribution(uint32_t value) { m_sh_regs.m_vgtTessDistribution = value; }
|
|
void SetLsHsConfig(uint32_t value) { m_sh_regs.m_vgtLsHsConfig = value; }
|
|
void SetTfParam(uint32_t value) { m_sh_regs.m_vgtTfParam = value; }
|
|
|
|
void SetPsInputSettings(uint32_t id, uint32_t value) {
|
|
m_sh_regs.ps_interpolator_settings[id] = value;
|
|
// m_sh_regs.ps_input_num = ((id + 1) > m_sh_regs.ps_input_num ? (id + 1) :
|
|
// m_sh_regs.ps_input_num);
|
|
}
|
|
|
|
void SetShaderZFormat(uint32_t value) { m_sh_regs.shader_z_format = value; }
|
|
void SetTargetOutputMode(uint32_t slot, uint8_t value) {
|
|
m_sh_regs.target_output_mode[slot] = value;
|
|
}
|
|
void SetPsInputEna(uint32_t value) { m_sh_regs.ps_input_ena = value; }
|
|
void SetPsInputAddr(uint32_t value) { m_sh_regs.ps_input_addr = value; }
|
|
void SetPsInControl(uint32_t value) { m_sh_regs.ps_in_control = value; }
|
|
void SetBarycCntl(uint32_t value) { m_sh_regs.baryc_cntl = value; }
|
|
void SetShaderMask(uint32_t value) { m_sh_regs.m_cbShaderMask = value; }
|
|
void SetDepthShaderControl(const DepthShaderControl& value) {
|
|
m_sh_regs.db_shader_control = value;
|
|
}
|
|
|
|
void SetScShaderControl(uint32_t value) { m_sh_regs.m_paScShaderControl = value; }
|
|
|
|
private:
|
|
float m_line_width = 1.0f;
|
|
uint32_t m_primitive_reset_index = 0xffffffffu;
|
|
|
|
BlendControl m_blend_control[8];
|
|
BlendColor m_blend_color;
|
|
RenderTarget m_render_targets[8];
|
|
uint32_t m_render_target_mask = 0;
|
|
ScreenViewport m_screen_viewport;
|
|
ClipControl m_clip_control;
|
|
ColorControl m_color_control;
|
|
ScanModeControl m_scan_mode_control;
|
|
|
|
AaSampleControl m_aa_sample_control;
|
|
AaConfig m_aa_config;
|
|
|
|
uint32_t m_shader_stages = 0;
|
|
|
|
DepthRenderTarget m_depth_render_target;
|
|
RenderControl m_render_control;
|
|
DepthRenderOverride m_depth_render_override;
|
|
DepthControl m_depth_control;
|
|
StencilControl m_stencil_control;
|
|
StencilMask m_stencil_mask;
|
|
float m_depth_clear_value = 0.0f;
|
|
float m_depth_bounds_min = 0.0f;
|
|
float m_depth_bounds_max = 1.0f;
|
|
uint8_t m_stencil_clear_value = 0;
|
|
|
|
ModeControl m_mode_control;
|
|
PolyOffset m_poly_offset;
|
|
EqaaControl m_eqaa_control;
|
|
|
|
ShaderRegisters m_sh_regs;
|
|
};
|
|
|
|
struct FsrView {
|
|
uint32_t control_points[2][4] {};
|
|
uint32_t alphas[2][2] {};
|
|
uint32_t window[2] {};
|
|
};
|
|
|
|
class UserConfig {
|
|
public:
|
|
UserConfig() = default;
|
|
~UserConfig() = default;
|
|
|
|
KYTY_CLASS_DEFAULT_COPY(UserConfig);
|
|
|
|
void Reset() { *this = UserConfig(); }
|
|
|
|
void SetPrimitiveType(Prospero::PrimitiveType prim_type) { m_prim_type = prim_type; }
|
|
[[nodiscard]] Prospero::PrimitiveType GetPrimType() const { return m_prim_type; }
|
|
void SetIndexOffset(uint32_t index_offset) { m_index_offset = index_offset; }
|
|
[[nodiscard]] uint32_t GetIndexOffset() const { return m_index_offset; }
|
|
void SetObjectId(uint32_t object_id) { m_object_id = object_id; }
|
|
[[nodiscard]] uint32_t GetObjectId() const { return m_object_id; }
|
|
void SetPrimitiveResetControl(uint32_t control) { m_primitive_reset_control = control; }
|
|
[[nodiscard]] uint32_t GetPrimitiveResetControl() const { return m_primitive_reset_control; }
|
|
|
|
[[nodiscard]] const GeControl& GetGeControl() const { return m_ge_cntl; }
|
|
void SetGeControl(const GeControl& control) { m_ge_cntl = control; }
|
|
[[nodiscard]] const GeUserVgprEn& GetGeUserVgprEn() const { return m_ge_user_vgpr_en; }
|
|
void SetGeUserVgprEn(const GeUserVgprEn& en) { m_ge_user_vgpr_en = en; }
|
|
[[nodiscard]] const GdsOaState& GetGdsOaState() const { return m_gds_oa; }
|
|
[[nodiscard]] const GdsOaCounter& GetGdsOaCounter(uint32_t index) const {
|
|
return m_gds_oa.counters[index & 0x0fu];
|
|
}
|
|
void SetGdsOaCntl(uint32_t value) { m_gds_oa.cntl = value; }
|
|
void SetGdsOaCounter(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].counter = value; }
|
|
void SetGdsOaAddress(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].address = value; }
|
|
void SetFsrControlPoint(uint32_t axis, uint32_t index, uint32_t value) {
|
|
m_fsr_view.control_points[axis][index] = value;
|
|
}
|
|
void SetFsrAlpha(uint32_t axis, uint32_t index, uint32_t value) {
|
|
m_fsr_view.alphas[axis][index] = value;
|
|
}
|
|
void SetFsrWindow(uint32_t index, uint32_t value) { m_fsr_view.window[index] = value; }
|
|
[[nodiscard]] const FsrView& GetFsrView() const { return m_fsr_view; }
|
|
|
|
private:
|
|
FsrView m_fsr_view;
|
|
Prospero::PrimitiveType m_prim_type = Prospero::PrimitiveType::kNone;
|
|
uint32_t m_index_offset = 0;
|
|
uint32_t m_object_id = 0;
|
|
uint32_t m_primitive_reset_control = 0;
|
|
|
|
GeControl m_ge_cntl;
|
|
GeUserVgprEn m_ge_user_vgpr_en;
|
|
GdsOaState m_gds_oa;
|
|
};
|
|
|
|
class Shader {
|
|
public:
|
|
Shader() = default;
|
|
~Shader() = default;
|
|
|
|
KYTY_CLASS_DEFAULT_COPY(Shader);
|
|
|
|
void Reset() { *this = Shader(); }
|
|
|
|
void SetEsShaderBase(uint64_t addr) { m_vs.es_regs.data_addr = addr; }
|
|
void SetLsShaderBase(uint64_t addr) { m_vs.ls_regs.data_addr = addr; }
|
|
void SetHsShaderBase(uint64_t addr) { m_vs.hs_regs.data_addr = addr; }
|
|
void SetHsUserDataAddress(uint32_t word, uint32_t value) {
|
|
SetUserDataAddressWord(m_vs.hs_regs.user_data_addr, word, value);
|
|
}
|
|
void SetHsShaderResource1(const HsShaderResource1& rsrc1) { m_vs.hs_regs.rsrc1 = rsrc1; }
|
|
void SetHsShaderResource2(const HsShaderResource2& rsrc2) { m_vs.hs_regs.rsrc2 = rsrc2; }
|
|
void SetGsShaderBase(uint64_t addr) { m_vs.gs_regs.data_addr = addr; }
|
|
void SetGsUserDataAddress(uint32_t word, uint32_t value) {
|
|
SetUserDataAddressWord(m_vs.gs_regs.user_data_addr, word, value);
|
|
}
|
|
void SetGsShaderResource1(const GsShaderResource1& rsrc1) { m_vs.gs_regs.rsrc1 = rsrc1; }
|
|
void SetGsShaderResource2(const GsShaderResource2& rsrc2) { m_vs.gs_regs.rsrc2 = rsrc2; }
|
|
|
|
void SetPsShaderBase(uint64_t addr) { m_ps.ps_regs.data_addr = addr; }
|
|
void SetPsShaderResource1(const PsShaderResource1& rsrc1) { m_ps.ps_regs.rsrc1 = rsrc1; }
|
|
void SetPsShaderResource2(const PsShaderResource2& rsrc2) { m_ps.ps_regs.rsrc2 = rsrc2; }
|
|
|
|
void SetCsShader(const CsStageRegisters& cs_regs) { m_cs.cs_regs = cs_regs; }
|
|
void SetCsWaveSize(uint8_t wave_size) { m_cs.cs_regs.wave_size = wave_size; }
|
|
|
|
void SetPsUserSgpr(uint32_t id, uint32_t value, UserSgprType type) {
|
|
m_ps.ps_user_sgpr.value[id] = value;
|
|
m_ps.ps_user_sgpr.type[id] = type;
|
|
m_ps.ps_user_sgpr.count =
|
|
((id + 1) > m_ps.ps_user_sgpr.count ? (id + 1) : m_ps.ps_user_sgpr.count);
|
|
}
|
|
void SetCsUserSgpr(uint32_t id, uint32_t value, UserSgprType type) {
|
|
m_cs.cs_user_sgpr.value[id] = value;
|
|
m_cs.cs_user_sgpr.type[id] = type;
|
|
m_cs.cs_user_sgpr.count =
|
|
((id + 1) > m_cs.cs_user_sgpr.count ? (id + 1) : m_cs.cs_user_sgpr.count);
|
|
}
|
|
void SetHsUserSgpr(uint32_t id, uint32_t value, UserSgprType type) {
|
|
m_vs.hs_user_sgpr.value[id] = value;
|
|
m_vs.hs_user_sgpr.type[id] = type;
|
|
m_vs.hs_user_sgpr.count =
|
|
((id + 1) > m_vs.hs_user_sgpr.count ? (id + 1) : m_vs.hs_user_sgpr.count);
|
|
}
|
|
void SetGsUserSgpr(uint32_t id, uint32_t value, UserSgprType type) {
|
|
m_vs.gs_user_sgpr.value[id] = value;
|
|
m_vs.gs_user_sgpr.type[id] = type;
|
|
m_vs.gs_user_sgpr.count =
|
|
((id + 1) > m_vs.gs_user_sgpr.count ? (id + 1) : m_vs.gs_user_sgpr.count);
|
|
}
|
|
|
|
[[nodiscard]] const PixelShaderInfo& GetPs() const { return m_ps; }
|
|
[[nodiscard]] const VertexShaderInfo& GetVs() const { return m_vs; }
|
|
[[nodiscard]] const ComputeShaderInfo& GetCs() const { return m_cs; }
|
|
|
|
private:
|
|
static void SetUserDataAddressWord(uint64_t& address, uint32_t word, uint32_t value) {
|
|
const auto shift = word * 32u;
|
|
address = (address & ~(uint64_t {0xffffffffu} << shift)) |
|
|
(static_cast<uint64_t>(value) << shift);
|
|
}
|
|
|
|
VertexShaderInfo m_vs;
|
|
PixelShaderInfo m_ps;
|
|
ComputeShaderInfo m_cs;
|
|
};
|
|
|
|
} // namespace Libs::Graphics::HW
|
|
|
|
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_HARDWARECONTEXT_H_ */
|