mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-26 10:50:06 +00:00
Extract functions on Command Processor
This commit is contained in:
parent
6fc123d67c
commit
f74f4e73b9
@ -28,6 +28,7 @@ set(SRCS
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
command_map.h
|
||||
command_processor.h
|
||||
debug_utils/debug_utils.h
|
||||
geometry_pipeline.h
|
||||
|
810
src/video_core/command_map.h
Normal file
810
src/video_core/command_map.h
Normal file
@ -0,0 +1,810 @@
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Pica {
|
||||
namespace CommandProcessor {
|
||||
|
||||
struct Command;
|
||||
|
||||
static void nop(const Command&) {}
|
||||
static void TriggerIRQ(const Command&);
|
||||
static void TriangleTopology(const Command&);
|
||||
static void RestartPrimitive(const Command&);
|
||||
static void DefaultAttributes(const Command&);
|
||||
static void GpuMode(const Command&);
|
||||
static void TriggerCommandBuffer(const Command&);
|
||||
static void TriggerDraw(const Command&);
|
||||
static void DefaultAttribSetup(const Command&);
|
||||
static void UniformBoolGs(const Command&);
|
||||
static void UniformBoolVs(const Command&);
|
||||
static void UniformIntGs(const Command&);
|
||||
static void UniformIntVs(const Command&);
|
||||
static void UniformFloatGs(const Command&);
|
||||
static void UniformFloatVs(const Command&);
|
||||
static void SetWordGs(const Command&);
|
||||
static void SetWordVs(const Command&);
|
||||
static void SetWordSwizzleGs(const Command&);
|
||||
static void SetWordSwizzleVs(const Command&);
|
||||
static void LightingLut(const Command&);
|
||||
static void FogLut(const Command&);
|
||||
static void ProcTexLut(const Command&);
|
||||
|
||||
using CommandAction = void (*)(const Command&);
|
||||
static const CommandAction CommandMap[] = {
|
||||
nop, // 0x000
|
||||
nop, // 0x001
|
||||
nop, // 0x002
|
||||
nop, // 0x003
|
||||
nop, // 0x004
|
||||
nop, // 0x005
|
||||
nop, // 0x006
|
||||
nop, // 0x007
|
||||
nop, // 0x008
|
||||
nop, // 0x009
|
||||
nop, // 0x00a
|
||||
nop, // 0x00b
|
||||
nop, // 0x00c
|
||||
nop, // 0x00d
|
||||
nop, // 0x00e
|
||||
nop, // 0x00f
|
||||
TriggerIRQ, // 0x010 FINALIZE PICA__INTERRUPT
|
||||
nop, // 0x011
|
||||
nop, // 0x012
|
||||
nop, // 0x013
|
||||
nop, // 0x014
|
||||
nop, // 0x015
|
||||
nop, // 0x016
|
||||
nop, // 0x017
|
||||
nop, // 0x018
|
||||
nop, // 0x019
|
||||
nop, // 0x01a
|
||||
nop, // 0x01b
|
||||
nop, // 0x01c
|
||||
nop, // 0x01d
|
||||
nop, // 0x01e
|
||||
nop, // 0x01f
|
||||
nop, // 0x020
|
||||
nop, // 0x021
|
||||
nop, // 0x022
|
||||
nop, // 0x023
|
||||
nop, // 0x024
|
||||
nop, // 0x025
|
||||
nop, // 0x026
|
||||
nop, // 0x027
|
||||
nop, // 0x028
|
||||
nop, // 0x029
|
||||
nop, // 0x02a
|
||||
nop, // 0x02b
|
||||
nop, // 0x02c
|
||||
nop, // 0x02d
|
||||
nop, // 0x02e
|
||||
nop, // 0x02f
|
||||
nop, // 0x030
|
||||
nop, // 0x031
|
||||
nop, // 0x032
|
||||
nop, // 0x033
|
||||
nop, // 0x034
|
||||
nop, // 0x035
|
||||
nop, // 0x036
|
||||
nop, // 0x037
|
||||
nop, // 0x038
|
||||
nop, // 0x039
|
||||
nop, // 0x03a
|
||||
nop, // 0x03b
|
||||
nop, // 0x03c
|
||||
nop, // 0x03d
|
||||
nop, // 0x03e
|
||||
nop, // 0x03f
|
||||
nop, // 0x040 CULLING_CONFIG PICA__CULL_FACE
|
||||
nop, // 0x041 VIEWPORT_WIDTH PICA__VIEWPORT_WIDTH1
|
||||
nop, // 0x042 VIEWPORT_INVW PICA__VIEWPORT_WIDTH2
|
||||
nop, // 0x043 VIEWPORT_HEIGHT PICA__VIEWPORT_HEIGHT1
|
||||
nop, // 0x044 VIEWPORT_INVH PICA__VIEWPORT_HEIGHT2
|
||||
nop, // 0x045
|
||||
nop, // 0x046
|
||||
nop, // 0x047 FRAGOP_CLIP PICA__FRAGOP_CLIP
|
||||
nop, // 0x048 FRAGOP_CLIP_DATA0 PICA__FRAGOP_CLIP_DATA1
|
||||
nop, // 0x049 FRAGOP_CLIP_DATA1 PICA__FRAGOP_CLIP_DATA2
|
||||
nop, // 0x04a FRAGOP_CLIP_DATA2 PICA__FRAGOP_CLIP_DATA3
|
||||
nop, // 0x04b FRAGOP_CLIP_DATA3 PICA__FRAGOP_CLIP_DATA4
|
||||
nop, // 0x04c
|
||||
nop, // 0x04d DEPTHMAP_SCALE PICA__FRAGOP_WSCALE_DATA1
|
||||
nop, // 0x04e DEPTHMAP_OFFSET PICA__FRAGOP_WSCALE_DATA2
|
||||
nop, // 0x04f SH_OUTMAP_TOTAL PICA__GS_OUT__NUM0 / PICA__VS_OUT__NUM0
|
||||
nop, // 0x050 SH_OUTMAP_O0 PICA__GS_OUT_ATTR0 / PICA__VS_OUT_ATTR0
|
||||
nop, // 0x051 SH_OUTMAP_O1 PICA__GS_OUT_ATTR1 / PICA__VS_OUT_ATTR1
|
||||
nop, // 0x052 SH_OUTMAP_O2 PICA__GS_OUT_ATTR2 / PICA__VS_OUT_ATTR2
|
||||
nop, // 0x053 SH_OUTMAP_O3 PICA__GS_OUT_ATTR3 / PICA__VS_OUT_ATTR3
|
||||
nop, // 0x054 SH_OUTMAP_O4 PICA__GS_OUT_ATTR4 / PICA__VS_OUT_ATTR4
|
||||
nop, // 0x055 SH_OUTMAP_O5 PICA__GS_OUT_ATTR5 / PICA__VS_OUT_ATTR5
|
||||
nop, // 0x056 SH_OUTMAP_O6 PICA__GS_OUT_ATTR6 / PICA__VS_OUT_ATTR6
|
||||
nop, // 0x057
|
||||
nop, // 0x058
|
||||
nop, // 0x059
|
||||
nop, // 0x05a
|
||||
nop, // 0x05b
|
||||
nop, // 0x05c
|
||||
nop, // 0x05d
|
||||
nop, // 0x05e
|
||||
nop, // 0x05f
|
||||
nop, // 0x060
|
||||
nop, // 0x061 EARLYDEPTH_FUNC PICA__EARLY_DEPTH_FUNC
|
||||
nop, // 0x062 EARLYDEPTH_TEST1 PICA__EARLY_DEPTH_TEST1
|
||||
nop, // 0x063 EARLYDEPTH_CLEAR PICA__EARLY_DEPTH_CLEAR
|
||||
nop, // 0x064 SH_OUTATTR_MODE PICA__GS_OUT_ATTR_MODE / PICA__VS_OUT_ATTR_MODE
|
||||
nop, // 0x065 SCISSORTEST_MODE PICA__SCISSOR
|
||||
nop, // 0x066 SCISSORTEST_POS PICA__SCISSOR_XY
|
||||
nop, // 0x067 SCISSORTEST_DIM PICA__SCISSOR_SIZE
|
||||
nop, // 0x068 VIEWPORT_XY PICA__VIEWPORT_XY
|
||||
nop, // 0x069
|
||||
nop, // 0x06a EARLYDEPTH_DATA PICA__EARLY_DEPTH_DATA
|
||||
nop, // 0x06b
|
||||
nop, // 0x06c
|
||||
nop, // 0x06d DEPTHMAP_ENABLE PICA__FRAGOP_WSCALE
|
||||
nop, // 0x06e RENDERBUF_DIM PICA__RENDER_BUF_RESOLUTION1
|
||||
nop, // 0x06f SH_OUTATTR_CLOCK PICA__GS_OUT_ATTR_CLK / PICA__VS_OUT_ATTR_CLK
|
||||
nop, // 0x070
|
||||
nop, // 0x071
|
||||
nop, // 0x072
|
||||
nop, // 0x073
|
||||
nop, // 0x074
|
||||
nop, // 0x075
|
||||
nop, // 0x076
|
||||
nop, // 0x077
|
||||
nop, // 0x078
|
||||
nop, // 0x079
|
||||
nop, // 0x07a
|
||||
nop, // 0x07b
|
||||
nop, // 0x07c
|
||||
nop, // 0x07d
|
||||
nop, // 0x07e
|
||||
nop, // 0x07f
|
||||
nop, // 0x080 TEXUNIT_CONFIG PICA__TEXTURE_FUNC
|
||||
nop, // 0x081 TEXUNIT0_BORDER_COLOR PICA__TEXTURE0_BORDER_COLOR
|
||||
nop, // 0x082 TEXUNIT0_DIM PICA__TEXTURE0_SIZE
|
||||
nop, // 0x083 TEXUNIT0_PARAM PICA__TEXTURE0_WRAP_FILTER
|
||||
nop, // 0x084 TEXUNIT0_LOD PICA__TEXTURE0_LOD
|
||||
nop, // 0x085 TEXUNIT0_ADDR1 PICA__TEXTURE0_ADDR1
|
||||
nop, // 0x086 TEXUNIT0_ADDR2 PICA__TEXTURE0_ADDR2
|
||||
nop, // 0x087 TEXUNIT0_ADDR3 PICA__TEXTURE0_ADDR3
|
||||
nop, // 0x088 TEXUNIT0_ADDR4 PICA__TEXTURE0_ADDR4
|
||||
nop, // 0x089 TEXUNIT0_ADDR5 PICA__TEXTURE0_ADDR5
|
||||
nop, // 0x08a TEXUNIT0_ADDR6 PICA__TEXTURE0_ADDR6
|
||||
nop, // 0x08b TEXUNIT0_SHADOW PICA__TEXTURE0_SHADOW
|
||||
nop, // 0x08c
|
||||
nop, // 0x08d
|
||||
nop, // 0x08e TEXUNIT0_TYPE PICA__TEXTURE0_FORMAT
|
||||
nop, // 0x08f LIGHTING_ENABLE0 PICA__FRAG_LIGHT_EN0
|
||||
nop, // 0x090
|
||||
nop, // 0x091 TEXUNIT1_BORDER_COLOR PICA__TEXTURE1_BORDER_COLOR
|
||||
nop, // 0x092 TEXUNIT1_DIM PICA__TEXTURE1_SIZE
|
||||
nop, // 0x093 TEXUNIT1_PARAM PICA__TEXTURE1_WRAP_FILTER
|
||||
nop, // 0x094 TEXUNIT1_LOD PICA__TEXTURE1_LOD
|
||||
nop, // 0x095 TEXUNIT1_ADDR PICA__TEXTURE1_ADDR
|
||||
nop, // 0x096 TEXUNIT1_TYPE PICA__TEXTURE1_FORMAT
|
||||
nop, // 0x097
|
||||
nop, // 0x098
|
||||
nop, // 0x099 TEXUNIT2_BORDER_COLOR PICA__TEXTURE2_BORDER_COLOR
|
||||
nop, // 0x09a TEXUNIT2_DIM PICA__TEXTURE2_SIZE
|
||||
nop, // 0x09b TEXUNIT2_PARAM PICA__TEXTURE2_WRAP_FILTER
|
||||
nop, // 0x09c TEXUNIT2_LOD PICA__TEXTURE2_LOD
|
||||
nop, // 0x09d TEXUNIT2_ADDR PICA__TEXTURE2_ADDR
|
||||
nop, // 0x09e TEXUNIT2_TYPE PICA__TEXTURE2_FORMAT
|
||||
nop, // 0x09f
|
||||
nop, // 0x0a0
|
||||
nop, // 0x0a1
|
||||
nop, // 0x0a2
|
||||
nop, // 0x0a3
|
||||
nop, // 0x0a4
|
||||
nop, // 0x0a5
|
||||
nop, // 0x0a6
|
||||
nop, // 0x0a7
|
||||
nop, // 0x0a8 TEXUNIT3_PROCTEX0 PICA__TEXTURE3_PROCTEX0
|
||||
nop, // 0x0a9 TEXUNIT3_PROCTEX1 PICA__TEXTURE3_PROCTEX1
|
||||
nop, // 0x0aa TEXUNIT3_PROCTEX2 PICA__TEXTURE3_PROCTEX2
|
||||
nop, // 0x0ab TEXUNIT3_PROCTEX3 PICA__TEXTURE3_PROCTEX3
|
||||
nop, // 0x0ac TEXUNIT3_PROCTEX4 PICA__TEXTURE3_PROCTEX4
|
||||
nop, // 0x0ad TEXUNIT3_PROCTEX5 PICA__TEXTURE3_PROCTEX5
|
||||
nop, // 0x0ae
|
||||
nop, // 0x0af PROCTEX_LUT PICA__PROCTEX_LUT
|
||||
ProcTexLut, // 0x0b0 PROCTEX_LUT_DATA0 PICA__PROCTEX_LUT_DATA0
|
||||
ProcTexLut, // 0x0b1 PROCTEX_LUT_DATA1 PICA__PROCTEX_LUT_DATA1
|
||||
ProcTexLut, // 0x0b2 PROCTEX_LUT_DATA2 PICA__PROCTEX_LUT_DATA2
|
||||
ProcTexLut, // 0x0b3 PROCTEX_LUT_DATA3 PICA__PROCTEX_LUT_DATA3
|
||||
ProcTexLut, // 0x0b4 PROCTEX_LUT_DATA4 PICA__PROCTEX_LUT_DATA4
|
||||
ProcTexLut, // 0x0b5 PROCTEX_LUT_DATA5 PICA__PROCTEX_LUT_DATA5
|
||||
ProcTexLut, // 0x0b6 PROCTEX_LUT_DATA6 PICA__PROCTEX_LUT_DATA6
|
||||
ProcTexLut, // 0x0b7 PROCTEX_LUT_DATA7 PICA__PROCTEX_LUT_DATA7
|
||||
nop, // 0x0b8
|
||||
nop, // 0x0b9
|
||||
nop, // 0x0ba
|
||||
nop, // 0x0bb
|
||||
nop, // 0x0bc
|
||||
nop, // 0x0bd
|
||||
nop, // 0x0be
|
||||
nop, // 0x0bf
|
||||
nop, // 0x0c0 TEXENV0_SOURCE PICA__TEX_ENV_0
|
||||
nop, // 0x0c1 TEXENV0_OPERAND PICA__TEX_ENV_0_OPERAND
|
||||
nop, // 0x0c2 TEXENV0_COMBINER PICA__TEX_ENV_0_COMBINE
|
||||
nop, // 0x0c3 TEXENV0_COLOR PICA__TEX_ENV_0_COLOR
|
||||
nop, // 0x0c4 TEXENV0_SCALE PICA__TEX_ENV_0_SCALE
|
||||
nop, // 0x0c5
|
||||
nop, // 0x0c6
|
||||
nop, // 0x0c7
|
||||
nop, // 0x0c8 TEXENV1_SOURCE PICA__TEX_ENV_1
|
||||
nop, // 0x0c9 TEXENV1_OPERAND PICA__TEX_ENV_1_OPERAND
|
||||
nop, // 0x0ca TEXENV1_COMBINER PICA__TEX_ENV_1_COMBINE
|
||||
nop, // 0x0cb TEXENV1_COLOR PICA__TEX_ENV_1_COLOR
|
||||
nop, // 0x0cc TEXENV1_SCALE PICA__TEX_ENV_1_SCALE
|
||||
nop, // 0x0cd
|
||||
nop, // 0x0ce
|
||||
nop, // 0x0cf
|
||||
nop, // 0x0d0 TEXENV2_SOURCE PICA__TEX_ENV_2
|
||||
nop, // 0x0d1 TEXENV2_OPERAND PICA__TEX_ENV_2_OPERAND
|
||||
nop, // 0x0d2 TEXENV2_COMBINER PICA__TEX_ENV_2_COMBINE
|
||||
nop, // 0x0d3 TEXENV2_COLOR PICA__TEX_ENV_2_COLOR
|
||||
nop, // 0x0d4 TEXENV2_SCALE PICA__TEX_ENV_2_SCALE
|
||||
nop, // 0x0d5
|
||||
nop, // 0x0d6
|
||||
nop, // 0x0d7
|
||||
nop, // 0x0d8 TEXENV3_SOURCE PICA__TEX_ENV_3
|
||||
nop, // 0x0d9 TEXENV3_OPERAND PICA__TEX_ENV_3_OPERAND
|
||||
nop, // 0x0da TEXENV3_COMBINER PICA__TEX_ENV_3_COMBINE
|
||||
nop, // 0x0db TEXENV3_COLOR PICA__TEX_ENV_3_COLOR
|
||||
nop, // 0x0dc TEXENV3_SCALE PICA__TEX_ENV_3_SCALE
|
||||
nop, // 0x0dd
|
||||
nop, // 0x0de
|
||||
nop, // 0x0df
|
||||
nop, // 0x0e0 TEXENV_UPDATE_BUFFER PICA__GAS_FOG_MODE / PICA__TEX_ENV_BUF_INPUT
|
||||
nop, // 0x0e1 FOG_COLOR PICA__FOG_COLOR
|
||||
nop, // 0x0e2
|
||||
nop, // 0x0e3
|
||||
nop, // 0x0e4 GAS_ATTENUATION PICA__GAS_ATTENUATION
|
||||
nop, // 0x0e5 GAS_ACCMAX PICA__GAS_ACCMAX
|
||||
nop, // 0x0e6 FOG_LUT_INDEX PICA__FOG_LUT_INDEX
|
||||
nop, // 0x0e7
|
||||
FogLut, // 0x0e8 FOG_LUT_DATA0 PICA__FOG_LUT_DATA0
|
||||
FogLut, // 0x0e9 FOG_LUT_DATA1 PICA__FOG_LUT_DATA1
|
||||
FogLut, // 0x0ea FOG_LUT_DATA2 PICA__FOG_LUT_DATA2
|
||||
FogLut, // 0x0eb FOG_LUT_DATA3 PICA__FOG_LUT_DATA3
|
||||
FogLut, // 0x0ec FOG_LUT_DATA4 PICA__FOG_LUT_DATA4
|
||||
FogLut, // 0x0ed FOG_LUT_DATA5 PICA__FOG_LUT_DATA5
|
||||
FogLut, // 0x0ee FOG_LUT_DATA6 PICA__FOG_LUT_DATA6
|
||||
FogLut, // 0x0ef FOG_LUT_DATA7 PICA__FOG_LUT_DATA7
|
||||
nop, // 0x0f0 TEXENV4_SOURCE PICA__TEX_ENV_4
|
||||
nop, // 0x0f1 TEXENV4_OPERAND PICA__TEX_ENV_4_OPERAND
|
||||
nop, // 0x0f2 TEXENV4_COMBINER PICA__TEX_ENV_4_COMBINE
|
||||
nop, // 0x0f3 TEXENV4_COLOR PICA__TEX_ENV_4_COLOR
|
||||
nop, // 0x0f4 TEXENV4_SCALE PICA__TEX_ENV_4_SCALE
|
||||
nop, // 0x0f5
|
||||
nop, // 0x0f6
|
||||
nop, // 0x0f7
|
||||
nop, // 0x0f8 TEXENV5_SOURCE PICA__TEX_ENV_5
|
||||
nop, // 0x0f9 TEXENV5_OPERAND PICA__TEX_ENV_5_OPERAND
|
||||
nop, // 0x0fa TEXENV5_COMBINER PICA__TEX_ENV_5_COMBINE
|
||||
nop, // 0x0fb TEXENV5_COLOR PICA__TEX_ENV_5_COLOR
|
||||
nop, // 0x0fc TEXENV5_SCALE PICA__TEX_ENV_5_SCALE
|
||||
nop, // 0x0fd TEXENV_BUFFER_COLOR PICA__TEX_ENV_BUF_COLOR
|
||||
nop, // 0x0fe
|
||||
nop, // 0x0ff
|
||||
nop, // 0x100 COLOR_OPERATION PICA__COLOR_OPERATION
|
||||
nop, // 0x101 BLEND_FUNC PICA__BLEND_FUNC
|
||||
nop, // 0x102 LOGIC_OP PICA__LOGIC_OP
|
||||
nop, // 0x103 BLEND_COLOR PICA__BLEND_COLOR
|
||||
nop, // 0x104 FRAGOP_ALPHA_TEST PICA__FRAGOP_ALPHA_TEST
|
||||
nop, // 0x105 STENCIL_TEST PICA__STENCIL_TEST
|
||||
nop, // 0x106 STENCIL_OP PICA__STENCIL_OP
|
||||
nop, // 0x107 DEPTH_COLOR_MASK PICA__DEPTH_COLOR_MASK
|
||||
nop, // 0x108
|
||||
nop, // 0x109
|
||||
nop, // 0x10a
|
||||
nop, // 0x10b
|
||||
nop, // 0x10c
|
||||
nop, // 0x10d
|
||||
nop, // 0x10e
|
||||
nop, // 0x10f
|
||||
nop, // 0x110 FRAMEBUFFER_INVALIDATE PICA__COLOR_BUFFER_CLEAR0
|
||||
nop, // 0x111 FRAMEBUFFER_FLUSH PICA__COLOR_BUFFER_CLEAR1
|
||||
nop, // 0x112 COLORBUFFER_READ PICA__COLOR_BUFFER_READ
|
||||
nop, // 0x113 COLORBUFFER_WRITE PICA__COLOR_BUFFER_WRITE
|
||||
nop, // 0x114 DEPTHBUFFER_READ PICA__DEPTH_STENCIL_READ
|
||||
nop, // 0x115 DEPTHBUFFER_WRITE PICA__DEPTH_STENCIL_WRITE
|
||||
nop, // 0x116 DEPTHBUFFER_FORMAT PICA__RENDER_BUF_DEPTH_MODE
|
||||
nop, // 0x117 COLORBUFFER_FORMAT PICA__RENDER_BUF_COLOR_MODE
|
||||
nop, // 0x118 EARLYDEPTH_TEST2 PICA__EARLY_DEPTH_TEST2
|
||||
nop, // 0x119
|
||||
nop, // 0x11a
|
||||
nop, // 0x11b FRAMEBUFFER_BLOCK32 PICA__RENDER_BLOCK_FORMAT
|
||||
nop, // 0x11c DEPTHBUFFER_LOC PICA__RENDER_BUF_DEPTH_ADDR
|
||||
nop, // 0x11d COLORBUFFER_LOC PICA__RENDER_BUF_COLOR_ADDR
|
||||
nop, // 0x11e FRAMEBUFFER_DIM PICA__RENDER_BUF_RESOLUTION0
|
||||
nop, // 0x11f
|
||||
nop, // 0x120 GAS_LIGHT_XY PICA__GAS_LIGHT_XY
|
||||
nop, // 0x121 GAS_LIGHT_Z PICA__GAS_LIGHT_Z
|
||||
nop, // 0x122 GAS_LIGHT_Z_COLOR PICA__GAS_LIGHT_Z_COLOR
|
||||
nop, // 0x123 GAS_LUT_INDEX PICA__GAS_LUT_INDEX
|
||||
nop, // 0x124 GAS_LUT_DATA PICA__GAS_LUT_DATA
|
||||
nop, // 0x125
|
||||
nop, // 0x126 GAS_DELTAZ_DEPTH PICA__GAS_DELTAZ_DEPTH
|
||||
nop, // 0x127
|
||||
nop, // 0x128
|
||||
nop, // 0x129
|
||||
nop, // 0x12a
|
||||
nop, // 0x12b
|
||||
nop, // 0x12c
|
||||
nop, // 0x12d
|
||||
nop, // 0x12e
|
||||
nop, // 0x12f
|
||||
nop, // 0x130 FRAGOP_SHADOW PICA__FRAGOP_SHADOW
|
||||
nop, // 0x131
|
||||
nop, // 0x132
|
||||
nop, // 0x133
|
||||
nop, // 0x134
|
||||
nop, // 0x135
|
||||
nop, // 0x136
|
||||
nop, // 0x137
|
||||
nop, // 0x138
|
||||
nop, // 0x139
|
||||
nop, // 0x13a
|
||||
nop, // 0x13b
|
||||
nop, // 0x13c
|
||||
nop, // 0x13d
|
||||
nop, // 0x13e
|
||||
nop, // 0x13f
|
||||
nop, // 0x140 LIGHT0_SPECULAR0 PICA__FRAG_LIGHT0_SPECULAR0 / PICA__FRAG_LIGHT_START
|
||||
nop, // 0x141 LIGHT0_SPECULAR1 PICA__FRAG_LIGHT0_SPECULAR1
|
||||
nop, // 0x142 LIGHT0_DIFFUSE PICA__FRAG_LIGHT0_DIFFUSE
|
||||
nop, // 0x143 LIGHT0_AMBIENT PICA__FRAG_LIGHT0_AMBIENT
|
||||
nop, // 0x144 LIGHT0_XY PICA__FRAG_LIGHT0_POSITION_XY
|
||||
nop, // 0x145 LIGHT0_Z PICA__FRAG_LIGHT0_POSITION_Z
|
||||
nop, // 0x146 LIGHT0_SPOTDIR_XY PICA__FRAG_LIGHT0_SPOT_XY
|
||||
nop, // 0x147 LIGHT0_SPOTDIR_Z PICA__FRAG_LIGHT0_SPOT_Z
|
||||
nop, // 0x148
|
||||
nop, // 0x149 LIGHT0_CONFIG PICA__FRAG_LIGHT0_TYPE
|
||||
nop, // 0x14a LIGHT0_ATTENUATION_BIAS PICA__FRAG_LIGHT0_DIST_ATTN_BIAS
|
||||
nop, // 0x14b LIGHT0_ATTENUATION_SCALE PICA__FRAG_LIGHT0_DIST_ATTN_SCALE
|
||||
nop, // 0x14c
|
||||
nop, // 0x14d
|
||||
nop, // 0x14e
|
||||
nop, // 0x14f
|
||||
nop, // 0x150 LIGHT1_SPECULAR0 PICA__FRAG_LIGHT1_SPECULAR0
|
||||
nop, // 0x151 LIGHT1_SPECULAR1 PICA__FRAG_LIGHT1_SPECULAR1
|
||||
nop, // 0x152 LIGHT1_DIFFUSE PICA__FRAG_LIGHT1_DIFFUSE
|
||||
nop, // 0x153 LIGHT1_AMBIENT PICA__FRAG_LIGHT1_AMBIENT
|
||||
nop, // 0x154 LIGHT1_XY PICA__FRAG_LIGHT1_POSITION_XY
|
||||
nop, // 0x155 LIGHT1_Z PICA__FRAG_LIGHT1_POSITION_Z
|
||||
nop, // 0x156 LIGHT1_SPOTDIR_XY PICA__FRAG_LIGHT1_SPOT_XY
|
||||
nop, // 0x157 LIGHT1_SPOTDIR_Z PICA__FRAG_LIGHT1_SPOT_Z
|
||||
nop, // 0x158
|
||||
nop, // 0x159 LIGHT1_CONFIG PICA__FRAG_LIGHT1_TYPE
|
||||
nop, // 0x15a LIGHT1_ATTENUATION_BIAS PICA__FRAG_LIGHT1_DIST_ATTN_BIAS
|
||||
nop, // 0x15b LIGHT1_ATTENUATION_SCALE PICA__FRAG_LIGHT1_DIST_ATTN_SCALE
|
||||
nop, // 0x15c
|
||||
nop, // 0x15d
|
||||
nop, // 0x15e
|
||||
nop, // 0x15f
|
||||
nop, // 0x160 LIGHT2_SPECULAR0 PICA__FRAG_LIGHT2_SPECULAR0
|
||||
nop, // 0x161 LIGHT2_SPECULAR1 PICA__FRAG_LIGHT2_SPECULAR1
|
||||
nop, // 0x162 LIGHT2_DIFFUSE PICA__FRAG_LIGHT2_DIFFUSE
|
||||
nop, // 0x163 LIGHT2_AMBIENT PICA__FRAG_LIGHT2_AMBIENT
|
||||
nop, // 0x164 LIGHT2_XY PICA__FRAG_LIGHT2_POSITION_XY
|
||||
nop, // 0x165 LIGHT2_Z PICA__FRAG_LIGHT2_POSITION_Z
|
||||
nop, // 0x166 LIGHT2_SPOTDIR_XY PICA__FRAG_LIGHT2_SPOT_XY
|
||||
nop, // 0x167 LIGHT2_SPOTDIR_Z PICA__FRAG_LIGHT2_SPOT_Z
|
||||
nop, // 0x168
|
||||
nop, // 0x169 LIGHT2_CONFIG PICA__FRAG_LIGHT2_TYPE
|
||||
nop, // 0x16a LIGHT2_ATTENUATION_BIAS PICA__FRAG_LIGHT2_DIST_ATTN_BIAS
|
||||
nop, // 0x16b LIGHT2_ATTENUATION_SCALE PICA__FRAG_LIGHT2_DIST_ATTN_SCALE
|
||||
nop, // 0x16c
|
||||
nop, // 0x16d
|
||||
nop, // 0x16e
|
||||
nop, // 0x16f
|
||||
nop, // 0x170 LIGHT3_SPECULAR0 PICA__FRAG_LIGHT3_SPECULAR0
|
||||
nop, // 0x171 LIGHT3_SPECULAR1 PICA__FRAG_LIGHT3_SPECULAR1
|
||||
nop, // 0x172 LIGHT3_DIFFUSE PICA__FRAG_LIGHT3_DIFFUSE
|
||||
nop, // 0x173 LIGHT3_AMBIENT PICA__FRAG_LIGHT3_AMBIENT
|
||||
nop, // 0x174 LIGHT3_XY PICA__FRAG_LIGHT3_POSITION_XY
|
||||
nop, // 0x175 LIGHT3_Z PICA__FRAG_LIGHT3_POSITION_Z
|
||||
nop, // 0x176 LIGHT3_SPOTDIR_XY PICA__FRAG_LIGHT3_SPOT_XY
|
||||
nop, // 0x177 LIGHT3_SPOTDIR_Z PICA__FRAG_LIGHT3_SPOT_Z
|
||||
nop, // 0x178
|
||||
nop, // 0x179 LIGHT3_CONFIG PICA__FRAG_LIGHT3_TYPE
|
||||
nop, // 0x17a LIGHT3_ATTENUATION_BIAS PICA__FRAG_LIGHT3_DIST_ATTN_BIAS
|
||||
nop, // 0x17b LIGHT3_ATTENUATION_SCALE PICA__FRAG_LIGHT3_DIST_ATTN_SCALE
|
||||
nop, // 0x17c
|
||||
nop, // 0x17d
|
||||
nop, // 0x17e
|
||||
nop, // 0x17f
|
||||
nop, // 0x180 LIGHT4_SPECULAR0 PICA__FRAG_LIGHT4_SPECULAR0
|
||||
nop, // 0x181 LIGHT4_SPECULAR1 PICA__FRAG_LIGHT4_SPECULAR1
|
||||
nop, // 0x182 LIGHT4_DIFFUSE PICA__FRAG_LIGHT4_DIFFUSE
|
||||
nop, // 0x183 LIGHT4_AMBIENT PICA__FRAG_LIGHT4_AMBIENT
|
||||
nop, // 0x184 LIGHT4_XY PICA__FRAG_LIGHT4_POSITION_XY
|
||||
nop, // 0x185 LIGHT4_Z PICA__FRAG_LIGHT4_POSITION_Z
|
||||
nop, // 0x186 LIGHT4_SPOTDIR_XY PICA__FRAG_LIGHT4_SPOT_XY
|
||||
nop, // 0x187 LIGHT4_SPOTDIR_Z PICA__FRAG_LIGHT4_SPOT_Z
|
||||
nop, // 0x188
|
||||
nop, // 0x189 LIGHT4_CONFIG PICA__FRAG_LIGHT4_TYPE
|
||||
nop, // 0x18a LIGHT4_ATTENUATION_BIAS PICA__FRAG_LIGHT4_DIST_ATTN_BIAS
|
||||
nop, // 0x18b LIGHT4_ATTENUATION_SCALE PICA__FRAG_LIGHT4_DIST_ATTN_SCALE
|
||||
nop, // 0x18c
|
||||
nop, // 0x18d
|
||||
nop, // 0x18e
|
||||
nop, // 0x18f
|
||||
nop, // 0x190 LIGHT5_SPECULAR0 PICA__FRAG_LIGHT5_SPECULAR0
|
||||
nop, // 0x191 LIGHT5_SPECULAR1 PICA__FRAG_LIGHT5_SPECULAR1
|
||||
nop, // 0x192 LIGHT5_DIFFUSE PICA__FRAG_LIGHT5_DIFFUSE
|
||||
nop, // 0x193 LIGHT5_AMBIENT PICA__FRAG_LIGHT5_AMBIENT
|
||||
nop, // 0x194 LIGHT5_XY PICA__FRAG_LIGHT5_POSITION_XY
|
||||
nop, // 0x195 LIGHT5_Z PICA__FRAG_LIGHT5_POSITION_Z
|
||||
nop, // 0x196 LIGHT5_SPOTDIR_XY PICA__FRAG_LIGHT5_SPOT_XY
|
||||
nop, // 0x197 LIGHT5_SPOTDIR_Z PICA__FRAG_LIGHT5_SPOT_Z
|
||||
nop, // 0x198
|
||||
nop, // 0x199 LIGHT5_CONFIG PICA__FRAG_LIGHT5_TYPE
|
||||
nop, // 0x19a LIGHT5_ATTENUATION_BIAS PICA__FRAG_LIGHT5_DIST_ATTN_BIAS
|
||||
nop, // 0x19b LIGHT5_ATTENUATION_SCALE PICA__FRAG_LIGHT5_DIST_ATTN_SCALE
|
||||
nop, // 0x19c
|
||||
nop, // 0x19d
|
||||
nop, // 0x19e
|
||||
nop, // 0x19f
|
||||
nop, // 0x1a0 LIGHT6_SPECULAR0 PICA__FRAG_LIGHT6_SPECULAR0
|
||||
nop, // 0x1a1 LIGHT6_SPECULAR1 PICA__FRAG_LIGHT6_SPECULAR1
|
||||
nop, // 0x1a2 LIGHT6_DIFFUSE PICA__FRAG_LIGHT6_DIFFUSE
|
||||
nop, // 0x1a3 LIGHT6_AMBIENT PICA__FRAG_LIGHT6_AMBIENT
|
||||
nop, // 0x1a4 LIGHT6_XY PICA__FRAG_LIGHT6_POSITION_XY
|
||||
nop, // 0x1a5 LIGHT6_Z PICA__FRAG_LIGHT6_POSITION_Z
|
||||
nop, // 0x1a6 LIGHT6_SPOTDIR_XY PICA__FRAG_LIGHT6_SPOT_XY
|
||||
nop, // 0x1a7 LIGHT6_SPOTDIR_Z PICA__FRAG_LIGHT6_SPOT_Z
|
||||
nop, // 0x1a8
|
||||
nop, // 0x1a9 LIGHT6_CONFIG PICA__FRAG_LIGHT6_TYPE
|
||||
nop, // 0x1aa LIGHT6_ATTENUATION_BIAS PICA__FRAG_LIGHT6_DIST_ATTN_BIAS
|
||||
nop, // 0x1ab LIGHT6_ATTENUATION_SCALE PICA__FRAG_LIGHT6_DIST_ATTN_SCALE
|
||||
nop, // 0x1ac
|
||||
nop, // 0x1ad
|
||||
nop, // 0x1ae
|
||||
nop, // 0x1af
|
||||
nop, // 0x1b0 LIGHT7_SPECULAR0 PICA__FRAG_LIGHT7_SPECULAR0
|
||||
nop, // 0x1b1 LIGHT7_SPECULAR1 PICA__FRAG_LIGHT7_SPECULAR1
|
||||
nop, // 0x1b2 LIGHT7_DIFFUSE PICA__FRAG_LIGHT7_DIFFUSE
|
||||
nop, // 0x1b3 LIGHT7_AMBIENT PICA__FRAG_LIGHT7_AMBIENT
|
||||
nop, // 0x1b4 LIGHT7_XY PICA__FRAG_LIGHT7_POSITION_XY
|
||||
nop, // 0x1b5 LIGHT7_Z PICA__FRAG_LIGHT7_POSITION_Z
|
||||
nop, // 0x1b6 LIGHT7_SPOTDIR_XY PICA__FRAG_LIGHT7_SPOT_XY
|
||||
nop, // 0x1b7 LIGHT7_SPOTDIR_Z PICA__FRAG_LIGHT7_SPOT_Z
|
||||
nop, // 0x1b8
|
||||
nop, // 0x1b9 LIGHT7_CONFIG PICA__FRAG_LIGHT7_TYPE
|
||||
nop, // 0x1ba LIGHT7_ATTENUATION_BIAS PICA__FRAG_LIGHT7_DIST_ATTN_BIAS
|
||||
nop, // 0x1bb LIGHT7_ATTENUATION_SCALE PICA__FRAG_LIGHT7_DIST_ATTN_SCALE
|
||||
nop, // 0x1bc
|
||||
nop, // 0x1bd
|
||||
nop, // 0x1be
|
||||
nop, // 0x1bf
|
||||
nop, // 0x1c0 LIGHTING_AMBIENT PICA__FRAG_LIGHT_AMBIENT
|
||||
nop, // 0x1c1
|
||||
nop, // 0x1c2 LIGHTING_NUM_LIGHTS PICA__FRAG_LIGHT_SRC_NUM
|
||||
nop, // 0x1c3 LIGHTING_CONFIG0 PICA__FRAG_LIGHT_FUNC_MODE0
|
||||
nop, // 0x1c4 LIGHTING_CONFIG1 PICA__FRAG_LIGHT_FUNC_MODE1
|
||||
nop, // 0x1c5 LIGHTING_LUT_INDEX PICA__FRAG_LIGHT_LUT
|
||||
nop, // 0x1c6 LIGHTING_ENABLE1 PICA__FRAG_LIGHT_EN1
|
||||
nop, // 0x1c7
|
||||
LightingLut, // 0x1c8 LIGHTING_LUT_DATA0 PICA__FRAG_LIGHT_LUT_DATA0
|
||||
LightingLut, // 0x1c9 LIGHTING_LUT_DATA1 PICA__FRAG_LIGHT_LUT_DATA1
|
||||
LightingLut, // 0x1ca LIGHTING_LUT_DATA2 PICA__FRAG_LIGHT_LUT_DATA2
|
||||
LightingLut, // 0x1cb LIGHTING_LUT_DATA3 PICA__FRAG_LIGHT_LUT_DATA3
|
||||
LightingLut, // 0x1cc LIGHTING_LUT_DATA4 PICA__FRAG_LIGHT_LUT_DATA4
|
||||
LightingLut, // 0x1cd LIGHTING_LUT_DATA5 PICA__FRAG_LIGHT_LUT_DATA5
|
||||
LightingLut, // 0x1ce LIGHTING_LUT_DATA6 PICA__FRAG_LIGHT_LUT_DATA6
|
||||
LightingLut, // 0x1cf LIGHTING_LUT_DATA7 PICA__FRAG_LIGHT_LUT_DATA7
|
||||
nop, // 0x1d0 LIGHTING_LUTINPUT_ABS PICA__FRAG_LIGHT_ABSLUTINPUT
|
||||
nop, // 0x1d1 LIGHTING_LUTINPUT_SELECT PICA__FRAG_LIGHT_LUTINPUT
|
||||
nop, // 0x1d2 LIGHTING_LUTINPUT_SCALE PICA__FRAG_LIGHT_LUTSCALE
|
||||
nop, // 0x1d3
|
||||
nop, // 0x1d4
|
||||
nop, // 0x1d5
|
||||
nop, // 0x1d6
|
||||
nop, // 0x1d7
|
||||
nop, // 0x1d8
|
||||
nop, // 0x1d9 LIGHTING_LIGHT_PERMUTATION PICA__FRAG_LIGHT_SRC_EN_ID
|
||||
nop, // 0x1da
|
||||
nop, // 0x1db
|
||||
nop, // 0x1dc
|
||||
nop, // 0x1dd
|
||||
nop, // 0x1de
|
||||
nop, // 0x1df
|
||||
nop, // 0x1e0
|
||||
nop, // 0x1e1
|
||||
nop, // 0x1e2
|
||||
nop, // 0x1e3
|
||||
nop, // 0x1e4
|
||||
nop, // 0x1e5
|
||||
nop, // 0x1e6
|
||||
nop, // 0x1e7
|
||||
nop, // 0x1e8
|
||||
nop, // 0x1e9
|
||||
nop, // 0x1ea
|
||||
nop, // 0x1eb
|
||||
nop, // 0x1ec
|
||||
nop, // 0x1ed
|
||||
nop, // 0x1ee
|
||||
nop, // 0x1ef
|
||||
nop, // 0x1f0
|
||||
nop, // 0x1f1
|
||||
nop, // 0x1f2
|
||||
nop, // 0x1f3
|
||||
nop, // 0x1f4
|
||||
nop, // 0x1f5
|
||||
nop, // 0x1f6
|
||||
nop, // 0x1f7
|
||||
nop, // 0x1f8
|
||||
nop, // 0x1f9
|
||||
nop, // 0x1fa
|
||||
nop, // 0x1fb
|
||||
nop, // 0x1fc
|
||||
nop, // 0x1fd
|
||||
nop, // 0x1fe
|
||||
nop, // 0x1ff
|
||||
nop, // 0x200 ATTRIBBUFFERS_LOC PICA__VTX_ATTR_ARRAYS_BASE_ADDR
|
||||
nop, // 0x201 ATTRIBBUFFERS_FORMAT_LOW PICA__VTX_ATTR_ARRAYS0
|
||||
nop, // 0x202 ATTRIBBUFFERS_FORMAT_HIGH PICA__VTX_ATTR_ARRAYS1
|
||||
nop, // 0x203 ATTRIBBUFFER0_OFFSET PICA__LOAD_ARRAY0_ATTR_OFFSET
|
||||
nop, // 0x204 ATTRIBBUFFER0_CONFIG1 PICA__LOAD_ARRAY0_ELEMENT0
|
||||
nop, // 0x205 ATTRIBBUFFER0_CONFIG2 PICA__LOAD_ARRAY0_ELEMENT1
|
||||
nop, // 0x206 ATTRIBBUFFER1_OFFSET
|
||||
nop, // 0x207 ATTRIBBUFFER1_CONFIG1
|
||||
nop, // 0x208 ATTRIBBUFFER1_CONFIG2
|
||||
nop, // 0x209 ATTRIBBUFFER2_OFFSET
|
||||
nop, // 0x20a ATTRIBBUFFER2_CONFIG1
|
||||
nop, // 0x20b ATTRIBBUFFER2_CONFIG2
|
||||
nop, // 0x20c ATTRIBBUFFER3_OFFSET
|
||||
nop, // 0x20d ATTRIBBUFFER3_CONFIG1
|
||||
nop, // 0x20e ATTRIBBUFFER3_CONFIG2
|
||||
nop, // 0x20f ATTRIBBUFFER4_OFFSET
|
||||
nop, // 0x210 ATTRIBBUFFER4_CONFIG1
|
||||
nop, // 0x211 ATTRIBBUFFER4_CONFIG2
|
||||
nop, // 0x212 ATTRIBBUFFER5_OFFSET
|
||||
nop, // 0x213 ATTRIBBUFFER5_CONFIG1
|
||||
nop, // 0x214 ATTRIBBUFFER5_CONFIG2
|
||||
nop, // 0x215 ATTRIBBUFFER6_OFFSET
|
||||
nop, // 0x216 ATTRIBBUFFER6_CONFIG1
|
||||
nop, // 0x217 ATTRIBBUFFER6_CONFIG2
|
||||
nop, // 0x218 ATTRIBBUFFER7_OFFSET
|
||||
nop, // 0x219 ATTRIBBUFFER7_CONFIG1
|
||||
nop, // 0x21a ATTRIBBUFFER7_CONFIG2
|
||||
nop, // 0x21b ATTRIBBUFFER8_OFFSET
|
||||
nop, // 0x21c ATTRIBBUFFER8_CONFIG1
|
||||
nop, // 0x21d ATTRIBBUFFER8_CONFIG2
|
||||
nop, // 0x21e ATTRIBBUFFER9_OFFSET
|
||||
nop, // 0x21f ATTRIBBUFFER9_CONFIG1
|
||||
nop, // 0x220 ATTRIBBUFFER9_CONFIG2
|
||||
nop, // 0x221 ATTRIBBUFFER10_OFFSET
|
||||
nop, // 0x222 ATTRIBBUFFER10_CONFIG1
|
||||
nop, // 0x223 ATTRIBBUFFER10_CONFIG2
|
||||
nop, // 0x224 ATTRIBBUFFER11_OFFSET
|
||||
nop, // 0x225 ATTRIBBUFFER11_CONFIG1
|
||||
nop, // 0x226 ATTRIBBUFFER11_CONFIG2
|
||||
nop, // 0x227 INDEXBUFFER_CONFIG PICA__INDEX_ARRAY_ADDR_OFFSET
|
||||
nop, // 0x228 NUMVERTICES PICA__DRAW_VERTEX_NUM
|
||||
nop, // 0x229 GEOSTAGE_CONFIG PICA__DRAW_MODE0
|
||||
nop, // 0x22a VERTEX_OFFSET PICA__DRAW_VERTEX_OFFSET
|
||||
nop, // 0x22b
|
||||
nop, // 0x22c
|
||||
nop, // 0x22d POST_VERTEX_CACHE_NUM PICA__POST_VERTEX_CACHE_NUM
|
||||
TriggerDraw, // 0x22e DRAWARRAYS PICA__START_DRAW_ARRAY
|
||||
TriggerDraw, // 0x22f DRAWELEMENTS PICA__START_DRAW_ELEMENT
|
||||
nop, // 0x230
|
||||
nop, // 0x231 VTX_FUNC PICA__VTX_FUNC
|
||||
DefaultAttributes, // 0x232 FIXEDATTRIB_INDEX PICA__VS_FIXED_ATTR
|
||||
DefaultAttribSetup, // 0x233 FIXEDATTRIB_DATA0 PICA__VS_FIXED_ATTR_DATA0
|
||||
DefaultAttribSetup, // 0x234 FIXEDATTRIB_DATA1 PICA__VS_FIXED_ATTR_DATA1
|
||||
DefaultAttribSetup, // 0x235 FIXEDATTRIB_DATA2 PICA__VS_FIXED_ATTR_DATA2
|
||||
nop, // 0x236
|
||||
nop, // 0x237
|
||||
nop, // 0x238 CMDBUF_SIZE0 PICA__COMMAND_BUF_SIZE_CH0
|
||||
nop, // 0x239 CMDBUF_SIZE1 PICA__COMMAND_BUF_SIZE_CH1
|
||||
nop, // 0x23a CMDBUF_ADDR0 PICA__COMMAND_BUF_ADDR_CH0
|
||||
nop, // 0x23b CMDBUF_ADDR1 PICA__COMMAND_BUF_ADDR_CH1
|
||||
TriggerCommandBuffer, // 0x23c CMDBUF_JUMP0 PICA__COMMAND_BUF_KICK_CH0
|
||||
TriggerCommandBuffer, // 0x23d CMDBUF_JUMP1 PICA__COMMAND_BUF_KICK_CH1
|
||||
nop, // 0x23e
|
||||
nop, // 0x23f
|
||||
nop, // 0x240
|
||||
nop, // 0x241
|
||||
nop, // 0x242 VSH_NUM_ATTR PICA__VS_ATTR_NUM1
|
||||
nop, // 0x243
|
||||
nop, // 0x244 VSH_COM_MODE PICA__VS_COM_MODE
|
||||
GpuMode, // 0x245 START_DRAW_FUNC0 PICA__START_DRAW_FUNC0
|
||||
nop, // 0x246
|
||||
nop, // 0x247
|
||||
nop, // 0x248
|
||||
nop, // 0x249
|
||||
nop, // 0x24a VSH_OUTMAP_TOTAL1 PICA__VS_OUT__NUM1
|
||||
nop, // 0x24b
|
||||
nop, // 0x24c
|
||||
nop, // 0x24d
|
||||
nop, // 0x24e
|
||||
nop, // 0x24f
|
||||
nop, // 0x250
|
||||
nop, // 0x251 VSH_OUTMAP_TOTAL2 PICA__VS_OUT__NUM2
|
||||
nop, // 0x252 GSH_MISC0 PICA__GS_MISC_0
|
||||
nop, // 0x253 GEOSTAGE_CONFIG2 PICA__DRAW_MODE1
|
||||
nop, // 0x254 GSH_MISC1 PICA__GS_MISC_1
|
||||
nop, // 0x255
|
||||
nop, // 0x256
|
||||
nop, // 0x257
|
||||
nop, // 0x258
|
||||
nop, // 0x259
|
||||
nop, // 0x25a
|
||||
nop, // 0x25b
|
||||
nop, // 0x25c
|
||||
nop, // 0x25d
|
||||
TriangleTopology, // 0x25e PRIMITIVE_CONFIG
|
||||
RestartPrimitive, // 0x25f RESTART_PRIMITIVE PICA__START_DRAW_FUNC1
|
||||
nop, // 0x260
|
||||
nop, // 0x261
|
||||
nop, // 0x262
|
||||
nop, // 0x263
|
||||
nop, // 0x264
|
||||
nop, // 0x265
|
||||
nop, // 0x266
|
||||
nop, // 0x267
|
||||
nop, // 0x268
|
||||
nop, // 0x269
|
||||
nop, // 0x26a
|
||||
nop, // 0x26b
|
||||
nop, // 0x26c
|
||||
nop, // 0x26d
|
||||
nop, // 0x26e
|
||||
nop, // 0x26f
|
||||
nop, // 0x270
|
||||
nop, // 0x271
|
||||
nop, // 0x272
|
||||
nop, // 0x273
|
||||
nop, // 0x274
|
||||
nop, // 0x275
|
||||
nop, // 0x276
|
||||
nop, // 0x277
|
||||
nop, // 0x278
|
||||
nop, // 0x279
|
||||
nop, // 0x27a
|
||||
nop, // 0x27b
|
||||
nop, // 0x27c
|
||||
nop, // 0x27d
|
||||
nop, // 0x27e
|
||||
nop, // 0x27f
|
||||
UniformBoolGs, // 0x280 GSH_BOOLUNIFORM PICA__GS_BOOL
|
||||
UniformIntGs, // 0x281 GSH_INTUNIFORM_I0 PICA__GS_INT0
|
||||
UniformIntGs, // 0x282 GSH_INTUNIFORM_I1 PICA__GS_INT1
|
||||
UniformIntGs, // 0x283 GSH_INTUNIFORM_I2 PICA__GS_INT2
|
||||
UniformIntGs, // 0x284 GSH_INTUNIFORM_I3 PICA__GS_INT3
|
||||
nop, // 0x285
|
||||
nop, // 0x286
|
||||
nop, // 0x287
|
||||
nop, // 0x288
|
||||
nop, // 0x289 GSH_INPUTBUFFER_CONFIG PICA__GS_ATTR_NUM
|
||||
nop, // 0x28a GSH_ENTRYPOINT PICA__GS_START_ADDR
|
||||
nop, // 0x28b GSH_ATTRIBUTES_PERMUTATION_LOW PICA__GS_ATTR_IN__MAP0
|
||||
nop, // 0x28c GSH_ATTRIBUTES_PERMUTATION_HIGH PICA__GS_ATTR_IN__MAP1
|
||||
nop, // 0x28d GSH_OUTMAP_MASK PICA__GS_OUT__MASK
|
||||
nop, // 0x28e
|
||||
nop, // 0x28f GSH_CODETRANSFER_END PICA__GS_PROG_RENEWAL_END
|
||||
nop, // 0x290 GSH_FLOATUNIFORM_INDEX PICA__GS_FLOAT_ADDR
|
||||
UniformFloatGs, // 0x291 GSH_FLOATUNIFORM_DATA0 PICA__GS_FLOAT_DATA0
|
||||
UniformFloatGs, // 0x292 GSH_FLOATUNIFORM_DATA1 PICA__GS_FLOAT_DATA1
|
||||
UniformFloatGs, // 0x293 GSH_FLOATUNIFORM_DATA2 PICA__GS_FLOAT_DATA2
|
||||
UniformFloatGs, // 0x294 GSH_FLOATUNIFORM_DATA3 PICA__GS_FLOAT_DATA3
|
||||
UniformFloatGs, // 0x295 GSH_FLOATUNIFORM_DATA4 PICA__GS_FLOAT_DATA4
|
||||
UniformFloatGs, // 0x296 GSH_FLOATUNIFORM_DATA5 PICA__GS_FLOAT_DATA5
|
||||
UniformFloatGs, // 0x297 GSH_FLOATUNIFORM_DATA6 PICA__GS_FLOAT_DATA6
|
||||
UniformFloatGs, // 0x298 GSH_FLOATUNIFORM_DATA7 PICA__GS_FLOAT_DATA7
|
||||
nop, // 0x299
|
||||
nop, // 0x29a
|
||||
nop, // 0x29b GSH_CODETRANSFER_INDEX PICA__GS_PROG_ADDR
|
||||
SetWordGs, // 0x29c GSH_CODETRANSFER_DATA0 PICA__GS_PROG_DATA0
|
||||
SetWordGs, // 0x29d GSH_CODETRANSFER_DATA1 PICA__GS_PROG_DATA1
|
||||
SetWordGs, // 0x29e GSH_CODETRANSFER_DATA2 PICA__GS_PROG_DATA2
|
||||
SetWordGs, // 0x29f GSH_CODETRANSFER_DATA3 PICA__GS_PROG_DATA3
|
||||
SetWordGs, // 0x2a0 GSH_CODETRANSFER_DATA4 PICA__GS_PROG_DATA4
|
||||
SetWordGs, // 0x2a1 GSH_CODETRANSFER_DATA5 PICA__GS_PROG_DATA5
|
||||
SetWordGs, // 0x2a2 GSH_CODETRANSFER_DATA6 PICA__GS_PROG_DATA6
|
||||
SetWordGs, // 0x2a3 GSH_CODETRANSFER_DATA7 PICA__GS_PROG_DATA7
|
||||
nop, // 0x2a4
|
||||
nop, // 0x2a5 GSH_OPDESCS_INDEX PICA__GS_PROG_SWIZZLE_ADDR
|
||||
SetWordSwizzleGs, // 0x2a6 GSH_OPDESCS_DATA0 PICA__GS_PROG_SWIZZLE_DATA0
|
||||
SetWordSwizzleGs, // 0x2a7 GSH_OPDESCS_DATA1 PICA__GS_PROG_SWIZZLE_DATA1
|
||||
SetWordSwizzleGs, // 0x2a8 GSH_OPDESCS_DATA2 PICA__GS_PROG_SWIZZLE_DATA2
|
||||
SetWordSwizzleGs, // 0x2a9 GSH_OPDESCS_DATA3 PICA__GS_PROG_SWIZZLE_DATA3
|
||||
SetWordSwizzleGs, // 0x2aa GSH_OPDESCS_DATA4 PICA__GS_PROG_SWIZZLE_DATA4
|
||||
SetWordSwizzleGs, // 0x2ab GSH_OPDESCS_DATA5 PICA__GS_PROG_SWIZZLE_DATA5
|
||||
SetWordSwizzleGs, // 0x2ac GSH_OPDESCS_DATA6 PICA__GS_PROG_SWIZZLE_DATA6
|
||||
SetWordSwizzleGs, // 0x2ad GSH_OPDESCS_DATA7 PICA__GS_PROG_SWIZZLE_DATA7
|
||||
nop, // 0x2ae
|
||||
nop, // 0x2af
|
||||
UniformBoolVs, // 0x2b0 VSH_BOOLUNIFORM PICA__VS_BOOL
|
||||
UniformIntVs, // 0x2b1 VSH_INTUNIFORM_I0 PICA__VS_INT0
|
||||
UniformIntVs, // 0x2b2 VSH_INTUNIFORM_I1 PICA__VS_INT1
|
||||
UniformIntVs, // 0x2b3 VSH_INTUNIFORM_I2 PICA__VS_INT2
|
||||
UniformIntVs, // 0x2b4 VSH_INTUNIFORM_I3 PICA__VS_INT3
|
||||
nop, // 0x2b5
|
||||
nop, // 0x2b6
|
||||
nop, // 0x2b7
|
||||
nop, // 0x2b8
|
||||
nop, // 0x2b9 VSH_INPUTBUFFER_CONFIG PICA__VS_ATTR_NUM0
|
||||
nop, // 0x2ba VSH_ENTRYPOINT PICA__VS_START_ADDR
|
||||
nop, // 0x2bb VSH_ATTRIBUTES_PERMUTATION_LOW PICA__VS_ATTR_IN__MAP0
|
||||
nop, // 0x2bc VSH_ATTRIBUTES_PERMUTATION_HIGH PICA__VS_ATTR_IN__MAP1
|
||||
nop, // 0x2bd VSH_OUTMAP_MASK PICA__VS_OUT__MASK
|
||||
nop, // 0x2be
|
||||
nop, // 0x2bf VSH_CODETRANSFER_END PICA__VS_PROG_RENEWAL_END
|
||||
nop, // 0x2c0 VSH_FLOATUNIFORM_INDEX PICA__VS_FLOAT_ADDR
|
||||
UniformFloatVs, // 0x2c1 VSH_FLOATUNIFORM_DATA0 PICA__VS_FLOAT_DATA0
|
||||
UniformFloatVs, // 0x2c2 VSH_FLOATUNIFORM_DATA1 PICA__VS_FLOAT_DATA1
|
||||
UniformFloatVs, // 0x2c3 VSH_FLOATUNIFORM_DATA2 PICA__VS_FLOAT_DATA2
|
||||
UniformFloatVs, // 0x2c4 VSH_FLOATUNIFORM_DATA3 PICA__VS_FLOAT_DATA3
|
||||
UniformFloatVs, // 0x2c5 VSH_FLOATUNIFORM_DATA4 PICA__VS_FLOAT_DATA4
|
||||
UniformFloatVs, // 0x2c6 VSH_FLOATUNIFORM_DATA5 PICA__VS_FLOAT_DATA5
|
||||
UniformFloatVs, // 0x2c7 VSH_FLOATUNIFORM_DATA6 PICA__VS_FLOAT_DATA6
|
||||
UniformFloatVs, // 0x2c8 VSH_FLOATUNIFORM_DATA7 PICA__VS_FLOAT_DATA7
|
||||
nop, // 0x2c9
|
||||
nop, // 0x2ca
|
||||
nop, // 0x2cb VSH_CODETRANSFER_INDEX PICA__VS_PROG_ADDR
|
||||
SetWordVs, // 0x2cc VSH_CODETRANSFER_DATA0 PICA__VS_PROG_DATA0
|
||||
SetWordVs, // 0x2cd VSH_CODETRANSFER_DATA1 PICA__VS_PROG_DATA1
|
||||
SetWordVs, // 0x2ce VSH_CODETRANSFER_DATA2 PICA__VS_PROG_DATA2
|
||||
SetWordVs, // 0x2cf VSH_CODETRANSFER_DATA3 PICA__VS_PROG_DATA3
|
||||
SetWordVs, // 0x2d0 VSH_CODETRANSFER_DATA4 PICA__VS_PROG_DATA4
|
||||
SetWordVs, // 0x2d1 VSH_CODETRANSFER_DATA5 PICA__VS_PROG_DATA5
|
||||
SetWordVs, // 0x2d2 VSH_CODETRANSFER_DATA6 PICA__VS_PROG_DATA6
|
||||
SetWordVs, // 0x2d3 VSH_CODETRANSFER_DATA7 PICA__VS_PROG_DATA7
|
||||
nop, // 0x2d4
|
||||
nop, // 0x2d5 VSH_OPDESCS_INDEX PICA__VS_PROG_SWIZZLE_ADDR
|
||||
SetWordSwizzleVs, // 0x2d6 VSH_OPDESCS_DATA0 PICA__VS_PROG_SWIZZLE_DATA0
|
||||
SetWordSwizzleVs, // 0x2d7 VSH_OPDESCS_DATA1 PICA__VS_PROG_SWIZZLE_DATA1
|
||||
SetWordSwizzleVs, // 0x2d8 VSH_OPDESCS_DATA2 PICA__VS_PROG_SWIZZLE_DATA2
|
||||
SetWordSwizzleVs, // 0x2d9 VSH_OPDESCS_DATA3 PICA__VS_PROG_SWIZZLE_DATA3
|
||||
SetWordSwizzleVs, // 0x2da VSH_OPDESCS_DATA4 PICA__VS_PROG_SWIZZLE_DATA4
|
||||
SetWordSwizzleVs, // 0x2db VSH_OPDESCS_DATA5 PICA__VS_PROG_SWIZZLE_DATA5
|
||||
SetWordSwizzleVs, // 0x2dc VSH_OPDESCS_DATA6 PICA__VS_PROG_SWIZZLE_DATA6
|
||||
SetWordSwizzleVs, // 0x2dd VSH_OPDESCS_DATA7 PICA__VS_PROG_SWIZZLE_DATA7
|
||||
nop, // 0x2de
|
||||
nop, // 0x2df
|
||||
nop, // 0x2e0
|
||||
nop, // 0x2e1
|
||||
nop, // 0x2e2
|
||||
nop, // 0x2e3
|
||||
nop, // 0x2e4
|
||||
nop, // 0x2e5
|
||||
nop, // 0x2e6
|
||||
nop, // 0x2e7
|
||||
nop, // 0x2e8
|
||||
nop, // 0x2e9
|
||||
nop, // 0x2ea
|
||||
nop, // 0x2eb
|
||||
nop, // 0x2ec
|
||||
nop, // 0x2ed
|
||||
nop, // 0x2ee
|
||||
nop, // 0x2ef
|
||||
nop, // 0x2f0
|
||||
nop, // 0x2f1
|
||||
nop, // 0x2f2
|
||||
nop, // 0x2f3
|
||||
nop, // 0x2f4
|
||||
nop, // 0x2f5
|
||||
nop, // 0x2f6
|
||||
nop, // 0x2f7
|
||||
nop, // 0x2f8
|
||||
nop, // 0x2f9
|
||||
nop, // 0x2fa
|
||||
nop, // 0x2fb
|
||||
nop, // 0x2fc
|
||||
nop, // 0x2fd
|
||||
nop, // 0x2fe
|
||||
nop // 0x2ff
|
||||
};
|
||||
|
||||
} // namespace CommandProcessor
|
||||
} // namespace Pica
|
@ -14,6 +14,7 @@
|
||||
#include "core/hw/gpu.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/tracer/recorder.h"
|
||||
#include "video_core/command_map.h"
|
||||
#include "video_core/command_processor.h"
|
||||
#include "video_core/debug_utils/debug_utils.h"
|
||||
#include "video_core/pica_state.h"
|
||||
@ -47,6 +48,12 @@ static const u32 expand_bits_to_bytes[] = {
|
||||
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
|
||||
};
|
||||
|
||||
struct Command {
|
||||
const u32 ID;
|
||||
const u32 Value;
|
||||
const u32 Mask;
|
||||
};
|
||||
|
||||
MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240));
|
||||
|
||||
static const char* GetShaderSetupTypeName(Shader::ShaderSetup& setup) {
|
||||
@ -119,495 +126,403 @@ static void WriteUniformFloatReg(ShaderRegs& config, Shader::ShaderSetup& setup,
|
||||
}
|
||||
}
|
||||
|
||||
static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
||||
auto& regs = g_state.regs;
|
||||
static void TriggerIRQ(const Command&) {
|
||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::P3D);
|
||||
}
|
||||
|
||||
if (id >= Regs::NUM_REGS) {
|
||||
LOG_ERROR(HW_GPU,
|
||||
"Commandlist tried to write to invalid register 0x%03X (value: %08X, mask: %X)",
|
||||
id, value, mask);
|
||||
return;
|
||||
}
|
||||
static void TriangleTopology(const Command&) {
|
||||
g_state.primitive_assembler.Reconfigure(g_state.regs.pipeline.triangle_topology);
|
||||
}
|
||||
|
||||
// TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
|
||||
u32 old_value = regs.reg_array[id];
|
||||
static void RestartPrimitive(const Command&) {
|
||||
g_state.primitive_assembler.Reset();
|
||||
}
|
||||
|
||||
const u32 write_mask = expand_bits_to_bytes[mask];
|
||||
static void DefaultAttributes(const Command&) {
|
||||
g_state.immediate.current_attribute = 0;
|
||||
g_state.immediate.reset_geometry_pipeline = true;
|
||||
default_attr_counter = 0;
|
||||
}
|
||||
|
||||
regs.reg_array[id] = (old_value & ~write_mask) | (value & write_mask);
|
||||
|
||||
// Double check for is_pica_tracing to avoid call overhead
|
||||
if (DebugUtils::IsPicaTracing()) {
|
||||
DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs.reg_array[id]});
|
||||
}
|
||||
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded,
|
||||
reinterpret_cast<void*>(&id));
|
||||
|
||||
switch (id) {
|
||||
// Trigger IRQ
|
||||
case PICA_REG_INDEX(trigger_irq):
|
||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::P3D);
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX(pipeline.triangle_topology):
|
||||
g_state.primitive_assembler.Reconfigure(regs.pipeline.triangle_topology);
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX(pipeline.restart_primitive):
|
||||
g_state.primitive_assembler.Reset();
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX(pipeline.vs_default_attributes_setup.index):
|
||||
g_state.immediate.current_attribute = 0;
|
||||
g_state.immediate.reset_geometry_pipeline = true;
|
||||
default_attr_counter = 0;
|
||||
break;
|
||||
|
||||
// Load default vertex input attributes
|
||||
case PICA_REG_INDEX_WORKAROUND(pipeline.vs_default_attributes_setup.set_value[0], 0x233):
|
||||
case PICA_REG_INDEX_WORKAROUND(pipeline.vs_default_attributes_setup.set_value[1], 0x234):
|
||||
case PICA_REG_INDEX_WORKAROUND(pipeline.vs_default_attributes_setup.set_value[2], 0x235): {
|
||||
// TODO: Does actual hardware indeed keep an intermediate buffer or does
|
||||
// it directly write the values?
|
||||
default_attr_write_buffer[default_attr_counter++] = value;
|
||||
|
||||
// Default attributes are written in a packed format such that four float24 values are
|
||||
// encoded in
|
||||
// three 32-bit numbers. We write to internal memory once a full such vector is
|
||||
// written.
|
||||
if (default_attr_counter >= 3) {
|
||||
default_attr_counter = 0;
|
||||
|
||||
auto& setup = regs.pipeline.vs_default_attributes_setup;
|
||||
|
||||
if (setup.index >= 16) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index);
|
||||
break;
|
||||
}
|
||||
|
||||
Math::Vec4<float24> attribute;
|
||||
|
||||
// NOTE: The destination component order indeed is "backwards"
|
||||
attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
|
||||
attribute.z = float24::FromRaw(((default_attr_write_buffer[0] & 0xFF) << 16) |
|
||||
((default_attr_write_buffer[1] >> 16) & 0xFFFF));
|
||||
attribute.y = float24::FromRaw(((default_attr_write_buffer[1] & 0xFFFF) << 8) |
|
||||
((default_attr_write_buffer[2] >> 24) & 0xFF));
|
||||
attribute.x = float24::FromRaw(default_attr_write_buffer[2] & 0xFFFFFF);
|
||||
|
||||
LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index,
|
||||
attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(),
|
||||
attribute.w.ToFloat32());
|
||||
|
||||
// TODO: Verify that this actually modifies the register!
|
||||
if (setup.index < 15) {
|
||||
g_state.input_default_attributes.attr[setup.index] = attribute;
|
||||
setup.index++;
|
||||
} else {
|
||||
// Put each attribute into an immediate input buffer. When all specified immediate
|
||||
// attributes are present, the Vertex Shader is invoked and everything is sent to
|
||||
// the primitive assembler.
|
||||
|
||||
auto& immediate_input = g_state.immediate.input_vertex;
|
||||
auto& immediate_attribute_id = g_state.immediate.current_attribute;
|
||||
|
||||
immediate_input.attr[immediate_attribute_id] = attribute;
|
||||
|
||||
if (immediate_attribute_id < regs.pipeline.max_input_attrib_index) {
|
||||
immediate_attribute_id += 1;
|
||||
} else {
|
||||
MICROPROFILE_SCOPE(GPU_Drawing);
|
||||
immediate_attribute_id = 0;
|
||||
|
||||
auto* shader_engine = Shader::GetEngine();
|
||||
shader_engine->SetupBatch(g_state.vs, regs.vs.main_offset);
|
||||
|
||||
// Send to vertex shader
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
|
||||
static_cast<void*>(&immediate_input));
|
||||
Shader::UnitState shader_unit;
|
||||
Shader::AttributeBuffer output{};
|
||||
|
||||
shader_unit.LoadInput(regs.vs, immediate_input);
|
||||
shader_engine->Run(g_state.vs, shader_unit);
|
||||
shader_unit.WriteOutput(regs.vs, output);
|
||||
|
||||
// Send to geometry pipeline
|
||||
if (g_state.immediate.reset_geometry_pipeline) {
|
||||
g_state.geometry_pipeline.Reconfigure();
|
||||
g_state.immediate.reset_geometry_pipeline = false;
|
||||
}
|
||||
ASSERT(!g_state.geometry_pipeline.NeedIndexInput());
|
||||
g_state.geometry_pipeline.Setup(shader_engine);
|
||||
g_state.geometry_pipeline.SubmitVertex(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX(pipeline.gpu_mode):
|
||||
if (regs.pipeline.gpu_mode == PipelineRegs::GPUMode::Configuring) {
|
||||
MICROPROFILE_SCOPE(GPU_Drawing);
|
||||
|
||||
// Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring
|
||||
VideoCore::g_renderer->Rasterizer()->DrawTriangles();
|
||||
|
||||
if (g_debug_context) {
|
||||
g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(pipeline.command_buffer.trigger[0], 0x23c):
|
||||
case PICA_REG_INDEX_WORKAROUND(pipeline.command_buffer.trigger[1], 0x23d): {
|
||||
unsigned index =
|
||||
static_cast<unsigned>(id - PICA_REG_INDEX(pipeline.command_buffer.trigger[0]));
|
||||
u32* head_ptr = (u32*)Memory::GetPhysicalPointer(
|
||||
regs.pipeline.command_buffer.GetPhysicalAddress(index));
|
||||
g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr;
|
||||
g_state.cmd_list.length = regs.pipeline.command_buffer.GetSize(index) / sizeof(u32);
|
||||
break;
|
||||
}
|
||||
|
||||
// It seems like these trigger vertex rendering
|
||||
case PICA_REG_INDEX(pipeline.trigger_draw):
|
||||
case PICA_REG_INDEX(pipeline.trigger_draw_indexed): {
|
||||
static void GpuMode(const Command&) {
|
||||
if (g_state.regs.pipeline.gpu_mode == PipelineRegs::GPUMode::Configuring) {
|
||||
MICROPROFILE_SCOPE(GPU_Drawing);
|
||||
|
||||
// Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring
|
||||
VideoCore::g_renderer->Rasterizer()->DrawTriangles();
|
||||
|
||||
if (g_debug_context) {
|
||||
g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TriggerCommandBuffer(const Command& cmd) {
|
||||
unsigned index =
|
||||
static_cast<unsigned>(cmd.ID - PICA_REG_INDEX(pipeline.command_buffer.trigger[0]));
|
||||
u32* head_ptr = (u32*)Memory::GetPhysicalPointer(
|
||||
g_state.regs.pipeline.command_buffer.GetPhysicalAddress(index));
|
||||
g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr;
|
||||
g_state.cmd_list.length = g_state.regs.pipeline.command_buffer.GetSize(index) / sizeof(u32);
|
||||
}
|
||||
|
||||
static void TriggerDraw(const Command& cmd) {
|
||||
MICROPROFILE_SCOPE(GPU_Drawing);
|
||||
|
||||
#if PICA_LOG_TEV
|
||||
DebugUtils::DumpTevStageConfig(regs.GetTevStages());
|
||||
DebugUtils::DumpTevStageConfig(regs.GetTevStages());
|
||||
#endif
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
|
||||
|
||||
// Processes information about internal vertex attributes to figure out how a vertex is
|
||||
// loaded.
|
||||
// Later, these can be compiled and cached.
|
||||
const u32 base_address = regs.pipeline.vertex_attributes.GetPhysicalBaseAddress();
|
||||
VertexLoader loader(regs.pipeline);
|
||||
// Processes information about internal vertex attributes to figure out how a vertex is
|
||||
// loaded.
|
||||
// Later, these can be compiled and cached.
|
||||
const u32 base_address = g_state.regs.pipeline.vertex_attributes.GetPhysicalBaseAddress();
|
||||
VertexLoader loader(g_state.regs.pipeline);
|
||||
|
||||
// Load vertices
|
||||
bool is_indexed = (id == PICA_REG_INDEX(pipeline.trigger_draw_indexed));
|
||||
// Load vertices
|
||||
bool is_indexed = (cmd.ID == PICA_REG_INDEX(pipeline.trigger_draw_indexed));
|
||||
|
||||
const auto& index_info = regs.pipeline.index_array;
|
||||
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
|
||||
const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
|
||||
bool index_u16 = index_info.format != 0;
|
||||
const auto& index_info = g_state.regs.pipeline.index_array;
|
||||
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
|
||||
const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
|
||||
bool index_u16 = index_info.format != 0;
|
||||
|
||||
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
|
||||
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
|
||||
|
||||
if (g_debug_context && g_debug_context->recorder) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const auto texture = regs.texturing.GetTextures()[i];
|
||||
if (!texture.enabled)
|
||||
continue;
|
||||
if (g_debug_context && g_debug_context->recorder) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const auto texture = g_state.regs.texturing.GetTextures()[i];
|
||||
if (!texture.enabled)
|
||||
continue;
|
||||
|
||||
u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress());
|
||||
g_debug_context->recorder->MemoryAccessed(
|
||||
texture_data, Pica::TexturingRegs::NibblesPerPixel(texture.format) *
|
||||
texture.config.width / 2 * texture.config.height,
|
||||
texture.config.GetPhysicalAddress());
|
||||
u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress());
|
||||
g_debug_context->recorder->MemoryAccessed(
|
||||
texture_data, Pica::TexturingRegs::NibblesPerPixel(texture.format) *
|
||||
texture.config.width / 2 * texture.config.height,
|
||||
texture.config.GetPhysicalAddress());
|
||||
}
|
||||
}
|
||||
|
||||
DebugUtils::MemoryAccessTracker memory_accesses;
|
||||
|
||||
// Simple circular-replacement vertex cache
|
||||
// The size has been tuned for optimal balance between hit-rate and the cost of lookup
|
||||
const size_t VERTEX_CACHE_SIZE = 32;
|
||||
std::array<u16, VERTEX_CACHE_SIZE> vertex_cache_ids;
|
||||
std::array<Shader::AttributeBuffer, VERTEX_CACHE_SIZE> vertex_cache;
|
||||
Shader::AttributeBuffer vs_output;
|
||||
|
||||
unsigned int vertex_cache_pos = 0;
|
||||
vertex_cache_ids.fill(-1);
|
||||
|
||||
auto* shader_engine = Shader::GetEngine();
|
||||
Shader::UnitState shader_unit;
|
||||
|
||||
shader_engine->SetupBatch(g_state.vs, g_state.regs.vs.main_offset);
|
||||
|
||||
g_state.geometry_pipeline.Reconfigure();
|
||||
g_state.geometry_pipeline.Setup(shader_engine);
|
||||
if (g_state.geometry_pipeline.NeedIndexInput())
|
||||
ASSERT(is_indexed);
|
||||
|
||||
for (unsigned int index = 0; index < g_state.regs.pipeline.num_vertices; ++index) {
|
||||
// Indexed rendering doesn't use the start offset
|
||||
unsigned int vertex = is_indexed
|
||||
? (index_u16 ? index_address_16[index] : index_address_8[index])
|
||||
: (index + g_state.regs.pipeline.vertex_offset);
|
||||
|
||||
// -1 is a common special value used for primitive restart. Since it's unknown if
|
||||
// the PICA supports it, and it would mess up the caching, guard against it here.
|
||||
ASSERT(vertex != -1);
|
||||
|
||||
bool vertex_cache_hit = false;
|
||||
|
||||
if (is_indexed) {
|
||||
if (g_state.geometry_pipeline.NeedIndexInput()) {
|
||||
g_state.geometry_pipeline.SubmitIndex(vertex);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_debug_context && Pica::g_debug_context->recorder) {
|
||||
int size = index_u16 ? 2 : 1;
|
||||
memory_accesses.AddAccess(base_address + index_info.offset + size * index, size);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < VERTEX_CACHE_SIZE; ++i) {
|
||||
if (vertex == vertex_cache_ids[i]) {
|
||||
vs_output = vertex_cache[i];
|
||||
vertex_cache_hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugUtils::MemoryAccessTracker memory_accesses;
|
||||
if (!vertex_cache_hit) {
|
||||
// Initialize data for the current vertex
|
||||
Shader::AttributeBuffer input;
|
||||
loader.LoadVertex(base_address, index, vertex, input, memory_accesses);
|
||||
|
||||
// Simple circular-replacement vertex cache
|
||||
// The size has been tuned for optimal balance between hit-rate and the cost of lookup
|
||||
const size_t VERTEX_CACHE_SIZE = 32;
|
||||
std::array<u16, VERTEX_CACHE_SIZE> vertex_cache_ids;
|
||||
std::array<Shader::AttributeBuffer, VERTEX_CACHE_SIZE> vertex_cache;
|
||||
Shader::AttributeBuffer vs_output;
|
||||
|
||||
unsigned int vertex_cache_pos = 0;
|
||||
vertex_cache_ids.fill(-1);
|
||||
|
||||
auto* shader_engine = Shader::GetEngine();
|
||||
Shader::UnitState shader_unit;
|
||||
|
||||
shader_engine->SetupBatch(g_state.vs, regs.vs.main_offset);
|
||||
|
||||
g_state.geometry_pipeline.Reconfigure();
|
||||
g_state.geometry_pipeline.Setup(shader_engine);
|
||||
if (g_state.geometry_pipeline.NeedIndexInput())
|
||||
ASSERT(is_indexed);
|
||||
|
||||
for (unsigned int index = 0; index < regs.pipeline.num_vertices; ++index) {
|
||||
// Indexed rendering doesn't use the start offset
|
||||
unsigned int vertex =
|
||||
is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index])
|
||||
: (index + regs.pipeline.vertex_offset);
|
||||
|
||||
// -1 is a common special value used for primitive restart. Since it's unknown if
|
||||
// the PICA supports it, and it would mess up the caching, guard against it here.
|
||||
ASSERT(vertex != -1);
|
||||
|
||||
bool vertex_cache_hit = false;
|
||||
// Send to vertex shader
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
|
||||
(void*)&input);
|
||||
shader_unit.LoadInput(g_state.regs.vs, input);
|
||||
shader_engine->Run(g_state.vs, shader_unit);
|
||||
shader_unit.WriteOutput(g_state.regs.vs, vs_output);
|
||||
|
||||
if (is_indexed) {
|
||||
if (g_state.geometry_pipeline.NeedIndexInput()) {
|
||||
g_state.geometry_pipeline.SubmitIndex(vertex);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_debug_context && Pica::g_debug_context->recorder) {
|
||||
int size = index_u16 ? 2 : 1;
|
||||
memory_accesses.AddAccess(base_address + index_info.offset + size * index,
|
||||
size);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < VERTEX_CACHE_SIZE; ++i) {
|
||||
if (vertex == vertex_cache_ids[i]) {
|
||||
vs_output = vertex_cache[i];
|
||||
vertex_cache_hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vertex_cache[vertex_cache_pos] = vs_output;
|
||||
vertex_cache_ids[vertex_cache_pos] = vertex;
|
||||
vertex_cache_pos = (vertex_cache_pos + 1) % VERTEX_CACHE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vertex_cache_hit) {
|
||||
// Initialize data for the current vertex
|
||||
Shader::AttributeBuffer input;
|
||||
loader.LoadVertex(base_address, index, vertex, input, memory_accesses);
|
||||
// Send to geometry pipeline
|
||||
g_state.geometry_pipeline.SubmitVertex(vs_output);
|
||||
}
|
||||
|
||||
for (auto& range : memory_accesses.ranges) {
|
||||
g_debug_context->recorder->MemoryAccessed(Memory::GetPhysicalPointer(range.first),
|
||||
range.second, range.first);
|
||||
}
|
||||
}
|
||||
|
||||
static void DefaultAttribSetup(const Command& cmd) {
|
||||
// TODO: Does actual hardware indeed keep an intermediate buffer or does
|
||||
// it directly write the values?
|
||||
default_attr_write_buffer[default_attr_counter++] = cmd.Value;
|
||||
|
||||
// Default attributes are written in a packed format such that four float24 values are
|
||||
// encoded in
|
||||
// three 32-bit numbers. We write to internal memory once a full such vector is
|
||||
// written.
|
||||
if (default_attr_counter >= 3) {
|
||||
default_attr_counter = 0;
|
||||
|
||||
auto& setup = g_state.regs.pipeline.vs_default_attributes_setup;
|
||||
|
||||
if (setup.index >= 16) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index);
|
||||
return;
|
||||
}
|
||||
|
||||
Math::Vec4<float24> attribute;
|
||||
|
||||
// NOTE: The destination component order indeed is "backwards"
|
||||
attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8);
|
||||
attribute.z = float24::FromRaw(((default_attr_write_buffer[0] & 0xFF) << 16) |
|
||||
((default_attr_write_buffer[1] >> 16) & 0xFFFF));
|
||||
attribute.y = float24::FromRaw(((default_attr_write_buffer[1] & 0xFFFF) << 8) |
|
||||
((default_attr_write_buffer[2] >> 24) & 0xFF));
|
||||
attribute.x = float24::FromRaw(default_attr_write_buffer[2] & 0xFFFFFF);
|
||||
|
||||
LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index,
|
||||
attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(),
|
||||
attribute.w.ToFloat32());
|
||||
|
||||
// TODO: Verify that this actually modifies the register!
|
||||
if (setup.index < 15) {
|
||||
g_state.input_default_attributes.attr[setup.index] = attribute;
|
||||
setup.index++;
|
||||
} else {
|
||||
// Put each attribute into an immediate input buffer. When all specified immediate
|
||||
// attributes are present, the Vertex Shader is invoked and everything is sent to
|
||||
// the primitive assembler.
|
||||
|
||||
auto& immediate_input = g_state.immediate.input_vertex;
|
||||
auto& immediate_attribute_id = g_state.immediate.current_attribute;
|
||||
|
||||
immediate_input.attr[immediate_attribute_id] = attribute;
|
||||
|
||||
if (immediate_attribute_id < g_state.regs.pipeline.max_input_attrib_index) {
|
||||
immediate_attribute_id += 1;
|
||||
} else {
|
||||
MICROPROFILE_SCOPE(GPU_Drawing);
|
||||
immediate_attribute_id = 0;
|
||||
|
||||
auto* shader_engine = Shader::GetEngine();
|
||||
shader_engine->SetupBatch(g_state.vs, g_state.regs.vs.main_offset);
|
||||
|
||||
// Send to vertex shader
|
||||
if (g_debug_context)
|
||||
g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
|
||||
(void*)&input);
|
||||
shader_unit.LoadInput(regs.vs, input);
|
||||
static_cast<void*>(&immediate_input));
|
||||
Shader::UnitState shader_unit;
|
||||
Shader::AttributeBuffer output{};
|
||||
|
||||
shader_unit.LoadInput(g_state.regs.vs, immediate_input);
|
||||
shader_engine->Run(g_state.vs, shader_unit);
|
||||
shader_unit.WriteOutput(regs.vs, vs_output);
|
||||
shader_unit.WriteOutput(g_state.regs.vs, output);
|
||||
|
||||
if (is_indexed) {
|
||||
vertex_cache[vertex_cache_pos] = vs_output;
|
||||
vertex_cache_ids[vertex_cache_pos] = vertex;
|
||||
vertex_cache_pos = (vertex_cache_pos + 1) % VERTEX_CACHE_SIZE;
|
||||
// Send to geometry pipeline
|
||||
if (g_state.immediate.reset_geometry_pipeline) {
|
||||
g_state.geometry_pipeline.Reconfigure();
|
||||
g_state.immediate.reset_geometry_pipeline = false;
|
||||
}
|
||||
ASSERT(!g_state.geometry_pipeline.NeedIndexInput());
|
||||
g_state.geometry_pipeline.Setup(shader_engine);
|
||||
g_state.geometry_pipeline.SubmitVertex(output);
|
||||
}
|
||||
|
||||
// Send to geometry pipeline
|
||||
g_state.geometry_pipeline.SubmitVertex(vs_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& range : memory_accesses.ranges) {
|
||||
g_debug_context->recorder->MemoryAccessed(Memory::GetPhysicalPointer(range.first),
|
||||
range.second, range.first);
|
||||
static void UniformBoolGs(const Command&) {
|
||||
WriteUniformBoolReg(g_state.gs, g_state.regs.gs.bool_uniforms.Value());
|
||||
}
|
||||
|
||||
static void UniformBoolVs(const Command&) {
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value());
|
||||
}
|
||||
|
||||
static void UniformIntGs(const Command& cmd) {
|
||||
unsigned index = (cmd.ID - PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[0], 0x281));
|
||||
auto values = g_state.regs.gs.int_uniforms[index];
|
||||
WriteUniformIntReg(g_state.gs, index, Math::Vec4<u8>(values.x, values.y, values.z, values.w));
|
||||
}
|
||||
|
||||
static void UniformIntVs(const Command& cmd) {
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
unsigned index = (cmd.ID - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
|
||||
auto values = g_state.regs.vs.int_uniforms[index];
|
||||
WriteUniformIntReg(g_state.vs, index, Math::Vec4<u8>(values.x, values.y, values.z, values.w));
|
||||
}
|
||||
|
||||
static void UniformFloatGs(const Command& cmd) {
|
||||
WriteUniformFloatReg(g_state.regs.gs, g_state.gs, gs_float_regs_counter,
|
||||
gs_uniform_write_buffer, cmd.Value);
|
||||
}
|
||||
|
||||
static void UniformFloatVs(const Command& cmd) {
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter,
|
||||
vs_uniform_write_buffer, cmd.Value);
|
||||
}
|
||||
|
||||
static void SetWordGs(const Command& cmd) {
|
||||
u32& offset = g_state.regs.gs.program.offset;
|
||||
if (offset >= 4096) {
|
||||
LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
|
||||
} else {
|
||||
g_state.gs.program_code[offset] = cmd.Value;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetWordVs(const Command& cmd) {
|
||||
u32& offset = g_state.regs.vs.program.offset;
|
||||
if (offset >= 512) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
|
||||
} else {
|
||||
g_state.vs.program_code[offset] = cmd.Value;
|
||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||
g_state.gs.program_code[offset] = cmd.Value;
|
||||
}
|
||||
|
||||
break;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX(gs.bool_uniforms):
|
||||
WriteUniformBoolReg(g_state.gs, g_state.regs.gs.bool_uniforms.Value());
|
||||
break;
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[0], 0x281):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[1], 0x282):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[2], 0x283):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[3], 0x284): {
|
||||
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(gs.int_uniforms[0], 0x281));
|
||||
auto values = regs.gs.int_uniforms[index];
|
||||
WriteUniformIntReg(g_state.gs, index,
|
||||
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
|
||||
break;
|
||||
static void SetWordSwizzleGs(const Command& cmd) {
|
||||
u32& offset = g_state.regs.gs.swizzle_patterns.offset;
|
||||
if (offset >= g_state.gs.swizzle_data.size()) {
|
||||
LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset);
|
||||
} else {
|
||||
g_state.gs.swizzle_data[offset] = cmd.Value;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[0], 0x291):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[1], 0x292):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[2], 0x293):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[3], 0x294):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[4], 0x295):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[5], 0x296):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[6], 0x297):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.uniform_setup.set_value[7], 0x298): {
|
||||
WriteUniformFloatReg(g_state.regs.gs, g_state.gs, gs_float_regs_counter,
|
||||
gs_uniform_write_buffer, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[0], 0x29c):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[1], 0x29d):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[2], 0x29e):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[3], 0x29f):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[4], 0x2a0):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[5], 0x2a1):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[6], 0x2a2):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[7], 0x2a3): {
|
||||
u32& offset = g_state.regs.gs.program.offset;
|
||||
if (offset >= 4096) {
|
||||
LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
|
||||
} else {
|
||||
g_state.gs.program_code[offset] = value;
|
||||
offset++;
|
||||
static void SetWordSwizzleVs(const Command& cmd) {
|
||||
u32& offset = g_state.regs.vs.swizzle_patterns.offset;
|
||||
if (offset >= g_state.vs.swizzle_data.size()) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset);
|
||||
} else {
|
||||
g_state.vs.swizzle_data[offset] = cmd.Value;
|
||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||
g_state.gs.swizzle_data[offset] = cmd.Value;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
static void LightingLut(const Command& cmd) {
|
||||
auto& lut_config = g_state.regs.lighting.lut_config;
|
||||
|
||||
ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!");
|
||||
|
||||
g_state.lighting.luts[lut_config.type][lut_config.index].raw = cmd.Value;
|
||||
lut_config.index.Assign(lut_config.index + 1);
|
||||
}
|
||||
|
||||
static void FogLut(const Command& cmd) {
|
||||
g_state.fog.lut[g_state.regs.texturing.fog_lut_offset % 128].raw = cmd.Value;
|
||||
g_state.regs.texturing.fog_lut_offset.Assign(g_state.regs.texturing.fog_lut_offset + 1);
|
||||
}
|
||||
|
||||
static void ProcTexLut(const Command& cmd) {
|
||||
auto& index = g_state.regs.texturing.proctex_lut_config.index;
|
||||
auto& pt = g_state.proctex;
|
||||
|
||||
switch (g_state.regs.texturing.proctex_lut_config.ref_table.Value()) {
|
||||
case TexturingRegs::ProcTexLutTable::Noise:
|
||||
pt.noise_table[index % pt.noise_table.size()].raw = cmd.Value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::ColorMap:
|
||||
pt.color_map_table[index % pt.color_map_table.size()].raw = cmd.Value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::AlphaMap:
|
||||
pt.alpha_map_table[index % pt.alpha_map_table.size()].raw = cmd.Value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::Color:
|
||||
pt.color_table[index % pt.color_table.size()].raw = cmd.Value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::ColorDiff:
|
||||
pt.color_diff_table[index % pt.color_diff_table.size()].raw = cmd.Value;
|
||||
break;
|
||||
}
|
||||
index.Assign(index + 1);
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[0], 0x2a6):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[1], 0x2a7):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[2], 0x2a8):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[3], 0x2a9):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[4], 0x2aa):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[5], 0x2ab):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[6], 0x2ac):
|
||||
case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[7], 0x2ad): {
|
||||
u32& offset = g_state.regs.gs.swizzle_patterns.offset;
|
||||
if (offset >= g_state.gs.swizzle_data.size()) {
|
||||
LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset);
|
||||
} else {
|
||||
g_state.gs.swizzle_data[offset] = value;
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
static void WritePicaReg(const Command& cmd) {
|
||||
auto& regs = g_state.regs;
|
||||
|
||||
if (cmd.ID >= Regs::NUM_REGS) {
|
||||
LOG_ERROR(HW_GPU,
|
||||
"Commandlist tried to write to invalid register 0x%03X (value: %08X, mask: %X)",
|
||||
cmd.ID, cmd.Value, cmd.Mask);
|
||||
return;
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX(vs.bool_uniforms):
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value());
|
||||
break;
|
||||
// TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
|
||||
u32 old_value = regs.reg_array[cmd.ID];
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): {
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
|
||||
auto values = regs.vs.int_uniforms[index];
|
||||
WriteUniformIntReg(g_state.vs, index,
|
||||
Math::Vec4<u8>(values.x, values.y, values.z, values.w));
|
||||
break;
|
||||
const u32 write_mask = expand_bits_to_bytes[cmd.Mask];
|
||||
|
||||
regs.reg_array[cmd.ID] = (old_value & ~write_mask) | (cmd.Value & write_mask);
|
||||
|
||||
// Double check for is_pica_tracing to avoid call overhead
|
||||
if (DebugUtils::IsPicaTracing()) {
|
||||
DebugUtils::OnPicaRegWrite({(u16)cmd.ID, (u16)cmd.Mask, regs.reg_array[cmd.ID]});
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[0], 0x2c1):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[1], 0x2c2):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[2], 0x2c3):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[3], 0x2c4):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[4], 0x2c5):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): {
|
||||
// TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
|
||||
WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter,
|
||||
vs_uniform_write_buffer, value);
|
||||
break;
|
||||
if (g_debug_context) {
|
||||
auto id = cmd.ID;
|
||||
g_debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded,
|
||||
reinterpret_cast<void*>(&id));
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[0], 0x2cc):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[1], 0x2cd):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[2], 0x2ce):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[3], 0x2cf):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[4], 0x2d0):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): {
|
||||
u32& offset = g_state.regs.vs.program.offset;
|
||||
if (offset >= 512) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
|
||||
} else {
|
||||
g_state.vs.program_code[offset] = value;
|
||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||
g_state.gs.program_code[offset] = value;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CommandMap[cmd.ID](cmd);
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[0], 0x2d6):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[1], 0x2d7):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[2], 0x2d8):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[3], 0x2d9):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[4], 0x2da):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc):
|
||||
case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): {
|
||||
u32& offset = g_state.regs.vs.swizzle_patterns.offset;
|
||||
if (offset >= g_state.vs.swizzle_data.size()) {
|
||||
LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset);
|
||||
} else {
|
||||
g_state.vs.swizzle_data[offset] = value;
|
||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||
g_state.gs.swizzle_data[offset] = value;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
VideoCore::g_renderer->Rasterizer()->NotifyPicaRegisterChanged(cmd.ID);
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce):
|
||||
case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): {
|
||||
auto& lut_config = regs.lighting.lut_config;
|
||||
|
||||
ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!");
|
||||
|
||||
g_state.lighting.luts[lut_config.type][lut_config.index].raw = value;
|
||||
lut_config.index.Assign(lut_config.index + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[0], 0xe8):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[1], 0xe9):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[2], 0xea):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[3], 0xeb):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[4], 0xec):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[5], 0xed):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[6], 0xee):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[7], 0xef): {
|
||||
g_state.fog.lut[regs.texturing.fog_lut_offset % 128].raw = value;
|
||||
regs.texturing.fog_lut_offset.Assign(regs.texturing.fog_lut_offset + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[0], 0xb0):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[1], 0xb1):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[2], 0xb2):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[3], 0xb3):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[4], 0xb4):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[5], 0xb5):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[6], 0xb6):
|
||||
case PICA_REG_INDEX_WORKAROUND(texturing.proctex_lut_data[7], 0xb7): {
|
||||
auto& index = regs.texturing.proctex_lut_config.index;
|
||||
auto& pt = g_state.proctex;
|
||||
|
||||
switch (regs.texturing.proctex_lut_config.ref_table.Value()) {
|
||||
case TexturingRegs::ProcTexLutTable::Noise:
|
||||
pt.noise_table[index % pt.noise_table.size()].raw = value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::ColorMap:
|
||||
pt.color_map_table[index % pt.color_map_table.size()].raw = value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::AlphaMap:
|
||||
pt.alpha_map_table[index % pt.alpha_map_table.size()].raw = value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::Color:
|
||||
pt.color_table[index % pt.color_table.size()].raw = value;
|
||||
break;
|
||||
case TexturingRegs::ProcTexLutTable::ColorDiff:
|
||||
pt.color_diff_table[index % pt.color_diff_table.size()].raw = value;
|
||||
break;
|
||||
}
|
||||
index.Assign(index + 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VideoCore::g_renderer->Rasterizer()->NotifyPicaRegisterChanged(id);
|
||||
|
||||
if (g_debug_context)
|
||||
if (g_debug_context) {
|
||||
auto id = cmd.ID;
|
||||
g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed,
|
||||
reinterpret_cast<void*>(&id));
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessCommandList(const u32* list, u32 size) {
|
||||
@ -623,11 +538,11 @@ void ProcessCommandList(const u32* list, u32 size) {
|
||||
u32 value = *g_state.cmd_list.current_ptr++;
|
||||
const CommandHeader header = {*g_state.cmd_list.current_ptr++};
|
||||
|
||||
WritePicaReg(header.cmd_id, value, header.parameter_mask);
|
||||
WritePicaReg(Command{header.cmd_id, value, header.parameter_mask});
|
||||
|
||||
for (unsigned i = 0; i < header.extra_data_length; ++i) {
|
||||
u32 cmd = header.cmd_id + (header.group_commands ? i + 1 : 0);
|
||||
WritePicaReg(cmd, *g_state.cmd_list.current_ptr++, header.parameter_mask);
|
||||
WritePicaReg(Command{cmd, *g_state.cmd_list.current_ptr++, header.parameter_mask});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user