mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-24 16:30:44 +00:00
0d6a2158f0
Inline index draws arrive as a batch but were processed one word at a time, so each index ran through the full per-method path and got appended a byte at a time. Handle the whole batch in one pass instead, updating state once and appending all the indices together. Replay shadow control still goes word by word since it has to reload each one. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4083 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
3628 lines
140 KiB
C++
3628 lines
140 KiB
C++
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <bitset>
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include <optional>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
#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.h"
|
|
#include "video_core/textures/texture.h"
|
|
#include "video_core/engines/maxwell_3d.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(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 (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
|
}
|
|
};
|
|
|
|
struct PeerSemaphore {
|
|
u32 address_high;
|
|
u32 address_low;
|
|
|
|
GPUVAddr Address() const {
|
|
return (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{offset_high} << 32) | GPUVAddr{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 1U << (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 {
|
|
u32 raw;
|
|
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<f32, 4> outer;
|
|
std::array<f32, 2> inner;
|
|
} lod;
|
|
|
|
std::array<u32, 9> 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 (GPUVAddr{address_high} << 32) | GPUVAddr{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<TransformFeedback::Buffer, NumTransformFeedbackBuffers> buffers;
|
|
|
|
INSERT_PADDING_BYTES_NOINIT(0x300);
|
|
|
|
std::array<TransformFeedback::Control, NumTransformFeedbackBuffers> 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 (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
|
}
|
|
|
|
u64 Size() const {
|
|
return (u64{size_high} << 32) | u64{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 (GPUVAddr{storage_address_high} << 32) | GPUVAddr{storage_address_low};
|
|
}
|
|
GPUVAddr StorageLimitAddress() const {
|
|
return (GPUVAddr{storage_limit_address_high} << 32) |
|
|
GPUVAddr{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<u32, u32> 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<u32, NumRenderTargets> maps{target0, target1, target2, target3,
|
|
target4, target5, target6, target7};
|
|
ASSERT(index < maps.size());
|
|
return maps[index];
|
|
}
|
|
};
|
|
|
|
struct CompressionThresholdSamples {
|
|
u32 samples;
|
|
|
|
u32 Samples() const {
|
|
if (samples == 0) {
|
|
return 0;
|
|
}
|
|
return 1U << (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 {
|
|
DefineArraySize = 0,
|
|
ArraySizeIsOne = 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,
|
|
StreamingPrimitivesNeededMinusSucceeded = 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 {
|
|
DefineArraySize = 0,
|
|
DefineDepthSize = 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 (GPUVAddr{address_high} << 32) | GPUVAddr{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<f32> 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 {
|
|
u32 raw_x;
|
|
BitField<0, 16, u32> x_min;
|
|
BitField<16, 16, u32> x_max;
|
|
};
|
|
union {
|
|
u32 raw_y;
|
|
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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 DrawTexture {
|
|
s32 dst_x0;
|
|
s32 dst_y0;
|
|
s32 dst_width;
|
|
s32 dst_height;
|
|
s64 dx_du;
|
|
s64 dy_dv;
|
|
u32 src_sampler;
|
|
u32 src_texture;
|
|
s32 src_x0;
|
|
s32 src_y0;
|
|
};
|
|
static_assert(sizeof(DrawTexture) == 0x30);
|
|
|
|
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<Attributes, 2> a;
|
|
std::array<Attributes, 2> 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 (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
|
}
|
|
};
|
|
|
|
struct TexSampler {
|
|
u32 address_high;
|
|
u32 address_low;
|
|
u32 limit;
|
|
|
|
GPUVAddr Address() const {
|
|
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
|
}
|
|
};
|
|
|
|
struct TexHeader {
|
|
u32 address_high;
|
|
u32 address_low;
|
|
u32 limit;
|
|
|
|
GPUVAddr Address() const {
|
|
return (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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;
|
|
|
|
size_t FormatSizeInBytes() const {
|
|
switch (format) {
|
|
case IndexFormat::UnsignedByte:
|
|
return 1;
|
|
case IndexFormat::UnsignedShort:
|
|
return 2;
|
|
case IndexFormat::UnsignedInt:
|
|
return 4;
|
|
}
|
|
UNREACHABLE();
|
|
return 1;
|
|
}
|
|
|
|
GPUVAddr StartAddress() const {
|
|
return (GPUVAddr{start_addr_high} << 32) | GPUVAddr{start_addr_low};
|
|
}
|
|
|
|
GPUVAddr EndAddress() const {
|
|
return (GPUVAddr{limit_addr_high} << 32) | GPUVAddr{limit_addr_low};
|
|
}
|
|
|
|
/// Adjust the index buffer offset so it points to the first desired index.
|
|
GPUVAddr IndexStart() const {
|
|
return StartAddress() + size_t{first} * size_t{FormatSizeInBytes()};
|
|
}
|
|
};
|
|
|
|
struct IndexBufferSmall {
|
|
union {
|
|
u32 raw;
|
|
BitField<0, 16, u32> first;
|
|
BitField<16, 12, u32> count;
|
|
BitField<28, 4, PrimitiveTopology> topology;
|
|
};
|
|
};
|
|
|
|
struct VertexStreamInstances {
|
|
std::array<u32, NumVertexArrays> 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 bool(is_instanced[index]); //FUCK YOU MSVC
|
|
}
|
|
};
|
|
|
|
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 {
|
|
AfterAllPrecedingReads = 0,
|
|
AfterAllPrecedingWrites = 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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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 (GPUVAddr{address_high} << 32) | GPUVAddr{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<u32, 4> 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<std::size_t>(ShaderType::VertexB)) {
|
|
return true;
|
|
}
|
|
return pipelines[index].enable != 0;
|
|
}
|
|
|
|
bool IsShaderConfigEnabled(ShaderType type) const {
|
|
return IsShaderConfigEnabled(static_cast<std::size_t>(type));
|
|
}
|
|
|
|
struct ConstantBuffer {
|
|
u32 size;
|
|
u32 address_high;
|
|
u32 address_low;
|
|
u32 offset;
|
|
std::array<u32, NumCBData> buffer;
|
|
|
|
GPUVAddr Address() const {
|
|
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
|
}
|
|
};
|
|
|
|
struct BindGroup {
|
|
std::array<u32, 4> 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<u32, 8> values_upper;
|
|
std::array<u32, 8> values;
|
|
std::array<u32, 8> events;
|
|
std::array<ControlA, 8> control_a;
|
|
std::array<ControlB, 8> 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<RenderTargetConfig, NumRenderTargets> rt; ///< 0x0800
|
|
std::array<ViewportTransform, NumViewports> viewport_transform; ///< 0x0A00
|
|
std::array<Viewport, NumViewports> viewports; ///< 0x0C00
|
|
std::array<Window, 8> windows; ///< 0x0D00
|
|
std::array<ClipIdExtent, 4> 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<f32, 4> 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<ScissorTest, NumViewports> 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
|
|
u32 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<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030
|
|
std::array<u32, 15> spare_nop; ///< 0x1044
|
|
DrawTexture draw_texture; ///< 0x1080
|
|
std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0
|
|
ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC
|
|
std::array<u32, 4> 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<VertexAttribute, NumVertexAttributes> vertex_attrib_format; ///< 0x1160
|
|
std::array<MsaaSampleLocation, 4> 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<u32, 8> 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
|
|
u32 stencil_front_ref; ///< 0x1394
|
|
u32 stencil_front_func_mask; ///< 0x1398
|
|
u32 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_register_watermarks; ///< 0x1454
|
|
INSERT_PADDING_BYTES_NOINIT(0xC);
|
|
u32 store_zcull; ///< 0x1464
|
|
INSERT_PADDING_BYTES_NOINIT(0x18);
|
|
std::array<IteratedBlendConstants, NumRenderTargets>
|
|
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<LineSmoothEdgeTable, 4> 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<u32, 32> 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<u32, NumRenderTargets> color_compression_enable; ///< 0x19E0
|
|
std::array<ColorMask, NumRenderTargets> color_mask; ///< 0x1A00
|
|
INSERT_PADDING_BYTES_NOINIT(0xC);
|
|
u32 pipe_nop; ///< 0x1A2C
|
|
std::array<u32, 4> spare; ///< 0x1A30
|
|
INSERT_PADDING_BYTES_NOINIT(0xC0);
|
|
ReportSemaphore report_semaphore; ///< 0x1B00
|
|
INSERT_PADDING_BYTES_NOINIT(0xF0);
|
|
std::array<VertexStream, NumVertexArrays> vertex_streams; ///< 0x1C00
|
|
BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00
|
|
std::array<VertexStreamLimit, NumVertexArrays> vertex_stream_limits; ///< 0x1F00
|
|
std::array<Pipeline, MaxShaderProgram> 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<std::array<StreamOutLayout, 32>, NumTransformFeedbackBuffers> stream_out_layout; ///< 0x2800
|
|
INSERT_PADDING_BYTES_NOINIT(0x93C);
|
|
ShaderPerformance shader_performance; ///< 0x333C
|
|
INSERT_PADDING_BYTES_NOINIT(0x18);
|
|
std::array<u32, 0x100> shadow_scratch; ///< 0x3400
|
|
};
|
|
std::array<u32, NUM_REGS> reg_array;
|
|
};
|
|
};
|
|
// clang-format on
|
|
|
|
struct DrawManager {
|
|
enum class DrawMode : u32 { General = 0, Instance, InlineIndex };
|
|
struct State {
|
|
Maxwell3D::Regs::PrimitiveTopology topology{};
|
|
DrawMode draw_mode{};
|
|
bool draw_indexed{};
|
|
u32 base_index{};
|
|
Maxwell3D::Regs::VertexBuffer vertex_buffer;
|
|
Maxwell3D::Regs::IndexBuffer index_buffer;
|
|
u32 base_instance{};
|
|
u32 instance_count{};
|
|
std::vector<u8> inline_index_draw_indexes;
|
|
};
|
|
struct DrawTextureState {
|
|
f32 dst_x0;
|
|
f32 dst_y0;
|
|
f32 dst_x1;
|
|
f32 dst_y1;
|
|
f32 src_x0;
|
|
f32 src_y0;
|
|
f32 src_x1;
|
|
f32 src_y1;
|
|
u32 src_sampler;
|
|
u32 src_texture;
|
|
};
|
|
struct IndirectParams {
|
|
bool is_byte_count;
|
|
bool is_indexed;
|
|
bool include_count;
|
|
GPUVAddr count_start_address;
|
|
GPUVAddr indirect_start_address;
|
|
size_t buffer_size;
|
|
size_t max_draw_counts;
|
|
size_t stride;
|
|
};
|
|
void ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument);
|
|
void Clear(Maxwell3D& maxwell3d, u32 layer_count);
|
|
void DrawDeferred(Maxwell3D& maxwell3d);
|
|
void DrawArray(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, u32 base_instance, u32 num_instances);
|
|
void DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent);
|
|
void DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances);
|
|
void DrawArrayIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology);
|
|
void DrawIndexedIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count);
|
|
void SetInlineIndexBuffer(Maxwell3D& maxwell3d, u32 index);
|
|
void SetInlineIndexBuffer(Maxwell3D& maxwell3d, u32 method, const u32* base_start, u32 amount);
|
|
void DrawBegin(Maxwell3D& maxwell3d);
|
|
void DrawEnd(Maxwell3D& maxwell3d, u32 instance_count = 1, bool force_draw = false);
|
|
void DrawIndexSmall(Maxwell3D& maxwell3d, u32 argument);
|
|
void DrawTexture(Maxwell3D& maxwell3d);
|
|
void UpdateTopology(Maxwell3D& maxwell3d);
|
|
void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count);
|
|
void ProcessDrawIndirect(Maxwell3D& maxwell3d);
|
|
State draw_state{};
|
|
DrawTextureState draw_texture_state{};
|
|
IndirectParams indirect_state{};
|
|
};
|
|
|
|
Regs regs{};
|
|
|
|
/// Store temporary hw register values, used by some calls to restore state after a operation
|
|
Regs shadow_state;
|
|
|
|
// None Engine
|
|
enum class EngineHint : u32 {
|
|
None = 0x0,
|
|
OnHLEMacro = 0x1,
|
|
};
|
|
|
|
EngineHint engine_state{EngineHint::None};
|
|
|
|
enum class HLEReplacementAttributeType : u32 {
|
|
BaseVertex = 0x0,
|
|
BaseInstance = 0x1,
|
|
DrawID = 0x2,
|
|
};
|
|
|
|
void SetHLEReplacementAttributeType(u32 bank, u32 offset, HLEReplacementAttributeType name);
|
|
|
|
ankerl::unordered_dense::map<u64, HLEReplacementAttributeType> replace_table;
|
|
|
|
static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
|
|
static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
|
|
|
|
struct State {
|
|
struct ShaderStageInfo {
|
|
std::array<ConstBufferInfo, Regs::MaxConstBuffers> const_buffers;
|
|
};
|
|
|
|
std::array<ShaderStageInfo, Regs::MaxShaderStage> 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(Core::System& system, u32 method, u32 method_argument, bool is_last_call) override;
|
|
|
|
/// Write multiple values to the register identified by method.
|
|
void CallMultiMethod(Core::System& system, 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<(std::numeric_limits<u8>::max)() + 1>;
|
|
using Table = std::array<u8, Regs::NUM_REGS>;
|
|
using Tables = std::array<std::array<u8, Regs::NUM_REGS>, 2>;
|
|
|
|
Flags flags;
|
|
Tables tables{};
|
|
} dirty;
|
|
|
|
DrawManager draw_manager;
|
|
|
|
GPUVAddr GetMacroAddress(size_t index) const {
|
|
size_t base = 0;
|
|
for (const auto& [addr, count] : macro_segments) {
|
|
if (index < base + count) {
|
|
return addr + (index - base) * sizeof(u32);
|
|
}
|
|
base += count;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void RefreshParameters() {
|
|
if (!current_macro_dirty) {
|
|
return;
|
|
}
|
|
RefreshParametersImpl();
|
|
}
|
|
|
|
bool AnyParametersDirty() const {
|
|
return current_macro_dirty;
|
|
}
|
|
|
|
u32 GetMaxCurrentVertices();
|
|
|
|
size_t EstimateIndexBufferSize();
|
|
|
|
/// Handles a write to the CLEAR_BUFFERS register.
|
|
void ProcessClearBuffers(u32 layer_count);
|
|
|
|
/// Handles a write to the CB_BIND register.
|
|
void ProcessCBBind(size_t stage_index);
|
|
|
|
/// Handles a write to the CB_DATA[i] register.
|
|
void ProcessCBData(u32 value);
|
|
void ProcessCBMultiData(const u32* start_base, u32 amount);
|
|
|
|
void ProcessInlineIndexMultiData(u32 method, const u32* start_base, u32 amount);
|
|
|
|
private:
|
|
void InitializeRegisterDefaults();
|
|
|
|
void ProcessMacro(Core::System& system, 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 ConsumeSinkImpl(Core::System& system) override;
|
|
|
|
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(Core::System& system, u32 method, const std::vector<u32>& 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(Core::System& system, u64 payload, bool long_query);
|
|
|
|
/// Handles conditional rendering.
|
|
void ProcessQueryCondition();
|
|
|
|
/// Handles counter resets.
|
|
void ProcessCounterReset();
|
|
|
|
/// Handles writes to syncing register.
|
|
void ProcessSyncPoint();
|
|
|
|
void RefreshParametersImpl();
|
|
|
|
bool IsMethodExecutable(u32 method);
|
|
|
|
MemoryManager& memory_manager;
|
|
|
|
VideoCore::RasterizerInterface* rasterizer = nullptr;
|
|
|
|
/// Start offsets of each macro in macro_memory
|
|
std::array<u32, 0x80> 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<u32> macro_params;
|
|
|
|
/// Interpreter for the macro codes uploaded to the GPU.
|
|
MacroEngine macro_engine;
|
|
|
|
Upload::State upload_state;
|
|
|
|
bool execute_on{true};
|
|
|
|
std::vector<std::pair<GPUVAddr, size_t>> macro_segments;
|
|
bool current_macro_dirty{};
|
|
};
|
|
|
|
#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_register_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
|