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/gx2utExpandColor.h"
31
32
33 // ----- GX2 Shader
34 static const GX2VertexShader* const VS_SHADERS[] = { &gx2utExpandColor_VS,};
35
36 static const GX2PixelShader* const PS_SHADERS[] = { &gx2utExpandColor_PS,
37 };
38
39 static const u32 NUM_SHADERS = 1;
40
41 typedef struct _ExpandColorShader {
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 } ExpandColorShader;
55
56 static ExpandColorShader g_expandColorShader[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
GX2UTExpandAAColorInit()81 void GX2UTExpandAAColorInit()
82 {
83 // Setup shaders
84 u32 i;
85
86 for (i = 0; i < NUM_SHADERS; ++i)
87 {
88 g_expandColorShader[i].pVertexShader = VS_SHADERS[i];
89 g_expandColorShader[i].pPixelShader = PS_SHADERS[i];
90
91 GX2Invalidate(GX2_INVALIDATE_CPU_SHADER,
92 g_expandColorShader[i].pVertexShader->shaderPtr,
93 g_expandColorShader[i].pVertexShader->shaderSize);
94
95 GX2NotifyMemAlloc(g_expandColorShader[i].pVertexShader->shaderPtr,
96 g_expandColorShader[i].pVertexShader->shaderSize,
97 GX2_SHADER_ALIGNMENT);
98
99 GX2Invalidate(GX2_INVALIDATE_CPU_SHADER,
100 g_expandColorShader[i].pPixelShader->shaderPtr,
101 g_expandColorShader[i].pPixelShader->shaderSize);
102
103 GX2NotifyMemAlloc(g_expandColorShader[i].pPixelShader->shaderPtr,
104 g_expandColorShader[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_expandColorShader[i].u_positionLocation =
110 (u32)GX2GetVertexUniformVarOffset(g_expandColorShader[i].pVertexShader, "u_positions");
111 ASSERT((g_expandColorShader[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
GX2UTExpandAAColorBufferOp(GX2ColorBuffer * colorBuffer)120 void GX2UTExpandAAColorBufferOp(GX2ColorBuffer* colorBuffer)
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 color buffer
132 GX2UTExpandAAColorInit();
133
134 initDone = GX2_TRUE;
135 }
136
137 ASSERT((colorBuffer != NULL));
138
139 // Set shaders
140 GX2SetFetchShader(&fetchShader);
141 GX2SetVertexShader(g_expandColorShader[shaderIdx].pVertexShader);
142 GX2SetPixelShader(g_expandColorShader[shaderIdx].pPixelShader);
143
144 // Set the uniforms to be used by the vertex shader
145 f32 position_base_scale[] =
146 {
147 -1.0f,
148 1.0f,
149 2.0f,
150 -2.0f,
151 };
152
153 for (int i = 0; i < 4; i++)
154 {
155 f32 pos[] = {
156 position_base_scale[0] + position_base_scale[2] * EXPAND_SURFACE_RECT_POSITION_DATA[i].texcoord[0],
157 position_base_scale[1] + position_base_scale[3] * EXPAND_SURFACE_RECT_POSITION_DATA[i].texcoord[1],
158 0.0,
159 1.0
160 };
161
162 GX2SetVertexUniformReg(g_expandColorShader[shaderIdx].u_positionLocation + i*4, 1*4, pos);
163 }
164
165 // Invalidate the color buffer to guarantee all writes have been flushed
166 if ( colorBuffer->viewMip )
167 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER, colorBuffer->surface.mipPtr, colorBuffer->surface.mipSize);
168 else
169 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER, colorBuffer->surface.imagePtr, colorBuffer->surface.imageSize);
170
171 GX2ColorBuffer cb = *colorBuffer;
172 for (int slice = colorBuffer->viewFirstSlice; slice < colorBuffer->viewNumSlices; slice++)
173 {
174 cb.viewFirstSlice = slice;
175 cb.viewNumSlices = 1;
176 GX2InitColorBufferRegs(&cb);
177
178 // Copy the dimensions
179 expandWidth = cb.surface.width;
180 expandHeight = cb.surface.height;
181
182 // Set the color buffer
183 GX2SetColorBuffer(&cb, GX2_RENDER_TARGET_0);
184
185 // Render to destination surface dimensions
186 GX2SetViewport(0, 0, (f32)expandWidth, (f32)expandHeight, 0.0f, 1.0f);
187 GX2SetScissor(0, 0, expandWidth, expandHeight);
188
189 // Draw a full quad that covers the display
190 GX2Draw(GX2_PRIMITIVE_RECTS, VERTEX_COUNT);
191 }
192
193 // Invalidate the color buffer to guarantee all writes have been flushed
194 if ( colorBuffer->viewMip )
195 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER, colorBuffer->surface.mipPtr, colorBuffer->surface.mipSize);
196 else
197 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER, colorBuffer->surface.imagePtr, colorBuffer->surface.imageSize);
198
199
200 GX2UTDebugTagUndent();
201 }
202
203
204 //Setup all of the constant renderstate needed for the copy.
GX2UTSetExpandAAColorState(GX2Boolean enable)205 void GX2UTSetExpandAAColorState(GX2Boolean enable)
206 {
207 if (enable)
208 {
209 // If your application's steady state can be set to GX2UT common state
210 // using a small number of discrete GX2 calls, then customize here
211 // instead of using GX2UTSetCommonState().
212 GX2UTSetCommonState();
213
214 // Set additional required GX2 state
215 GX2SetDepthStencilControl(GX2_FALSE,
216 GX2_FALSE,
217 GX2_COMPARE_NEVER,
218 GX2_FALSE,
219 GX2_FALSE,
220 GX2_COMPARE_NEVER,
221 GX2_STENCIL_KEEP,
222 GX2_STENCIL_KEEP,
223 GX2_STENCIL_KEEP,
224 GX2_COMPARE_NEVER,
225 GX2_STENCIL_KEEP,
226 GX2_STENCIL_KEEP,
227 GX2_STENCIL_KEEP);
228
229 // Set Complex GX2 State for our operation
230 GX2SetSpecialState(GX2_SPECIAL_STATE_EXPAND_COLOR, GX2_TRUE);
231 }
232 else
233 {
234 // Disable any complex GX2 state
235 GX2SetSpecialState(GX2_SPECIAL_STATE_EXPAND_COLOR, GX2_FALSE);
236
237 // The purpose of the following is to return the context to GX2 default
238 // state. If your application uses a different "steady state", then
239 // customize
240 GX2SetDepthStencilControl(
241 GX2_TRUE, //depthTestEnable
242 GX2_TRUE, //depthWriteEnable
243 GX2_COMPARE_LESS, //depthFunc
244 GX2_FALSE, //stencilTestEnable
245 GX2_FALSE, //backStencilEnable
246 GX2_COMPARE_ALWAYS, //frontStencilFunc
247 GX2_STENCIL_REPLACE, //frontStencilZPass
248 GX2_STENCIL_REPLACE, //frontStencilZFail
249 GX2_STENCIL_REPLACE, //frontStencilFail
250 GX2_COMPARE_ALWAYS, //backStencilFunc
251 GX2_STENCIL_REPLACE, //backStencilZPass
252 GX2_STENCIL_REPLACE, //backStencilZFail
253 GX2_STENCIL_REPLACE);//backStencilFail
254
255 }
256 }
257