2021-03-24 21:09:21 +01:00
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
2021-08-20 22:17:13 +02:00
// Copyright © 2018-2020 fincs (https://github.com/devkitPro/deko3d)
2021-03-24 21:09:21 +01:00
# pragma once
2021-09-14 18:00:12 +02:00
# include <gpu/interconnect/graphics_context.h>
2021-03-24 21:09:21 +01:00
# include "engine.h"
# include "maxwell/macro_interpreter.h"
2021-10-08 21:25:21 +02:00
namespace skyline : : soc : : gm20b {
struct ChannelContext ;
}
2021-03-24 21:09:21 +01:00
namespace skyline : : soc : : gm20b : : engine : : maxwell3d {
/**
* @ brief The Maxwell 3 D engine handles processing 3 D graphics
*/
class Maxwell3D : public Engine {
private :
std : : array < size_t , 0x80 > macroPositions { } ; //!< The positions of each individual macro in macro memory, there can be a maximum of 0x80 macros at any one time
struct {
2021-09-27 23:05:05 +02:00
i32 index { - 1 } ;
2021-03-24 21:09:21 +01:00
std : : vector < u32 > arguments ;
} macroInvocation { } ; //!< Data for a macro that is pending execution
MacroInterpreter macroInterpreter ;
2021-09-14 18:00:12 +02:00
gpu : : interconnect : : GraphicsContext context ;
2021-03-24 21:09:21 +01:00
2021-11-12 09:54:43 +01:00
/**
* @ brief Calls the appropriate function corresponding to a certain method with the supplied argument
*/
2021-11-12 09:59:17 +01:00
void HandleMethod ( u32 method , u32 argument ) ;
2021-11-12 09:54:43 +01:00
2021-07-23 04:57:11 +02:00
/**
* @ brief Writes back a semaphore result to the guest with an auto - generated timestamp ( if required )
* @ note If the semaphore is OneWord then the result will be downcasted to a 32 - bit unsigned integer
*/
2021-03-24 21:09:21 +01:00
void WriteSemaphoreResult ( u64 result ) ;
public :
static constexpr u32 RegisterCount { 0xE00 } ; //!< The number of Maxwell 3D registers
/**
2021-07-23 04:57:11 +02:00
* @ url https : //github.com/devkitPro/deko3d/blob/master/source/maxwell/engine_3d.def
2021-03-24 21:09:21 +01:00
*/
2021-04-16 17:05:24 +02:00
# pragma pack(push, 1)
2021-03-24 21:09:21 +01:00
union Registers {
std : : array < u32 , RegisterCount > raw ;
2021-11-10 17:01:45 +01:00
template < size_t Offset , typename Type >
using Register = util : : OffsetMember < Offset , Type , u32 > ;
Register < 0x40 , u32 > noOperation ;
Register < 0x44 , u32 > waitForIdle ;
struct MME {
u32 instructionRamPointer ; // 0x45
u32 instructionRamLoad ; // 0x46
u32 startAddressRamPointer ; // 0x47
u32 startAddressRamLoad ; // 0x48
type : : MmeShadowRamControl shadowRamControl ; // 0x49
} ;
Register < 0x45 , MME > mme ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0xB2 , type : : SyncpointAction > syncpointAction ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0xDF , u32 > rasterizerEnable ;
Register < 0x200 , std : : array < type : : RenderTarget , type : : RenderTargetCount > > renderTargets ;
Register < 0x280 , std : : array < type : : ViewportTransform , type : : ViewportCount > > viewportTransforms ;
Register < 0x300 , std : : array < type : : Viewport , type : : ViewportCount > > viewports ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x360 , std : : array < u32 , 4 > > clearColorValue ;
Register < 0x364 , u32 > clearDepthValue ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
struct PolygonMode {
type : : PolygonMode front ; // 0x36B
type : : PolygonMode back ; // 0x36C
} ;
Register < 0x36B , PolygonMode > polygonMode ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x380 , std : : array < type : : Scissor , type : : ViewportCount > > scissors ;
2021-03-24 21:09:21 +01:00
2021-11-11 21:11:04 +01:00
struct DepthBiasEnable {
u32 point ; // 0x370
u32 line ; // 0x371
u32 fill ; // 0x372
} ;
Register < 0x370 , DepthBiasEnable > depthBiasEnable ;
2021-11-10 17:01:45 +01:00
struct StencilBackExtra {
u32 compareRef ; // 0x3D5
u32 writeMask ; // 0x3D6
u32 compareMask ; // 0x3D7
} ;
Register < 0x3D5 , StencilBackExtra > stencilBackExtra ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x3D8 , u32 > tiledCacheEnable ;
struct TiledCacheSize {
u16 width ;
u16 height ;
} ;
Register < 0x3D9 , TiledCacheSize > tiledCacheSize ;
2021-11-15 19:25:32 +01:00
Register < 0x3E4 , u32 > commonColorWriteMask ; //!< If enabled, the color write masks for all RTs must be set to that of the first RT
2021-11-10 17:01:45 +01:00
Register < 0x3EB , u32 > rtSeparateFragData ;
2021-11-16 16:50:34 +01:00
Register < 0x458 , std : : array < type : : VertexAttribute , type : : VertexAttributeCount > > vertexAttributeState ;
2021-11-10 17:01:45 +01:00
Register < 0x487 , type : : RenderTargetControl > renderTargetControl ;
2021-11-15 19:22:47 +01:00
Register < 0x4B9 , u32 > independentBlendEnable ;
2021-11-14 15:27:25 +01:00
Register < 0x4BB , u32 > alphaTestEnable ;
2021-11-10 17:01:45 +01:00
Register < 0x4C3 , type : : CompareOp > depthTestFunc ;
Register < 0x4C4 , float > alphaTestRef ;
Register < 0x4C5 , type : : CompareOp > alphaTestFunc ;
Register < 0x4C6 , u32 > drawTFBStride ;
struct BlendConstant {
2021-11-15 19:22:47 +01:00
float red ; // 0x4C7
float green ; // 0x4C8
float blue ; // 0x4C9
float alpha ; // 0x4CA
2021-11-10 17:01:45 +01:00
} ;
2021-11-15 19:22:47 +01:00
Register < 0x4C7 , std : : array < float , type : : BlendColorChannelCount > > blendConstant ;
2021-11-10 17:01:45 +01:00
2021-11-15 19:22:47 +01:00
struct BlendStateCommon {
2021-11-10 17:01:45 +01:00
u32 seperateAlpha ; // 0x4CF
2021-11-15 19:22:47 +01:00
type : : BlendOp colorOp ; // 0x4D0
type : : BlendFactor colorSrcFactor ; // 0x4D1
type : : BlendFactor colorDstFactor ; // 0x4D2
type : : BlendOp alphaOp ; // 0x4D3
type : : BlendFactor alphaSrcFactor ; // 0x4D4
u32 pad ; // 0x4D5
type : : BlendFactor alphaDstFactor ; // 0x4D6
u32 enable ; // 0x4D7
2021-11-10 17:01:45 +01:00
} ;
2021-11-15 19:22:47 +01:00
Register < 0x4CF , BlendStateCommon > blendStateCommon ;
Register < 0x4D8 , std : : array < u32 , type : : RenderTargetCount > > rtBlendEnable ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x4E0 , u32 > stencilEnable ;
struct StencilFront {
type : : StencilOp failOp ; // 0x4E1
type : : StencilOp zFailOp ; // 0x4E2
type : : StencilOp zPassOp ; // 0x4E3
2021-03-24 21:09:21 +01:00
struct {
2021-11-10 17:01:45 +01:00
type : : CompareOp op ; // 0x4E4
i32 ref ; // 0x4E5
u32 mask ; // 0x4E6
} compare ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
u32 writeMask ; // 0x4E7
} ;
Register < 0x4E1 , StencilFront > stencilFront ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x4EC , float > lineWidthSmooth ;
2021-11-14 16:19:42 +01:00
Register < 0x4ED , float > lineWidthAliased ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x50D , u32 > drawBaseVertex ;
Register < 0x50E , u32 > drawBaseInstance ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x544 , u32 > clipDistanceEnable ;
Register < 0x545 , u32 > sampleCounterEnable ;
Register < 0x546 , float > pointSpriteSize ;
Register < 0x547 , u32 > zCullStatCountersEnable ;
Register < 0x548 , u32 > pointSpriteEnable ;
Register < 0x54A , u32 > shaderExceptions ;
Register < 0x54D , u32 > multisampleEnable ;
Register < 0x54E , u32 > depthTargetEnable ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x54F , type : : MultisampleControl > multisampleControl ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
struct SamplerPool {
type : : Address address ; // 0x557
u32 maximumIndex ; // 0x559
} ;
Register < 0x557 , SamplerPool > samplerPool ;
2021-03-24 21:09:21 +01:00
2021-11-11 21:11:04 +01:00
Register < 0x55B , float > depthBiasFactor ;
2021-11-10 17:01:45 +01:00
Register < 0x55C , u32 > lineSmoothEnable ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
struct TexturePool {
type : : Address address ; // 0x55D
u32 maximumIndex ; // 0x55F
} ;
Register < 0x55D , TexturePool > texturePool ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x565 , u32 > stencilTwoSideEnable ;
2021-03-24 21:09:21 +01:00
2021-11-10 17:01:45 +01:00
struct StencilBack {
type : : StencilOp failOp ; // 0x566
type : : StencilOp zFailOp ; // 0x567
type : : StencilOp zPassOp ; // 0x568
type : : CompareOp compareOp ; // 0x569
} ;
Register < 0x566 , StencilBack > stencilBack ;
2021-11-11 21:11:04 +01:00
Register < 0x56F , float > depthBiasUnits ;
2021-11-10 17:01:45 +01:00
Register < 0x581 , type : : PointCoordReplace > pointCoordReplace ;
2021-11-11 21:11:04 +01:00
Register < 0x582 , type : : Address > setProgramRegion ;
Register < 0x5A1 , u32 > provokingVertexIsLast ;
2021-11-10 17:01:45 +01:00
2021-11-16 10:43:15 +01:00
Register < 0x61F , float > depthBiasClamp ;
2021-11-16 10:58:05 +01:00
Register < 0x620 , std : : array < u32 , type : : VertexBufferCount > > isVertexInputRatePerInstance ; //!< A per-VBO boolean denoting if the vertex input rate should be per vertex or per instance
2021-11-10 17:01:45 +01:00
Register < 0x646 , u32 > cullFaceEnable ;
Register < 0x647 , type : : FrontFace > frontFace ;
Register < 0x648 , type : : CullFace > cullFace ;
2021-11-11 21:11:04 +01:00
2021-11-10 17:01:45 +01:00
Register < 0x649 , u32 > pixelCentreImage ;
Register < 0x64B , u32 > viewportTransformEnable ;
2021-11-16 10:43:15 +01:00
Register < 0x64F , type : : ViewVolumeClipControl > viewVolumeClipControl ;
struct ColorLogicOp {
u32 enable ;
type : : ColorLogicOp type ;
} ;
Register < 0x671 , ColorLogicOp > colorLogicOp ;
2021-11-10 17:01:45 +01:00
Register < 0x674 , type : : ClearBuffers > clearBuffers ;
2021-11-15 19:25:32 +01:00
Register < 0x680 , std : : array < type : : ColorWriteMask , type : : RenderTargetCount > > colorWriteMask ;
2021-11-10 17:01:45 +01:00
struct Semaphore {
type : : Address address ; // 0x6C0
u32 payload ; // 0x6C2
type : : SemaphoreInfo info ; // 0x6C3
2021-03-24 21:09:21 +01:00
} ;
2021-11-10 17:01:45 +01:00
Register < 0x6C0 , Semaphore > semaphore ;
2021-11-16 06:02:01 +01:00
struct VertexBuffer {
union {
u32 raw ;
struct {
u32 stride : 12 ;
u32 enable : 1 ;
} ;
} config ;
type : : Address iova ;
u32 divisor ;
} ;
static_assert ( sizeof ( VertexBuffer ) = = sizeof ( u32 ) * 4 ) ;
Register < 0x700 , std : : array < VertexBuffer , type : : VertexBufferCount > > vertexBuffers ;
2021-11-15 19:22:47 +01:00
struct IndependentBlend {
u32 seperateAlpha ;
type : : BlendOp colorOp ;
type : : BlendFactor colorSrcFactor ;
type : : BlendFactor colorDstFactor ;
type : : BlendOp alphaOp ;
type : : BlendFactor alphaSrcFactor ;
type : : BlendFactor alphaDstFactor ;
u32 _pad_ ;
} ;
Register < 0x780 , std : : array < IndependentBlend , type : : RenderTargetCount > > independentBlend ;
2021-11-11 20:06:05 +01:00
2021-11-16 11:42:30 +01:00
Register < 0x7C0 , std : : array < type : : Address , type : : VertexBufferCount > > vertexBufferLimits ; //!< A per-VBO IOVA denoting the end of the vertex buffer
2021-11-11 20:06:05 +01:00
Register < 0x800 , std : : array < type : : SetProgramInfo , type : : StageCount > > setProgram ;
2021-11-10 17:01:45 +01:00
Register < 0x8C0 , u32 [ 0x20 ] > firmwareCall ;
2021-03-24 21:09:21 +01:00
} ;
static_assert ( sizeof ( Registers ) = = ( RegisterCount * sizeof ( u32 ) ) ) ;
2021-04-16 17:05:24 +02:00
# pragma pack(pop)
2021-03-24 21:09:21 +01:00
Registers registers { } ;
2021-07-23 04:57:11 +02:00
Registers shadowRegisters { } ; //!< A shadow-copy of the registers, their function is controlled by the 'shadowRamControl' register
2021-03-24 21:09:21 +01:00
2021-10-08 21:25:21 +02:00
ChannelContext & channelCtx ;
2021-07-23 04:57:11 +02:00
std : : array < u32 , 0x2000 > macroCode { } ; //!< Stores GPU macros, writes to it will wraparound on overflow
2021-03-24 21:09:21 +01:00
2021-10-08 21:25:21 +02:00
Maxwell3D ( const DeviceState & state , ChannelContext & channelCtx , gpu : : interconnect : : CommandExecutor & executor ) ;
2021-03-24 21:09:21 +01:00
/**
2021-11-12 09:54:43 +01:00
* @ brief Initializes Maxwell 3 D registers to their default values
2021-03-24 21:09:21 +01:00
*/
2021-11-12 09:54:43 +01:00
void InitializeRegisters ( ) ;
2021-03-24 21:09:21 +01:00
2021-11-12 09:54:43 +01:00
void CallMethod ( u32 method , u32 argument , bool lastCall = false ) ;
2021-03-24 21:09:21 +01:00
} ;
}