~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/VideoBackends/Software/Src/HwRasterizer.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include "Common.h"
 
6
#include "MemoryUtil.h"
 
7
 
 
8
#include <VideoCommon.h>
 
9
 
 
10
#include "BPMemLoader.h"
 
11
#include "HwRasterizer.h"
 
12
#include "NativeVertexFormat.h"
 
13
#include "DebugUtil.h"
 
14
 
 
15
#define TEMP_SIZE (1024*1024*4)
 
16
 
 
17
namespace HwRasterizer
 
18
{
 
19
        float efbHalfWidth;
 
20
        float efbHalfHeight;
 
21
        bool hasTexture;
 
22
 
 
23
        u8 *temp;
 
24
 
 
25
        // Programs
 
26
        static GLuint colProg, texProg, clearProg;
 
27
 
 
28
        // Color
 
29
        static GLint col_apos = -1, col_atex = -1;
 
30
        // Tex
 
31
        static GLint tex_apos = -1, tex_atex = -1, tex_utex = -1;
 
32
        // Clear shader
 
33
        static GLint clear_apos = -1, clear_ucol = -1;
 
34
 
 
35
        void CreateShaders()
 
36
        {
 
37
                // Color Vertices
 
38
                static const char *fragcolText =
 
39
                        "varying " PREC " vec4 TexCoordOut;\n"
 
40
                        "void main() {\n"
 
41
                        "       gl_FragColor = TexCoordOut;\n"
 
42
                        "}\n";
 
43
                // Texture Vertices
 
44
                static const char *fragtexText =
 
45
                        "varying " PREC " vec4 TexCoordOut;\n"
 
46
                        "uniform " TEXTYPE " Texture;\n"
 
47
                        "void main() {\n"
 
48
                        "       gl_FragColor = " TEXFUNC "(Texture, TexCoordOut.xy);\n"
 
49
                        "}\n";
 
50
                // Clear shader
 
51
                static const char *fragclearText =
 
52
                        "uniform " PREC " vec4 Color;\n"
 
53
                        "void main() {\n"
 
54
                        "       gl_FragColor = Color;\n"
 
55
                        "}\n";
 
56
                // Generic passthrough vertice shaders
 
57
                static const char *vertShaderText =
 
58
                        "attribute vec4 pos;\n"
 
59
                        "attribute vec4 TexCoordIn;\n "
 
60
                        "varying vec4 TexCoordOut;\n "
 
61
                        "void main() {\n"
 
62
                        "       gl_Position = pos;\n"
 
63
                        "       TexCoordOut = TexCoordIn;\n"
 
64
                        "}\n";
 
65
                static const char *vertclearText =
 
66
                        "attribute vec4 pos;\n"
 
67
                        "void main() {\n"
 
68
                        "       gl_Position = pos;\n"
 
69
                        "}\n";
 
70
 
 
71
                // Color Program
 
72
                colProg = OpenGL_CompileProgram(vertShaderText, fragcolText);
 
73
 
 
74
                // Texture Program
 
75
                texProg = OpenGL_CompileProgram(vertShaderText, fragtexText);
 
76
 
 
77
                // Clear Program
 
78
                clearProg = OpenGL_CompileProgram(vertclearText, fragclearText);
 
79
 
 
80
                // Color attributes
 
81
                col_apos = glGetAttribLocation(colProg, "pos");
 
82
                col_atex = glGetAttribLocation(colProg, "TexCoordIn");
 
83
                // Texture attributes
 
84
                tex_apos = glGetAttribLocation(texProg, "pos");
 
85
                tex_atex = glGetAttribLocation(texProg, "TexCoordIn");
 
86
                tex_utex = glGetUniformLocation(texProg, "Texture");
 
87
                // Clear attributes
 
88
                clear_apos = glGetAttribLocation(clearProg, "pos");
 
89
                clear_ucol = glGetUniformLocation(clearProg, "Color");
 
90
        }
 
91
 
 
92
        void Init()
 
93
        {
 
94
                efbHalfWidth = EFB_WIDTH / 2.0f;
 
95
                efbHalfHeight = 480 / 2.0f;
 
96
 
 
97
                temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
 
98
        }
 
99
        void Shutdown()
 
100
        {
 
101
                glDeleteProgram(colProg);
 
102
                glDeleteProgram(texProg);
 
103
                glDeleteProgram(clearProg);
 
104
        }
 
105
        void Prepare()
 
106
        {
 
107
                //legacy multitexturing: select texture channel only.
 
108
                glActiveTexture(GL_TEXTURE0);
 
109
                glPixelStorei(GL_UNPACK_ALIGNMENT, 4);  // 4-byte pixel alignment
 
110
#ifndef USE_GLES
 
111
                glShadeModel(GL_SMOOTH);
 
112
                glDisable(GL_BLEND);
 
113
                glClearDepth(1.0f);
 
114
                glEnable(GL_SCISSOR_TEST);
 
115
                glDisable(GL_LIGHTING);
 
116
                glMatrixMode(GL_PROJECTION);
 
117
                glLoadIdentity();
 
118
                glMatrixMode(GL_MODELVIEW);
 
119
                glLoadIdentity();
 
120
 
 
121
                glClientActiveTexture(GL_TEXTURE0);
 
122
                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
123
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
124
                glEnable(GL_TEXTURE_RECTANGLE_ARB);
 
125
                glStencilFunc(GL_ALWAYS, 0, 0);
 
126
                glDisable(GL_STENCIL_TEST);
 
127
#endif
 
128
                // used by hw rasterizer if it enables blending and depth test
 
129
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
130
                glDepthFunc(GL_LEQUAL);
 
131
 
 
132
                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
133
                
 
134
                CreateShaders();
 
135
                GL_REPORT_ERRORD();
 
136
        }
 
137
        static float width, height;
 
138
        void LoadTexture()
 
139
        {
 
140
                FourTexUnits &texUnit = bpmem.tex[0];
 
141
                u32 imageAddr = texUnit.texImage3[0].image_base;
 
142
                // Texture Rectangle uses pixel coordinates
 
143
                // While GLES uses texture coordinates
 
144
#ifdef USE_GLES 
 
145
                width = texUnit.texImage0[0].width;
 
146
                height = texUnit.texImage0[0].height;
 
147
#else
 
148
                width = 1;
 
149
                height = 1;
 
150
#endif
 
151
                TexCacheEntry &cacheEntry = textures[imageAddr];
 
152
                cacheEntry.Update();
 
153
 
 
154
                glBindTexture(TEX2D, cacheEntry.texture);
 
155
                glTexParameteri(TEX2D, GL_TEXTURE_MAG_FILTER, texUnit.texMode0[0].mag_filter ? GL_LINEAR : GL_NEAREST);
 
156
                glTexParameteri(TEX2D, GL_TEXTURE_MIN_FILTER, (texUnit.texMode0[0].min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
 
157
                GL_REPORT_ERRORD();
 
158
        }
 
159
 
 
160
        void BeginTriangles()
 
161
        {
 
162
                // disabling depth test sometimes allows more things to be visible
 
163
                glEnable(GL_DEPTH_TEST);
 
164
                glEnable(GL_BLEND);
 
165
 
 
166
                hasTexture = bpmem.tevorders[0].enable0;
 
167
 
 
168
                if (hasTexture)
 
169
                        LoadTexture();
 
170
        }
 
171
 
 
172
        void EndTriangles()
 
173
        {
 
174
                glBindTexture(TEX2D, 0);
 
175
                glDisable(GL_DEPTH_TEST);
 
176
                glDisable(GL_BLEND);
 
177
        }
 
178
 
 
179
        void DrawColorVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
 
180
        {
 
181
                float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
 
182
                float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
 
183
                float z0 = v0->screenPosition.z / (float)0x00ffffff;
 
184
 
 
185
                float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
 
186
                float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
 
187
                float z1 = v1->screenPosition.z / (float)0x00ffffff;
 
188
 
 
189
                float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
 
190
                float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
 
191
                float z2 = v2->screenPosition.z / (float)0x00ffffff;
 
192
 
 
193
                float r0 = v0->color[0][OutputVertexData::RED_C] / 255.0f;
 
194
                float g0 = v0->color[0][OutputVertexData::GRN_C] / 255.0f;
 
195
                float b0 = v0->color[0][OutputVertexData::BLU_C] / 255.0f;
 
196
 
 
197
                float r1 = v1->color[0][OutputVertexData::RED_C] / 255.0f;
 
198
                float g1 = v1->color[0][OutputVertexData::GRN_C] / 255.0f;
 
199
                float b1 = v1->color[0][OutputVertexData::BLU_C] / 255.0f;
 
200
 
 
201
                float r2 = v2->color[0][OutputVertexData::RED_C] / 255.0f;
 
202
                float g2 = v2->color[0][OutputVertexData::GRN_C] / 255.0f;
 
203
                float b2 = v2->color[0][OutputVertexData::BLU_C] / 255.0f;
 
204
 
 
205
                static const GLfloat verts[3][3] = {
 
206
                        { x0, y0, z0 },
 
207
                        { x1, y1, z1 },
 
208
                        { x2, y2, z2 }
 
209
                };
 
210
                static const GLfloat col[3][4] = {
 
211
                        { r0, g0, b0, 1.0f },
 
212
                        { r1, g1, b1, 1.0f },
 
213
                        { r2, g2, b2, 1.0f }
 
214
                };
 
215
                {
 
216
                        glUseProgram(colProg);
 
217
                        glEnableVertexAttribArray(col_apos);
 
218
                        glEnableVertexAttribArray(col_atex);
 
219
 
 
220
                        glVertexAttribPointer(col_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
 
221
                        glVertexAttribPointer(col_atex, 4, GL_FLOAT, GL_FALSE, 0, col);
 
222
                                glDrawArrays(GL_TRIANGLES, 0, 3);
 
223
                        glDisableVertexAttribArray(col_atex);
 
224
                        glDisableVertexAttribArray(col_apos);
 
225
                }
 
226
                GL_REPORT_ERRORD();
 
227
        }
 
228
 
 
229
        void DrawTextureVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
 
230
        {
 
231
                float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
 
232
                float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
 
233
                float z0 = v0->screenPosition.z;
 
234
 
 
235
                float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
 
236
                float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
 
237
                float z1 = v1->screenPosition.z;
 
238
 
 
239
                float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
 
240
                float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
 
241
                float z2 = v2->screenPosition.z;
 
242
 
 
243
                float s0 = v0->texCoords[0].x / width;
 
244
                float t0 = v0->texCoords[0].y / height;
 
245
 
 
246
                float s1 = v1->texCoords[0].x / width;
 
247
                float t1 = v1->texCoords[0].y / height;
 
248
 
 
249
                float s2 = v2->texCoords[0].x / width;
 
250
                float t2 = v2->texCoords[0].y / height;
 
251
 
 
252
                static const GLfloat verts[3][3] = {
 
253
                        { x0, y0, z0 },
 
254
                        { x1, y1, z1 },
 
255
                        { x2, y2, z2 }
 
256
                };
 
257
                static const GLfloat tex[3][2] = {
 
258
                        { s0, t0 },
 
259
                        { s1, t1 },
 
260
                        { s2, t2 }
 
261
                };
 
262
                {
 
263
                        glUseProgram(texProg);
 
264
                        glEnableVertexAttribArray(tex_apos);
 
265
                        glEnableVertexAttribArray(tex_atex);
 
266
 
 
267
                        glVertexAttribPointer(tex_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
 
268
                        glVertexAttribPointer(tex_atex, 2, GL_FLOAT, GL_FALSE, 0, tex);
 
269
                                glUniform1i(tex_utex, 0);
 
270
                                glDrawArrays(GL_TRIANGLES, 0, 3);
 
271
                        glDisableVertexAttribArray(tex_atex);
 
272
                        glDisableVertexAttribArray(tex_apos);
 
273
                }
 
274
                GL_REPORT_ERRORD();
 
275
        }
 
276
 
 
277
        void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
 
278
        {
 
279
                if (hasTexture)
 
280
                        DrawTextureVertex(v0, v1, v2);
 
281
                else
 
282
                        DrawColorVertex(v0, v1, v2);
 
283
        }
 
284
 
 
285
        void Clear()
 
286
        {
 
287
                u8 r = (bpmem.clearcolorAR & 0x00ff);
 
288
                u8 g = (bpmem.clearcolorGB & 0xff00) >> 8;
 
289
                u8 b = (bpmem.clearcolorGB & 0x00ff);
 
290
                u8 a = (bpmem.clearcolorAR & 0xff00) >> 8;
 
291
 
 
292
                GLfloat left   = (GLfloat)bpmem.copyTexSrcXY.x / efbHalfWidth - 1.0f;
 
293
                GLfloat top    = 1.0f - (GLfloat)bpmem.copyTexSrcXY.y / efbHalfHeight;
 
294
                GLfloat right  = (GLfloat)(left + bpmem.copyTexSrcWH.x + 1) / efbHalfWidth - 1.0f;
 
295
                GLfloat bottom = 1.0f - (GLfloat)(top + bpmem.copyTexSrcWH.y + 1) / efbHalfHeight;
 
296
                GLfloat depth = (GLfloat)bpmem.clearZValue / (GLfloat)0x00ffffff;
 
297
                static const GLfloat verts[4][3] = {
 
298
                        { left, top, depth },
 
299
                        { right, top, depth },
 
300
                        { right, bottom, depth },
 
301
                        { left, bottom, depth }
 
302
                };
 
303
                {
 
304
                        glUseProgram(clearProg);
 
305
                        glVertexAttribPointer(clear_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
 
306
                        glUniform4f(clear_ucol, r, g, b, a);    
 
307
                        glEnableVertexAttribArray(col_apos);
 
308
                                glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
309
                        glDisableVertexAttribArray(col_apos);
 
310
                }
 
311
                GL_REPORT_ERRORD();
 
312
        }
 
313
 
 
314
        TexCacheEntry::TexCacheEntry()
 
315
        {
 
316
                Create();
 
317
        }
 
318
 
 
319
        void TexCacheEntry::Create()
 
320
        {
 
321
                FourTexUnits &texUnit = bpmem.tex[0];
 
322
 
 
323
                texImage0.hex = texUnit.texImage0[0].hex;
 
324
                texImage1.hex = texUnit.texImage1[0].hex;
 
325
                texImage2.hex = texUnit.texImage2[0].hex;
 
326
                texImage3.hex = texUnit.texImage3[0].hex;
 
327
                texTlut.hex = texUnit.texTlut[0].hex;
 
328
 
 
329
                int image_width = texImage0.width;
 
330
                int image_height = texImage0.height;
 
331
 
 
332
                DebugUtil::GetTextureBGRA(temp, 0, 0, image_width, image_height);
 
333
 
 
334
                glGenTextures(1, (GLuint *)&texture);
 
335
                glBindTexture(TEX2D, texture);
 
336
#ifdef USE_GLES
 
337
                glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)image_width, (GLsizei)image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
 
338
#else
 
339
                glTexImage2D(TEX2D, 0, GL_RGBA8, (GLsizei)image_width, (GLsizei)image_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp);
 
340
#endif
 
341
                GL_REPORT_ERRORD();
 
342
        }
 
343
 
 
344
        void TexCacheEntry::Destroy()
 
345
        {
 
346
                if (texture == 0)
 
347
                        return;
 
348
 
 
349
                glDeleteTextures(1, &texture);
 
350
                texture = 0;
 
351
        }
 
352
 
 
353
        void TexCacheEntry::Update()
 
354
        {
 
355
                FourTexUnits &texUnit = bpmem.tex[0];
 
356
 
 
357
                // extra checks cause textures to be reloaded much more
 
358
                if (texUnit.texImage0[0].hex != texImage0.hex ||
 
359
                //      texUnit.texImage1[0].hex != texImage1.hex ||
 
360
                //      texUnit.texImage2[0].hex != texImage2.hex ||
 
361
                        texUnit.texImage3[0].hex != texImage3.hex ||
 
362
                        texUnit.texTlut[0].hex   != texTlut.hex)
 
363
                {
 
364
                        Destroy();
 
365
                        Create();
 
366
                }
 
367
        }
 
368
}
 
369