1 /*---------------------------------------------------------------------------*
2
3 Copyright 2014 Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <math.h>
16
17 #if defined(WIN32) || defined(WIN64)
18 #include <pc/gx2.h>
19 #include <pc/demo.h>
20 #endif
21 #include <cafe/os.h>
22 #include <cafe/mem.h>
23 #include <cafe/gx2.h>
24 #include <cafe/demo.h>
25
26 #include <cafe/gfd.h>
27 #include <cafe/gx2ut.h>
28
29 //Include generated shaders
30 #include "shaders/headers/gx2utExpandDepth.h"
31
32
33 // ----- GX2 Shader
34 static const GX2VertexShader* const VS_SHADERS[] = { &gx2utExpandDepth_VS,};
35
36 static const GX2PixelShader* const PS_SHADERS[] = { &gx2utExpandDepth_PS,
37 };
38
39 static const u32 NUM_SHADERS = 1;
40
41 typedef struct _ExpandDepthShader {
42 // These variables hold the three types of shaders needed for a call to
43 // GX2SetShaders. The vertex and pixel shaders are loaded from the
44 // header, but since the fetch shader is generated at run-time
45 // it must be handled slightly differently.
46 const GX2VertexShader *pVertexShader;
47 const GX2PixelShader *pPixelShader;
48
49 // The register locations where the offset uniforms are stored for
50 // the pixel and vertex shaders.
51 u32 u_positionLocation;
52 u32 u_texcoordLocation;
53
54 } ExpandDepthShader;
55
56 static ExpandDepthShader g_expandDepthShader[NUM_SHADERS];
57 static GX2FetchShader fetchShader;
58
59 #define FETCH_SHADER_SIZE 32 //hard code this value for now
60 ALIGNVAR(GX2_SHADER_ALIGNMENT) static u8 g_GX2UTFetchShader[FETCH_SHADER_SIZE];
61
62 // ----- GX2 Texture
63
64 typedef struct _VtxFmtF32x2 {
65 f32 texcoord[2];
66 } VtxFmtF32x2;
67
68 static const VtxFmtF32x2 EXPAND_SURFACE_RECT_POSITION_DATA[] =
69 {
70 {0.0f, 0.0f},
71 {1.0f, 0.0f},
72 {1.0f, 1.0f},
73 {0.0f, 1.0f}
74 };
75
76 // Same for both rect and triangle strips
77 static const u32 VERTEX_COUNT = sizeof(EXPAND_SURFACE_RECT_POSITION_DATA)
78 / sizeof(EXPAND_SURFACE_RECT_POSITION_DATA[0]);
79
80 // Initializes how surfaces will be copied
GX2UTExpandDepthInit()81 void GX2UTExpandDepthInit()
82 {
83 // Setup shaders
84 u32 i;
85
86 for (i = 0; i < NUM_SHADERS; ++i)
87 {
88 g_expandDepthShader[i].pVertexShader = VS_SHADERS[i];
89 g_expandDepthShader[i].pPixelShader = PS_SHADERS[i];
90
91 GX2Invalidate(GX2_INVALIDATE_CPU_SHADER,
92 g_expandDepthShader[i].pVertexShader->shaderPtr,
93 g_expandDepthShader[i].pVertexShader->shaderSize);
94
95 GX2NotifyMemAlloc(g_expandDepthShader[i].pVertexShader->shaderPtr,
96 g_expandDepthShader[i].pVertexShader->shaderSize,
97 GX2_SHADER_ALIGNMENT);
98
99 GX2Invalidate(GX2_INVALIDATE_CPU_SHADER,
100 g_expandDepthShader[i].pPixelShader->shaderPtr,
101 g_expandDepthShader[i].pPixelShader->shaderSize);
102
103 GX2NotifyMemAlloc(g_expandDepthShader[i].pPixelShader->shaderPtr,
104 g_expandDepthShader[i].pPixelShader->shaderSize,
105 GX2_SHADER_ALIGNMENT);
106
107 // Lookup the uniform locations in the vertex shader.
108 // The shader author chose the name "u_positions"
109 g_expandDepthShader[i].u_positionLocation =
110 (u32)GX2GetVertexUniformVarOffset(g_expandDepthShader[i].pVertexShader, "u_positions");
111 ASSERT((g_expandDepthShader[i].u_positionLocation != GX2_UNIFORM_VAR_INVALID_OFFSET)
112 && "Couldn't find the correct vertex shader uniforms.");
113
114 }
115
116 ASSERT(GX2CalcFetchShaderSize(0) <= sizeof(g_GX2UTFetchShader) && "g_GX2UTFetchShader too small!\n");
117 GX2InitFetchShader(&fetchShader, g_GX2UTFetchShader, 0, NULL);
118 }
119
GX2UTExpandDepthBufferOp(GX2DepthBuffer * depthBuffer)120 void GX2UTExpandDepthBufferOp(GX2DepthBuffer* depthBuffer)
121 {
122 static GX2Boolean initDone = GX2_FALSE;
123 u32 expandWidth;
124 u32 expandHeight;
125 u32 shaderIdx = 0;
126
127 GX2UTDebugTagIndent(__func__);
128
129 if (initDone == GX2_FALSE)
130 {
131 // Initialize the resources needed to expand a depth buffer
132 GX2UTExpandDepthInit();
133
134 initDone = GX2_TRUE;
135 }
136
137 ASSERT((depthBuffer != NULL));
138
139 //
140 // Enable special depth expand state
141 //
142 // Invalidate the depth buffer to guarantee all writes have been flushed
143 if (depthBuffer->viewMip)
144 GX2Invalidate(GX2_INVALIDATE_DEPTH_BUFFER, depthBuffer->surface.mipPtr, depthBuffer->surface.mipSize);
145 else
146 GX2Invalidate(GX2_INVALIDATE_DEPTH_BUFFER, depthBuffer->surface.imagePtr, depthBuffer->surface.imageSize);
147
148 for (int slice = depthBuffer->viewFirstSlice; slice < depthBuffer->viewNumSlices; slice++)
149 {
150 GX2DepthBuffer db = *depthBuffer;
151
152 // Set the view slice for this pass
153 db.viewFirstSlice = slice;
154 db.viewNumSlices = 1;
155 GX2InitDepthBufferRegs(&db);
156
157 // Copy the dimensions
158 expandWidth = db.surface.width;
159 expandHeight = db.surface.height;
160
161 // Set shaders
162 GX2SetFetchShader(&fetchShader);
163 GX2SetVertexShader(g_expandDepthShader[shaderIdx].pVertexShader);
164 GX2SetPixelShader(g_expandDepthShader[shaderIdx].pPixelShader);
165
166 // Set the uniforms to be used by the vertex shader
167 f32 position_base_scale[] =
168 {
169 -1.0f,
170 1.0f,
171 2.0f,
172 -2.0f,
173 };
174
175 for (int i = 0; i < 4; i++)
176 {
177 f32 pos[] = {
178 position_base_scale[0] + position_base_scale[2] * EXPAND_SURFACE_RECT_POSITION_DATA[i].texcoord[0],
179 position_base_scale[1] + position_base_scale[3] * EXPAND_SURFACE_RECT_POSITION_DATA[i].texcoord[1],
180 0.0,
181 1.0
182 };
183
184 GX2SetVertexUniformReg(g_expandDepthShader[shaderIdx].u_positionLocation + i*4, 1*4, pos);
185 }
186
187 // Set the depth buffer
188 GX2SetDepthBuffer(&db);
189
190 // Render to destination surface dimensions
191 GX2SetViewport(0, 0, (f32)expandWidth, (f32)expandHeight, 0.0f, 1.0f);
192 GX2SetScissor(0, 0, expandWidth, expandHeight);
193
194 // Draw a full quad that covers the display
195 GX2Draw(GX2_PRIMITIVE_RECTS, VERTEX_COUNT);
196 }
197
198 // Invalidate the depth buffer to guarantee all writes have been flushed
199 if (depthBuffer->viewMip)
200 GX2Invalidate(GX2_INVALIDATE_DEPTH_BUFFER, depthBuffer->surface.mipPtr, depthBuffer->surface.mipSize);
201 else
202 GX2Invalidate(GX2_INVALIDATE_DEPTH_BUFFER, depthBuffer->surface.imagePtr, depthBuffer->surface.imageSize);
203
204
205 GX2UTDebugTagUndent();
206 }
207
208
209 //Setup all of the constant renderstate needed for the copy.
GX2UTSetExpandDepthState(GX2Boolean enable)210 void GX2UTSetExpandDepthState(GX2Boolean enable)
211 {
212 if (enable)
213 {
214 // If your application's steady state can be set to GX2UT common state
215 // using a small number of discrete GX2 calls, then customize here
216 // instead of using GX2UTSetCommonState().
217 GX2UTSetCommonState();
218
219 // Set additional required GX2 state
220 GX2SetColorControl(GX2_LOGIC_OP_COPY, GX2_DISABLE, GX2_DISABLE, GX2_DISABLE);
221
222 // Setup depth/stencil state:
223 GX2SetDepthStencilControl(GX2_FALSE,
224 GX2_FALSE,
225 GX2_COMPARE_NEVER,
226 GX2_FALSE,
227 GX2_FALSE,
228 GX2_COMPARE_NEVER,
229 GX2_STENCIL_KEEP,
230 GX2_STENCIL_KEEP,
231 GX2_STENCIL_KEEP,
232 GX2_COMPARE_NEVER,
233 GX2_STENCIL_KEEP,
234 GX2_STENCIL_KEEP,
235 GX2_STENCIL_KEEP);
236
237 // Set Complex GX2 State for our operation
238 GX2SetSpecialState(GX2_SPECIAL_STATE_EXPAND_DEPTH, GX2_ENABLE);
239 }
240 else
241 {
242 // Disable any complex GX2 state
243 GX2SetSpecialState(GX2_SPECIAL_STATE_EXPAND_DEPTH, GX2_DISABLE);
244
245 // Set additional required GX2 state
246 GX2SetColorControl(GX2_LOGIC_OP_COPY, GX2_DISABLE, GX2_DISABLE, GX2_ENABLE);
247
248 // The purpose of the following is to return the context to GX2 default
249 // state. If your application uses a different "steady state", then
250 // customize
251 GX2SetDepthStencilControl(
252 GX2_TRUE, //depthTestEnable
253 GX2_TRUE, //depthWriteEnable
254 GX2_COMPARE_LESS, //depthFunc
255 GX2_FALSE, //stencilTestEnable
256 GX2_FALSE, //backStencilEnable
257 GX2_COMPARE_ALWAYS, //frontStencilFunc
258 GX2_STENCIL_REPLACE, //frontStencilZPass
259 GX2_STENCIL_REPLACE, //frontStencilZFail
260 GX2_STENCIL_REPLACE, //frontStencilFail
261 GX2_COMPARE_ALWAYS, //backStencilFunc
262 GX2_STENCIL_REPLACE, //backStencilZPass
263 GX2_STENCIL_REPLACE, //backStencilZFail
264 GX2_STENCIL_REPLACE);//backStencilFail
265 }
266
267 }
268