// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include #include #include #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/math_util.h" #include "video_core/engines/const_buffer_info.h" #include "video_core/engines/engine_interface.h" #include "video_core/engines/engine_upload.h" #include "video_core/gpu.h" #include "video_core/macro/macro.h" #include "video_core/textures/texture.h" namespace Core { class System; } namespace Tegra { class MemoryManager; } namespace VideoCore { class RasterizerInterface; } namespace Tegra::Engines { /** * This Engine is known as GF100_3D. Documentation can be found in: * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h * https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml * https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h * * Note: nVidia have confirmed that their open docs have had parts redacted, so this list is * currently incomplete, and the gaps are still worth exploring. */ #define MAXWELL3D_REG_INDEX(field_name) (offsetof(Maxwell3D::Regs, field_name) / sizeof(u32)) class Maxwell3D final : public EngineInterface { public: explicit Maxwell3D(Core::System& system, MemoryManager& memory_manager); ~Maxwell3D(); /// Binds a rasterizer to this engine. void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); /// Register structure of the Maxwell3D engine. struct Regs { static constexpr std::size_t NUM_REGS = 0xE00; static constexpr std::size_t NumRenderTargets = 8; static constexpr std::size_t NumViewports = 16; static constexpr std::size_t NumCBData = 16; static constexpr std::size_t NumVertexArrays = 32; static constexpr std::size_t NumVertexAttributes = 32; static constexpr std::size_t NumVaryings = 31; static constexpr std::size_t NumImages = 8; // TODO(Rodrigo): Investigate this number static constexpr std::size_t NumClipDistances = 8; static constexpr std::size_t NumTransformFeedbackBuffers = 4; static constexpr std::size_t MaxShaderProgram = 6; static constexpr std::size_t MaxShaderStage = 5; // Maximum number of const buffers per shader stage. static constexpr std::size_t MaxConstBuffers = 18; static constexpr std::size_t MaxConstBufferSize = 0x10000; struct ID { union { BitField<0, 16, u32> cls; BitField<16, 5, u32> engine; }; }; struct LoadMME { u32 instruction_ptr; u32 instruction; u32 start_address_ptr; u32 start_address; }; struct Notify { u32 address_high; u32 address_low; u32 type; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct PeerSemaphore { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct GlobalRender { enum class Mode : u32 { False = 0, True = 1, Conditional = 2, IfEqual = 3, IfNotEqual = 4, }; u32 offset_high; u32 offset_low; Mode mode; GPUVAddr Address() const { return static_cast((static_cast(offset_high) << 32) | offset_low); } }; enum class ReductionOp : u32 { RedAdd = 0, RedMin = 1, RedMax = 2, RedInc = 3, RedDec = 4, RedAnd = 5, RedOr = 6, RedXor = 7, }; struct LaunchDMA { enum class Layout : u32 { Blocklinear = 0, Pitch = 1, }; enum class CompletionType : u32 { FlushDisable = 0, FlushOnly = 1, Release = 2, }; union { BitField<0, 1, Layout> memory_layout; BitField<4, 2, CompletionType> completion_type; BitField<8, 2, u32> interrupt_type; BitField<12, 1, u32> sem_size; BitField<1, 1, u32> reduction_enable; BitField<13, 3, ReductionOp> reduction_op; BitField<2, 2, u32> reduction_format; BitField<6, 1, u32> sysmembar_disable; }; }; struct I2M { u32 address_high; u32 address_low; u32 payload; INSERT_PADDING_BYTES_NOINIT(0x8); u32 nop0; u32 nop1; u32 nop2; u32 nop3; }; struct OpportunisticEarlyZ { BitField<0, 5, u32> threshold; u32 Threshold() const { switch (threshold) { case 0x0: return 0; case 0x1F: return 0x1F; default: // Thresholds begin at 0x10 (1 << 4) // Threshold is in the range 0x1 to 0x13 return 1 << (4 + threshold.Value() - 1); } } }; struct GeometryShaderDmFifo { union { BitField<0, 13, u32> raster_on; BitField<16, 13, u32> raster_off; BitField<31, 1, u32> spill_enabled; }; }; struct L2CacheControl { enum class EvictPolicy : u32 { First = 0, Normal = 1, Last = 2, }; union { BitField<4, 2, EvictPolicy> policy; }; }; struct InvalidateShaderCache { union { BitField<0, 1, u32> instruction; BitField<4, 1, u32> data; BitField<12, 1, u32> constant; BitField<1, 1, u32> locks; BitField<2, 1, u32> flush_data; }; }; struct SyncInfo { enum class Condition : u32 { StreamOutWritesDone = 0, RopWritesDone = 1, }; union { BitField<0, 16, u32> sync_point; BitField<16, 1, u32> clean_l2; BitField<20, 1, Condition> condition; }; }; struct SurfaceClipBlockId { union { BitField<0, 4, u32> block_width; BitField<4, 4, u32> block_height; BitField<8, 4, u32> block_depth; }; }; struct DecompressSurface { union { BitField<0, 3, u32> mrt_select; BitField<4, 16, u32> rt_array_index; }; }; struct ZCullRopBypass { union { BitField<0, 1, u32> enable; BitField<4, 1, u32> no_stall; BitField<8, 1, u32> cull_everything; BitField<12, 4, u32> threshold; }; }; struct ZCullSubregion { union { BitField<0, 1, u32> enable; BitField<4, 24, u32> normalized_aliquots; }; }; struct RasterBoundingBox { enum class Mode : u32 { BoundingBox = 0, FullViewport = 1, }; union { BitField<0, 1, Mode> mode; BitField<4, 8, u32> pad; }; }; struct IteratedBlendOptimization { enum class Noop : u32 { Never = 0, SourceRGBA0000 = 1, SourceAlpha = 2, SourceRGBA0001 = 3, }; union { BitField<0, 1, Noop> noop; }; }; struct ZCullSubregionAllocation { enum class Format : u32 { Z_16x16x2_4x4 = 0, ZS_16x16_4x4 = 1, Z_16x16_4x2 = 2, Z_16x16_2x4 = 3, Z_16x8_4x4 = 4, Z_8x8_4x2 = 5, Z_8x8_2x4 = 6, Z_16x16_4x8 = 7, Z_4x8_2x2 = 8, ZS_16x8_4x2 = 9, ZS_16x8_2x4 = 10, ZS_8x8_2x2 = 11, Z_4x8_1x1 = 12, None = 15, }; union { BitField<0, 8, u32> id; BitField<8, 16, u32> aliquots; BitField<24, 4, Format> format; }; }; enum class ZCullSubregionAlgorithm : u32 { Static = 0, Adaptive = 1, }; struct PixelShaderOutputSampleMaskUsage { union { BitField<0, 1, u32> enable; BitField<1, 1, u32> qualify_by_aa; }; }; struct L1Configuration { enum class AddressableMemory : u32 { Size16Kb = 0, Size48Kb = 3, }; union { BitField<0, 3, AddressableMemory> direct_addressable_memory; }; }; struct SPAVersion { union { BitField<0, 8, u32> minor; BitField<8, 8, u32> major; }; }; struct SnapGrid { enum class Location : u32 { Pixel2x2 = 1, Pixel4x4 = 2, Pixel8x8 = 3, Pixel16x16 = 4, Pixel32x32 = 5, Pixel64x64 = 6, Pixel128x128 = 7, Pixel256x256 = 8, }; enum class Mode : u32 { RTNE = 0, Tesla = 1, }; struct { union { BitField<0, 4, Location> location; BitField<8, 1, Mode> rounding_mode; }; } line; struct { union { BitField<0, 4, Location> location; BitField<8, 1, Mode> rounding_mode; }; } non_line; }; struct Tessellation { enum class DomainType : u32 { Isolines = 0, Triangles = 1, Quads = 2, }; enum class Spacing : u32 { Integer = 0, FractionalOdd = 1, FractionalEven = 2, }; enum class OutputPrimitives : u32 { Points = 0, Lines = 1, Triangles_CW = 2, Triangles_CCW = 3, }; struct Parameters { union { BitField<0, 2, DomainType> domain_type; BitField<4, 2, Spacing> spacing; BitField<8, 2, OutputPrimitives> output_primitives; }; } params; struct LOD { std::array outer; std::array inner; } lod; std::array reserved; }; struct SubTilingPerf { struct { union { BitField<0, 8, u32> spm_triangle_register_file_per; BitField<8, 8, u32> spm_pixel_output_buffer_per; BitField<16, 8, u32> spm_triangle_ram_per; BitField<24, 8, u32> max_quads_per; }; } knob_a; struct { union { BitField<0, 8, u32> max_primitives_per; }; } knob_b; u32 knob_c; }; struct ZCullSubregionReport { enum class ReportType : u32 { DepthTest = 0, DepthTestNoAccept = 1, DepthTestLateZ = 2, StencilTest = 3, }; union { BitField<0, 1, u32> enabled; BitField<4, 8, u32> subregion_id; } to_report; union { BitField<0, 1, u32> enabled; BitField<4, 3, ReportType> type; } report_type; }; struct BalancedPrimitiveWorkload { union { BitField<0, 1, u32> unpartitioned_mode; BitField<4, 1, u32> timesliced_mode; }; }; struct TransformFeedback { struct Buffer { u32 enable; u32 address_high; u32 address_low; s32 size; s32 start_offset; INSERT_PADDING_BYTES_NOINIT(0xC); GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; static_assert(sizeof(Buffer) == 0x20); struct Control { u32 stream; u32 varying_count; u32 stride; INSERT_PADDING_BYTES_NOINIT(0x4); }; static_assert(sizeof(Control) == 0x10); std::array buffers; INSERT_PADDING_BYTES_NOINIT(0x300); std::array controls; }; struct HybridAntiAliasControl { enum class Centroid : u32 { PerFragment = 0, PerPass = 1, }; union { BitField<0, 4, u32> passes; BitField<4, 1, Centroid> centroid; BitField<5, 1, u32> passes_extended; }; }; struct ShaderLocalMemory { u32 base_address; INSERT_PADDING_BYTES_NOINIT(0x10); u32 address_high; u32 address_low; u32 size_high; u32 size_low; u32 default_size_per_warp; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } u64 Size() const { return (static_cast(size_high) << 32) | size_low; } }; struct ZCullRegion { u32 width; u32 height; u32 depth; u32 offset; INSERT_PADDING_BYTES_NOINIT(0xC); u32 fetch_streams_once; union { BitField<0, 16, u32> start_aliquot; BitField<16, 16, u32> aliquot_count; } location; u32 aliquots_per_layer; u32 storage_address_high; u32 storage_address_low; u32 storage_limit_address_high; u32 storage_limit_address_low; GPUVAddr StorageAddress() const { return static_cast((static_cast(storage_address_high) << 32) | storage_address_low); } GPUVAddr StorageLimitAddress() const { return static_cast( (static_cast(storage_limit_address_high) << 32) | storage_limit_address_low); } }; struct ZetaReadOnly { union { BitField<0, 1, u32> enable_z; BitField<4, 1, u32> enable_stencil; }; }; struct VertexAttribute { enum class Size : u32 { Invalid = 0x0, Size_R32_G32_B32_A32 = 0x01, Size_R32_G32_B32 = 0x02, Size_R16_G16_B16_A16 = 0x03, Size_R32_G32 = 0x04, Size_R16_G16_B16 = 0x05, Size_R8_G8_B8_A8 = 0x0A, Size_R16_G16 = 0x0F, Size_R32 = 0x12, Size_R8_G8_B8 = 0x13, Size_R8_G8 = 0x18, Size_R16 = 0x1B, Size_R8 = 0x1D, Size_A2_B10_G10_R10 = 0x30, Size_B10_G11_R11 = 0x31, Size_G8_R8 = 0x32, Size_X8_B8_G8_R8 = 0x33, Size_A8 = 0x34, }; enum class Type : u32 { UnusedEnumDoNotUseBecauseItWillGoAway = 0, SNorm = 1, UNorm = 2, SInt = 3, UInt = 4, UScaled = 5, SScaled = 6, Float = 7, }; union { BitField<0, 5, u32> buffer; BitField<6, 1, u32> constant; BitField<7, 14, u32> offset; BitField<21, 6, Size> size; BitField<27, 3, Type> type; BitField<31, 1, u32> bgra; u32 hex; }; u32 ComponentCount() const { switch (size) { case Size::Size_R32_G32_B32_A32: return 4; case Size::Size_R32_G32_B32: return 3; case Size::Size_R16_G16_B16_A16: return 4; case Size::Size_R32_G32: return 2; case Size::Size_R16_G16_B16: return 3; case Size::Size_R8_G8_B8_A8: case Size::Size_X8_B8_G8_R8: return 4; case Size::Size_R16_G16: return 2; case Size::Size_R32: return 1; case Size::Size_R8_G8_B8: return 3; case Size::Size_R8_G8: case Size::Size_G8_R8: return 2; case Size::Size_R16: return 1; case Size::Size_R8: case Size::Size_A8: return 1; case Size::Size_A2_B10_G10_R10: return 4; case Size::Size_B10_G11_R11: return 3; default: ASSERT(false); return 1; } } u32 SizeInBytes() const { switch (size) { case Size::Size_R32_G32_B32_A32: return 16; case Size::Size_R32_G32_B32: return 12; case Size::Size_R16_G16_B16_A16: return 8; case Size::Size_R32_G32: return 8; case Size::Size_R16_G16_B16: return 6; case Size::Size_R8_G8_B8_A8: case Size::Size_X8_B8_G8_R8: return 4; case Size::Size_R16_G16: return 4; case Size::Size_R32: return 4; case Size::Size_R8_G8_B8: return 3; case Size::Size_R8_G8: case Size::Size_G8_R8: return 2; case Size::Size_R16: return 2; case Size::Size_R8: case Size::Size_A8: return 1; case Size::Size_A2_B10_G10_R10: return 4; case Size::Size_B10_G11_R11: return 4; default: ASSERT(false); return 1; } } std::string SizeString() const { switch (size) { case Size::Size_R32_G32_B32_A32: return "32_32_32_32"; case Size::Size_R32_G32_B32: return "32_32_32"; case Size::Size_R16_G16_B16_A16: return "16_16_16_16"; case Size::Size_R32_G32: return "32_32"; case Size::Size_R16_G16_B16: return "16_16_16"; case Size::Size_R8_G8_B8_A8: return "8_8_8_8"; case Size::Size_R16_G16: return "16_16"; case Size::Size_R32: return "32"; case Size::Size_R8_G8_B8: return "8_8_8"; case Size::Size_R8_G8: case Size::Size_G8_R8: return "8_8"; case Size::Size_R16: return "16"; case Size::Size_R8: case Size::Size_A8: return "8"; case Size::Size_A2_B10_G10_R10: return "2_10_10_10"; case Size::Size_B10_G11_R11: return "10_11_11"; default: ASSERT(false); return {}; } } std::string TypeString() const { switch (type) { case Type::UnusedEnumDoNotUseBecauseItWillGoAway: return "Unused"; case Type::SNorm: return "SNORM"; case Type::UNorm: return "UNORM"; case Type::SInt: return "SINT"; case Type::UInt: return "UINT"; case Type::UScaled: return "USCALED"; case Type::SScaled: return "SSCALED"; case Type::Float: return "FLOAT"; } ASSERT(false); return {}; } bool IsNormalized() const { return (type == Type::SNorm) || (type == Type::UNorm); } bool IsValid() const { return size != Size::Invalid; } bool operator<(const VertexAttribute& other) const { return hex < other.hex; } }; static_assert(sizeof(VertexAttribute) == 0x4); struct MsaaSampleLocation { union { BitField<0, 4, u32> x0; BitField<4, 4, u32> y0; BitField<8, 4, u32> x1; BitField<12, 4, u32> y1; BitField<16, 4, u32> x2; BitField<20, 4, u32> y2; BitField<24, 4, u32> x3; BitField<28, 4, u32> y3; }; constexpr std::pair Location(int index) const { switch (index) { case 0: return {x0, y0}; case 1: return {x1, y1}; case 2: return {x2, y2}; case 3: return {x3, y3}; default: ASSERT(false); return {0, 0}; } } }; struct MultisampleCoverageToColor { union { BitField<0, 1, u32> enable; BitField<4, 3, u32> target; }; }; struct DecompressZetaSurface { union { BitField<0, 1, u32> z_enable; BitField<4, 1, u32> stencil_enable; }; }; struct ZetaSparse { enum class UnmappedCompare : u32 { Unmapped = 0, FailAlways = 1, }; union { BitField<0, 1, u32> enable; BitField<1, 1, UnmappedCompare> unmapped_compare; }; }; struct RtControl { union { BitField<0, 4, u32> count; BitField<4, 3, u32> target0; BitField<7, 3, u32> target1; BitField<10, 3, u32> target2; BitField<13, 3, u32> target3; BitField<16, 3, u32> target4; BitField<19, 3, u32> target5; BitField<22, 3, u32> target6; BitField<25, 3, u32> target7; }; u32 Map(std::size_t index) const { const std::array maps{target0, target1, target2, target3, target4, target5, target6, target7}; ASSERT(index < maps.size()); return maps[index]; } }; struct CompressionThresholdSamples { u32 samples; u32 Samples() { if (samples == 0) { return 0; } return 1 << (samples - 1); } }; struct PixelShaderInterlockControl { enum class TileMode : u32 { NoConflictDetect = 0, DetectSampleConflict = 1, DetectPixelConflict = 2, }; enum class TileSize : u32 { Size_16x16 = 0, Size_8x8 = 1, }; enum class FragmentOrder : u32 { FragmentOrdered = 0, FragmentUnordered = 1, }; union { BitField<0, 2, TileMode> tile_mode; BitField<2, 1, TileSize> tile_size; BitField<3, 1, FragmentOrder> fragment_order; }; }; struct ZetaSize { enum class DimensionControl : u32 { DepthDefinesArray = 0, ArraySizeOne = 1, }; u32 width; u32 height; union { BitField<0, 16, u32> depth; BitField<16, 1, DimensionControl> dim_control; }; }; enum class PrimitiveTopology : u32 { Points = 0x0, Lines = 0x1, LineLoop = 0x2, LineStrip = 0x3, Triangles = 0x4, TriangleStrip = 0x5, TriangleFan = 0x6, Quads = 0x7, QuadStrip = 0x8, Polygon = 0x9, LinesAdjacency = 0xA, LineStripAdjacency = 0xB, TrianglesAdjacency = 0xC, TriangleStripAdjacency = 0xD, Patches = 0xE, }; struct VertexArray { union { BitField<0, 16, u32> start; BitField<16, 12, u32> count; BitField<28, 3, PrimitiveTopology> topology; }; }; enum class PrimitiveTopologyOverride : u32 { None = 0x0, Points = 0x1, Lines = 0x2, LineStrip = 0x3, Triangles = 0x4, TriangleStrip = 0x5, LinesAdjacency = 0xA, LineStripAdjacency = 0xB, TrianglesAdjacency = 0xC, TriangleStripAdjacency = 0xD, Patches = 0xE, LegacyPoints = 0x1001, LegacyIndexedLines = 0x1002, LegacyIndexedTriangles = 0x1003, LegacyLines = 0x100F, LegacyLineStrip = 0x1010, LegacyIndexedLineStrip = 0x1011, LegacyTriangles = 0x1012, LegacyTriangleStrip = 0x1013, LegacyIndexedTriangleStrip = 0x1014, LegacyTriangleFan = 0x1015, LegacyIndexedTriangleFan = 0x1016, LegacyTriangleFanImm = 0x1017, LegacyLinesImm = 0x1018, LegacyIndexedTriangles2 = 0x101A, LegacyIndexedLines2 = 0x101B, }; enum class DepthMode : u32 { MinusOneToOne = 0, ZeroToOne = 1, }; enum class IndexFormat : u32 { UnsignedByte = 0x0, UnsignedShort = 0x1, UnsignedInt = 0x2, }; enum class ComparisonOp : u32 { Never_D3D = 1, Less_D3D = 2, Equal_D3D = 3, LessEqual_D3D = 4, Greater_D3D = 5, NotEqual_D3D = 6, GreaterEqual_D3D = 7, Always_D3D = 8, Never_GL = 0x200, Less_GL = 0x201, Equal_GL = 0x202, LessEqual_GL = 0x203, Greater_GL = 0x204, NotEqual_GL = 0x205, GreaterEqual_GL = 0x206, Always_GL = 0x207, }; enum class ClearReport : u32 { ZPassPixelCount = 0x01, ZCullStats = 0x02, StreamingPrimitvesNeededMinusSucceeded = 0x03, AlphaBetaClocks = 0x04, StreamingPrimitivesSucceeded = 0x10, StreamingPrimitivesNeeded = 0x11, VerticesGenerated = 0x12, PrimitivesGenerated = 0x13, VertexShaderInvocations = 0x15, TessellationInitInvocations = 0x16, TessellationShaderInvocations = 0x17, TessellationShaderPrimitivesGenerated = 0x18, GeometryShaderInvocations = 0x1A, GeometryShaderPrimitivesGenerated = 0x1B, ClipperInvocations = 0x1C, ClipperPrimitivesGenerated = 0x1D, PixelShaderInvocations = 0x1E, VtgPrimitivesOut = 0x1F, }; enum class FrontFace : u32 { ClockWise = 0x900, CounterClockWise = 0x901, }; enum class CullFace : u32 { Front = 0x404, Back = 0x405, FrontAndBack = 0x408, }; struct Blend { enum class Equation : u32 { Add_D3D = 1, Subtract_D3D = 2, ReverseSubtract_D3D = 3, Min_D3D = 4, Max_D3D = 5, Add_GL = 0x8006, Min_GL = 0x8007, Max_GL = 0x8008, Subtract_GL = 0x800A, ReverseSubtract_GL = 0x800B }; enum class Factor : u32 { Zero_D3D = 0x1, One_D3D = 0x2, SourceColor_D3D = 0x3, OneMinusSourceColor_D3D = 0x4, SourceAlpha_D3D = 0x5, OneMinusSourceAlpha_D3D = 0x6, DestAlpha_D3D = 0x7, OneMinusDestAlpha_D3D = 0x8, DestColor_D3D = 0x9, OneMinusDestColor_D3D = 0xA, SourceAlphaSaturate_D3D = 0xB, BothSourceAlpha_D3D = 0xC, OneMinusBothSourceAlpha_D3D = 0xD, BlendFactor_D3D = 0xE, OneMinusBlendFactor_D3D = 0xF, Source1Color_D3D = 0x10, OneMinusSource1Color_D3D = 0x11, Source1Alpha_D3D = 0x12, OneMinusSource1Alpha_D3D = 0x13, Zero_GL = 0x4000, One_GL = 0x4001, SourceColor_GL = 0x4300, OneMinusSourceColor_GL = 0x4301, SourceAlpha_GL = 0x4302, OneMinusSourceAlpha_GL = 0x4303, DestAlpha_GL = 0x4304, OneMinusDestAlpha_GL = 0x4305, DestColor_GL = 0x4306, OneMinusDestColor_GL = 0x4307, SourceAlphaSaturate_GL = 0x4308, ConstantColor_GL = 0xC001, OneMinusConstantColor_GL = 0xC002, ConstantAlpha_GL = 0xC003, OneMinusConstantAlpha_GL = 0xC004, Source1Color_GL = 0xC900, OneMinusSource1Color_GL = 0xC901, Source1Alpha_GL = 0xC902, OneMinusSource1Alpha_GL = 0xC903, }; u32 separate_alpha; Equation color_op; Factor color_source; Factor color_dest; Equation alpha_op; Factor alpha_source; u32 enable_global_color_key; Factor alpha_dest; u32 single_rop_control_enable; u32 enable[NumRenderTargets]; }; struct BlendPerTarget { u32 separate_alpha; Blend::Equation color_op; Blend::Factor color_source; Blend::Factor color_dest; Blend::Equation alpha_op; Blend::Factor alpha_source; Blend::Factor alpha_dest; INSERT_PADDING_BYTES_NOINIT(0x4); }; static_assert(sizeof(BlendPerTarget) == 0x20); enum class PolygonMode : u32 { Point = 0x1B00, Line = 0x1B01, Fill = 0x1B02, }; enum class ShadowRamControl : u32 { // write value to shadow ram Track = 0, // write value to shadow ram ( with validation ??? ) TrackWithFilter = 1, // only write to real hw register Passthrough = 2, // write value from shadow ram to real hw register Replay = 3, }; enum class ViewportSwizzle : u32 { PositiveX = 0, NegativeX = 1, PositiveY = 2, NegativeY = 3, PositiveZ = 4, NegativeZ = 5, PositiveW = 6, NegativeW = 7, }; enum class SamplerBinding : u32 { Independently = 0, ViaHeaderBinding = 1, }; struct TileMode { enum class DimensionControl : u32 { DepthDefinesArray = 0, DepthDefinesDepth = 1, }; union { BitField<0, 4, u32> block_width; BitField<4, 4, u32> block_height; BitField<8, 4, u32> block_depth; BitField<12, 1, u32> is_pitch_linear; BitField<16, 1, DimensionControl> dim_control; }; }; static_assert(sizeof(TileMode) == 4); struct RenderTargetConfig { u32 address_high; u32 address_low; u32 width; u32 height; Tegra::RenderTargetFormat format; TileMode tile_mode; union { BitField<0, 16, u32> depth; BitField<16, 1, u32> volume; }; u32 array_pitch; u32 base_layer; u32 mark_ieee_clean; INSERT_PADDING_BYTES_NOINIT(0x18); GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; static_assert(sizeof(RenderTargetConfig) == 0x40); struct ColorMask { union { u32 raw; BitField<0, 1, u32> R; BitField<4, 1, u32> G; BitField<8, 1, u32> B; BitField<12, 1, u32> A; }; }; struct ViewportTransform { f32 scale_x; f32 scale_y; f32 scale_z; f32 translate_x; f32 translate_y; f32 translate_z; union { u32 raw; BitField<0, 3, ViewportSwizzle> x; BitField<4, 3, ViewportSwizzle> y; BitField<8, 3, ViewportSwizzle> z; BitField<12, 3, ViewportSwizzle> w; } swizzle; union { BitField<0, 5, u32> x; BitField<8, 5, u32> y; } snap_grid_precision; Common::Rectangle GetRect() const { return { GetX(), // left GetY() + GetHeight(), // top GetX() + GetWidth(), // right GetY() // bottom }; } f32 GetX() const { return std::max(0.0f, translate_x - std::fabs(scale_x)); } f32 GetY() const { return std::max(0.0f, translate_y - std::fabs(scale_y)); } f32 GetWidth() const { return translate_x + std::fabs(scale_x) - GetX(); } f32 GetHeight() const { return translate_y + std::fabs(scale_y) - GetY(); } }; static_assert(sizeof(ViewportTransform) == 0x20); struct Viewport { enum class PixelCenter : u32 { HalfIntegers = 0, Integers = 1, }; union { BitField<0, 16, u32> x; BitField<16, 16, u32> width; }; union { BitField<0, 16, u32> y; BitField<16, 16, u32> height; }; float depth_range_near; float depth_range_far; }; static_assert(sizeof(Viewport) == 0x10); struct Window { union { BitField<0, 16, u32> x_min; BitField<16, 16, u32> x_max; }; union { BitField<0, 16, u32> y_min; BitField<16, 16, u32> y_max; }; }; static_assert(sizeof(Window) == 0x8); struct ClipIdExtent { union { BitField<0, 16, u32> x; BitField<16, 16, u32> width; }; union { BitField<0, 16, u32> y; BitField<16, 16, u32> height; }; }; static_assert(sizeof(ClipIdExtent) == 0x8); enum class VisibleCallLimit : u32 { Limit0 = 0, Limit1 = 1, Limit2 = 2, Limit4 = 3, Limit8 = 4, Limit16 = 5, Limit32 = 6, Limit64 = 7, Limit128 = 8, None = 15, }; struct StatisticsCounter { union { BitField<0, 1, u32> da_vertices; BitField<1, 1, u32> da_primitives; BitField<2, 1, u32> vs_invocations; BitField<3, 1, u32> gs_invocations; BitField<4, 1, u32> gs_primitives; BitField<5, 1, u32> streaming_primitives_succeeded; BitField<6, 1, u32> streaming_primitives_needed; BitField<7, 1, u32> clipper_invocations; BitField<8, 1, u32> clipper_primitives; BitField<9, 1, u32> ps_invocations; BitField<11, 1, u32> ti_invocations; BitField<12, 1, u32> ts_invocations; BitField<13, 1, u32> ts_primitives; BitField<14, 1, u32> total_streaming_primitives_needed_succeeded; BitField<10, 1, u32> vtg_primitives_out; BitField<15, 1, u32> alpha_beta_clocks; }; }; struct ClearRect { union { BitField<0, 16, u32> x_min; BitField<16, 16, u32> x_max; }; union { BitField<0, 16, u32> y_min; BitField<16, 16, u32> y_max; }; }; struct VertexBuffer { u32 first; u32 count; }; struct InvalidateShaderCacheNoWFI { union { BitField<0, 1, u32> instruction; BitField<4, 1, u32> global_data; BitField<12, 1, u32> constant; }; }; struct ZCullSerialization { enum class Applied : u32 { Always = 0, LateZ = 1, OutOfGamutZ = 2, LateZOrOutOfGamutZ = 3, }; union { BitField<0, 1, u32> enable; BitField<4, 2, Applied> applied; }; }; struct ZCullDirFormat { enum class Zdir : u32 { Less = 0, Greater = 1, }; enum class Zformat : u32 { MSB = 0, FP = 1, Ztrick = 2, Zf32 = 3, }; union { BitField<0, 16, Zdir> dir; BitField<16, 16, Zformat> format; }; }; struct IteratedBlend { union { BitField<0, 1, u32> enable; BitField<1, 1, u32> enable_alpha; }; u32 pass_count; }; struct ZCullCriterion { enum class Sfunc : u32 { Never = 0, Less = 1, Equal = 2, LessOrEqual = 3, Greater = 4, NotEqual = 5, GreaterOrEqual = 6, Always = 7, }; union { BitField<0, 8, Sfunc> sfunc; BitField<8, 1, u32> no_invalidate; BitField<9, 1, u32> force_match; BitField<16, 8, u32> sref; BitField<24, 8, u32> smask; }; }; struct LoadIteratedBlend { enum class Test : u32 { False = 0, True = 1, Equal = 2, NotEqual = 3, LessThan = 4, LessOrEqual = 5, Greater = 6, GreaterOrEqual = 7, }; enum class Operation : u32 { AddProducts = 0, SubProducts = 1, Min = 2, Max = 3, Reciprocal = 4, Add = 5, Sub = 6, }; enum class OperandA : u32 { SrcRGB = 0, DstRGB = 1, SrcAAA = 2, DstAAA = 3, Temp0_RGB = 4, Temp1_RGB = 5, Temp2_RGB = 6, PBR_RGB = 7, }; enum class OperandB : u32 { Zero = 0, One = 1, SrcRGB = 2, SrcAAA = 3, OneMinusSrcAAA = 4, DstRGB = 5, DstAAA = 6, OneMinusDstAAA = 7, Temp0_RGB = 9, Temp1_RGB = 10, Temp2_RGB = 11, PBR_RGB = 12, ConstRGB = 13, ZeroATimesB = 14, }; enum class Swizzle : u32 { RGB = 0, GBR = 1, RRR = 2, GGG = 3, BBB = 4, RToA = 5, }; enum class WriteMask : u32 { RGB = 0, ROnly = 1, GOnly = 2, BOnly = 3, }; enum class Pass : u32 { Temp0 = 0, Temp1 = 1, Temp2 = 2, None = 3, }; u32 instruction_ptr; union { BitField<0, 3, Test> test; BitField<3, 3, Operation> operation; BitField<6, 3, u32> const_input; BitField<9, 3, OperandA> operand_a; BitField<12, 4, OperandB> operand_b; BitField<16, 3, OperandA> operand_c; BitField<19, 4, OperandB> operand_d; BitField<23, 3, Swizzle> output_swizzle; BitField<26, 2, WriteMask> output_mask; BitField<28, 2, Pass> output_pass; BitField<31, 1, u32> test_enabled; }; }; struct ScissorTest { u32 enable; union { BitField<0, 16, u32> min_x; BitField<16, 16, u32> max_x; }; union { BitField<0, 16, u32> min_y; BitField<16, 16, u32> max_y; }; INSERT_PADDING_BYTES_NOINIT(0x4); }; static_assert(sizeof(ScissorTest) == 0x10); struct VPCPerf { union { BitField<0, 8, u32> culled_small_lines; BitField<8, 8, u32> culled_small_triangles; BitField<16, 8, u32> nonculled_lines_and_points; BitField<24, 8, u32> nonculled_triangles; }; }; struct ConstantColorRendering { u32 enabled; u32 red; u32 green; u32 blue; u32 alpha; }; struct VertexStreamSubstitute { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct VTGWarpWatermarks { union { BitField<0, 16, u32> low; BitField<16, 16, u32> high; }; }; struct SampleMask { struct Target { union { BitField<0, 1, u32> raster_out; BitField<4, 1, u32> color_target; }; u32 target; }; struct Pos { u32 x0_y0; u32 x1_y0; u32 x0_y1; u32 x1_y1; }; }; enum class NonMultisampledZ : u32 { PerSample = 0, PixelCenter = 1, }; enum class TIRMode : u32 { Disabled = 0, RasterNTargetM = 1, }; enum class AntiAliasRaster : u32 { Mode1x1 = 0, Mode2x2 = 2, Mode4x2_D3D = 4, Mode2x1_D3D = 5, Mode4x4 = 6, }; struct SurfaceClipIDMemory { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct TIRModulation { enum class Component : u32 { None = 0, RGB = 1, AlphaOnly = 2, RGBA = 3, }; enum class Function : u32 { Linear = 0, Table = 1, }; Component component; Function function; }; struct Zeta { u32 address_high; u32 address_low; Tegra::DepthFormat format; TileMode tile_mode; u32 array_pitch; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct SurfaceClip { union { BitField<0, 16, u32> x; BitField<16, 16, u32> width; }; union { BitField<0, 16, u32> y; BitField<16, 16, u32> height; }; }; enum class L2CacheControlPolicy : u32 { First = 0, Normal = 1, Last = 2, }; struct L2CacheVAFRequests { union { BitField<0, 1, u32> system_memory_volatile; BitField<4, 2, L2CacheControlPolicy> policy; }; }; enum class ViewportMulticast : u32 { ViewportOrder = 0, PrimitiveOrder = 1, }; struct TIRModulationCoeff { union { BitField<0, 8, u32> table_v0; BitField<8, 8, u32> table_v1; BitField<16, 8, u32> table_v2; BitField<24, 8, u32> table_v3; }; }; static_assert(sizeof(TIRModulationCoeff) == 0x4); struct ReduceColorThreshold { union { BitField<0, 8, u32> all_hit_once; BitField<16, 8, u32> all_covered; }; }; struct ClearControl { union { BitField<0, 1, u32> respect_stencil_mask; BitField<4, 1, u32> use_clear_rect; BitField<8, 1, u32> use_scissor; BitField<12, 1, u32> use_viewport_clip0; }; }; struct L2CacheRopNonInterlockedReads { union { BitField<4, 2, L2CacheControlPolicy> policy; }; }; struct VertexOutputAttributeSkipMasks { struct Attributes { union { BitField<0, 1, u32> attribute0_comp0; BitField<1, 1, u32> attribute0_comp1; BitField<2, 1, u32> attribute0_comp2; BitField<3, 1, u32> attribute0_comp3; BitField<4, 1, u32> attribute1_comp0; BitField<5, 1, u32> attribute1_comp1; BitField<6, 1, u32> attribute1_comp2; BitField<7, 1, u32> attribute1_comp3; BitField<8, 1, u32> attribute2_comp0; BitField<9, 1, u32> attribute2_comp1; BitField<10, 1, u32> attribute2_comp2; BitField<11, 1, u32> attribute2_comp3; BitField<12, 1, u32> attribute3_comp0; BitField<13, 1, u32> attribute3_comp1; BitField<14, 1, u32> attribute3_comp2; BitField<15, 1, u32> attribute3_comp3; BitField<16, 1, u32> attribute4_comp0; BitField<17, 1, u32> attribute4_comp1; BitField<18, 1, u32> attribute4_comp2; BitField<19, 1, u32> attribute4_comp3; BitField<20, 1, u32> attribute5_comp0; BitField<21, 1, u32> attribute5_comp1; BitField<22, 1, u32> attribute5_comp2; BitField<23, 1, u32> attribute5_comp3; BitField<24, 1, u32> attribute6_comp0; BitField<25, 1, u32> attribute6_comp1; BitField<26, 1, u32> attribute6_comp2; BitField<27, 1, u32> attribute6_comp3; BitField<28, 1, u32> attribute7_comp0; BitField<29, 1, u32> attribute7_comp1; BitField<30, 1, u32> attribute7_comp2; BitField<31, 1, u32> attribute7_comp3; }; }; std::array a; std::array b; }; struct TIRControl { union { BitField<0, 1, u32> z_pass_pixel_count_use_raster_samples; BitField<4, 1, u32> alpha_coverage_use_raster_samples; BitField<1, 1, u32> reduce_coverage; }; }; enum class FillViaTriangleMode : u32 { Disabled = 0, FillAll = 1, FillBoundingBox = 2, }; struct PsTicketDispenserValue { union { BitField<0, 8, u32> index; BitField<8, 16, u32> value; }; }; struct RegisterWatermarks { union { BitField<0, 16, u32> low; BitField<16, 16, u32> high; }; }; enum class InvalidateCacheLines : u32 { All = 0, One = 1, }; struct InvalidateTextureDataCacheNoWfi { union { BitField<0, 1, InvalidateCacheLines> lines; BitField<4, 22, u32> tag; }; }; struct ZCullRegionEnable { union { BitField<0, 1, u32> enable_z; BitField<4, 1, u32> enable_stencil; BitField<1, 1, u32> rect_clear; BitField<2, 1, u32> use_rt_array_index; BitField<5, 16, u32> rt_array_index; BitField<3, 1, u32> make_conservative; }; }; enum class FillMode : u32 { Point = 1, Wireframe = 2, Solid = 3, }; enum class ShadeMode : u32 { Flat = 0x1, Gouraud = 0x2, GL_Flat = 0x1D00, GL_Smooth = 0x1D01, }; enum class AlphaToCoverageDither : u32 { Footprint_1x1 = 0, Footprint_2x2 = 1, Footprint_1x1_Virtual = 2, }; struct InlineIndex4x8 { union { BitField<0, 30, u32> count; BitField<30, 2, u32> start; }; union { BitField<0, 8, u32> index0; BitField<8, 8, u32> index1; BitField<16, 8, u32> index2; BitField<24, 8, u32> index3; }; }; enum class D3DCullMode : u32 { None = 0, CW = 1, CCW = 2, }; struct BlendColor { f32 r; f32 g; f32 b; f32 a; }; struct StencilOp { enum class Op : u32 { Keep_D3D = 1, Zero_D3D = 2, Replace_D3D = 3, IncrSaturate_D3D = 4, DecrSaturate_D3D = 5, Invert_D3D = 6, Incr_D3D = 7, Decr_D3D = 8, Keep_GL = 0x1E00, Zero_GL = 0, Replace_GL = 0x1E01, IncrSaturate_GL = 0x1E02, DecrSaturate_GL = 0x1E03, Invert_GL = 0x150A, Incr_GL = 0x8507, Decr_GL = 0x8508, }; Op fail; Op zfail; Op zpass; ComparisonOp func; }; struct PsSaturate { // Opposite of DepthMode enum class Depth : u32 { ZeroToOne = 0, MinusOneToOne = 1, }; union { BitField<0, 1, u32> output0_enable; BitField<1, 1, Depth> output0_range; BitField<4, 1, u32> output1_enable; BitField<5, 1, Depth> output1_range; BitField<8, 1, u32> output2_enable; BitField<9, 1, Depth> output2_range; BitField<12, 1, u32> output3_enable; BitField<13, 1, Depth> output3_range; BitField<16, 1, u32> output4_enable; BitField<17, 1, Depth> output4_range; BitField<20, 1, u32> output5_enable; BitField<21, 1, Depth> output5_range; BitField<24, 1, u32> output6_enable; BitField<25, 1, Depth> output6_range; BitField<28, 1, u32> output7_enable; BitField<29, 1, Depth> output7_range; }; bool AnyEnabled() const { return output0_enable || output1_enable || output2_enable || output3_enable || output4_enable || output5_enable || output6_enable || output7_enable; } }; struct WindowOrigin { enum class Mode : u32 { UpperLeft = 0, LowerLeft = 1, }; union { BitField<0, 1, Mode> mode; BitField<4, 1, u32> flip_y; }; }; struct IteratedBlendConstants { u32 r; u32 g; u32 b; INSERT_PADDING_BYTES_NOINIT(0x4); }; static_assert(sizeof(IteratedBlendConstants) == 0x10); struct UserClip { struct Enable { union { u32 raw; BitField<0, 1, u32> plane0; BitField<1, 1, u32> plane1; BitField<2, 1, u32> plane2; BitField<3, 1, u32> plane3; BitField<4, 1, u32> plane4; BitField<5, 1, u32> plane5; BitField<6, 1, u32> plane6; BitField<7, 1, u32> plane7; }; bool AnyEnabled() const { return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 || plane7; } }; struct Op { enum class ClipOrCull : u32 { Clip = 0, Cull = 1, }; union { u32 raw; BitField<0, 1, ClipOrCull> plane0; BitField<4, 1, ClipOrCull> plane1; BitField<8, 1, ClipOrCull> plane2; BitField<12, 1, ClipOrCull> plane3; BitField<16, 1, ClipOrCull> plane4; BitField<20, 1, ClipOrCull> plane5; BitField<24, 1, ClipOrCull> plane6; BitField<28, 1, ClipOrCull> plane7; }; }; }; struct AntiAliasAlphaControl { union { BitField<0, 1, u32> alpha_to_coverage; BitField<4, 1, u32> alpha_to_one; }; }; struct RenderEnable { enum class Override : u32 { UseRenderEnable = 0, AlwaysRender = 1, NeverRender = 2, }; enum class Mode : u32 { False = 0, True = 1, Conditional = 2, IfEqual = 3, IfNotEqual = 4, }; u32 address_high; u32 address_low; Mode mode; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct TexSampler { u32 address_high; u32 address_low; u32 limit; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct TexHeader { u32 address_high; u32 address_low; u32 limit; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; enum class ZCullRegionFormat : u32 { Z_4x4 = 0, ZS_4x4 = 1, Z_4x2 = 2, Z_2x4 = 3, Z_16x8_4x4 = 4, Z_8x8_4x2 = 5, Z_8x8_2x4 = 6, Z_16x16_4x8 = 7, Z_4x8_2x2 = 8, ZS_16x8_4x2 = 9, ZS_16x8_2x4 = 10, ZS_8x8_2x2 = 11, Z_4x8_1x1 = 12, }; struct RtLayer { enum class Control { LayerSelectsLayer = 0, GeometryShaderSelectsLayer = 1, }; union { BitField<0, 16, u32> layer; BitField<16, 1, u32> control; }; }; struct InlineIndex2x16 { union { BitField<0, 31, u32> count; BitField<31, 1, u32> start_odd; }; union { BitField<0, 16, u32> even; BitField<16, 16, u32> odd; }; }; struct VertexGlobalBaseOffset { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct ZCullRegionPixelOffset { u32 width; u32 height; }; struct PointSprite { enum class RMode : u32 { Zero = 0, FromR = 1, FromS = 2, }; enum class Origin : u32 { Bottom = 0, Top = 1, }; enum class Texture : u32 { Passthrough = 0, Generate = 1, }; union { BitField<0, 2, RMode> rmode; BitField<2, 1, Origin> origin; BitField<3, 1, Texture> texture0; BitField<4, 1, Texture> texture1; BitField<5, 1, Texture> texture2; BitField<6, 1, Texture> texture3; BitField<7, 1, Texture> texture4; BitField<8, 1, Texture> texture5; BitField<9, 1, Texture> texture6; BitField<10, 1, Texture> texture7; BitField<11, 1, Texture> texture8; BitField<12, 1, Texture> texture9; }; }; struct ProgramRegion { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct DefaultAttributes { enum class Diffuse : u32 { Vector_0001 = 0, Vector_1111 = 1, }; enum class Specular : u32 { Vector_0000 = 0, Vector_0001 = 1, }; enum class Vector : u32 { Vector_0000 = 0, Vector_0001 = 1, }; enum class FixedFncTexture : u32 { Vector_0000 = 0, Vector_0001 = 1, }; enum class DX9Color0 : u32 { Vector_0000 = 0, Vector_1111 = 1, }; enum class DX9Color1To15 : u32 { Vector_0000 = 0, Vector_0001 = 1, }; union { BitField<0, 1, Diffuse> color_front_diffuse; BitField<1, 1, Specular> color_front_specular; BitField<2, 1, Vector> generic_vector; BitField<3, 1, FixedFncTexture> fixed_fnc_texture; BitField<4, 1, DX9Color0> dx9_color0; BitField<5, 1, DX9Color1To15> dx9_color1_to_15; }; }; struct Draw { enum class PrimitiveId : u32 { First = 0, Unchanged = 1, }; enum class InstanceId : u32 { First = 0, Subsequent = 1, Unchanged = 2, }; enum class SplitMode : u32 { NormalBeginNormal = 0, NormalBeginOpen = 1, OpenBeginOpen = 2, OpenBeginNormal = 3, }; u32 end; union { u32 begin; BitField<0, 16, PrimitiveTopology> topology; BitField<24, 1, PrimitiveId> primitive_id; BitField<26, 2, InstanceId> instance_id; BitField<29, 2, SplitMode> split_mode; }; }; struct VertexIdCopy { union { BitField<0, 1, u32> enable; BitField<4, 8, u32> attribute_slot; }; }; struct ShaderBasedCull { union { BitField<1, 1, u32> batch_cull_enable; BitField<0, 1, u32> before_fetch_enable; }; }; struct ClassVersion { union { BitField<0, 16, u32> current; BitField<16, 16, u32> oldest_supported; }; }; struct PrimitiveRestart { u32 enabled; u32 index; }; struct OutputVertexId { union { BitField<12, 1, u32> uses_array_start; }; }; enum class PointCenterMode : u32 { GL = 0, D3D = 1, }; enum class LineSmoothParams : u32 { Falloff_1_00 = 0, Falloff_1_33 = 1, Falloff_1_66 = 2, }; struct LineSmoothEdgeTable { union { BitField<0, 8, u32> v0; BitField<8, 8, u32> v1; BitField<16, 8, u32> v2; BitField<24, 8, u32> v3; }; }; struct LineStippleParams { union { BitField<0, 8, u32> factor; BitField<8, 16, u32> pattern; }; }; enum class ProvokingVertex : u32 { First = 0, Last = 1, }; struct ShaderControl { enum class Partial : u32 { Zero = 0, Infinity = 1, }; enum class FP32NanBehavior : u32 { Legacy = 0, FP64Compatible = 1, }; enum class FP32F2INanBehavior : u32 { PassZero = 0, PassIndefinite = 1, }; union { BitField<0, 1, Partial> default_partial; BitField<1, 1, FP32NanBehavior> fp32_nan_behavior; BitField<2, 1, FP32F2INanBehavior> fp32_f2i_nan_behavior; }; }; struct SphVersion { union { BitField<0, 16, u32> current; BitField<16, 16, u32> oldest_supported; }; }; struct AlphaToCoverageOverride { union { BitField<0, 1, u32> qualify_by_anti_alias_enable; BitField<1, 1, u32> qualify_by_ps_sample_mask_enable; }; }; struct AamVersion { union { BitField<0, 16, u32> current; BitField<16, 16, u32> oldest_supported; }; }; struct IndexBuffer { u32 start_addr_high; u32 start_addr_low; u32 limit_addr_high; u32 limit_addr_low; IndexFormat format; u32 first; u32 count; unsigned FormatSizeInBytes() const { switch (format) { case IndexFormat::UnsignedByte: return 1; case IndexFormat::UnsignedShort: return 2; case IndexFormat::UnsignedInt: return 4; } ASSERT(false); return 1; } GPUVAddr StartAddress() const { return static_cast((static_cast(start_addr_high) << 32) | start_addr_low); } GPUVAddr EndAddress() const { return static_cast((static_cast(limit_addr_high) << 32) | limit_addr_low); } /// Adjust the index buffer offset so it points to the first desired index. GPUVAddr IndexStart() const { return StartAddress() + static_cast(first) * static_cast(FormatSizeInBytes()); } }; struct IndexBufferSmall { union { BitField<0, 16, u32> first; BitField<16, 12, u32> count; BitField<28, 4, PrimitiveTopology> topology; }; }; struct VertexStreamInstances { std::array is_instanced; /// Returns whether the vertex array specified by index is supposed to be /// accessed per instance or not. bool IsInstancingEnabled(std::size_t index) const { return is_instanced[index]; } }; struct AttributePointSize { union { BitField<0, 1, u32> enabled; BitField<4, 8, u32> slot; }; }; struct ViewportClipControl { enum class GeometryGuardband : u32 { Scale256 = 0, Scale1 = 1, }; enum class GeometryClip : u32 { WZero = 0, Passthrough = 1, FrustumXY = 2, FrustumXYZ = 3, WZeroNoZCull = 4, FrustumZ = 5, WZeroTriFillOrClip = 6, }; enum class GeometryGuardbandZ : u32 { SameAsXY = 0, Scale256 = 1, Scale1 = 2, }; union { BitField<0, 1, u32> depth_0_to_1; BitField<3, 1, u32> pixel_min_z; BitField<4, 1, u32> pixel_max_z; BitField<7, 1, GeometryGuardband> geometry_guardband; BitField<11, 3, GeometryClip> geometry_clip; BitField<1, 2, GeometryGuardbandZ> geometry_guardband_z; }; }; enum class PrimitiveTopologyControl : u32 { UseInBeginMethods = 0, UseSeparateState = 1, }; struct WindowClip { enum class Type : u32 { Inclusive = 0, Exclusive = 1, ClipAll = 2, }; u32 enable; Type type; }; enum class InvalidateZCull : u32 { Invalidate = 0, }; struct ZCull { union { BitField<0, 1, u32> z_enable; BitField<1, 1, u32> stencil_enable; }; union { BitField<0, 1, u32> z_min_enbounded; BitField<1, 1, u32> z_max_unbounded; }; }; struct LogicOp { enum class Op : u32 { Clear = 0x1500, And = 0x1501, AndReverse = 0x1502, Copy = 0x1503, AndInverted = 0x1504, NoOp = 0x1505, Xor = 0x1506, Or = 0x1507, Nor = 0x1508, Equiv = 0x1509, Invert = 0x150A, OrReverse = 0x150B, CopyInverted = 0x150C, OrInverted = 0x150D, Nand = 0x150E, Set = 0x150F, }; u32 enable; Op op; }; struct ClearSurface { union { u32 raw; BitField<0, 1, u32> Z; BitField<1, 1, u32> S; BitField<2, 1, u32> R; BitField<3, 1, u32> G; BitField<4, 1, u32> B; BitField<5, 1, u32> A; BitField<6, 4, u32> RT; BitField<10, 16, u32> layer; }; }; struct ReportSemaphore { struct Compare { u32 initial_sequence; u32 initial_mode; u32 unknown1; u32 unknown2; u32 current_sequence; u32 current_mode; }; enum class Operation : u32 { Release = 0, Acquire = 1, ReportOnly = 2, Trap = 3, }; enum class Release : u32 { AfterAllPreceedingReads = 0, AfterAllPreceedingWrites = 1, }; enum class Acquire : u32 { BeforeAnyFollowingWrites = 0, BeforeAnyFollowingReads = 1, }; enum class Location : u32 { None = 0, VertexFetch = 1, VertexShader = 2, VPC = 4, StreamingOutput = 5, GeometryShader = 6, ZCull = 7, TessellationInit = 8, TessellationShader = 9, PixelShader = 10, DepthTest = 12, All = 15, }; enum class Comparison : u32 { NotEqual = 0, GreaterOrEqual = 1, }; enum class Report : u32 { Payload = 0, // "None" in docs, but confirmed via hardware to return the payload VerticesGenerated = 1, ZPassPixelCount = 2, PrimitivesGenerated = 3, AlphaBetaClocks = 4, VertexShaderInvocations = 5, StreamingPrimitivesNeededMinusSucceeded = 6, GeometryShaderInvocations = 7, GeometryShaderPrimitivesGenerated = 9, ZCullStats0 = 10, StreamingPrimitivesSucceeded = 11, ZCullStats1 = 12, StreamingPrimitivesNeeded = 13, ZCullStats2 = 14, ClipperInvocations = 15, ZCullStats3 = 16, ClipperPrimitivesGenerated = 17, VtgPrimitivesOut = 18, PixelShaderInvocations = 19, ZPassPixelCount64 = 21, IEEECleanColorTarget = 24, IEEECleanZetaTarget = 25, StreamingByteCount = 26, TessellationInitInvocations = 27, BoundingRectangle = 28, TessellationShaderInvocations = 29, TotalStreamingPrimitivesNeededMinusSucceeded = 30, TessellationShaderPrimitivesGenerated = 31, }; u32 address_high; u32 address_low; u32 payload; union { u32 raw; BitField<0, 2, Operation> operation; BitField<4, 1, Release> release; BitField<8, 1, Acquire> acquire; BitField<12, 4, Location> location; BitField<16, 1, Comparison> comparison; BitField<20, 1, u32> awaken_enable; BitField<23, 5, Report> report; BitField<28, 1, u32> short_query; BitField<5, 3, u32> sub_report; BitField<21, 1, u32> dword_number; BitField<2, 1, u32> disable_flush; BitField<3, 1, u32> reduction_enable; BitField<9, 3, ReductionOp> reduction_op; BitField<17, 2, u32> format_signed; } query; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct VertexStream { union { BitField<0, 12, u32> stride; BitField<12, 1, u32> enable; }; u32 address_high; u32 address_low; u32 frequency; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } bool IsEnabled() const { return enable != 0 && Address() != 0; } }; static_assert(sizeof(VertexStream) == 0x10); struct VertexStreamLimit { u32 address_high; u32 address_low; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; static_assert(sizeof(VertexStreamLimit) == 0x8); enum class ShaderType : u32 { VertexA = 0, VertexB = 1, TessellationInit = 2, Tessellation = 3, Geometry = 4, Pixel = 5, }; struct Pipeline { union { BitField<0, 1, u32> enable; BitField<4, 4, ShaderType> program; }; u32 offset; u32 reservedA; u32 register_count; u32 binding_group; std::array reserved; INSERT_PADDING_BYTES_NOINIT(0x1C); }; static_assert(sizeof(Pipeline) == 0x40); bool IsShaderConfigEnabled(std::size_t index) const { // The VertexB is always enabled. if (index == static_cast(ShaderType::VertexB)) { return true; } return pipelines[index].enable != 0; } bool IsShaderConfigEnabled(ShaderType type) const { return IsShaderConfigEnabled(static_cast(type)); } struct ConstantBuffer { u32 size; u32 address_high; u32 address_low; u32 offset; std::array buffer; GPUVAddr Address() const { return static_cast((static_cast(address_high) << 32) | address_low); } }; struct BindGroup { std::array reserved; union { u32 raw_config; BitField<0, 1, u32> valid; BitField<4, 5, u32> shader_slot; }; INSERT_PADDING_BYTES_NOINIT(0xC); }; static_assert(sizeof(BindGroup) == 0x20); struct StreamOutLayout { union { BitField<0, 8, u32> attribute0; BitField<8, 8, u32> attribute1; BitField<16, 8, u32> attribute2; BitField<24, 8, u32> attribute3; }; }; struct ShaderPerformance { struct ControlA { union { BitField<0, 2, u32> event0; BitField<2, 3, u32> bit0; BitField<5, 2, u32> event1; BitField<7, 3, u32> bit1; BitField<10, 2, u32> event2; BitField<12, 3, u32> bit2; BitField<15, 2, u32> event3; BitField<17, 3, u32> bit3; BitField<20, 2, u32> event4; BitField<22, 3, u32> bit4; BitField<25, 2, u32> event5; BitField<27, 3, u32> bit5; BitField<30, 2, u32> spare; }; }; struct ControlB { union { BitField<0, 1, u32> edge; BitField<1, 2, u32> mode; BitField<3, 1, u32> windowed; BitField<4, 16, u32> func; }; }; std::array values_upper; std::array values; std::array events; std::array control_a; std::array control_b; u32 trap_control_mask; u32 start_shader_mask; u32 stop_shader_mask; }; // clang-format off union { struct { ID object_id; ///< 0x0000 INSERT_PADDING_BYTES_NOINIT(0xFC); u32 nop; ///< 0x0100 Notify notify; ///< 0x0104 u32 wait_for_idle; ///< 0x0110 LoadMME load_mme; ///< 0x0114 ShadowRamControl shadow_ram_control; ///< 0x0124 PeerSemaphore peer; ///< 0x0128 GlobalRender global_render; ///< 0x0130 u32 go_idle; ///< 0x013C u32 trigger; ///< 0x0140 u32 trigger_wfi; ///< 0x0144 INSERT_PADDING_BYTES_NOINIT(0x8); u32 instrumentation_method_header; ///< 0x0150 u32 instrumentation_method_data; ///< 0x0154 INSERT_PADDING_BYTES_NOINIT(0x28); Upload::Registers upload; ///< 0x0180 LaunchDMA launch_dma; ///< 0x01B0 u32 inline_data; ///< 0x01B4 INSERT_PADDING_BYTES_NOINIT(0x24); I2M i2m; ///< 0x01DC u32 run_ds_now; ///< 0x0200 OpportunisticEarlyZ opportunistic_early_z; ///< 0x0204 INSERT_PADDING_BYTES_NOINIT(0x4); u32 aliased_line_width_enabled; ///< 0x020C u32 mandated_early_z; ///< 0x0210 GeometryShaderDmFifo gs_dm_fifo; ///< 0x0214 L2CacheControl l2_cache_control; ///< 0x0218 InvalidateShaderCache invalidate_shader_cache; ///< 0x021C INSERT_PADDING_BYTES_NOINIT(0xA8); SyncInfo sync_info; ///< 0x02C8 INSERT_PADDING_BYTES_NOINIT(0x4); u32 prim_circular_buffer_throttle; ///< 0x02D0 u32 flush_invalidate_rop_mini_cache; ///< 0x02D4 SurfaceClipBlockId surface_clip_block_id; ///< 0x02D8 u32 alpha_circular_buffer_size; ///< 0x02DC DecompressSurface decompress_surface; ///< 0x02E0 ZCullRopBypass zcull_rop_bypass; ///< 0x02E4 ZCullSubregion zcull_subregion; ///< 0x02E8 RasterBoundingBox raster_bounding_box; ///< 0x02EC u32 peer_semaphore_release; ///< 0x02F0 u32 iterated_blend_optimization; ///< 0x02F4 ZCullSubregionAllocation zcull_subregion_allocation; ///< 0x02F8 ZCullSubregionAlgorithm zcull_subregion_algorithm; ///< 0x02FC PixelShaderOutputSampleMaskUsage ps_output_sample_mask_usage; ///< 0x0300 u32 draw_zero_index; ///< 0x0304 L1Configuration l1_configuration; ///< 0x0308 u32 render_enable_control_load_const_buffer; ///< 0x030C SPAVersion spa_version; ///< 0x0310 u32 ieee_clean_update; ///< 0x0314 SnapGrid snap_grid; ///< 0x0318 Tessellation tessellation; ///< 0x0320 SubTilingPerf sub_tiling_perf; ///< 0x0360 ZCullSubregionReport zcull_subregion_report; ///< 0x036C BalancedPrimitiveWorkload balanced_primitive_workload; ///< 0x0374 u32 max_patches_per_batch; ///< 0x0378 u32 rasterize_enable; ///< 0x037C TransformFeedback transform_feedback; ///< 0x0380 u32 raster_input; ///< 0x0740 u32 transform_feedback_enabled; ///< 0x0744 u32 primitive_restart_topology_change_enable; ///< 0x0748 u32 alpha_fraction; ///< 0x074C INSERT_PADDING_BYTES_NOINIT(0x4); HybridAntiAliasControl hybrid_aa_control; ///< 0x0754 INSERT_PADDING_BYTES_NOINIT(0x24); ShaderLocalMemory shader_local_memory; ///< 0x077C u32 color_zero_bandwidth_clear; ///< 0x07A4 u32 z_zero_bandwidth_clear; ///< 0x07A8 u32 isbe_save_restore_program_offset; ///< 0x07AC INSERT_PADDING_BYTES_NOINIT(0x10); ZCullRegion zcull_region; ///< 0x07C0 ZetaReadOnly zeta_read_only; ///< 0x07F8 INSERT_PADDING_BYTES_NOINIT(0x4); std::array rt; ///< 0x0800 std::array viewport_transform; ///< 0x0A00 std::array viewports; ///< 0x0C00 std::array windows; ///< 0x0D00 std::array clip_id_extent; ///< 0x0D40 u32 max_geometry_instances_per_task; ///< 0x0D60 VisibleCallLimit visible_call_limit; ///< 0x0D64 StatisticsCounter statistics_count; ///< 0x0D68 ClearRect clear_rect; ///< 0x0D6C VertexBuffer vertex_buffer; ///< 0x0D74 DepthMode depth_mode; ///< 0x0D7C std::array clear_color; ///< 0x0D80 f32 clear_depth; ///< 0x0D90 u32 shader_cache_icache_prefetch; ///< 0x0D94 u32 force_transition_to_beta; ///< 0x0D98 u32 reduce_colour_thresholds; ///< 0x0D9C s32 clear_stencil; ///< 0x0DA0 InvalidateShaderCacheNoWFI invalidate_shader_cache_no_wfi; ///< 0x0DA4 ZCullSerialization zcull_serialization; ///< 0x0DA8 PolygonMode polygon_mode_front; ///< 0x0DAC PolygonMode polygon_mode_back; ///< 0x0DB0 u32 polygon_smooth; ///< 0x0DB4 u32 zeta_mark_clean_ieee; ///< 0x0DB8 ZCullDirFormat zcull_dir_format; ///< 0x0DBC u32 polygon_offset_point_enable; ///< 0x0DC0 u32 polygon_offset_line_enable; ///< 0x0DC4 u32 polygon_offset_fill_enable; ///< 0x0DC8 u32 patch_vertices; ///< 0x0DCC IteratedBlend iterated_blend; ///< 0x0DD0 ZCullCriterion zcull_criteria; ///< 0x0DD8 INSERT_PADDING_BYTES_NOINIT(0x4); u32 fragment_barrier; ///< 0x0DE0 u32 sm_timeout; ///< 0x0DE4 u32 primitive_restart_array; ///< 0x0DE8 INSERT_PADDING_BYTES_NOINIT(0x4); LoadIteratedBlend load_iterated_blend; ///< 0x0DF0 u32 window_offset_x; ///< 0x0DF8 u32 window_offset_y; ///< 0x0DFC std::array scissor_test; ///< 0x0E00 INSERT_PADDING_BYTES_NOINIT(0x10); u32 select_texture_headers; ///< 0x0F10 VPCPerf vpc_perf; ///< 0x0F14 u32 pm_local_trigger; ///< 0x0F18 u32 post_z_pixel_imask; ///< 0x0F1C INSERT_PADDING_BYTES_NOINIT(0x20); ConstantColorRendering const_color_rendering; ///< 0x0F40 s32 stencil_back_ref; ///< 0x0F54 u32 stencil_back_mask; ///< 0x0F58 u32 stencil_back_func_mask; ///< 0x0F5C INSERT_PADDING_BYTES_NOINIT(0x14); u32 invalidate_texture_data_cache; ///< 0x0F74 Assumed - Not in official docs. INSERT_PADDING_BYTES_NOINIT(0x4); u32 tiled_cache_barrier; ///< 0x0F7C Assumed - Not in official docs. INSERT_PADDING_BYTES_NOINIT(0x4); VertexStreamSubstitute vertex_stream_substitute; ///< 0x0F84 u32 line_mode_clip_generated_edge_do_not_draw; ///< 0x0F8C u32 color_mask_common; ///< 0x0F90 INSERT_PADDING_BYTES_NOINIT(0x4); VTGWarpWatermarks vtg_warp_watermarks; ///< 0x0F98 f32 depth_bounds[2]; ///< 0x0F9C SampleMask::Target sample_mask_target; ///< 0x0FA4 u32 color_target_mrt_enable; ///< 0x0FAC NonMultisampledZ non_multisampled_z; ///< 0x0FB0 TIRMode tir_mode; ///< 0x0FB4 AntiAliasRaster anti_alias_raster; ///< 0x0FB8 SampleMask::Pos sample_mask_pos; ///< 0x0FBC SurfaceClipIDMemory surface_clip_id_memory; ///< 0x0FCC TIRModulation tir_modulation; ///< 0x0FD4 u32 blend_control_allow_float_pixel_kills; ///< 0x0FDC Zeta zeta; ///< 0x0FE0 SurfaceClip surface_clip; ///< 0x0FF4 u32 tiled_cache_treat_heavy_as_light; ///< 0x0FFC L2CacheVAFRequests l2_cache_vaf; ///< 0x1000 ViewportMulticast viewport_multicast; ///< 0x1004 u32 tessellation_cut_height; ///< 0x1008 u32 max_gs_instances_per_task; ///< 0x100C u32 max_gs_output_vertices_per_task; ///< 0x1010 u32 reserved_sw_method0; ///< 0x1014 u32 gs_output_cb_storage_multiplier; ///< 0x1018 u32 beta_cb_storage_constant; ///< 0x101C u32 ti_output_cb_storage_multiplier; ///< 0x1020 u32 alpha_cb_storage_constraint; ///< 0x1024 u32 reserved_sw_method1; ///< 0x1028 u32 reserved_sw_method2; ///< 0x102C std::array tir_modulation_coeff; ///< 0x1030 std::array spare_nop; ///< 0x1044 INSERT_PADDING_BYTES_NOINIT(0x30); std::array reserved_sw_method3_to_7; ///< 0x10B0 ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC std::array reserved_sw_method10_to_13; ///< 0x10D0 ReduceColorThreshold reduce_color_thresholds_unorm10; ///< 0x10E0 ReduceColorThreshold reduce_color_thresholds_unorm16; ///< 0x10E4 ReduceColorThreshold reduce_color_thresholds_fp11; ///< 0x10E8 ReduceColorThreshold reduce_color_thresholds_fp16; ///< 0x10EC ReduceColorThreshold reduce_color_thresholds_srgb8; ///< 0x10F0 u32 unbind_all_constant_buffers; ///< 0x10F4 ClearControl clear_control; ///< 0x10F8 L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_reads; ///< 0x10FC u32 reserved_sw_method14; ///< 0x1100 u32 reserved_sw_method15; ///< 0x1104 INSERT_PADDING_BYTES_NOINIT(0x4); u32 no_operation_data_high; ///< 0x110C u32 depth_bias_control; ///< 0x1110 u32 pm_trigger_end; ///< 0x1114 u32 vertex_id_base; ///< 0x1118 u32 stencil_compression_enabled; ///< 0x111C VertexOutputAttributeSkipMasks vertex_output_attribute_skip_masks; ///< 0x1120 TIRControl tir_control; ///< 0x1130 u32 mutable_method_treat_mutable_as_heavy; ///< 0x1134 u32 post_ps_use_pre_ps_coverage; ///< 0x1138 FillViaTriangleMode fill_via_triangle_mode; ///< 0x113C u32 blend_per_format_snorm8_unorm16_snorm16_enabled; ///< 0x1140 u32 flush_pending_writes_sm_gloal_store; ///< 0x1144 u32 conservative_raster_enable; ///< 0x1148 Assumed - Not in official docs. INSERT_PADDING_BYTES_NOINIT(0x14); std::array vertex_attrib_format; ///< 0x1160 std::array multisample_sample_locations; ///< 0x11E0 u32 offset_render_target_index_by_viewport_index; ///< 0x11F0 u32 force_heavy_method_sync; ///< 0x11F4 MultisampleCoverageToColor multisample_coverage_to_color; ///< 0x11F8 DecompressZetaSurface decompress_zeta_surface; ///< 0x11FC INSERT_PADDING_BYTES_NOINIT(0x8); ZetaSparse zeta_sparse; ///< 0x1208 u32 invalidate_sampler_cache; ///< 0x120C u32 invalidate_texture_header_cache; ///< 0x1210 VertexArray vertex_array_instance_first; ///< 0x1214 VertexArray vertex_array_instance_subsequent; ///< 0x1218 RtControl rt_control; ///< 0x121C CompressionThresholdSamples compression_threshold_samples; ///< 0x1220 PixelShaderInterlockControl ps_interlock_control; ///< 0x1224 ZetaSize zeta_size; ///< 0x1228 SamplerBinding sampler_binding; ///< 0x1234 INSERT_PADDING_BYTES_NOINIT(0x4); u32 draw_auto_byte_count; ///< 0x123C std::array post_vtg_shader_attrib_skip_mask; ///< 0x1240 PsTicketDispenserValue ps_ticket_dispenser_value; ///< 0x1260 INSERT_PADDING_BYTES_NOINIT(0x1C); u32 circular_buffer_size; ///< 0x1280 RegisterWatermarks vtg_register_watermarks; ///< 0x1284 InvalidateTextureDataCacheNoWfi invalidate_texture_cache_no_wfi; ///< 0x1288 INSERT_PADDING_BYTES_NOINIT(0x4); L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_reads; ///< 0x1290 INSERT_PADDING_BYTES_NOINIT(0x10); u32 primitive_restart_topology_change_index; ///< 0x12A4 INSERT_PADDING_BYTES_NOINIT(0x20); ZCullRegionEnable zcull_region_enable; ///< 0x12C8 u32 depth_test_enable; ///< 0x12CC FillMode fill_mode; ///< 0x12D0 ShadeMode shade_mode; ///< 0x12D4 L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_writes; ///< 0x12D8 L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_writes; ///< 0x12DC AlphaToCoverageDither alpha_to_coverage_dither; ///< 0x12E0 u32 blend_per_target_enabled; ///< 0x12E4 u32 depth_write_enabled; ///< 0x12E8 u32 alpha_test_enabled; ///< 0x12EC INSERT_PADDING_BYTES_NOINIT(0x10); InlineIndex4x8 inline_index_4x8; ///< 0x1300 D3DCullMode d3d_cull_mode; ///< 0x1308 ComparisonOp depth_test_func; ///< 0x130C f32 alpha_test_ref; ///< 0x1310 ComparisonOp alpha_test_func; ///< 0x1314 u32 draw_auto_stride; ///< 0x1318 BlendColor blend_color; ///< 0x131C INSERT_PADDING_BYTES_NOINIT(0x4); InvalidateCacheLines invalidate_sampler_cache_lines; ///< 0x1330 InvalidateCacheLines invalidate_texture_header_cache_lines; ///< 0x1334 InvalidateCacheLines invalidate_texture_data_cache_lines; ///< 0x1338 Blend blend; ///< 0x133C u32 stencil_enable; ///< 0x1380 StencilOp stencil_front_op; ///< 0x1384 s32 stencil_front_ref; ///< 0x1394 s32 stencil_front_func_mask; ///< 0x1398 s32 stencil_front_mask; ///< 0x139C INSERT_PADDING_BYTES_NOINIT(0x4); u32 draw_auto_start_byte_count; ///< 0x13A4 PsSaturate frag_color_clamp; ///< 0x13A8 WindowOrigin window_origin; ///< 0x13AC f32 line_width_smooth; ///< 0x13B0 f32 line_width_aliased; ///< 0x13B4 INSERT_PADDING_BYTES_NOINIT(0x60); u32 line_override_multisample; ///< 0x1418 INSERT_PADDING_BYTES_NOINIT(0x4); u32 alpha_hysteresis_rounds; ///< 0x1420 InvalidateCacheLines invalidate_sampler_cache_no_wfi; ///< 0x1424 InvalidateCacheLines invalidate_texture_header_cache_no_wfi; ///< 0x1428 INSERT_PADDING_BYTES_NOINIT(0x8); u32 global_base_vertex_index; ///< 0x1434 u32 global_base_instance_index; ///< 0x1438 INSERT_PADDING_BYTES_NOINIT(0x14); RegisterWatermarks ps_warp_watermarks; ///< 0x1450 RegisterWatermarks ps_regster_watermarks; ///< 0x1454 INSERT_PADDING_BYTES_NOINIT(0xC); u32 store_zcull; ///< 0x1464 INSERT_PADDING_BYTES_NOINIT(0x18); std::array iterated_blend_constants; ///< 0x1480 u32 load_zcull; ///< 0x1500 u32 surface_clip_id_height; ///< 0x1504 Window surface_clip_id_clear_rect; ///< 0x1508 UserClip::Enable user_clip_enable; ///< 0x1510 u32 zpass_pixel_count_enable; ///< 0x1514 f32 point_size; ///< 0x1518 u32 zcull_stats_enable; ///< 0x151C u32 point_sprite_enable; ///< 0x1520 INSERT_PADDING_BYTES_NOINIT(0x4); u32 shader_exceptions_enable; ///< 0x1528 INSERT_PADDING_BYTES_NOINIT(0x4); ClearReport clear_report_value; ///< 0x1530 u32 anti_alias_enable; ///< 0x1534 u32 zeta_enable; ///< 0x1538 AntiAliasAlphaControl anti_alias_alpha_control; ///< 0x153C INSERT_PADDING_BYTES_NOINIT(0x10); RenderEnable render_enable; ///< 0x1550 TexSampler tex_sampler; ///< 0x155C INSERT_PADDING_BYTES_NOINIT(0x4); f32 slope_scale_depth_bias; ///< 0x156C u32 line_anti_alias_enable; ///< 0x1570 TexHeader tex_header; ///< 0x1574 INSERT_PADDING_BYTES_NOINIT(0x10); u32 active_zcull_region_id; ///< 0x1590 u32 stencil_two_side_enable; ///< 0x1594 StencilOp stencil_back_op; ///< 0x1598 INSERT_PADDING_BYTES_NOINIT(0x10); u32 framebuffer_srgb; ///< 0x15B8 f32 depth_bias; ///< 0x15BC INSERT_PADDING_BYTES_NOINIT(0x8); ZCullRegionFormat zcull_region_format; ///< 0x15C8 RtLayer rt_layer; ///< 0x15CC Tegra::Texture::MsaaMode anti_alias_samples_mode; ///< 0x15D0 INSERT_PADDING_BYTES_NOINIT(0x10); u32 edge_flag; ///< 0x15E4 u32 draw_inline_index; ///< 0x15E8 InlineIndex2x16 inline_index_2x16; ///< 0x15EC VertexGlobalBaseOffset vertex_global_base_offset; ///< 0x15F4 ZCullRegionPixelOffset zcull_region_pixel_offset; ///< 0x15FC PointSprite point_sprite; ///< 0x1604 ProgramRegion program_region; ///< 0x1608 DefaultAttributes default_attributes; ///< 0x1610 Draw draw; ///< 0x1614 VertexIdCopy vertex_id_copy; ///< 0x161C u32 add_to_primitive_id; ///< 0x1620 u32 load_to_primitive_id; ///< 0x1624 INSERT_PADDING_BYTES_NOINIT(0x4); ShaderBasedCull shader_based_cull; ///< 0x162C INSERT_PADDING_BYTES_NOINIT(0x8); ClassVersion class_version; ///< 0x1638 INSERT_PADDING_BYTES_NOINIT(0x8); PrimitiveRestart primitive_restart; ///< 0x1644 OutputVertexId output_vertex_id; ///< 0x164C INSERT_PADDING_BYTES_NOINIT(0x8); u32 anti_alias_point_enable; ///< 0x1658 PointCenterMode point_center_mode; ///< 0x165C INSERT_PADDING_BYTES_NOINIT(0x8); LineSmoothParams line_smooth_params; ///< 0x1668 u32 line_stipple_enable; ///< 0x166C std::array line_smooth_edge_table; ///< 0x1670 LineStippleParams line_stipple_params; ///< 0x1680 ProvokingVertex provoking_vertex; ///< 0x1684 u32 two_sided_light_enabled; ///< 0x1688 u32 polygon_stipple_enabled; ///< 0x168C ShaderControl shader_control; ///< 0x1690 INSERT_PADDING_BYTES_NOINIT(0xC); ClassVersion class_version_check; ///< 0x16A0 SphVersion sph_version; ///< 0x16A4 SphVersion sph_version_check; ///< 0x16A8 INSERT_PADDING_BYTES_NOINIT(0x8); AlphaToCoverageOverride alpha_to_coverage_override; ///< 0x16B4 INSERT_PADDING_BYTES_NOINIT(0x48); std::array polygon_stipple_pattern; ///< 0x1700 INSERT_PADDING_BYTES_NOINIT(0x10); AamVersion aam_version; ///< 0x1790 AamVersion aam_version_check; ///< 0x1794 INSERT_PADDING_BYTES_NOINIT(0x4); u32 zeta_layer_offset; ///< 0x179C INSERT_PADDING_BYTES_NOINIT(0x28); IndexBuffer index_buffer; ///< 0x17C8 IndexBufferSmall index_buffer32_first; ///< 0x17E4 IndexBufferSmall index_buffer16_first; ///< 0x17E8 IndexBufferSmall index_buffer8_first; ///< 0x17EC IndexBufferSmall index_buffer32_subsequent; ///< 0x17F0 IndexBufferSmall index_buffer16_subsequent; ///< 0x17F4 IndexBufferSmall index_buffer8_subsequent; ///< 0x17F8 INSERT_PADDING_BYTES_NOINIT(0x80); f32 depth_bias_clamp; ///< 0x187C VertexStreamInstances vertex_stream_instances; ///< 0x1880 INSERT_PADDING_BYTES_NOINIT(0x10); AttributePointSize point_size_attribute; ///< 0x1910 INSERT_PADDING_BYTES_NOINIT(0x4); u32 gl_cull_test_enabled; ///< 0x1918 FrontFace gl_front_face; ///< 0x191C CullFace gl_cull_face; ///< 0x1920 Viewport::PixelCenter viewport_pixel_center; ///< 0x1924 INSERT_PADDING_BYTES_NOINIT(0x4); u32 viewport_scale_offset_enabled; ///< 0x192C INSERT_PADDING_BYTES_NOINIT(0xC); ViewportClipControl viewport_clip_control; ///< 0x193C UserClip::Op user_clip_op; ///< 0x1940 RenderEnable::Override render_enable_override; ///< 0x1944 PrimitiveTopologyControl primitive_topology_control; ///< 0x1948 WindowClip window_clip_enable; ///< 0x194C INSERT_PADDING_BYTES_NOINIT(0x4); InvalidateZCull invalidate_zcull; ///< 0x1958 INSERT_PADDING_BYTES_NOINIT(0xC); ZCull zcull; ///< 0x1968 PrimitiveTopologyOverride topology_override; ///< 0x1970 INSERT_PADDING_BYTES_NOINIT(0x4); u32 zcull_sync; ///< 0x1978 u32 clip_id_test_enable; ///< 0x197C u32 surface_clip_id_width; ///< 0x1980 u32 clip_id; ///< 0x1984 INSERT_PADDING_BYTES_NOINIT(0x34); u32 depth_bounds_enable; ///< 0x19BC u32 blend_float_zero_times_anything_is_zero; ///< 0x19C0 LogicOp logic_op; ///< 0x19C4 u32 z_compression_enable; ///< 0x19CC ClearSurface clear_surface; ///< 0x19D0 u32 clear_clip_id_surface; ///< 0x19D4 INSERT_PADDING_BYTES_NOINIT(0x8); std::array color_compression_enable; ///< 0x19E0 std::array color_mask; ///< 0x1A00 INSERT_PADDING_BYTES_NOINIT(0xC); u32 pipe_nop; ///< 0x1A2C std::array spare; ///< 0x1A30 INSERT_PADDING_BYTES_NOINIT(0xC0); ReportSemaphore report_semaphore; ///< 0x1B00 INSERT_PADDING_BYTES_NOINIT(0xF0); std::array vertex_streams; ///< 0x1C00 BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00 std::array vertex_stream_limits; ///< 0x1F00 std::array pipelines; ///< 0x2000 INSERT_PADDING_BYTES_NOINIT(0x180); u32 falcon[32]; ///< 0x2300 ConstantBuffer const_buffer; ///< 0x2380 INSERT_PADDING_BYTES_NOINIT(0x30); BindGroup bind_groups[MaxShaderStage]; ///< 0x2400 INSERT_PADDING_BYTES_NOINIT(0x160); u32 color_clamp_enable; ///< 0x2600 INSERT_PADDING_BYTES_NOINIT(0x4); u32 bindless_texture_const_buffer_slot; ///< 0x2608 u32 trap_handler; ///< 0x260C INSERT_PADDING_BYTES_NOINIT(0x1F0); std::array, NumTransformFeedbackBuffers> stream_out_layout; ///< 0x2800 INSERT_PADDING_BYTES_NOINIT(0x93C); ShaderPerformance shader_performance; ///< 0x333C INSERT_PADDING_BYTES_NOINIT(0x18); std::array shadow_scratch; ///< 0x3400 }; std::array reg_array; }; }; // clang-format on Regs regs{}; /// Store temporary hw register values, used by some calls to restore state after a operation Regs shadow_state; static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); static_assert(std::is_trivially_copyable_v, "Maxwell3D Regs must be trivially copyable"); struct State { struct ShaderStageInfo { std::array const_buffers; }; std::array shader_stages; }; State state{}; /// Reads a register value located at the input method address u32 GetRegisterValue(u32 method) const; /// Write the value to the register identified by method. void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; /// Write multiple values to the register identified by method. void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) override; bool ShouldExecute() const { return execute_on; } VideoCore::RasterizerInterface& Rasterizer() { return *rasterizer; } const VideoCore::RasterizerInterface& Rasterizer() const { return *rasterizer; } struct DirtyState { using Flags = std::bitset::max()>; using Table = std::array; using Tables = std::array; Flags flags; Tables tables{}; } dirty; std::vector inline_index_draw_indexes; /// Handles a write to the CLEAR_BUFFERS register. void ProcessClearBuffers(u32 layer_count); private: void InitializeRegisterDefaults(); void ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call); u32 ProcessShadowRam(u32 method, u32 argument); void ProcessDirtyRegisters(u32 method, u32 argument); void ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call); /// Retrieves information about a specific TIC entry from the TIC buffer. Texture::TICEntry GetTICEntry(u32 tic_index) const; /// Retrieves information about a specific TSC entry from the TSC buffer. Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; /** * Call a macro on this engine. * * @param method Method to call * @param parameters Arguments to the method call */ void CallMacroMethod(u32 method, const std::vector& parameters); /// Handles writes to the macro uploading register. void ProcessMacroUpload(u32 data); /// Handles writes to the macro bind register. void ProcessMacroBind(u32 data); /// Handles firmware blob 4 void ProcessFirmwareCall4(); /// Handles a write to the QUERY_GET register. void ProcessQueryGet(); /// Writes the query result accordingly. void StampQueryResult(u64 payload, bool long_query); /// Handles conditional rendering. void ProcessQueryCondition(); /// Handles counter resets. void ProcessCounterReset(); /// Handles writes to syncing register. void ProcessSyncPoint(); /// Handles a write to the CB_DATA[i] register. void ProcessCBData(u32 value); void ProcessCBMultiData(const u32* start_base, u32 amount); /// Handles a write to the CB_BIND register. void ProcessCBBind(size_t stage_index); /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) void ProcessTopologyOverride(); void ProcessDraw(u32 instance_count = 1); void ProcessDeferredDraw(); /// Returns a query's value or an empty object if the value will be deferred through a cache. std::optional GetQueryResult(); Core::System& system; MemoryManager& memory_manager; VideoCore::RasterizerInterface* rasterizer = nullptr; /// Start offsets of each macro in macro_memory std::array macro_positions{}; /// Macro method that is currently being executed / being fed parameters. u32 executing_macro = 0; /// Parameters that have been submitted to the macro call so far. std::vector macro_params; /// Interpreter for the macro codes uploaded to the GPU. std::unique_ptr macro_engine; Upload::State upload_state; bool execute_on{true}; bool use_topology_override{false}; std::array draw_command{}; std::vector deferred_draw_method; }; #define ASSERT_REG_POSITION(field_name, position) \ static_assert(offsetof(Maxwell3D::Regs, field_name) == position, \ "Field " #field_name " has invalid position") ASSERT_REG_POSITION(object_id, 0x0000); ASSERT_REG_POSITION(nop, 0x0100); ASSERT_REG_POSITION(notify, 0x0104); ASSERT_REG_POSITION(wait_for_idle, 0x0110); ASSERT_REG_POSITION(load_mme, 0x0114); ASSERT_REG_POSITION(shadow_ram_control, 0x0124); ASSERT_REG_POSITION(peer, 0x0128); ASSERT_REG_POSITION(global_render, 0x0130); ASSERT_REG_POSITION(go_idle, 0x013C); ASSERT_REG_POSITION(trigger, 0x0140); ASSERT_REG_POSITION(trigger_wfi, 0x0144); ASSERT_REG_POSITION(instrumentation_method_header, 0x0150); ASSERT_REG_POSITION(instrumentation_method_data, 0x0154); ASSERT_REG_POSITION(upload, 0x0180); ASSERT_REG_POSITION(launch_dma, 0x01B0); ASSERT_REG_POSITION(inline_data, 0x01B4); ASSERT_REG_POSITION(i2m, 0x01DC); ASSERT_REG_POSITION(run_ds_now, 0x0200); ASSERT_REG_POSITION(opportunistic_early_z, 0x0204); ASSERT_REG_POSITION(aliased_line_width_enabled, 0x020C); ASSERT_REG_POSITION(mandated_early_z, 0x0210); ASSERT_REG_POSITION(gs_dm_fifo, 0x0214); ASSERT_REG_POSITION(l2_cache_control, 0x0218); ASSERT_REG_POSITION(invalidate_shader_cache, 0x021C); ASSERT_REG_POSITION(sync_info, 0x02C8); ASSERT_REG_POSITION(prim_circular_buffer_throttle, 0x02D0); ASSERT_REG_POSITION(flush_invalidate_rop_mini_cache, 0x02D4); ASSERT_REG_POSITION(surface_clip_block_id, 0x02D8); ASSERT_REG_POSITION(alpha_circular_buffer_size, 0x02DC); ASSERT_REG_POSITION(decompress_surface, 0x02E0); ASSERT_REG_POSITION(zcull_rop_bypass, 0x02E4); ASSERT_REG_POSITION(zcull_subregion, 0x02E8); ASSERT_REG_POSITION(raster_bounding_box, 0x02EC); ASSERT_REG_POSITION(peer_semaphore_release, 0x02F0); ASSERT_REG_POSITION(iterated_blend_optimization, 0x02F4); ASSERT_REG_POSITION(zcull_subregion_allocation, 0x02F8); ASSERT_REG_POSITION(zcull_subregion_algorithm, 0x02FC); ASSERT_REG_POSITION(ps_output_sample_mask_usage, 0x0300); ASSERT_REG_POSITION(draw_zero_index, 0x0304); ASSERT_REG_POSITION(l1_configuration, 0x0308); ASSERT_REG_POSITION(render_enable_control_load_const_buffer, 0x030C); ASSERT_REG_POSITION(spa_version, 0x0310); ASSERT_REG_POSITION(ieee_clean_update, 0x0314); ASSERT_REG_POSITION(snap_grid, 0x0318); ASSERT_REG_POSITION(tessellation, 0x0320); ASSERT_REG_POSITION(sub_tiling_perf, 0x0360); ASSERT_REG_POSITION(zcull_subregion_report, 0x036C); ASSERT_REG_POSITION(balanced_primitive_workload, 0x0374); ASSERT_REG_POSITION(max_patches_per_batch, 0x0378); ASSERT_REG_POSITION(rasterize_enable, 0x037C); ASSERT_REG_POSITION(transform_feedback, 0x0380); ASSERT_REG_POSITION(transform_feedback.controls, 0x0700); ASSERT_REG_POSITION(raster_input, 0x0740); ASSERT_REG_POSITION(transform_feedback_enabled, 0x0744); ASSERT_REG_POSITION(primitive_restart_topology_change_enable, 0x0748); ASSERT_REG_POSITION(alpha_fraction, 0x074C); ASSERT_REG_POSITION(hybrid_aa_control, 0x0754); ASSERT_REG_POSITION(shader_local_memory, 0x077C); ASSERT_REG_POSITION(color_zero_bandwidth_clear, 0x07A4); ASSERT_REG_POSITION(z_zero_bandwidth_clear, 0x07A8); ASSERT_REG_POSITION(isbe_save_restore_program_offset, 0x07AC); ASSERT_REG_POSITION(zcull_region, 0x07C0); ASSERT_REG_POSITION(zeta_read_only, 0x07F8); ASSERT_REG_POSITION(rt, 0x0800); ASSERT_REG_POSITION(viewport_transform, 0x0A00); ASSERT_REG_POSITION(viewports, 0x0C00); ASSERT_REG_POSITION(windows, 0x0D00); ASSERT_REG_POSITION(clip_id_extent, 0x0D40); ASSERT_REG_POSITION(max_geometry_instances_per_task, 0x0D60); ASSERT_REG_POSITION(visible_call_limit, 0x0D64); ASSERT_REG_POSITION(statistics_count, 0x0D68); ASSERT_REG_POSITION(clear_rect, 0x0D6C); ASSERT_REG_POSITION(vertex_buffer, 0x0D74); ASSERT_REG_POSITION(depth_mode, 0x0D7C); ASSERT_REG_POSITION(clear_color, 0x0D80); ASSERT_REG_POSITION(clear_depth, 0x0D90); ASSERT_REG_POSITION(shader_cache_icache_prefetch, 0x0D94); ASSERT_REG_POSITION(force_transition_to_beta, 0x0D98); ASSERT_REG_POSITION(reduce_colour_thresholds, 0x0D9C); ASSERT_REG_POSITION(clear_stencil, 0x0DA0); ASSERT_REG_POSITION(invalidate_shader_cache_no_wfi, 0x0DA4); ASSERT_REG_POSITION(zcull_serialization, 0x0DA8); ASSERT_REG_POSITION(polygon_mode_front, 0x0DAC); ASSERT_REG_POSITION(polygon_mode_back, 0x0DB0); ASSERT_REG_POSITION(polygon_smooth, 0x0DB4); ASSERT_REG_POSITION(zeta_mark_clean_ieee, 0x0DB8); ASSERT_REG_POSITION(zcull_dir_format, 0x0DBC); ASSERT_REG_POSITION(polygon_offset_point_enable, 0x0DC0); ASSERT_REG_POSITION(polygon_offset_line_enable, 0x0DC4); ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x0DC8); ASSERT_REG_POSITION(patch_vertices, 0x0DCC); ASSERT_REG_POSITION(iterated_blend, 0x0DD0); ASSERT_REG_POSITION(zcull_criteria, 0x0DD8); ASSERT_REG_POSITION(fragment_barrier, 0x0DE0); ASSERT_REG_POSITION(sm_timeout, 0x0DE4); ASSERT_REG_POSITION(primitive_restart_array, 0x0DE8); ASSERT_REG_POSITION(load_iterated_blend, 0x0DF0); ASSERT_REG_POSITION(window_offset_x, 0x0DF8); ASSERT_REG_POSITION(window_offset_y, 0x0DFC); ASSERT_REG_POSITION(scissor_test, 0x0E00); ASSERT_REG_POSITION(select_texture_headers, 0x0F10); ASSERT_REG_POSITION(vpc_perf, 0x0F14); ASSERT_REG_POSITION(pm_local_trigger, 0x0F18); ASSERT_REG_POSITION(post_z_pixel_imask, 0x0F1C); ASSERT_REG_POSITION(const_color_rendering, 0x0F40); ASSERT_REG_POSITION(stencil_back_ref, 0x0F54); ASSERT_REG_POSITION(stencil_back_mask, 0x0F58); ASSERT_REG_POSITION(stencil_back_func_mask, 0x0F5C); ASSERT_REG_POSITION(invalidate_texture_data_cache, 0x0F74); ASSERT_REG_POSITION(tiled_cache_barrier, 0x0F7C); ASSERT_REG_POSITION(vertex_stream_substitute, 0x0F84); ASSERT_REG_POSITION(line_mode_clip_generated_edge_do_not_draw, 0x0F8C); ASSERT_REG_POSITION(color_mask_common, 0x0F90); ASSERT_REG_POSITION(vtg_warp_watermarks, 0x0F98); ASSERT_REG_POSITION(depth_bounds, 0x0F9C); ASSERT_REG_POSITION(sample_mask_target, 0x0FA4); ASSERT_REG_POSITION(color_target_mrt_enable, 0x0FAC); ASSERT_REG_POSITION(non_multisampled_z, 0x0FB0); ASSERT_REG_POSITION(tir_mode, 0x0FB4); ASSERT_REG_POSITION(anti_alias_raster, 0x0FB8); ASSERT_REG_POSITION(sample_mask_pos, 0x0FBC); ASSERT_REG_POSITION(surface_clip_id_memory, 0x0FCC); ASSERT_REG_POSITION(tir_modulation, 0x0FD4); ASSERT_REG_POSITION(blend_control_allow_float_pixel_kills, 0x0FDC); ASSERT_REG_POSITION(zeta, 0x0FE0); ASSERT_REG_POSITION(surface_clip, 0x0FF4); ASSERT_REG_POSITION(tiled_cache_treat_heavy_as_light, 0x0FFC); ASSERT_REG_POSITION(l2_cache_vaf, 0x1000); ASSERT_REG_POSITION(viewport_multicast, 0x1004); ASSERT_REG_POSITION(tessellation_cut_height, 0x1008); ASSERT_REG_POSITION(max_gs_instances_per_task, 0x100C); ASSERT_REG_POSITION(max_gs_output_vertices_per_task, 0x1010); ASSERT_REG_POSITION(reserved_sw_method0, 0x1014); ASSERT_REG_POSITION(gs_output_cb_storage_multiplier, 0x1018); ASSERT_REG_POSITION(beta_cb_storage_constant, 0x101C); ASSERT_REG_POSITION(ti_output_cb_storage_multiplier, 0x1020); ASSERT_REG_POSITION(alpha_cb_storage_constraint, 0x1024); ASSERT_REG_POSITION(reserved_sw_method1, 0x1028); ASSERT_REG_POSITION(reserved_sw_method2, 0x102C); ASSERT_REG_POSITION(tir_modulation_coeff, 0x1030); ASSERT_REG_POSITION(spare_nop, 0x1044); ASSERT_REG_POSITION(reserved_sw_method3_to_7, 0x10B0); ASSERT_REG_POSITION(reduce_color_thresholds_unorm8, 0x10CC); ASSERT_REG_POSITION(reserved_sw_method10_to_13, 0x10D0); ASSERT_REG_POSITION(reduce_color_thresholds_unorm10, 0x10E0); ASSERT_REG_POSITION(reduce_color_thresholds_unorm16, 0x10E4); ASSERT_REG_POSITION(reduce_color_thresholds_fp11, 0x10E8); ASSERT_REG_POSITION(reduce_color_thresholds_fp16, 0x10EC); ASSERT_REG_POSITION(reduce_color_thresholds_srgb8, 0x10F0); ASSERT_REG_POSITION(unbind_all_constant_buffers, 0x10F4); ASSERT_REG_POSITION(clear_control, 0x10F8); ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_reads, 0x10FC); ASSERT_REG_POSITION(reserved_sw_method14, 0x1100); ASSERT_REG_POSITION(reserved_sw_method15, 0x1104); ASSERT_REG_POSITION(no_operation_data_high, 0x110C); ASSERT_REG_POSITION(depth_bias_control, 0x1110); ASSERT_REG_POSITION(pm_trigger_end, 0x1114); ASSERT_REG_POSITION(vertex_id_base, 0x1118); ASSERT_REG_POSITION(stencil_compression_enabled, 0x111C); ASSERT_REG_POSITION(vertex_output_attribute_skip_masks, 0x1120); ASSERT_REG_POSITION(tir_control, 0x1130); ASSERT_REG_POSITION(mutable_method_treat_mutable_as_heavy, 0x1134); ASSERT_REG_POSITION(post_ps_use_pre_ps_coverage, 0x1138); ASSERT_REG_POSITION(fill_via_triangle_mode, 0x113C); ASSERT_REG_POSITION(blend_per_format_snorm8_unorm16_snorm16_enabled, 0x1140); ASSERT_REG_POSITION(flush_pending_writes_sm_gloal_store, 0x1144); ASSERT_REG_POSITION(conservative_raster_enable, 0x1148); ASSERT_REG_POSITION(vertex_attrib_format, 0x1160); ASSERT_REG_POSITION(multisample_sample_locations, 0x11E0); ASSERT_REG_POSITION(offset_render_target_index_by_viewport_index, 0x11F0); ASSERT_REG_POSITION(force_heavy_method_sync, 0x11F4); ASSERT_REG_POSITION(multisample_coverage_to_color, 0x11F8); ASSERT_REG_POSITION(decompress_zeta_surface, 0x11FC); ASSERT_REG_POSITION(zeta_sparse, 0x1208); ASSERT_REG_POSITION(invalidate_sampler_cache, 0x120C); ASSERT_REG_POSITION(invalidate_texture_header_cache, 0x1210); ASSERT_REG_POSITION(vertex_array_instance_first, 0x1214); ASSERT_REG_POSITION(vertex_array_instance_subsequent, 0x1218); ASSERT_REG_POSITION(rt_control, 0x121C); ASSERT_REG_POSITION(compression_threshold_samples, 0x1220); ASSERT_REG_POSITION(ps_interlock_control, 0x1224); ASSERT_REG_POSITION(zeta_size, 0x1228); ASSERT_REG_POSITION(sampler_binding, 0x1234); ASSERT_REG_POSITION(draw_auto_byte_count, 0x123C); ASSERT_REG_POSITION(post_vtg_shader_attrib_skip_mask, 0x1240); ASSERT_REG_POSITION(ps_ticket_dispenser_value, 0x1260); ASSERT_REG_POSITION(circular_buffer_size, 0x1280); ASSERT_REG_POSITION(vtg_register_watermarks, 0x1284); ASSERT_REG_POSITION(invalidate_texture_cache_no_wfi, 0x1288); ASSERT_REG_POSITION(l2_cache_rop_interlocked_reads, 0x1290); ASSERT_REG_POSITION(primitive_restart_topology_change_index, 0x12A4); ASSERT_REG_POSITION(zcull_region_enable, 0x12C8); ASSERT_REG_POSITION(depth_test_enable, 0x12CC); ASSERT_REG_POSITION(fill_mode, 0x12D0); ASSERT_REG_POSITION(shade_mode, 0x12D4); ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_writes, 0x12D8); ASSERT_REG_POSITION(l2_cache_rop_interlocked_writes, 0x12DC); ASSERT_REG_POSITION(alpha_to_coverage_dither, 0x12E0); ASSERT_REG_POSITION(blend_per_target_enabled, 0x12E4); ASSERT_REG_POSITION(depth_write_enabled, 0x12E8); ASSERT_REG_POSITION(alpha_test_enabled, 0x12EC); ASSERT_REG_POSITION(inline_index_4x8, 0x1300); ASSERT_REG_POSITION(d3d_cull_mode, 0x1308); ASSERT_REG_POSITION(depth_test_func, 0x130C); ASSERT_REG_POSITION(alpha_test_ref, 0x1310); ASSERT_REG_POSITION(alpha_test_func, 0x1314); ASSERT_REG_POSITION(draw_auto_stride, 0x1318); ASSERT_REG_POSITION(blend_color, 0x131C); ASSERT_REG_POSITION(invalidate_sampler_cache_lines, 0x1330); ASSERT_REG_POSITION(invalidate_texture_header_cache_lines, 0x1334); ASSERT_REG_POSITION(invalidate_texture_data_cache_lines, 0x1338); ASSERT_REG_POSITION(blend, 0x133C); ASSERT_REG_POSITION(stencil_enable, 0x1380); ASSERT_REG_POSITION(stencil_front_op, 0x1384); ASSERT_REG_POSITION(stencil_front_ref, 0x1394); ASSERT_REG_POSITION(stencil_front_func_mask, 0x1398); ASSERT_REG_POSITION(stencil_front_mask, 0x139C); ASSERT_REG_POSITION(draw_auto_start_byte_count, 0x13A4); ASSERT_REG_POSITION(frag_color_clamp, 0x13A8); ASSERT_REG_POSITION(window_origin, 0x13AC); ASSERT_REG_POSITION(line_width_smooth, 0x13B0); ASSERT_REG_POSITION(line_width_aliased, 0x13B4); ASSERT_REG_POSITION(line_override_multisample, 0x1418); ASSERT_REG_POSITION(alpha_hysteresis_rounds, 0x1420); ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x1424); ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x1428); ASSERT_REG_POSITION(global_base_vertex_index, 0x1434); ASSERT_REG_POSITION(global_base_instance_index, 0x1438); ASSERT_REG_POSITION(ps_warp_watermarks, 0x1450); ASSERT_REG_POSITION(ps_regster_watermarks, 0x1454); ASSERT_REG_POSITION(store_zcull, 0x1464); ASSERT_REG_POSITION(iterated_blend_constants, 0x1480); ASSERT_REG_POSITION(load_zcull, 0x1500); ASSERT_REG_POSITION(surface_clip_id_height, 0x1504); ASSERT_REG_POSITION(surface_clip_id_clear_rect, 0x1508); ASSERT_REG_POSITION(user_clip_enable, 0x1510); ASSERT_REG_POSITION(zpass_pixel_count_enable, 0x1514); ASSERT_REG_POSITION(point_size, 0x1518); ASSERT_REG_POSITION(zcull_stats_enable, 0x151C); ASSERT_REG_POSITION(point_sprite_enable, 0x1520); ASSERT_REG_POSITION(shader_exceptions_enable, 0x1528); ASSERT_REG_POSITION(clear_report_value, 0x1530); ASSERT_REG_POSITION(anti_alias_enable, 0x1534); ASSERT_REG_POSITION(zeta_enable, 0x1538); ASSERT_REG_POSITION(anti_alias_alpha_control, 0x153C); ASSERT_REG_POSITION(render_enable, 0x1550); ASSERT_REG_POSITION(tex_sampler, 0x155C); ASSERT_REG_POSITION(slope_scale_depth_bias, 0x156C); ASSERT_REG_POSITION(line_anti_alias_enable, 0x1570); ASSERT_REG_POSITION(tex_header, 0x1574); ASSERT_REG_POSITION(active_zcull_region_id, 0x1590); ASSERT_REG_POSITION(stencil_two_side_enable, 0x1594); ASSERT_REG_POSITION(stencil_back_op, 0x1598); ASSERT_REG_POSITION(framebuffer_srgb, 0x15B8); ASSERT_REG_POSITION(depth_bias, 0x15BC); ASSERT_REG_POSITION(zcull_region_format, 0x15C8); ASSERT_REG_POSITION(rt_layer, 0x15CC); ASSERT_REG_POSITION(anti_alias_samples_mode, 0x15D0); ASSERT_REG_POSITION(edge_flag, 0x15E4); ASSERT_REG_POSITION(draw_inline_index, 0x15E8); ASSERT_REG_POSITION(inline_index_2x16, 0x15EC); ASSERT_REG_POSITION(vertex_global_base_offset, 0x15F4); ASSERT_REG_POSITION(zcull_region_pixel_offset, 0x15FC); ASSERT_REG_POSITION(point_sprite, 0x1604); ASSERT_REG_POSITION(program_region, 0x1608); ASSERT_REG_POSITION(default_attributes, 0x1610); ASSERT_REG_POSITION(draw, 0x1614); ASSERT_REG_POSITION(vertex_id_copy, 0x161C); ASSERT_REG_POSITION(add_to_primitive_id, 0x1620); ASSERT_REG_POSITION(load_to_primitive_id, 0x1624); ASSERT_REG_POSITION(shader_based_cull, 0x162C); ASSERT_REG_POSITION(class_version, 0x1638); ASSERT_REG_POSITION(primitive_restart, 0x1644); ASSERT_REG_POSITION(output_vertex_id, 0x164C); ASSERT_REG_POSITION(anti_alias_point_enable, 0x1658); ASSERT_REG_POSITION(point_center_mode, 0x165C); ASSERT_REG_POSITION(line_smooth_params, 0x1668); ASSERT_REG_POSITION(line_stipple_enable, 0x166C); ASSERT_REG_POSITION(line_smooth_edge_table, 0x1670); ASSERT_REG_POSITION(line_stipple_params, 0x1680); ASSERT_REG_POSITION(provoking_vertex, 0x1684); ASSERT_REG_POSITION(two_sided_light_enabled, 0x1688); ASSERT_REG_POSITION(polygon_stipple_enabled, 0x168C); ASSERT_REG_POSITION(shader_control, 0x1690); ASSERT_REG_POSITION(class_version_check, 0x16A0); ASSERT_REG_POSITION(sph_version, 0x16A4); ASSERT_REG_POSITION(sph_version_check, 0x16A8); ASSERT_REG_POSITION(alpha_to_coverage_override, 0x16B4); ASSERT_REG_POSITION(polygon_stipple_pattern, 0x1700); ASSERT_REG_POSITION(aam_version, 0x1790); ASSERT_REG_POSITION(aam_version_check, 0x1794); ASSERT_REG_POSITION(zeta_layer_offset, 0x179C); ASSERT_REG_POSITION(index_buffer, 0x17C8); ASSERT_REG_POSITION(index_buffer32_first, 0x17E4); ASSERT_REG_POSITION(index_buffer16_first, 0x17E8); ASSERT_REG_POSITION(index_buffer8_first, 0x17EC); ASSERT_REG_POSITION(index_buffer32_subsequent, 0x17F0); ASSERT_REG_POSITION(index_buffer16_subsequent, 0x17F4); ASSERT_REG_POSITION(index_buffer8_subsequent, 0x17F8); ASSERT_REG_POSITION(depth_bias_clamp, 0x187C); ASSERT_REG_POSITION(vertex_stream_instances, 0x1880); ASSERT_REG_POSITION(point_size_attribute, 0x1910); ASSERT_REG_POSITION(gl_cull_test_enabled, 0x1918); ASSERT_REG_POSITION(gl_front_face, 0x191C); ASSERT_REG_POSITION(gl_cull_face, 0x1920); ASSERT_REG_POSITION(viewport_pixel_center, 0x1924); ASSERT_REG_POSITION(viewport_scale_offset_enabled, 0x192C); ASSERT_REG_POSITION(viewport_clip_control, 0x193C); ASSERT_REG_POSITION(user_clip_op, 0x1940); ASSERT_REG_POSITION(render_enable_override, 0x1944); ASSERT_REG_POSITION(primitive_topology_control, 0x1948); ASSERT_REG_POSITION(window_clip_enable, 0x194C); ASSERT_REG_POSITION(invalidate_zcull, 0x1958); ASSERT_REG_POSITION(zcull, 0x1968); ASSERT_REG_POSITION(topology_override, 0x1970); ASSERT_REG_POSITION(zcull_sync, 0x1978); ASSERT_REG_POSITION(clip_id_test_enable, 0x197C); ASSERT_REG_POSITION(surface_clip_id_width, 0x1980); ASSERT_REG_POSITION(clip_id, 0x1984); ASSERT_REG_POSITION(depth_bounds_enable, 0x19BC); ASSERT_REG_POSITION(blend_float_zero_times_anything_is_zero, 0x19C0); ASSERT_REG_POSITION(logic_op, 0x19C4); ASSERT_REG_POSITION(z_compression_enable, 0x19CC); ASSERT_REG_POSITION(clear_surface, 0x19D0); ASSERT_REG_POSITION(clear_clip_id_surface, 0x19D4); ASSERT_REG_POSITION(color_compression_enable, 0x19E0); ASSERT_REG_POSITION(color_mask, 0x1A00); ASSERT_REG_POSITION(pipe_nop, 0x1A2C); ASSERT_REG_POSITION(spare, 0x1A30); ASSERT_REG_POSITION(report_semaphore, 0x1B00); ASSERT_REG_POSITION(vertex_streams, 0x1C00); ASSERT_REG_POSITION(blend_per_target, 0x1E00); ASSERT_REG_POSITION(vertex_stream_limits, 0x1F00); ASSERT_REG_POSITION(pipelines, 0x2000); ASSERT_REG_POSITION(falcon, 0x2300); ASSERT_REG_POSITION(const_buffer, 0x2380); ASSERT_REG_POSITION(bind_groups, 0x2400); ASSERT_REG_POSITION(color_clamp_enable, 0x2600); ASSERT_REG_POSITION(bindless_texture_const_buffer_slot, 0x2608); ASSERT_REG_POSITION(trap_handler, 0x260C); ASSERT_REG_POSITION(stream_out_layout, 0x2800); ASSERT_REG_POSITION(shader_performance, 0x333C); ASSERT_REG_POSITION(shadow_scratch, 0x3400); #undef ASSERT_REG_POSITION } // namespace Tegra::Engines