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