Merge branch 'GLES3'

Conflicts:
	Source/Android/.idea/workspace.xml
This commit is contained in:
Ryan Houdek 2013-06-12 03:29:18 -05:00
commit 3ddd24872b
12 changed files with 385 additions and 12 deletions

View File

@ -12,7 +12,7 @@
<string-array name="gpuOptions">
<item>Software Renderer</item>
<!--item>OpenGL</item-->
<item>OpenGL</item>
</string-array>
<string-array name="gpuValues">

View File

@ -4,6 +4,7 @@ set(SRCS Src/BPFunctions.cpp
Src/CPMemory.cpp
Src/CommandProcessor.cpp
Src/Debugger.cpp
Src/DriverDetails.cpp
Src/Fifo.cpp
Src/FPSCounter.cpp
Src/FramebufferManagerBase.cpp

View File

@ -0,0 +1,69 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <map>
#include "LogManager.h"
#include "DriverDetails.h"
namespace DriverDetails
{
struct BugInfo
{
Bug m_bug; // Which bug it is
u32 m_devfamily; // Which device(family) has the error
double m_versionstart; // When it started
double m_versionend; // When it ended
bool m_hasbug; // Does it have it?
};
// Local members
Vendor m_vendor = VENDOR_UNKNOWN;
u32 m_devfamily = 0;
double m_version = 0.0;
// This is a list of all known bugs for each vendor
// We use this to check if the device and driver has a issue
BugInfo m_qualcommbugs[] = {
{BUG_NODYNUBOACCESS, 300, 14.0, -1.0},
{BUG_BROKENCENTROID, 300, 14.0, -1.0},
};
std::map<std::pair<Vendor, Bug>, BugInfo> m_bugs;
// Private function
void InitBugMap()
{
switch(m_vendor)
{
case VENDOR_QUALCOMM:
for (int a = 0; a < (sizeof(m_qualcommbugs) / sizeof(BugInfo)); ++a)
m_bugs[std::make_pair(m_vendor, m_qualcommbugs[a].m_bug)] = m_qualcommbugs[a];
break;
default:
break;
}
}
void Init(Vendor vendor, const u32 devfamily, const double version)
{
m_vendor = vendor;
m_devfamily = devfamily;
m_version = version;
InitBugMap();
for (auto it = m_bugs.begin(); it != m_bugs.end(); ++it)
if (it->second.m_devfamily == m_devfamily)
if (it->second.m_versionend == -1.0 || (it->second.m_versionstart <= m_version && it->second.m_versionend > m_version))
it->second.m_hasbug = true;
}
const bool HasBug(Bug bug)
{
auto it = m_bugs.find(std::make_pair(m_vendor, bug));
if (it == m_bugs.end())
return false;
return it->second.m_hasbug;
}
}

View File

@ -0,0 +1,52 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once
#include "CommonTypes.h"
namespace DriverDetails
{
// Enum of known vendors
// Tegra and Nvidia are separated out due to such substantial differences
enum Vendor
{
VENDOR_NVIDIA = 0,
VENDOR_ATI,
VENDOR_INTEL,
VENDOR_ARM,
VENDOR_QUALCOMM,
VENDOR_IMGTEC,
VENDOR_TEGRA,
VENDOR_VIVANTE,
VENDOR_UNKNOWN
};
// Enum of known bugs
// These can be vendor specific, but we put them all in here
// For putting a new bug in here, make sure to put a detailed comment above the enum
// This'll ensure we know exactly what the issue is.
enum Bug
{
// Bug: No Dynamic UBO array object access
// Affected Devices: Qualcomm/Adreno
// Started Version: 14
// Ended Version: -1
// Accessing UBO array members dynamically causes the Adreno shader compiler to crash
// Errors out with "Internal Error"
BUG_NODYNUBOACCESS = 0,
// Bug: Centroid is broken in shaders
// Affected devices: Qualcomm/Adreno
// Started Version: 14
// Ended Version: -1
// Centroid in/out, used in the shaders, is used for multisample buffers to get the texel correctly
// When MSAA is disabled, it acts like a regular in/out
// Tends to cause the driver to render full white or black
BUG_BROKENCENTROID,
};
// Initializes our internal vendor, device family, and driver version
void Init(Vendor vendor, const u32 devfamily, const double version);
// Once Vendor and driver version is set, this will return if it has the applicable bug passed to it.
const bool HasBug(Bug bug);
}

View File

@ -9,6 +9,7 @@
#include "BPMemory.h"
#include "CPMemory.h"
#include "DriverDetails.h"
#include "LightingShaderGen.h"
#include "VertexShaderGen.h"
#include "VideoConfig.h"
@ -322,13 +323,22 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType)
WRITE(p, "int posmtx = int(fposmtx);\n");
}
WRITE(p, "float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL) {
WRITE(p, "int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n");
WRITE(p, "float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n");
if (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS))
{
// This'll cause issues, but it can't be helped
WRITE(p, "float4 pos = float4(dot(" I_TRANSFORMMATRICES"[0], rawpos), dot(" I_TRANSFORMMATRICES"[1], rawpos), dot(" I_TRANSFORMMATRICES"[2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL)
WRITE(p, "float3 N0 = " I_NORMALMATRICES"[0].xyz, N1 = " I_NORMALMATRICES"[1].xyz, N2 = " I_NORMALMATRICES"[2].xyz;\n");
}
else
{
WRITE(p, "float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL) {
WRITE(p, "int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n");
WRITE(p, "float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n");
}
}
if (components & VB_HAS_NRM0)
WRITE(p, "float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n");
if (components & VB_HAS_NRM1)

View File

@ -182,6 +182,7 @@
<ClCompile Include="Src\CommandProcessor.cpp" />
<ClCompile Include="Src\CPMemory.cpp" />
<ClCompile Include="Src\Debugger.cpp" />
<ClCompile Include="Src\DriverDetails.cpp" />
<ClCompile Include="Src\EmuWindow.cpp" />
<ClCompile Include="Src\Fifo.cpp" />
<ClCompile Include="Src\FPSCounter.cpp" />
@ -229,6 +230,7 @@
<ClInclude Include="Src\CPMemory.h" />
<ClInclude Include="Src\DataReader.h" />
<ClInclude Include="Src\Debugger.h" />
<ClInclude Include="Src\DriverDetails.h" />
<ClInclude Include="Src\DLCache.h" />
<ClInclude Include="Src\EmuWindow.h" />
<ClInclude Include="Src\Fifo.h" />
@ -302,4 +304,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -24,9 +24,10 @@ if(USE_EGL)
EGL)
endif()
if(USE_GLES)
if(USE_GLES3)
set(LIBS ${LIBS}
GLESv2)
set(SRCS ${SRCS} Src/GLFunctions.cpp)
else()
set(LIBS ${LIBS}
GLEW

View File

@ -0,0 +1,93 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "GLFunctions.h"
#include "Log.h"
#ifdef USE_GLES3
PFNGLMAPBUFFERPROC glMapBuffer;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
PFNGLUNMAPBUFFERPROC glUnmapBuffer;
PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
PFNGLDELETESYNCPROC glDeleteSync;
PFNGLFENCESYNCPROC glFenceSync;
PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf;
PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri;
PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv;
PFNGLBINDSAMPLERPROC glBindSampler;
PFNGLDELETESAMPLERSPROC glDeleteSamplers;
PFNGLGENSAMPLERSPROC glGenSamplers;
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary;
PFNGLPROGRAMBINARYPROC glProgramBinary;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
PFNGLBEGINQUERYPROC glBeginQuery;
PFNGLENDQUERYPROC glEndQuery;
PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
PFNGLDELETEQUERIESPROC glDeleteQueries;
PFNGLGENQUERIESPROC glGenQueries;
#endif
namespace GLFunc
{
void LoadFunction(const char *name, void **func)
{
#ifdef USE_GLES3
*func = (void*)eglGetProcAddress(name);
if (*func == NULL)
{
ERROR_LOG(VIDEO, "Couldn't load function %s", name);
exit(0);
}
#endif
}
void Init()
{
LoadFunction("glBeginQuery", (void**)&glBeginQuery);
LoadFunction("glEndQuery", (void**)&glEndQuery);
LoadFunction("glGetQueryObjectuiv", (void**)&glGetQueryObjectuiv);
LoadFunction("glDeleteQueries", (void**)&glDeleteQueries);
LoadFunction("glGenQueries", (void**)&glGenQueries);
{
LoadFunction("glMapBuffer", (void**)&glMapBuffer);
LoadFunction("glUnmapBuffer", (void**)&glUnmapBuffer);
LoadFunction("glMapBufferRange", (void**)&glMapBufferRange);
LoadFunction("glBindBufferRange", (void**)&glBindBufferRange);
LoadFunction("glBlitFramebuffer", (void**)&glBlitFramebuffer);
LoadFunction("glGenVertexArrays", (void**)&glGenVertexArrays);
LoadFunction("glDeleteVertexArrays", (void**)&glDeleteVertexArrays);
LoadFunction("glBindVertexArray", (void**)&glBindVertexArray);
LoadFunction("glClientWaitSync", (void**)&glClientWaitSync);
LoadFunction("glDeleteSync", (void**)&glDeleteSync);
LoadFunction("glFenceSync", (void**)&glFenceSync);
LoadFunction("glSamplerParameterf", (void**)&glSamplerParameterf);
LoadFunction("glSamplerParameteri", (void**)&glSamplerParameteri);
LoadFunction("glSamplerParameterfv", (void**)&glSamplerParameterfv);
LoadFunction("glBindSampler", (void**)&glBindSampler);
LoadFunction("glDeleteSamplers", (void**)&glDeleteSamplers);
LoadFunction("glGenSamplers", (void**)&glGenSamplers);
}
LoadFunction("glGetProgramBinary", (void**)&glGetProgramBinary);
LoadFunction("glProgramBinary", (void**)&glProgramBinary);
LoadFunction("glProgramParameteri", (void**)&glProgramParameteri);
LoadFunction("glGetUniformBlockIndex", (void**)&glGetUniformBlockIndex);
LoadFunction("glUniformBlockBinding", (void**)&glUniformBlockBinding);
}
}

View File

@ -0,0 +1,90 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#ifndef GLFUNCTIONS_H_
#define GLFUNCTIONS_H_
#include "GLInterface.h"
#ifdef USE_GLES3
typedef GLvoid* (*PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
typedef GLvoid* (*PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
typedef void (*PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef GLboolean (*PFNGLUNMAPBUFFERPROC) (GLenum target);
typedef void (*PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
// VAOS
typedef void (*PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays);
typedef void (*PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays);
typedef void (*PFNGLBINDVERTEXARRAYPROC) (GLuint array);
// Sync
typedef GLenum (*PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
typedef void (*PFNGLDELETESYNCPROC) (GLsync GLsync);
typedef GLsync (*PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags);
//Sampler
typedef void (*PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
typedef void (*PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
typedef void (*PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params);
typedef void (*PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
typedef void (*PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers);
typedef void (*PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers);
//Program binar
typedef void (*PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, GLvoid*binary);
typedef void (*PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void* binary, GLsizei length);
typedef void (*PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
typedef GLuint (*PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName);
typedef void (*PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
//Query
typedef void (*PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
typedef void (*PFNGLENDQUERYPROC) (GLenum target);
typedef void (*PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params);
typedef void (*PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids);
typedef void (*PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids);
// ptrs
extern PFNGLBEGINQUERYPROC glBeginQuery;
extern PFNGLENDQUERYPROC glEndQuery;
extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
extern PFNGLGENQUERIESPROC glGenQueries;
extern PFNGLMAPBUFFERPROC glMapBuffer;
extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
extern PFNGLDELETESYNCPROC glDeleteSync;
extern PFNGLFENCESYNCPROC glFenceSync;
extern PFNGLGETPROGRAMBINARYPROC glGetProgramBinary;
extern PFNGLPROGRAMBINARYPROC glProgramBinary;
extern PFNGLPROGRAMPARAMETERIPROC glProgramParameteri;
//Sampler
extern PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf;
extern PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri;
extern PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv;
extern PFNGLBINDSAMPLERPROC glBindSampler;
extern PFNGLDELETESAMPLERSPROC glDeleteSamplers;
extern PFNGLGENSAMPLERSPROC glGenSamplers;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
#endif
namespace GLFunc
{
void Init();
}
#endif

View File

@ -21,6 +21,9 @@
#define PREC "highp"
#define TEXTYPE "sampler2D"
#define TEXFUNC "texture2D"
#ifdef USE_GLES3
#include "GLFunctions.h"
#endif
#else
#define TEX2D GL_TEXTURE_RECTANGLE_ARB
#define PREC

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "ProgramShaderCache.h"
#include "DriverDetails.h"
#include "MathUtil.h"
#include "StreamBuffer.h"
#include "Debugger.h"
@ -532,15 +533,15 @@ void ProgramShaderCache::CreateHeader ( void )
"%s\n"
"%s\n"
"#define COLOROUT(name) %s\n"
, v==GLSLES3 ? "300 es" : v==GLSL_120 ? "120" : v==GLSL_130 ? "130" : "140"
, v==GLSLES3 ? "precision highp float;" : ""
, v==GLSLES3 ? "" : v<=GLSL_130 ? "#extension GL_ARB_texture_rectangle : enable" : "#define texture2DRect texture"
, g_ActiveConfig.backend_info.bSupportsGLSLUBO && v<GLSL_140 ? "#extension GL_ARB_uniform_buffer_object : enable" : ""
, v==GLSL_120 ? "attribute" : "in"
, v==GLSL_120 ? "attribute" : "out"
, v==GLSL_120 ? "varying" : "centroid in"
, v==GLSL_120 ? "varying" : "centroid out"
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "in" : v==GLSL_120 ? "varying" : "centroid in"
, DriverDetails::HasBug(DriverDetails::BUG_BROKENCENTROID) ? "out" : v==GLSL_120 ? "varying" : "centroid out"
, v==GLSL_120 ? "#define texture texture2D" : ""
, v==GLSL_120 ? "#define round(x) floor((x)+0.5f)" : ""
, v==GLSL_120 ? "#define out " : ""

View File

@ -22,6 +22,7 @@
#endif
#include "CommonPaths.h"
#include "DriverDetails.h"
#include "VideoConfig.h"
#include "Statistics.h"
#include "ImageWrite.h"
@ -254,6 +255,53 @@ void ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsi
#endif
}
void InitDriverInfo()
{
// Get Vendor
std::string svendor = std::string(g_ogl_config.gl_vendor);
std::string srenderer = std::string(g_ogl_config.gl_renderer);
DriverDetails::Vendor vendor = DriverDetails::VENDOR_UNKNOWN;
u32 devfamily = 0;
double version = 0.0;
// Get Vendor first
if (svendor == "NVIDIA Corporation" && srenderer != "NVIDIA Tegra")
vendor = DriverDetails::VENDOR_NVIDIA;
else if (svendor == "ATI Technologies Inc.")
vendor = DriverDetails::VENDOR_ATI;
else if (std::string::npos != svendor.find("Intel"))
vendor = DriverDetails::VENDOR_INTEL;
else if (svendor == "ARM")
vendor = DriverDetails::VENDOR_ARM;
else if (svendor == "Qualcomm")
vendor = DriverDetails::VENDOR_QUALCOMM;
else if (svendor == "Imagination Technologies")
vendor = DriverDetails::VENDOR_IMGTEC;
else if (svendor == "NVIDIA Corporation" && srenderer != "NVIDIA Tegra")
vendor = DriverDetails::VENDOR_TEGRA;
else if (svendor == "Vivante Corporation")
vendor = DriverDetails::VENDOR_VIVANTE;
// Get device family and driver version...if we care about it
switch(vendor)
{
case DriverDetails::VENDOR_QUALCOMM:
{
if (std::string::npos != srenderer.find("Adreno (TM) 3"))
devfamily = 300;
else
devfamily = 200;
double glVersion;
sscanf(g_ogl_config.gl_version, "OpenGL ES %lg V@%lg", &glVersion, &version);
}
break;
// We don't care about these
default:
break;
}
DriverDetails::Init(vendor, devfamily, version);
}
// Init functions
Renderer::Renderer()
{
@ -271,10 +319,13 @@ Renderer::Renderer()
g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER);
g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION);
g_ogl_config.glsl_version = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
InitDriverInfo();
// Init extension support.
#ifdef USE_GLES3
// Set default GLES3 options
GLFunc::Init();
WARN_LOG(VIDEO, "Running the OpenGL ES 3 backend!");
g_Config.backend_info.bSupportsDualSourceBlend = false;
g_Config.backend_info.bSupportsGLSLUBO = true;
@ -1432,7 +1483,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
DrawDebugText();
GL_REPORT_ERRORD();
// Do our OSD callbacks
OSD::DoCallbacks(OSD::OSD_ONFRAME);
OSD::DrawMessages();