RetroArch
ctr_gu.h
Go to the documentation of this file.
1 /* RetroArch - A frontend for libretro.
2  * Copyright (C) 2014-2017 - Ali Bouhlel
3  *
4  * RetroArch is free software: you can redistribute it and/or modify it under the terms
5  * of the GNU General Public License as published by the Free Software Found-
6  * ation, either version 3 of the License, or (at your option) any later version.
7  *
8  * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10  * PURPOSE. See the GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License along with RetroArch.
13  * If not, see <http://www.gnu.org/licenses/>.
14  */
15 
16 /* this file contains mostly modified functions from the ctrulib sdk */
17 
18 #ifndef CTR_GU_H
19 #define CTR_GU_H
20 
21 #include <3ds.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <retro_inline.h>
25 
26 #include "ctr/ctr_debug.h"
27 
28 #define VIRT_TO_PHYS(vaddr) \
29  (((u32)(vaddr)) >= 0x14000000 && ((u32)(vaddr)) < 0x1c000000)?(void*)((u32)(vaddr) + 0x0c000000):\
30  (((u32)(vaddr)) >= 0x1F000000 && ((u32)(vaddr)) < 0x1F600000)?(void*)((u32)(vaddr) - 0x07000000):\
31  (((u32)(vaddr)) >= 0x1FF00000 && ((u32)(vaddr)) < 0x1FF80000)?(void*)(vaddr):\
32  (((u32)(vaddr)) >= 0x30000000 && ((u32)(vaddr)) < 0x40000000)?(void*)((u32)(vaddr) - 0x10000000):(void*)0
33 
34 #define CTRGU_SIZE(W,H) (((u32)(W)&0xFFFF)|((u32)(H)<<16))
35 
36 /* DMA flags */
37 #define CTRGU_DMA_VFLIP (1 << 0)
38 #define CTRGU_DMA_L_TO_T (1 << 1)
39 #define CTRGU_DMA_T_TO_L (0 << 1)
40 #define CTRGU_DMA_TRUNCATE (1 << 2)
41 #define CTRGU_DMA_CONVERT_NONE (1 << 3)
42 
43 #define CTRGU_RGBA8 (0)
44 #define CTRGU_RGB8 (1)
45 #define CTRGU_RGB565 (2)
46 #define CTRGU_RGBA5551 (3)
47 #define CTRGU_RGBA4444 (4)
48 
49 #define CTRGU_MULTISAMPLE_NONE (0 << 24)
50 #define CTRGU_MULTISAMPLE_2x1 (1 << 24)
51 #define CTRGU_MULTISAMPLE_2x2 (2 << 24)
52 
53 #define CTR_CPU_TICKS_PER_SECOND 268123480
54 #define CTR_CPU_TICKS_PER_FRAME 4481134
55 
56 extern u32* gpuCmdBuf;
57 extern u32 gpuCmdBufOffset;
58 extern u32 __linear_heap_size;
59 extern u32 __linear_heap;
60 
61 __attribute__((always_inline))
62 static INLINE Result ctr_set_parallax_layer(bool state)
63 {
64  u32 reg_state = state? 0x00010001: 0x0;
65  return GSPGPU_WriteHWRegs(0x202000, &reg_state, 4);
66 }
67 
68 
69 __attribute__((always_inline))
70 static INLINE void ctrGuSetTexture(GPU_TEXUNIT unit, u32* data,
71  u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType)
72 {
73  switch (unit)
74  {
75  case GPU_TEXUNIT0:
76  GPUCMD_AddWrite(GPUREG_TEXUNIT0_TYPE, colorType);
77  GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, ((u32)data)>>3);
78  GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (height)|(width<<16));
79  GPUCMD_AddWrite(GPUREG_TEXUNIT0_PARAM, param);
80  break;
81 
82  case GPU_TEXUNIT1:
83  GPUCMD_AddWrite(GPUREG_TEXUNIT1_TYPE, colorType);
84  GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, ((u32)data)>>3);
85  GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (height)|(width<<16));
86  GPUCMD_AddWrite(GPUREG_TEXUNIT1_PARAM, param);
87  break;
88 
89  case GPU_TEXUNIT2:
90  GPUCMD_AddWrite(GPUREG_TEXUNIT2_TYPE, colorType);
91  GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, ((u32)data)>>3);
92  GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (height)|(width<<16));
93  GPUCMD_AddWrite(GPUREG_TEXUNIT2_PARAM, param);
94  break;
95  }
96 }
97 
98 __attribute__((always_inline))
99 static INLINE Result ctrGuSetCommandList_First(bool queued, u32* buf0a, u32 buf0s, u32* buf1a, u32 buf1s, u32* buf2a, u32 buf2s)
100 {
101  u32 gxCommand[0x8];
102  gxCommand[0]=0x05 | (queued? 0x01000000 : 0x0); //CommandID
103  gxCommand[1]=(u32)buf0a; //buf0 address
104  gxCommand[2]=(u32)buf0s; //buf0 size
105  gxCommand[3]=(u32)buf1a; //buf1 address
106  gxCommand[4]=(u32)buf1s; //buf1 size
107  gxCommand[5]=(u32)buf2a; //buf2 address
108  gxCommand[6]=(u32)buf2s; //buf2 size
109  gxCommand[7]=0x0;
110 
111  return gspSubmitGxCommand(gxCmdBuf, gxCommand);
112 }
113 
114 __attribute__((always_inline))
115 static INLINE Result ctrGuSetCommandList_Last(bool queued, u32* buf0a, u32 buf0s, u8 flags)
116 {
117  u32 gxCommand[0x8];
118  gxCommand[0]=0x01 | (queued? 0x01000000 : 0x0); //CommandID
119  gxCommand[1]=(u32)buf0a; //buf0 address
120  gxCommand[2]=(u32)buf0s; //buf0 size
121  gxCommand[3]=flags&1; //written to GSP module state
122  gxCommand[4]=gxCommand[5]=gxCommand[6]=0x0;
123  gxCommand[7]=(flags>>1)&1; //when non-zero, call svcFlushProcessDataCache() with the specified buffer
124 
125  return gspSubmitGxCommand(gxCmdBuf, gxCommand);
126 }
127 
128 __attribute__((always_inline))
129 static INLINE void ctrGuFlushAndRun(bool queued)
130 {
131  //take advantage of GX_SetCommandList_First to flush gsp heap
132  ctrGuSetCommandList_First(queued, gpuCmdBuf, gpuCmdBufOffset*4, (u32*)__linear_heap, __linear_heap_size, NULL, 0);
133  ctrGuSetCommandList_Last(queued, gpuCmdBuf, gpuCmdBufOffset*4, 0x0);
134 }
135 
136 __attribute__((always_inline))
137 static INLINE Result ctrGuSetMemoryFill(bool queued, u32* buf0a, u32 buf0v, u32* buf0e, u16 width0, u32* buf1a, u32 buf1v, u32* buf1e, u16 width1)
138 {
139  u32 gxCommand[0x8];
140  gxCommand[0]=0x02 | (queued? 0x01000000 : 0x0); //CommandID
141  gxCommand[1]=(u32)buf0a; //buf0 address
142  gxCommand[2]=buf0v; //buf0 value
143  gxCommand[3]=(u32)buf0e; //buf0 end addr
144  gxCommand[4]=(u32)buf1a; //buf1 address
145  gxCommand[5]=buf1v; //buf1 value
146  gxCommand[6]=(u32)buf1e; //buf1 end addr
147  gxCommand[7]=(width0)|(width1<<16);
148 
149  return gspSubmitGxCommand(gxCmdBuf, gxCommand);
150 }
151 
152 __attribute__((always_inline))
153 static INLINE Result ctrGuCopyImage
154  (bool queued,
155  const void* src, int src_w, int src_h, int src_fmt, bool src_is_tiled,
156  void* dst, int dst_w, int dst_fmt, bool dst_is_tiled)
157 {
158  u32 gxCommand[0x8];
159  gxCommand[0]=0x03 | (queued? 0x01000000 : 0x0); //CommandID
160  gxCommand[1]=(u32)src;
161  gxCommand[2]=(u32)dst;
162  gxCommand[3]=dst_w&0xFF8;
163  gxCommand[4]=CTRGU_SIZE(src_w, src_h);
164  gxCommand[5]=(src_fmt << 8)|(dst_fmt << 12)
165  | ((src_is_tiled == dst_is_tiled)? CTRGU_DMA_CONVERT_NONE
166  : src_is_tiled? CTRGU_DMA_T_TO_L
168  | ((dst_w > src_w) ? CTRGU_DMA_TRUNCATE : 0);
169  gxCommand[6]=gxCommand[7]=0x0;
170 
171  return gspSubmitGxCommand(gxCmdBuf, gxCommand);
172 
173 }
174 
175 __attribute__((always_inline))
176 static INLINE Result ctrGuDisplayTransfer
177  (bool queued,
178  void* src, int src_w, int src_h, int src_fmt,
179  void* dst, int dst_w, int dst_fmt, int multisample_lvl)
180 {
181  u32 gxCommand[0x8];
182  gxCommand[0]=0x03 | (queued? 0x01000000 : 0x0); //CommandID
183  gxCommand[1]=(u32)src;
184  gxCommand[2]=(u32)dst;
185  gxCommand[3]=CTRGU_SIZE(dst_w, 0);
186  gxCommand[4]=CTRGU_SIZE(src_w, src_h);
187  gxCommand[5]=(src_fmt << 8) | (dst_fmt << 12) | multisample_lvl;
188  gxCommand[6]=gxCommand[7]=0x0;
189 
190  return gspSubmitGxCommand(gxCmdBuf, gxCommand);
191 
192 }
193 
194 __attribute__((always_inline))
195 static INLINE void ctrGuSetVertexShaderFloatUniform(int id, float* data, int count)
196 {
197  GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG, 0x80000000|(u32)id);
198  GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA, (u32*)data, (u32)count * 4);
199 }
200 
201 
202 #define CTRGU_ATTRIBFMT(f, n) ((((n)-1)<<2)|((f)&3))
203 
204 __attribute__((always_inline))
205 static INLINE void ctrGuSetAttributeBuffers(u32 total_attributes,
206  void* base_address, u64 attribute_formats, u32 buffer_size)
207 {
208  u32 param[0x28];
209 
210  memset(param, 0x00, sizeof(param));
211 
212  param[0x0]=((u32)base_address)>>3;
213  param[0x1]=attribute_formats & 0xFFFFFFFF;
214  param[0x2]=((total_attributes-1)<<28)|0xFFF0000|((attribute_formats>>32)&0xFFFF);
215  param[0x4]=0x76543210;
216  param[0x5]=(total_attributes<<28)|((buffer_size&0xFFF)<<16)|0xBA98;
217 
218  GPUCMD_AddIncrementalWrites(GPUREG_ATTRIBBUFFERS_LOC, param, 0x00000027);
219  GPUCMD_AddMaskedWrite(GPUREG_VSH_INPUTBUFFER_CONFIG, 0xB, 0xA0000000|(total_attributes-1));
220  GPUCMD_AddWrite(GPUREG_VSH_NUM_ATTR, (total_attributes-1));
221  GPUCMD_AddIncrementalWrites(GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW, ((u32[]){0x76543210, 0xBA98}), 2);
222 }
223 
224 __attribute__((always_inline))
225 static INLINE void ctrGuSetAttributeBuffersAddress(u32* baseAddress)
226 {
227  GPUCMD_AddWrite(GPUREG_ATTRIBBUFFERS_LOC, ((u32)baseAddress)>>3);
228 }
229 
230 __attribute__((always_inline))
231 static INLINE void ctrGuSetVshGsh(shaderProgram_s* sp, DVLB_s* dvlb, u32 vsh_output_count, u32 gsh_input_count)
232 {
233  dvlb->DVLE[0].outmapData[0] = vsh_output_count;
234  dvlb->DVLE[0].outmapMask = (1 << vsh_output_count) - 1;
235  shaderProgramInit(sp);
236  shaderProgramSetVsh(sp, &dvlb->DVLE[0]);
237  shaderProgramSetGsh(sp, &dvlb->DVLE[1], gsh_input_count);
238 }
239 
240 __attribute__((always_inline))
241 static INLINE int ctrgu_swizzle_coords(int x, int y, int width)
242 {
243  int pos = (x & 0x1) << 0 | ((x & 0x2) << 1) | ((x & 0x4) << 2) |
244  (y & 0x1) << 1 | ((y & 0x2) << 2) | ((y & 0x4) << 3);
245 
246 
247  return ((x >> 3) << 6) + ((y >> 3) * ((width >> 3) << 6)) + pos;
248 
249 }
250 
251 #endif // CTR_GU_H
#define INLINE
Definition: retro_inline.h:35
GLfixed GLfixed x2
Definition: glsym_gl.h:1051
result_t Result
Definition: switch_audio_compat.h:53
Definition: ibxm.h:9
GLuint GLuint GLsizei count
Definition: glext.h:6292
#define CTRGU_DMA_T_TO_L
Definition: ctr_gu.h:39
GLfloat param
Definition: glext.h:6480
#define NULL
Pointer to 0.
Definition: gctypes.h:65
uint16_t u16
16bit unsigned integer
Definition: gctypes.h:18
#define CTRGU_SIZE(W, H)
Definition: ctr_gu.h:34
u32 gpuCmdBufOffset
__attribute__((always_inline)) static INLINE Result ctr_set_parallax_layer(bool state)
Definition: ctr_gu.h:61
#define CTRGU_DMA_CONVERT_NONE
Definition: ctr_gu.h:41
static uint64_t state[MAX_PADS]
Definition: xenon360_input.c:33
GLint GLint GLint GLint GLint GLint y
Definition: glext.h:6295
GLenum src
Definition: glext.h:6980
GLint GLint GLint GLint GLint x
Definition: glext.h:6295
uint64_t u64
64bit unsigned integer
Definition: gctypes.h:20
GLint GLint GLsizei width
Definition: glext.h:6293
#define CTRGU_DMA_L_TO_T
Definition: ctr_gu.h:38
GLenum GLenum dst
Definition: glext.h:6980
u32 __linear_heap_size
Definition: ctr_system.c:14
u32 * gpuCmdBuf
GLbitfield flags
Definition: glext.h:7828
#define CTRGU_DMA_TRUNCATE
Definition: ctr_gu.h:40
uint8_t u8
8bit unsigned integer
Definition: gctypes.h:17
uint32_t u32
32bit unsigned integer
Definition: gctypes.h:19
void * memset(void *b, int c, size_t len)
Definition: string.c:7
GLint GLint GLsizei GLsizei height
Definition: glext.h:6293
u32 __linear_heap
Definition: ctr_system.c:17