gsdx: merge back gsdx-ogl-wnd to the trunk

Here the list of the major change:
* Drop glew. It won't failed to load because of the wrong glew version
* shaders are include in the source code to ease release&packaging

* Port GSdx-ogl to MS Windows

* Fix lots of HW rendering bug. 8bits textures/upscale/transparency...
   - rendering isn't yet perfect but some games must be playable now.
* Add Fxaa shader.
* run on the opensouce driver (require mesa 9). You will need to build with EGL support
  - either use this cmake option -DEGL_API=TRUE
  - Or the handy script ./build.sh --egl ...
* Linux AMD users: you need to do a choice
    * speed but bad rendering => catalyst
    * correct rendering but slower => opensource radeon

* Some parts are still unimplemented:
 - MSAA
 - Vsync
 - Fully dynamic switch between EGL/GLX
 - Speed optimization
 - Others stuff that I have forgotten  :p



git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5667 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut
2013-06-15 20:11:13 +00:00
57 changed files with 5437 additions and 2709 deletions
+443 -4
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -14,8 +14,6 @@ INCLUDE(CheckCXXSymbolExists)
# include dir
find_path(EGL_INCLUDE_DIR EGL/eglext.h)
CHECK_CXX_SYMBOL_EXISTS(EGL_KHR_create_context "EGL/eglext.h" EGL_GL_CONTEXT_SUPPORT)
# finally the library itself
find_library(libEGL NAMES EGL)
set(EGL_LIBRARIES ${libEGL})
+10 -5
View File
@@ -2,20 +2,25 @@
use strict;
use warnings;
use File::Spec;
my @res = qw/convert interlace merge shadeboost tfx/;
my $path = "plugins/GSdx/res";
my $path = File::Spec->catdir("plugins", "GSdx", "res");
foreach my $r (@res) {
glsl2h($path, $r);
glsl2h($path, $r, "glsl");
}
glsl2h($path, "fxaa", "fx");
sub glsl2h {
my $path = shift;
my $glsl = shift;
my $ext = shift;
open(my $GLSL, "<$path/${glsl}.glsl");
open(my $H, ">$path/${glsl}.h");
my $in = File::Spec->catfile($path, "${glsl}.$ext");
my $out = File::Spec->catfile($path, "${glsl}.h");
open(my $GLSL, "<$in") or die;
open(my $H, ">$out") or die;
my $header = <<EOS;
/*
@@ -45,7 +50,7 @@ sub glsl2h {
#include "stdafx.h"
extern const char* ${glsl}_glsl =
static const char* ${glsl}_${ext} =
EOS
print $H $header;
+19 -26
View File
@@ -10,7 +10,6 @@ endif(NOT TOP_CMAKE_WAS_SOURCED)
set(Output GSdx-0.1.16)
set(CommonFlags
-DOGL_MT_HACK
-D_LINUX
-fno-operator-names
-mpreferred-stack-boundary=2
@@ -19,7 +18,6 @@ set(CommonFlags
-Wunused-variable
-std=c++0x
-fno-strict-aliasing
#-DOGL_DEBUG # FIXME remove me when code is ready
)
set(OptimizationFlags
@@ -29,7 +27,7 @@ set(OptimizationFlags
# Debug - Build
if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_definitions(${CommonFlags} -DOGL_DEBUG -g -Wall)
add_definitions(${CommonFlags} -D_DEBUG -g -Wall)
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
# Devel - Build
@@ -46,7 +44,13 @@ if(XDG_STD)
add_definitions(-DXDG_STD)
endif(XDG_STD)
# Select the EGL API
if(EGL_API AND EGL_FOUND)
add_definitions(-DEGL_API)
endif()
set(GSdxSources
GLLoader.cpp
GPU.cpp
GPUDrawScanline.cpp
GPUDrawScanlineCodeGenerator.cpp
@@ -105,6 +109,8 @@ set(GSdxSources
GSVector.cpp
GSVertexTrace.cpp
GSWnd.cpp
GSWndOGL.cpp
GSWndEGL.cpp
GSdx.cpp
stdafx.cpp
)
@@ -166,6 +172,8 @@ set(GSdxHeaders
GSVertexSW.h
GSVertexTrace.h
GSWnd.h
GSWndOGL.h
GSWndEGL.h
GSdx.h
stdafx.h
xbyak/xbyak.h
@@ -179,8 +187,10 @@ include_directories(.)
add_library(${Output} SHARED ${GSdxSources} ${GSdxHeaders})
target_link_libraries(${Output} ${X11_LIBRARIES})
target_link_libraries(${Output} ${GLEW_LIBRARY})
target_link_libraries(${Output} ${OPENGL_LIBRARIES})
if(EGL_API AND EGL_FOUND)
target_link_libraries(${Output} ${EGL_LIBRARIES})
endif()
if(Linux)
target_link_libraries(${Output} ${GTK2_LIBRARIES})
@@ -193,41 +203,24 @@ endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
if(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${PLUGIN_DIR})
foreach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
foreach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl fxaa.fx)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/${glsl} DESTINATION ${GLSL_SHADER_DIR})
endforeach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
endforeach()
else(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
foreach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
foreach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl fxaa.fx)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/${glsl} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
endforeach(glsl IN ITEMS convert.glsl interlace.glsl merge.glsl tfx.glsl shadeboost.glsl)
endforeach()
endif(PACKAGE_MODE)
################################### Replay Loader
if(BUILD_REPLAY_LOADERS)
set(Replay pcsx2_GSReplayLoader)
set(Static GSdx-static)
# We can have separate option for gsdx inside the player. It will only
# cost a 2nd rebuild of gsdx...
#add_definitions(${CommonFlags} ${OptimizationFlags} -W)
add_library(${Static} STATIC ${GSdxSources} ${GSdxHeaders})
add_executable(${Replay} linux_replay.cpp)
target_link_libraries(${Static} ${OPENGL_LIBRARIES})
target_link_libraries(${Static} ${X11_LIBRARIES})
target_link_libraries(${Static} ${GLEW_LIBRARY})
target_link_libraries(${Static} ${GTK2_LIBRARIES})
target_link_libraries(${Replay} ${Static})
# Warning others lib must be linked after GSdx...
target_link_libraries(${Replay} ${OPENGL_LIBRARIES})
target_link_libraries(${Replay} ${X11_LIBRARIES})
target_link_libraries(${Replay} ${GLEW_LIBRARY})
target_link_libraries(${Replay} ${GTK2_LIBRARIES})
target_link_libraries(${Replay} ${LIBC_LIBRARIES})
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
target_link_libraries(${Replay} "${USER_CMAKE_LD_FLAGS}")
+275
View File
@@ -0,0 +1,275 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GLLoader.h"
#include "GSdx.h"
PFNGLACTIVETEXTUREPROC gl_ActiveTexture = NULL;
PFNGLBLENDCOLORPROC gl_BlendColor = NULL;
PFNGLATTACHSHADERPROC gl_AttachShader = NULL;
PFNGLBINDBUFFERPROC gl_BindBuffer = NULL;
PFNGLBINDBUFFERBASEPROC gl_BindBufferBase = NULL;
PFNGLBINDFRAGDATALOCATIONINDEXEDPROC gl_BindFragDataLocationIndexed = NULL;
PFNGLBINDFRAMEBUFFERPROC gl_BindFramebuffer = NULL;
PFNGLBINDPROGRAMPIPELINEPROC gl_BindProgramPipeline = NULL;
PFNGLBINDSAMPLERPROC gl_BindSampler = NULL;
PFNGLBINDVERTEXARRAYPROC gl_BindVertexArray = NULL;
PFNGLBLENDEQUATIONSEPARATEPROC gl_BlendEquationSeparate = NULL;
PFNGLBLENDFUNCSEPARATEPROC gl_BlendFuncSeparate = NULL;
PFNGLBLITFRAMEBUFFERPROC gl_BlitFramebuffer = NULL;
PFNGLBUFFERDATAPROC gl_BufferData = NULL;
PFNGLCHECKFRAMEBUFFERSTATUSPROC gl_CheckFramebufferStatus = NULL;
PFNGLCLEARBUFFERFVPROC gl_ClearBufferfv = NULL;
PFNGLCLEARBUFFERIVPROC gl_ClearBufferiv = NULL;
PFNGLCOMPILESHADERPROC gl_CompileShader = NULL;
PFNGLCOPYIMAGESUBDATANVPROC gl_CopyImageSubDataNV = NULL;
PFNGLCREATEPROGRAMPROC gl_CreateProgram = NULL;
PFNGLCREATESHADERPROC gl_CreateShader = NULL;
PFNGLCREATESHADERPROGRAMVPROC gl_CreateShaderProgramv = NULL;
PFNGLDELETEBUFFERSPROC gl_DeleteBuffers = NULL;
PFNGLDELETEFRAMEBUFFERSPROC gl_DeleteFramebuffers = NULL;
PFNGLDELETEPROGRAMPROC gl_DeleteProgram = NULL;
PFNGLDELETEPROGRAMPIPELINESPROC gl_DeleteProgramPipelines = NULL;
PFNGLDELETESAMPLERSPROC gl_DeleteSamplers = NULL;
PFNGLDELETESHADERPROC gl_DeleteShader = NULL;
PFNGLDELETEVERTEXARRAYSPROC gl_DeleteVertexArrays = NULL;
PFNGLDETACHSHADERPROC gl_DetachShader = NULL;
PFNGLDRAWBUFFERSPROC gl_DrawBuffers = NULL;
PFNGLDRAWELEMENTSBASEVERTEXPROC gl_DrawElementsBaseVertex = NULL;
PFNGLENABLEVERTEXATTRIBARRAYPROC gl_EnableVertexAttribArray = NULL;
PFNGLFRAMEBUFFERRENDERBUFFERPROC gl_FramebufferRenderbuffer = NULL;
PFNGLFRAMEBUFFERTEXTURE2DPROC gl_FramebufferTexture2D = NULL;
PFNGLGENBUFFERSPROC gl_GenBuffers = NULL;
PFNGLGENFRAMEBUFFERSPROC gl_GenFramebuffers = NULL;
PFNGLGENPROGRAMPIPELINESPROC gl_GenProgramPipelines = NULL;
PFNGLGENSAMPLERSPROC gl_GenSamplers = NULL;
PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays = NULL;
PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv = NULL;
PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB = NULL;
PFNGLGETFRAGDATAINDEXPROC gl_GetFragDataIndex = NULL;
PFNGLGETFRAGDATALOCATIONPROC gl_GetFragDataLocation = NULL;
PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog = NULL;
PFNGLGETPROGRAMIVPROC gl_GetProgramiv = NULL;
PFNGLGETSHADERIVPROC gl_GetShaderiv = NULL;
PFNGLGETSTRINGIPROC gl_GetStringi = NULL;
PFNGLISFRAMEBUFFERPROC gl_IsFramebuffer = NULL;
PFNGLLINKPROGRAMPROC gl_LinkProgram = NULL;
PFNGLMAPBUFFERPROC gl_MapBuffer = NULL;
PFNGLMAPBUFFERRANGEPROC gl_MapBufferRange = NULL;
PFNGLPROGRAMPARAMETERIPROC gl_ProgramParameteri = NULL;
PFNGLSAMPLERPARAMETERFPROC gl_SamplerParameterf = NULL;
PFNGLSAMPLERPARAMETERIPROC gl_SamplerParameteri = NULL;
PFNGLSHADERSOURCEPROC gl_ShaderSource = NULL;
PFNGLUNIFORM1IPROC gl_Uniform1i = NULL;
PFNGLUNMAPBUFFERPROC gl_UnmapBuffer = NULL;
PFNGLUSEPROGRAMSTAGESPROC gl_UseProgramStages = NULL;
PFNGLVERTEXATTRIBIPOINTERPROC gl_VertexAttribIPointer = NULL;
PFNGLVERTEXATTRIBPOINTERPROC gl_VertexAttribPointer = NULL;
PFNGLTEXSTORAGE2DPROC gl_TexStorage2D = NULL;
PFNGLBUFFERSUBDATAPROC gl_BufferSubData = NULL;
// NO GL4.1
PFNGLUSEPROGRAMPROC gl_UseProgram = NULL;
PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog = NULL;
PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i = NULL;
// NO GL4.2
PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex = NULL;
PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding = NULL;
PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation = NULL;
namespace GLLoader {
bool fglrx_buggy_driver = false;
bool found_GL_ARB_separate_shader_objects = false;
bool found_GL_ARB_shading_language_420pack = false;
bool found_GL_ARB_texture_storage = false;
bool found_geometry_shader = true;
bool found_GL_NV_copy_image = false;
bool found_GL_ARB_copy_image = false;
bool found_only_gl30 = false;
bool check_gl_version(uint32 major, uint32 minor) {
const GLubyte* s = glGetString(GL_VERSION);
if (s == NULL) return false;
const char* vendor = (const char*)glGetString(GL_VENDOR);
fprintf(stderr, "Supported Opengl version: %s on GPU: %s. Vendor: %s\n", s, glGetString(GL_RENDERER), vendor);
// Name change but driver is still bad!
if (strstr(vendor, "ATI") || strstr(vendor, "Advanced Micro Devices"))
fglrx_buggy_driver = true;
GLuint dot = 0;
while (s[dot] != '\0' && s[dot] != '.') dot++;
if (dot == 0) return false;
GLuint major_gl = s[dot-1]-'0';
GLuint minor_gl = s[dot+1]-'0';
if ( (major_gl < 3) || ( major_gl == 3 && minor_gl < 2 ) ) {
fprintf(stderr, "Geometry shaders are not supported. Required openGL3.2\n");
found_geometry_shader = false;
}
if (theApp.GetConfig("override_geometry_shader", -1) != -1) {
found_geometry_shader = !!theApp.GetConfig("override_geometry_shader", -1);
fprintf(stderr, "Override geometry shaders detection\n");
}
if ( (major_gl == 3) && minor_gl < 3) {
// Opensource driver spotted
found_only_gl30 = true;
}
if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) {
fprintf(stderr, "OPENGL %d.%d is not supported\n", major, minor);
return false;
}
return true;
}
void init_gl_function() {
GL_LOADFN(gl_ActiveTexture, glActiveTexture);
GL_LOADFN(gl_BlendColor, glBlendColor);
GL_LOADFN(gl_AttachShader, glAttachShader);
GL_LOADFN(gl_BindBuffer, glBindBuffer);
GL_LOADFN(gl_BindBufferBase, glBindBufferBase);
GL_LOADFN(gl_BindFragDataLocationIndexed, glBindFragDataLocationIndexed);
GL_LOADFN(gl_BindFramebuffer, glBindFramebuffer);
GL_LOADFN(gl_BindProgramPipeline, glBindProgramPipeline);
GL_LOADFN(gl_BindSampler, glBindSampler);
GL_LOADFN(gl_BindVertexArray, glBindVertexArray);
GL_LOADFN(gl_BlendEquationSeparate, glBlendEquationSeparate);
GL_LOADFN(gl_BlendFuncSeparate, glBlendFuncSeparate);
GL_LOADFN(gl_BlitFramebuffer, glBlitFramebuffer);
GL_LOADFN(gl_BufferData, glBufferData);
GL_LOADFN(gl_CheckFramebufferStatus, glCheckFramebufferStatus);
GL_LOADFN(gl_ClearBufferfv, glClearBufferfv);
GL_LOADFN(gl_ClearBufferiv, glClearBufferiv);
GL_LOADFN(gl_CompileShader, glCompileShader);
GL_LOADFN(gl_CopyImageSubDataNV, glCopyImageSubDataNV);
GL_LOADFN(gl_CreateProgram, glCreateProgram);
GL_LOADFN(gl_CreateShader, glCreateShader);
GL_LOADFN(gl_CreateShaderProgramv, glCreateShaderProgramv);
GL_LOADFN(gl_DeleteBuffers, glDeleteBuffers);
GL_LOADFN(gl_DeleteFramebuffers, glDeleteFramebuffers);
GL_LOADFN(gl_DeleteProgram, glDeleteProgram);
GL_LOADFN(gl_DeleteProgramPipelines, glDeleteProgramPipelines);
GL_LOADFN(gl_DeleteSamplers, glDeleteSamplers);
GL_LOADFN(gl_DeleteShader, glDeleteShader);
GL_LOADFN(gl_DeleteVertexArrays, glDeleteVertexArrays);
GL_LOADFN(gl_DetachShader, glDetachShader);
GL_LOADFN(gl_DrawBuffers, glDrawBuffers);
GL_LOADFN(gl_DrawElementsBaseVertex, glDrawElementsBaseVertex);
GL_LOADFN(gl_EnableVertexAttribArray, glEnableVertexAttribArray);
GL_LOADFN(gl_FramebufferRenderbuffer, glFramebufferRenderbuffer);
GL_LOADFN(gl_FramebufferTexture2D, glFramebufferTexture2D);
GL_LOADFN(gl_GenBuffers, glGenBuffers);
GL_LOADFN(gl_GenFramebuffers, glGenFramebuffers);
GL_LOADFN(gl_GenProgramPipelines, glGenProgramPipelines);
GL_LOADFN(gl_GenSamplers, glGenSamplers);
GL_LOADFN(gl_GenVertexArrays, glGenVertexArrays);
GL_LOADFN(gl_GetBufferParameteriv, glGetBufferParameteriv);
GL_LOADFN(gl_GetDebugMessageLogARB, glGetDebugMessageLogARB);
GL_LOADFN(gl_GetFragDataIndex, glGetFragDataIndex);
GL_LOADFN(gl_GetFragDataLocation, glGetFragDataLocation);
GL_LOADFN(gl_GetProgramInfoLog, glGetProgramInfoLog);
GL_LOADFN(gl_GetProgramiv, glGetProgramiv);
GL_LOADFN(gl_GetShaderiv, glGetShaderiv);
GL_LOADFN(gl_GetStringi, glGetStringi);
GL_LOADFN(gl_IsFramebuffer, glIsFramebuffer);
GL_LOADFN(gl_LinkProgram, glLinkProgram);
GL_LOADFN(gl_MapBuffer, glMapBuffer);
GL_LOADFN(gl_MapBufferRange, glMapBufferRange);
GL_LOADFN(gl_ProgramParameteri, glProgramParameteri);
GL_LOADFN(gl_SamplerParameterf, glSamplerParameterf);
GL_LOADFN(gl_SamplerParameteri, glSamplerParameteri);
GL_LOADFN(gl_ShaderSource, glShaderSource);
GL_LOADFN(gl_Uniform1i, glUniform1i);
GL_LOADFN(gl_UnmapBuffer, glUnmapBuffer);
GL_LOADFN(gl_UseProgramStages, glUseProgramStages);
GL_LOADFN(gl_VertexAttribIPointer, glVertexAttribIPointer);
GL_LOADFN(gl_VertexAttribPointer, glVertexAttribPointer);
GL_LOADFN(gl_TexStorage2D, glTexStorage2D);
GL_LOADFN(gl_BufferSubData, glBufferSubData);
// NO GL4.1
GL_LOADFN(gl_UseProgram, glUseProgram);
GL_LOADFN(gl_GetShaderInfoLog, glGetShaderInfoLog);
GL_LOADFN(gl_ProgramUniform1i, glProgramUniform1i);
// NO GL4.2
GL_LOADFN(gl_GetUniformBlockIndex, glGetUniformBlockIndex);
GL_LOADFN(gl_UniformBlockBinding, glUniformBlockBinding);
GL_LOADFN(gl_GetUniformLocation, glGetUniformLocation);
}
bool check_gl_supported_extension() {
int max_ext = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &max_ext);
fprintf(stderr, "DEBUG: check_gl_supported_extension\n");
if (gl_GetStringi && max_ext) {
for (GLint i = 0; i < max_ext; i++) {
string ext((const char*)gl_GetStringi(GL_EXTENSIONS, i));
if (ext.compare("GL_ARB_separate_shader_objects") == 0) {
if (!fglrx_buggy_driver) found_GL_ARB_separate_shader_objects = true;
else fprintf(stderr, "Buggy driver detected, GL_ARB_separate_shader_objects will be disabled\n");
}
if (ext.compare("GL_ARB_shading_language_420pack") == 0) found_GL_ARB_shading_language_420pack = true;
if (ext.compare("GL_ARB_texture_storage") == 0) found_GL_ARB_texture_storage = true;
if (ext.compare("GL_NV_copy_image") == 0) found_GL_NV_copy_image = true;
// Replace previous extensions (when driver will be updated)
if (ext.compare("GL_ARB_copy_image") == 0) found_GL_ARB_copy_image = true;
}
}
if (!found_GL_ARB_separate_shader_objects) {
fprintf(stderr, "GL_ARB_separate_shader_objects is not supported\n");
}
if (!found_GL_ARB_shading_language_420pack) {
fprintf(stderr, "GL_ARB_shading_language_420pack is not supported\n");
}
if (!found_GL_ARB_texture_storage) {
fprintf(stderr, "GL_ARB_texture_storage is not supported\n");
return false;
}
if (theApp.GetConfig("override_GL_ARB_shading_language_420pack", -1) != -1) {
found_GL_ARB_shading_language_420pack = !!theApp.GetConfig("override_GL_ARB_shading_language_420pack", -1);
fprintf(stderr, "Override GL_ARB_shading_language_420pack detection\n");
}
if (theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1) != -1) {
found_GL_ARB_separate_shader_objects = !!theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1);
fprintf(stderr, "Override GL_ARB_separate_shader_objects detection\n");
}
if (theApp.GetConfig("ovveride_GL_ARB_copy_image", -1) != -1) {
// Same extension so override both
found_GL_ARB_copy_image = !!theApp.GetConfig("override_GL_ARB_copy_image", -1);
found_GL_NV_copy_image = !!theApp.GetConfig("override_GL_ARB_copy_image", -1);
fprintf(stderr, "Override GL_ARB_copy_image detection\n");
fprintf(stderr, "Override GL_NV_copy_image detection\n");
}
return true;
}
}
+138
View File
@@ -0,0 +1,138 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#ifdef _LINUX
#include <GL/glx.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
#ifdef _WINDOWS
#define GL_LOADFN(name, glName) { \
if( (*(void**)&name = (void*)wglGetProcAddress(#glName)) == NULL ) { \
fprintf(stderr,"Failed to find %s\n", #glName); \
} \
}
#else
#ifdef EGL_API
#define GL_LOADFN(name, glName) { \
if( (*(void**)&name = (void*)eglGetProcAddress(#glName)) == NULL ) { \
fprintf(stderr,"Failed to find %s\n", #glName); \
} \
}
#else
#define GL_LOADFN(name, glName) { \
if( (*(void**)&name = (void*)glXGetProcAddress((const GLubyte*)#glName)) == NULL ) { \
fprintf(stderr,"Failed to find %s\n", #glName); \
} \
}
#endif
#endif
extern PFNGLACTIVETEXTUREPROC gl_ActiveTexture;
extern PFNGLBLENDCOLORPROC gl_BlendColor;
extern PFNGLATTACHSHADERPROC gl_AttachShader;
extern PFNGLBINDBUFFERPROC gl_BindBuffer;
extern PFNGLBINDBUFFERBASEPROC gl_BindBufferBase;
extern PFNGLBINDFRAGDATALOCATIONINDEXEDPROC gl_BindFragDataLocationIndexed;
extern PFNGLBINDFRAMEBUFFERPROC gl_BindFramebuffer;
extern PFNGLBINDPROGRAMPIPELINEPROC gl_BindProgramPipeline;
extern PFNGLBINDSAMPLERPROC gl_BindSampler;
extern PFNGLBINDVERTEXARRAYPROC gl_BindVertexArray;
extern PFNGLBLENDEQUATIONSEPARATEPROC gl_BlendEquationSeparate;
extern PFNGLBLENDFUNCSEPARATEPROC gl_BlendFuncSeparate;
extern PFNGLBLITFRAMEBUFFERPROC gl_BlitFramebuffer;
extern PFNGLBUFFERDATAPROC gl_BufferData;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC gl_CheckFramebufferStatus;
extern PFNGLCLEARBUFFERFVPROC gl_ClearBufferfv;
extern PFNGLCLEARBUFFERIVPROC gl_ClearBufferiv;
extern PFNGLCOMPILESHADERPROC gl_CompileShader;
extern PFNGLCOPYIMAGESUBDATANVPROC gl_CopyImageSubDataNV;
extern PFNGLCREATEPROGRAMPROC gl_CreateProgram;
extern PFNGLCREATESHADERPROC gl_CreateShader;
extern PFNGLCREATESHADERPROGRAMVPROC gl_CreateShaderProgramv;
extern PFNGLDELETEBUFFERSPROC gl_DeleteBuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC gl_DeleteFramebuffers;
extern PFNGLDELETEPROGRAMPROC gl_DeleteProgram;
extern PFNGLDELETEPROGRAMPIPELINESPROC gl_DeleteProgramPipelines;
extern PFNGLDELETESAMPLERSPROC gl_DeleteSamplers;
extern PFNGLDELETESHADERPROC gl_DeleteShader;
extern PFNGLDELETEVERTEXARRAYSPROC gl_DeleteVertexArrays;
extern PFNGLDETACHSHADERPROC gl_DetachShader;
extern PFNGLDRAWBUFFERSPROC gl_DrawBuffers;
extern PFNGLDRAWELEMENTSBASEVERTEXPROC gl_DrawElementsBaseVertex;
extern PFNGLENABLEVERTEXATTRIBARRAYPROC gl_EnableVertexAttribArray;
extern PFNGLFRAMEBUFFERRENDERBUFFERPROC gl_FramebufferRenderbuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC gl_FramebufferTexture2D;
extern PFNGLGENBUFFERSPROC gl_GenBuffers;
extern PFNGLGENFRAMEBUFFERSPROC gl_GenFramebuffers;
extern PFNGLGENPROGRAMPIPELINESPROC gl_GenProgramPipelines;
extern PFNGLGENSAMPLERSPROC gl_GenSamplers;
extern PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays;
extern PFNGLGETBUFFERPARAMETERIVPROC gl_GetBufferParameteriv;
extern PFNGLGETDEBUGMESSAGELOGARBPROC gl_GetDebugMessageLogARB;
extern PFNGLGETFRAGDATAINDEXPROC gl_GetFragDataIndex;
extern PFNGLGETFRAGDATALOCATIONPROC gl_GetFragDataLocation;
extern PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog;
extern PFNGLGETPROGRAMIVPROC gl_GetProgramiv;
extern PFNGLGETSHADERIVPROC gl_GetShaderiv;
extern PFNGLGETSTRINGIPROC gl_GetStringi;
extern PFNGLISFRAMEBUFFERPROC gl_IsFramebuffer;
extern PFNGLLINKPROGRAMPROC gl_LinkProgram;
extern PFNGLMAPBUFFERPROC gl_MapBuffer;
extern PFNGLMAPBUFFERRANGEPROC gl_MapBufferRange;
extern PFNGLPROGRAMPARAMETERIPROC gl_ProgramParameteri;
extern PFNGLSAMPLERPARAMETERFPROC gl_SamplerParameterf;
extern PFNGLSAMPLERPARAMETERIPROC gl_SamplerParameteri;
extern PFNGLSHADERSOURCEPROC gl_ShaderSource;
extern PFNGLUNIFORM1IPROC gl_Uniform1i;
extern PFNGLUNMAPBUFFERPROC gl_UnmapBuffer;
extern PFNGLUSEPROGRAMSTAGESPROC gl_UseProgramStages;
extern PFNGLVERTEXATTRIBIPOINTERPROC gl_VertexAttribIPointer;
extern PFNGLVERTEXATTRIBPOINTERPROC gl_VertexAttribPointer;
extern PFNGLTEXSTORAGE2DPROC gl_TexStorage2D;
extern PFNGLBUFFERSUBDATAPROC gl_BufferSubData;
// NO GL4.1
extern PFNGLUSEPROGRAMPROC gl_UseProgram;
extern PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog;
extern PFNGLPROGRAMUNIFORM1IPROC gl_ProgramUniform1i;
// NO GL4.2
extern PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding;
extern PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
namespace GLLoader {
bool check_gl_version(uint32 major, uint32 minor);
void init_gl_function();
bool check_gl_supported_extension();
extern bool found_GL_ARB_separate_shader_objects;
extern bool found_GL_ARB_shading_language_420pack;
extern bool found_GL_ARB_texture_storage;
extern bool found_GL_ARB_copy_image;
extern bool found_GL_NV_copy_image;
extern bool found_geometry_shader;
extern bool fglrx_buggy_driver;
extern bool found_only_gl30;
}
+7 -5
View File
@@ -45,6 +45,8 @@ GPURenderer::GPURenderer(GSDevice* dev)
m_hWnd = NULL;
m_wndproc = NULL;
m_wnd = new GSWndDX();
#endif
}
@@ -74,7 +76,7 @@ bool GPURenderer::Create(void* hWnd)
SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
if(!m_wnd.Attach(m_hWnd))
if(!m_wnd->Attach(m_hWnd))
{
return false;
}
@@ -85,9 +87,9 @@ bool GPURenderer::Create(void* hWnd)
#endif
m_wnd.Show();
m_wnd->Show();
if(!m_dev->Create(&m_wnd))
if(!m_dev->Create(m_wnd))
{
return false;
}
@@ -189,10 +191,10 @@ void GPURenderer::VSync()
s = format("%s | %.2f mpps", s.c_str(), fps * fillrate / (1024 * 1024));
}
m_wnd.SetWindowText(s.c_str());
m_wnd->SetWindowText(s.c_str());
}
GSVector4i r = m_wnd.GetClientRect();
GSVector4i r = m_wnd->GetClientRect();
m_dev->Present(r.fit(m_aspectratio), 0);
}
+4 -1
View File
@@ -24,6 +24,9 @@
#include "GPUState.h"
#include "GSVertexList.h"
#include "GSDevice.h"
#ifdef _WINDOWS
#include "GSWndDX.h"
#endif
class GPURenderer : public GPUState
{
@@ -53,7 +56,7 @@ protected:
#endif
GSWnd m_wnd;
GSWnd* m_wnd;
public:
GPURenderer(GSDevice* dev);
+61 -47
View File
@@ -25,6 +25,8 @@
#include "GSRendererSW.h"
#include "GSRendererNull.h"
#include "GSDeviceNull.h"
#include "GSDeviceOGL.h"
#include "GSRendererOGL.h"
#ifdef _WINDOWS
@@ -32,6 +34,8 @@
#include "GSRendererDX11.h"
#include "GSDevice9.h"
#include "GSDevice11.h"
#include "GSWndDX.h"
#include "GSWndWGL.h"
#include "GSRendererCS.h"
#include "GSSettingsDlg.h"
@@ -39,8 +43,8 @@ static HRESULT s_hr = E_FAIL;
#else
#include "GSDeviceOGL.h"
#include "GSRendererOGL.h"
#include "GSWndOGL.h"
#include "GSWndEGL.h"
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -54,7 +58,7 @@ extern bool RunLinuxDialog();
#define PS2E_X86 0x01 // 32 bit
#define PS2E_X86_64 0x02 // 64 bit
#ifdef OGL_MT_HACK
#ifdef ENABLE_OGL_MT_HACK
GSRenderer* s_gs = NULL;
#else
static GSRenderer* s_gs = NULL;
@@ -173,7 +177,7 @@ EXPORT_C GSclose()
s_gs->m_dev = NULL;
s_gs->m_wnd.Detach();
s_gs->m_wnd->Detach();
}
static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
@@ -231,10 +235,8 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
case 0: dev = new GSDevice9(); break;
case 1: dev = new GSDevice11(); break;
#endif
#ifdef _LINUX
case 4: dev = new GSDeviceOGL(); break;
#endif
case 3: dev = new GSDeviceNull(); break;
case 4: dev = new GSDeviceOGL(); break;
}
if(dev == NULL)
@@ -246,25 +248,45 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
{
switch(renderer % 3)
{
default:
case 0:
default:
case 0:
switch(renderer)
{
default:
#ifdef _WINDOWS
s_gs = (renderer / 3) == 0 ? (GSRenderer*)new GSRendererDX9() : (GSRenderer*)new GSRendererDX11();
#else
s_gs = (GSRenderer*)new GSRendererOGL();
case 0: s_gs = (GSRenderer*)new GSRendererDX9(); break;
case 3: s_gs = (GSRenderer*)new GSRendererDX11(); break;
#endif
break;
case 1:
s_gs = new GSRendererSW(threads);
break;
case 2:
s_gs = new GSRendererNull();
break;
case 12: s_gs = (GSRenderer*)new GSRendererOGL(); break;
}
break;
case 1:
s_gs = new GSRendererSW(threads);
break;
case 2:
s_gs = new GSRendererNull();
break;
}
s_renderer = renderer;
}
}
if (s_gs->m_wnd == NULL)
{
#ifdef _WINDOWS
if (renderer / 3 == 4)
s_gs->m_wnd = new GSWndWGL();
else
s_gs->m_wnd = new GSWndDX();
#else
#ifdef EGL_API
s_gs->m_wnd = new GSWndEGL();
#else
s_gs->m_wnd = new GSWndOGL();
#endif
#endif
}
}
catch(std::exception& ex)
{
@@ -296,9 +318,9 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
return -1;
}
s_gs->m_wnd.Show();
s_gs->m_wnd->Show();
*dsp = s_gs->m_wnd.GetDisplay();
*dsp = s_gs->m_wnd->GetDisplay();
}
else
{
@@ -306,10 +328,10 @@ static int _GSopen(void** dsp, char* title, int renderer, int threads = -1)
#ifdef _LINUX
// Get the Xwindow from dsp.
if( !s_gs->m_wnd.Attach((void*)((uint32*)(dsp)+1), false) )
if( !s_gs->m_wnd->Attach((void*)((uint32*)(dsp)+1), false) )
return -1;
#else
s_gs->m_wnd.Attach(*dsp, false);
s_gs->m_wnd->Attach(*dsp, false);
#endif
}
@@ -440,19 +462,19 @@ EXPORT_C GSreadFIFO(uint8* mem)
{
try
{
#ifdef OGL_MT_HACK
#ifdef ENABLE_OGL_MT_HACK
// FIXME: double check which thread call this function
// See fifo2 issue below
#ifdef OGL_DEBUG
#ifdef ENABLE_OGL_DEBUG
if (theApp.GetConfig("renderer", 0) / 3 == 4) fprintf(stderr, "Disable FIFO1 on opengl\n");
#endif
s_gs->m_wnd.AttachContext();
s_gs->m_wnd->AttachContext();
#endif
s_gs->ReadFIFO(mem, 1);
#ifdef OGL_MT_HACK
s_gs->m_wnd.DetachContext();
#ifdef ENABLE_OGL_MT_HACK
s_gs->m_wnd->DetachContext();
#endif
}
catch (GSDXRecoverableError)
@@ -464,19 +486,16 @@ EXPORT_C GSreadFIFO2(uint8* mem, uint32 size)
{
try
{
#ifdef OGL_MT_HACK
#ifdef ENABLE_OGL_MT_HACK
// FIXME called from EE core thread not MTGS which cause
// invalidate data for opengl
#ifdef OGL_DEBUG
if (theApp.GetConfig("renderer", 0) / 3 == 4) fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size);
#endif
s_gs->m_wnd.AttachContext();
s_gs->m_wnd->AttachContext();
#endif
s_gs->ReadFIFO(mem, size);
#ifdef OGL_MT_HACK
s_gs->m_wnd.DetachContext();
#ifdef ENABLE_OGL_MT_HACK
s_gs->m_wnd->DetachContext();
#endif
}
catch (GSDXRecoverableError)
@@ -534,7 +553,7 @@ EXPORT_C GSvsync(int field)
{
#ifdef _WINDOWS
if(s_gs->m_wnd.IsManaged())
if(s_gs->m_wnd->IsManaged())
{
MSG msg;
@@ -549,8 +568,8 @@ EXPORT_C GSvsync(int field)
#endif
#ifdef OGL_MT_HACK
s_gs->m_wnd.AttachContext();
#ifdef ENABLE_OGL_MT_HACK
s_gs->m_wnd->AttachContext();
#endif
s_gs->VSync(field);
}
@@ -623,7 +642,7 @@ EXPORT_C GSconfigure()
if(GSSettingsDlg(s_isgsopen2).DoModal() == IDOK)
{
if(s_gs != NULL && s_gs->m_wnd.IsManaged())
if(s_gs != NULL && s_gs->m_wnd->IsManaged())
{
// Legacy apps like gsdxgui expect this...
@@ -633,15 +652,10 @@ EXPORT_C GSconfigure()
#else
// TODO: linux
if (RunLinuxDialog())
{
if(s_gs != NULL && s_gs->m_wnd.IsManaged())
{
GSshutdown();
}
if (RunLinuxDialog()) {
theApp.ReloadConfig();
}
#endif
} catch (GSDXRecoverableError)
{
+1 -1
View File
@@ -393,4 +393,4 @@ GSAdapter::GSAdapter(const D3DADAPTER_IDENTIFIER9 &desc_d3d9)
#endif
#ifdef _LINUX
// TODO
#endif
#endif
File diff suppressed because it is too large Load Diff
+18 -24
View File
@@ -105,11 +105,11 @@ public:
glEnable(GL_BLEND);
if (HasConstantFactor()) {
debug_factor = factor;
glBlendColor(factor, factor, factor, 0);
gl_BlendColor(factor, factor, factor, 0);
}
glBlendEquationSeparate(m_equation_RGB, m_equation_ALPHA);
glBlendFuncSeparate(m_func_sRGB, m_func_dRGB, m_func_sALPHA, m_func_dALPHA);
gl_BlendEquationSeparate(m_equation_RGB, m_equation_ALPHA);
gl_BlendFuncSeparate(m_func_sRGB, m_func_dRGB, m_func_sALPHA, m_func_dALPHA);
} else {
glDisable(GL_BLEND);
}
@@ -152,11 +152,11 @@ class GSDepthStencilOGL {
GLboolean m_depth_mask;
// Note front face and back might be split but it seems they have same parameter configuration
bool m_stencil_enable;
GLuint m_stencil_mask;
const GLuint m_stencil_mask;
GLuint m_stencil_func;
GLuint m_stencil_ref;
GLuint m_stencil_sfail_op;
GLuint m_stencil_spass_dfail_op;
const GLuint m_stencil_ref;
const GLuint m_stencil_sfail_op;
const GLuint m_stencil_spass_dfail_op;
GLuint m_stencil_spass_dpass_op;
char* NameOfParam(GLenum p)
@@ -182,7 +182,7 @@ public:
, m_stencil_enable(false)
, m_stencil_mask(1)
, m_stencil_func(0)
, m_stencil_ref(0)
, m_stencil_ref(1)
, m_stencil_sfail_op(GL_KEEP)
, m_stencil_spass_dfail_op(GL_KEEP)
, m_stencil_spass_dpass_op(GL_KEEP)
@@ -204,13 +204,16 @@ public:
glDisable(GL_DEPTH_TEST);
}
void SetupStencil(uint8 sref)
void SetupStencil()
{
uint ref = sref;
if (m_stencil_enable) {
glEnable(GL_STENCIL_TEST);
glStencilFunc(m_stencil_func, ref, m_stencil_mask);
// Note: here the mask control which bitplane is considered by the operation
glStencilFunc(m_stencil_func, m_stencil_ref, m_stencil_mask);
glStencilOp(m_stencil_sfail_op, m_stencil_spass_dfail_op, m_stencil_spass_dpass_op);
// FIXME only needed once since m_stencil_mask is constant
// Control which stencil bitplane are written
glStencilMask(m_stencil_mask);
} else
glDisable(GL_STENCIL_TEST);
}
@@ -280,8 +283,7 @@ class GSDeviceOGL : public GSDevice
uint32 tme:1;
uint32 fst:1;
uint32 logz:1;
uint32 rtcopy:1;
uint32 wildhack:2;
//uint32 rtcopy:1;
};
uint32 key;
@@ -504,7 +506,6 @@ class GSDeviceOGL : public GSDevice
GLuint ps[8]; // program object
GLuint ln; // sampler object
GLuint pt; // sampler object
GLuint gs;
GSDepthStencilOGL* dss;
GSBlendStateOGL* bs;
} m_convert;
@@ -540,7 +541,6 @@ class GSDeviceOGL : public GSDevice
GSVector2i viewport;
GSVector4i scissor;
GSDepthStencilOGL* dss;
uint8 sref;
GSBlendStateOGL* bs;
float bf;
// FIXME texture attachment in the FBO
@@ -552,9 +552,6 @@ class GSDeviceOGL : public GSDevice
GLenum draw;
} m_state;
bool m_srv_changed;
bool m_ss_changed;
hash_map<uint32, GLuint > m_vs;
hash_map<uint32, GLuint > m_gs;
hash_map<uint32, GLuint > m_ps;
@@ -574,8 +571,10 @@ class GSDeviceOGL : public GSDevice
protected:
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
void DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c);
void DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset = 0);
void DoFXAA(GSTexture* st, GSTexture* dt);
void DoShadeBoost(GSTexture* st, GSTexture* dt);
public:
@@ -584,9 +583,6 @@ class GSDeviceOGL : public GSDevice
void CheckDebugLog();
static void DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message);
void DebugOutput();
void DebugInput();
void DebugBB();
bool HasStencil() { return true; }
bool HasDepth32() { return true; }
@@ -607,6 +603,7 @@ class GSDeviceOGL : public GSDevice
void ClearDepth(GSTexture* t, float c);
void ClearStencil(GSTexture* t, uint8 c);
void CreateSampler(GLuint& sampler, bool bilinear, bool tau, bool tav);
GSTexture* CreateRenderTarget(int w, int h, bool msaa, int format = 0);
GSTexture* CreateDepthStencil(int w, int h, bool msaa, int format = 0);
GSTexture* CreateTexture(int w, int h, int format = 0);
@@ -657,9 +654,6 @@ class GSDeviceOGL : public GSDevice
void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
#ifdef DISABLE_GL41_SSO
hash_map<uint64, GLuint > m_single_prog;
GLuint link_prog();
#endif
};
+50 -43
View File
@@ -24,8 +24,8 @@
#include "GSdx.h"
#include "GSLinuxLogo.h"
GtkWidget *msaa_combo_box, *render_combo_box, *filter_combo_box;
GtkWidget *shadeboost_check, *paltex_check, *fba_check, *aa_check, *native_res_check;
GtkWidget *fsaa_combo_box, *render_combo_box, *filter_combo_box;
GtkWidget *shadeboost_check, *paltex_check, *fba_check, *aa_check, *native_res_check, *fxaa_check;
GtkWidget *sb_contrast, *sb_brightness, *sb_saturation;
GtkWidget *resx_spin, *resy_spin;
@@ -133,7 +133,7 @@ GtkWidget* CreateMsaaComboBox()
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "5x");
gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), "6x");
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), theApp.GetConfig("msaa", 0));
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), theApp.GetConfig("upscale_multiplier", 2)-1);
return combo_box;
}
@@ -152,31 +152,29 @@ GtkWidget* CreateFilterComboBox()
void toggle_widget_states( GtkWidget *widget, gpointer callback_data )
{
int render_type;
bool hardware_render = false, software_render = false, null_render = false;
render_type = gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box));
hardware_render = ((render_type % 3) == 1);
#if 0
int render_type = gtk_combo_box_get_active(GTK_COMBO_BOX(render_combo_box));
bool hardware_render = ((render_type % 3) == 1);
if (hardware_render)
{
gtk_widget_set_sensitive(filter_combo_box, true);
gtk_widget_set_sensitive(shadeboost_check, true);
gtk_widget_set_sensitive(paltex_check, true);
gtk_widget_set_sensitive(fba_check, true);
gtk_widget_set_sensitive(native_res_check, true);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_res_check)))
{
gtk_widget_set_sensitive(msaa_combo_box, false);
gtk_widget_set_sensitive(fsaa_combo_box, false);
gtk_widget_set_sensitive(resx_spin, false);
gtk_widget_set_sensitive(resy_spin, false);
}
else
{
gtk_widget_set_sensitive(msaa_combo_box, true);
gtk_widget_set_sensitive(fsaa_combo_box, true);
if (gtk_combo_box_get_active(GTK_COMBO_BOX(msaa_combo_box)) == 0)
if (gtk_combo_box_get_active(GTK_COMBO_BOX(fsaa_combo_box)) == 0)
{
gtk_widget_set_sensitive(resx_spin, true);
gtk_widget_set_sensitive(resy_spin, true);
@@ -188,26 +186,19 @@ void toggle_widget_states( GtkWidget *widget, gpointer callback_data )
}
}
gtk_widget_set_sensitive(sb_brightness,true);
gtk_widget_set_sensitive(sb_saturation,true);
gtk_widget_set_sensitive(sb_contrast,true);
}
else
{
gtk_widget_set_sensitive(filter_combo_box, false);
gtk_widget_set_sensitive(shadeboost_check, false);
gtk_widget_set_sensitive(paltex_check, false);
gtk_widget_set_sensitive(fba_check, false);
gtk_widget_set_sensitive(native_res_check, false);
gtk_widget_set_sensitive(msaa_combo_box, false);
gtk_widget_set_sensitive(fsaa_combo_box, false);
gtk_widget_set_sensitive(resx_spin, false);
gtk_widget_set_sensitive(resy_spin, false);
gtk_widget_set_sensitive(sb_brightness,false);
gtk_widget_set_sensitive(sb_saturation,false);
gtk_widget_set_sensitive(sb_contrast,false);
}
#endif
}
void set_hex_entry(GtkWidget *text_box, int hex_value) {
@@ -228,11 +219,11 @@ int get_hex_entry(GtkWidget *text_box) {
bool RunLinuxDialog()
{
GtkWidget *dialog;
GtkWidget *main_box, *res_box, *hw_box, *sw_box;
GtkWidget *native_box, *msaa_box, *resxy_box, *renderer_box, *interlace_box, *threads_box, *filter_box;
GtkWidget *hw_table, *res_frame, *hw_frame, *sw_frame;
GtkWidget *main_box, *res_box, *hw_box, *sw_box, *shader_box;
GtkWidget *native_box, *fsaa_box, *resxy_box, *renderer_box, *interlace_box, *threads_box, *filter_box;
GtkWidget *hw_table, *shader_table, *res_frame, *hw_frame, *sw_frame, *shader_frame;
GtkWidget *interlace_combo_box, *threads_spin;
GtkWidget *interlace_label, *threads_label, *native_label, *msaa_label, *rexy_label, *render_label, *filter_label;
GtkWidget *interlace_label, *threads_label, *native_label, *fsaa_label, *rexy_label, *render_label, *filter_label;
GtkWidget *hack_table, *hack_skipdraw_label, *hack_box, *hack_frame;
GtkWidget *hack_alpha_check, *hack_offset_check, *hack_skipdraw_spin, *hack_msaa_check, *hack_sprite_check, * hack_wild_check, *hack_enble_check;
@@ -261,6 +252,13 @@ bool RunLinuxDialog()
res_box = gtk_vbox_new(false, 5);
res_frame = gtk_frame_new ("OpenGL Internal Resolution (can cause glitches)");
gtk_container_add(GTK_CONTAINER(res_frame), res_box);
// The extra shader setting frame/container/table
shader_box = gtk_vbox_new(false, 5);
shader_frame = gtk_frame_new("Custom Shader Settings");
gtk_container_add(GTK_CONTAINER(shader_frame), shader_box);
shader_table = gtk_table_new(5,2, false);
gtk_container_add(GTK_CONTAINER(shader_box), shader_table);
// The hardware mode frame, container, and table.
hw_box = gtk_vbox_new(false, 5);
@@ -323,11 +321,11 @@ bool RunLinuxDialog()
gtk_box_pack_start(GTK_BOX(native_box), native_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(native_box), native_res_check, false, false, 5);
msaa_label = gtk_label_new("Or Use Scaling (broken):");
msaa_combo_box = CreateMsaaComboBox();
msaa_box = gtk_hbox_new(false, 5);
gtk_box_pack_start(GTK_BOX(msaa_box), msaa_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(msaa_box), msaa_combo_box, false, false, 5);
fsaa_label = gtk_label_new("Or Use Scaling (broken):");
fsaa_combo_box = CreateMsaaComboBox();
fsaa_box = gtk_hbox_new(false, 5);
gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_label, false, false, 5);
gtk_box_pack_start(GTK_BOX(fsaa_box), fsaa_combo_box, false, false, 5);
rexy_label = gtk_label_new("Custom Resolution:");
resx_spin = gtk_spin_button_new_with_range(256,8192,1);
@@ -368,15 +366,17 @@ bool RunLinuxDialog()
// Create our checkboxes.
shadeboost_check = gtk_check_button_new_with_label("Shade boost");
paltex_check = gtk_check_button_new_with_label("Allow 8 bit textures");
paltex_check = gtk_check_button_new_with_label("Allow 8 bits textures");
fba_check = gtk_check_button_new_with_label("Alpha correction (FBA)");
aa_check = gtk_check_button_new_with_label("Edge anti-aliasing (AA1)");
fxaa_check = gtk_check_button_new_with_label("Fxaa shader");
// Set the checkboxes.
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shadeboost_check), theApp.GetConfig("shadeboost", 1));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paltex_check), theApp.GetConfig("paltex", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fba_check), theApp.GetConfig("fba", 1));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa_check), theApp.GetConfig("aa1", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxaa_check), theApp.GetConfig("fxaa", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(native_res_check), theApp.GetConfig("nativeres", 0));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hack_alpha_check), theApp.GetConfig("UserHacks_AlphaHack", 0));
@@ -405,29 +405,32 @@ bool RunLinuxDialog()
// Populate all those boxes we created earlier with widgets.
gtk_container_add(GTK_CONTAINER(res_box), native_box);
gtk_container_add(GTK_CONTAINER(res_box), msaa_box);
gtk_container_add(GTK_CONTAINER(res_box), fsaa_box);
gtk_container_add(GTK_CONTAINER(res_box), resxy_box);
gtk_container_add(GTK_CONTAINER(sw_box), threads_box);
gtk_container_add(GTK_CONTAINER(sw_box), aa_check);
// Tables are strange. The numbers are for their position: left, right, top, bottom.
gtk_table_attach_defaults(GTK_TABLE(shader_table), fxaa_check, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(shader_table), shadeboost_check, 1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness_label, 0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_brightness, 1, 2, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast_label, 0, 1, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_contrast, 1, 2, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation_label, 0, 1, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(shader_table), sb_saturation, 1, 2, 3, 4);
// Tables are strange. The numbers are for their position: left, right, top, bottom.
gtk_table_attach_defaults(GTK_TABLE(hw_table), filter_box, 0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(hw_table), shadeboost_check, 1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(hw_table), paltex_check, 0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(hw_table), fba_check, 1, 2, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_brightness_label, 0, 1, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_brightness, 1, 2, 2, 3);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_contrast_label, 0, 1, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_contrast, 1, 2, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_saturation_label, 0, 1, 4, 5);
gtk_table_attach_defaults(GTK_TABLE(hw_table), sb_saturation, 1, 2, 4, 5);
// Put everything in the big box.
gtk_container_add(GTK_CONTAINER(main_box), renderer_box);
gtk_container_add(GTK_CONTAINER(main_box), interlace_box);
gtk_container_add(GTK_CONTAINER(main_box), res_frame);
gtk_container_add(GTK_CONTAINER(main_box), shader_frame);
gtk_container_add(GTK_CONTAINER(main_box), hw_frame);
gtk_container_add(GTK_CONTAINER(main_box), sw_frame);
@@ -437,7 +440,7 @@ bool RunLinuxDialog()
}
g_signal_connect(render_combo_box, "changed", G_CALLBACK(toggle_widget_states), NULL);
g_signal_connect(msaa_combo_box, "changed", G_CALLBACK(toggle_widget_states), NULL);
g_signal_connect(fsaa_combo_box, "changed", G_CALLBACK(toggle_widget_states), NULL);
g_signal_connect(native_res_check, "toggled", G_CALLBACK(toggle_widget_states), NULL);
// Put the box in the dialog and show it to the world.
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), main_box);
@@ -478,13 +481,14 @@ bool RunLinuxDialog()
theApp.SetConfig("paltex", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(paltex_check)));
theApp.SetConfig("fba", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fba_check)));
theApp.SetConfig("aa1", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aa_check)));
theApp.SetConfig("fxaa", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxaa_check)));
theApp.SetConfig("nativeres", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(native_res_check)));
theApp.SetConfig("ShadeBoost_Saturation", (int)gtk_range_get_value(GTK_RANGE(sb_saturation)));
theApp.SetConfig("ShadeBoost_Brightness", (int)gtk_range_get_value(GTK_RANGE(sb_brightness)));
theApp.SetConfig("ShadeBoost_Contrast", (int)gtk_range_get_value(GTK_RANGE(sb_contrast)));
theApp.SetConfig("msaa", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(msaa_combo_box)));
theApp.SetConfig("upscale_multiplier", (int)gtk_combo_box_get_active(GTK_COMBO_BOX(fsaa_combo_box))+1);
theApp.SetConfig("resx", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resx_spin)));
theApp.SetConfig("resy", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(resy_spin)));
@@ -497,6 +501,9 @@ bool RunLinuxDialog()
theApp.SetConfig("UserHacks_SpriteHack", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_sprite_check)));
theApp.SetConfig("UserHacks", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hack_enble_check)));
theApp.SetConfig("UserHacks_TCOffset", get_hex_entry(hack_tco_entry));
// NOT supported yet
theApp.SetConfig("msaa", 0);
// Let's just be windowed for the moment.
theApp.SetConfig("windowed", 1);
+10 -9
View File
@@ -23,7 +23,8 @@
#include "GSRenderer.h"
GSRenderer::GSRenderer()
: m_dev(NULL)
: m_wnd(NULL)
, m_dev(NULL)
, m_shader(0)
, m_shift_key(false)
, m_control_key(false)
@@ -52,7 +53,7 @@ GSRenderer::~GSRenderer()
bool GSRenderer::CreateWnd(const string& title, int w, int h)
{
return m_wnd.Create(title.c_str(), w, h);
return m_wnd->Create(title.c_str(), w, h);
}
bool GSRenderer::CreateDevice(GSDevice* dev)
@@ -60,7 +61,7 @@ bool GSRenderer::CreateDevice(GSDevice* dev)
ASSERT(dev);
ASSERT(!m_dev);
if(!dev->Create(&m_wnd))
if(!dev->Create(m_wnd))
{
return false;
}
@@ -330,7 +331,7 @@ void GSRenderer::VSync(int field)
#ifdef GSTITLEINFO_API_FORCE_VERBOSE
if (1)//force verbose reply
#else
if (m_wnd.IsManaged())
if (m_wnd->IsManaged())
#endif
{
//GSdx owns the window's title, be verbose.
@@ -379,9 +380,9 @@ void GSRenderer::VSync(int field)
s += " | Recording...";
}
if(m_wnd.IsManaged())
if(m_wnd->IsManaged())
{
m_wnd.SetWindowText(s.c_str());
m_wnd->SetWindowText(s.c_str());
}
else
{
@@ -411,7 +412,7 @@ void GSRenderer::VSync(int field)
// present
m_dev->Present(m_wnd.GetClientRect().fit(m_aspectratio), m_shader);
m_dev->Present(m_wnd->GetClientRect().fit(m_aspectratio), m_shader);
// snapshot
@@ -537,7 +538,7 @@ void GSRenderer::KeyEvent(GSKeyEventData* e)
printf("GSdx: Set deinterlace mode to %d (%s).\n", (int)m_interlace, theApp.m_gs_interlace.at(m_interlace).name.c_str());
return;
case VK_F6:
if( m_wnd.IsManaged() )
if( m_wnd->IsManaged() )
m_aspectratio = (m_aspectratio + 3 + step) % 3;
return;
case VK_F7:
@@ -571,7 +572,7 @@ void GSRenderer::KeyEvent(GSKeyEventData* e)
fprintf(stderr, "GSdx: Set deinterlace mode to %d (%s).\n", (int)m_interlace, theApp.m_gs_interlace.at(m_interlace).name.c_str());
return;
case XK_F6:
if( m_wnd.IsManaged() )
if( m_wnd->IsManaged() )
m_aspectratio = (m_aspectratio + 3 + step) % 3;
return;
case XK_F7:
+2 -2
View File
@@ -53,7 +53,7 @@ protected:
virtual GSTexture* GetOutput(int i) = 0;
public:
GSWnd m_wnd;
GSWnd* m_wnd;
GSDevice* m_dev;
public:
@@ -80,4 +80,4 @@ public:
GSCritSec m_pGSsetTitle_Crit;
char m_GStitleInfoBuffer[128];
};
};
+123 -16
View File
@@ -19,6 +19,7 @@
*
*/
#include "stdafx.h"
#include "GSRendererOGL.h"
#include "GSRenderer.h"
@@ -29,7 +30,6 @@ GSRendererOGL::GSRendererOGL()
m_logz = !!theApp.GetConfig("logz", 0);
m_fba = !!theApp.GetConfig("fba", 1);
UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0) && !!theApp.GetConfig("UserHacks", 0);
UserHacks_WildHack = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_WildHack", 0) : 0;
UserHacks_AlphaStencil = !!theApp.GetConfig("UserHacks_AlphaStencil", 0) && !!theApp.GetConfig("UserHacks", 0);
m_pixelcenter = GSVector2(-0.5f, -0.5f);
@@ -46,10 +46,113 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
return true;
}
void GSRendererOGL::EmulateGS()
{
switch(m_vt.m_primclass)
{
case GS_LINE_CLASS:
if(PRIM->IIP == 0)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 2)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 1];
m_index.buff[i + 1] = tmp;
}
}
break;
case GS_TRIANGLE_CLASS:
if(PRIM->IIP == 0)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 3)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 2];
m_index.buff[i + 2] = tmp;
}
}
break;
case GS_SPRITE_CLASS:
// each sprite converted to quad needs twice the space
while(m_vertex.tail * 2 > m_vertex.maxcount)
{
GrowVertexBuffer();
}
// assume vertices are tightly packed and sequentially indexed (it should be the case)
if(m_vertex.next >= 2)
{
size_t count = m_vertex.next;
int i = (int)count * 2 - 4;
GSVertex* s = &m_vertex.buff[count - 2];
GSVertex* q = &m_vertex.buff[count * 2 - 4];
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
{
GSVertex v0 = s[0];
GSVertex v1 = s[1];
v0.RGBAQ = v1.RGBAQ;
v0.XYZ.Z = v1.XYZ.Z;
v0.FOG = v1.FOG;
q[0] = v0;
q[3] = v1;
// swap x, s, u
uint16 x = v0.XYZ.X;
v0.XYZ.X = v1.XYZ.X;
v1.XYZ.X = x;
float s = v0.ST.S;
v0.ST.S = v1.ST.S;
v1.ST.S = s;
uint16 u = v0.U;
v0.U = v1.U;
v1.U = u;
q[1] = v0;
q[2] = v1;
index[0] = i + 0;
index[1] = i + 1;
index[2] = i + 2;
index[3] = i + 1;
index[4] = i + 2;
index[5] = i + 3;
}
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
m_index.tail = count * 3;
}
break;
default:
__assume(0);
}
}
void GSRendererOGL::SetupIA()
{
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
if (!GLLoader::found_geometry_shader)
EmulateGS();
void* ptr = NULL;
dev->IASetVertexState();
@@ -58,14 +161,15 @@ void GSRendererOGL::SetupIA()
{
GSVector4i::storent(ptr, m_vertex.buff, sizeof(GSVertex) * m_vertex.next);
if(UserHacks_WildHack && !isPackedUV_HackFlag)
{
GSVertex* RESTRICT d = (GSVertex*)ptr;
for(unsigned int i = 0; i < m_vertex.next; i++, d++)
if(PRIM->TME && PRIM->FST)
d->UV &= 0x3FEF3FEF;
}
if(UserHacks_WildHack && !isPackedUV_HackFlag)
{
GSVertex* RESTRICT d = (GSVertex*)ptr;
for(unsigned int i = 0; i < m_vertex.next; i++)
{
if(PRIM->TME && PRIM->FST) d[i].UV &= 0x3FEF3FEF;
}
}
dev->IAUnmapVertexBuffer();
}
@@ -80,9 +184,14 @@ void GSRendererOGL::SetupIA()
t = GL_POINTS;
break;
case GS_LINE_CLASS:
case GS_SPRITE_CLASS:
t = GL_LINES;
break;
case GS_SPRITE_CLASS:
if (GLLoader::found_geometry_shader)
t = GL_LINES;
else
t = GL_TRIANGLES;
break;
case GS_TRIANGLE_CLASS:
t = GL_TRIANGLES;
break;
@@ -129,10 +238,10 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
{GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)},
#else
{GSVector4(dst.x, -dst.w, 0.5f, 1.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, -dst.w, 0.5f, 1.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, -dst.y, 0.5f, 1.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, -dst.y, 0.5f, 1.0f), GSVector2(src.z, src.w)},
{GSVector4(dst.x, dst.y, 0.5f, 1.0f), GSVector2(src.x, src.y)},
{GSVector4(dst.z, dst.y, 0.5f, 1.0f), GSVector2(src.z, src.y)},
{GSVector4(dst.x, dst.w, 0.5f, 1.0f), GSVector2(src.x, src.w)},
{GSVector4(dst.z, dst.w, 0.5f, 1.0f), GSVector2(src.z, src.w)},
#endif
};
//fprintf(stderr, "DATE A:%fx%f B:%fx%f\n", dst.x, -dst.y, dst.z, -dst.w);
@@ -210,10 +319,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
vs_sel.tme = PRIM->TME;
vs_sel.fst = PRIM->FST;
//vs_sel.logz = dev->HasDepth32() ? 0 : m_logz ? 1 : 0;
vs_sel.logz = m_logz ? 1 : 0;
//OGL vs_sel.rtcopy = !!rtcopy;
vs_sel.rtcopy = false;
// The real GS appears to do no masking based on the Z buffer format and writing larger Z values
// than the buffer supports seems to be an error condition on the real GS, causing it to crash.
+1 -1
View File
@@ -39,11 +39,11 @@ class GSRendererOGL : public GSRendererHW
bool m_fba;
bool UserHacks_AlphaHack;
bool UserHacks_AlphaStencil;
unsigned int UserHacks_WildHack;
unsigned int UserHacks_TCOffset;
float UserHacks_TCO_x, UserHacks_TCO_y;
protected:
void EmulateGS();
void SetupIA();
public:
+5 -5
View File
@@ -23,7 +23,7 @@
#include "GSState.h"
#include "GSdx.h"
#ifdef OGL_MT_HACK
#ifdef ENABLE_OGL_MT_HACK
#include "GSRendererOGL.h"
extern GSRenderer* s_gs;
@@ -1275,8 +1275,8 @@ void GSState::GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r)
break;
case 1: // local -> host
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY);
#ifdef OGL_MT_HACK
s_gs->m_wnd.DetachContext();
#ifdef ENABLE_OGL_MT_HACK
s_gs->m_wnd->DetachContext();
#endif
break;
case 2: // local -> local
@@ -1782,8 +1782,8 @@ static hash_map<uint64, uint64> s_tags;
template<int index> void GSState::Transfer(const uint8* mem, uint32 size)
{
GSPerfMonAutoTimer pmat(&m_perfmon);
#ifdef OGL_MT_HACK
s_gs->m_wnd.AttachContext();
#ifdef ENABLE_OGL_MT_HACK
s_gs->m_wnd->AttachContext();
#endif
const uint8* start = mem;
+22 -56
View File
@@ -33,33 +33,15 @@ void GSDeviceOGL::CreateTextureFX()
m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer));
m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer));
glGenSamplers(1, &m_rt_ss);
// FIXME, seem to have no difference between sampler !!!
m_palette_ss = m_rt_ss;
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
// FIXME: need ogl extension sd.MaxAnisotropy = 16;
CreateSampler(m_palette_ss, false, false, false);
GSInputLayoutOGL vert_format[] =
{
// FIXME
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(0) } ,
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(8) } ,
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(12) } ,
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(16) } ,
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(20) } ,
// note: there is a 32 bits pad
{5 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertex) , (const GLvoid*)(24) } ,
{6 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertex) , (const GLvoid*)(28) } ,
};
@@ -67,10 +49,26 @@ void GSDeviceOGL::CreateTextureFX()
// Compile some dummy shaders to allow modification inside Apitrace for debug
GLuint dummy;
std::string macro = "";
std::string macro = "\n";
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &dummy, tfx_glsl, macro);
// Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution
GSDeviceOGL::GSSelector gs_sel;
for (uint32 key = 0; key < (1 << 3); key++) {
gs_sel.key = key;
SetupGS(gs_sel);
}
GSDeviceOGL::VSSelector vs_sel;
for (uint32 key = 0; key < (1 << 5); key++) {
vs_sel.key = key;
SetupVS(vs_sel, NULL);
}
// Use sane reset value
GSSetShader(0);
VSSetShader(0);
}
void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
@@ -85,8 +83,7 @@ void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
std::string macro = format("#define VS_BPPZ %d\n", sel.bppz)
+ format("#define VS_LOGZ %d\n", sel.logz)
+ format("#define VS_TME %d\n", sel.tme)
+ format("#define VS_FST %d\n", sel.fst)
+ format("#define VS_RTCOPY %d\n", sel.rtcopy);
+ format("#define VS_FST %d\n", sel.fst);
GLuint vs;
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &vs, tfx_glsl, macro);
@@ -98,7 +95,7 @@ void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
// *************************************************************
// Dynamic
// *************************************************************
if(m_vs_cb_cache.Update(cb)) {
if(cb != NULL && m_vs_cb_cache.Update(cb)) {
SetUniformBuffer(m_vs_cb);
m_vs_cb->upload(cb);
}
@@ -165,7 +162,6 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &ps, tfx_glsl, macro);
m_ps[sel] = ps;
i = m_ps.find(sel);
} else {
ps = i->second;
}
@@ -198,36 +194,7 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
// *************************************************************
// Static
// *************************************************************
glGenSamplers(1, &ss0);
if (ssel.ltf) {
glSamplerParameteri(ss0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glSamplerParameteri(ss0, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else {
glSamplerParameteri(ss0, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(ss0, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
// FIXME ensure U -> S, V -> T and W->R
if (ssel.tau)
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_S, GL_REPEAT);
else
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
if (ssel.tav)
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_T, GL_REPEAT);
else
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// FIXME which value for GL_TEXTURE_MIN_LOD
glSamplerParameterf(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
// FIXME: seems there is 2 possibility in opengl
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
// FIXME: need ogl extension sd.MaxAnisotropy = 16;
CreateSampler(ss0, ssel.ltf, ssel.tau, ssel.tav);
m_ps_ss[ssel] = ss0;
}
@@ -238,8 +205,7 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
}
}
PSSetSamplerState(ss0, ss1, sel.date ? m_rt_ss : 0);
PSSetSamplerState(ss0, ss1, 0);
PSSetShader(ps);
}
+142 -88
View File
@@ -19,10 +19,18 @@
*
*/
#include "stdafx.h"
#include <limits.h>
#include "GSTextureOGL.h"
static int g_state_texture_unit = -1;
static int g_state_texture_id = -1;
static GLuint g_state_texture_unit = -1;
static GLuint g_state_texture_id[7] = {0, 0, 0, 0, 0, 0, 0};
static GLuint g_color0 = 0;
static GLuint g_color1 = 0;
static GLuint g_depth = 0;
// FIXME: check if it possible to always use those setup by default
// glPixelStorei(GL_PACK_ALIGNMENT, 1);
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint fbo_read)
: m_pbo_id(0),
@@ -32,19 +40,19 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
// Opengl world
// Render work in parallal with framebuffer object (FBO) http://www.opengl.org/wiki/Framebuffer_Objects
// render are attached to FBO through : glFramebufferRenderbuffer. You can query the number of colorattachement with GL_MAX_COLOR_ATTACHMENTS
// FBO : constructor -> glGenFramebuffers, glDeleteFramebuffers
// binding -> glBindFramebuffer (target can be read/write/both)
// blit -> glBlitFramebuffer (read FB to draw FB)
// info -> glIsFramebuffer, glGetFramebufferAttachmentParameter, glCheckFramebufferStatus
// render are attached to FBO through : gl_FramebufferRenderbuffer. You can query the number of colorattachement with GL_MAX_COLOR_ATTACHMENTS
// FBO : constructor -> gl_GenFramebuffers, gl_DeleteFramebuffers
// binding -> gl_BindFramebuffer (target can be read/write/both)
// blit -> gl_BlitFramebuffer (read FB to draw FB)
// info -> gl_IsFramebuffer, glGetFramebufferAttachmentParameter, gl_CheckFramebufferStatus
//
// There are two types of framebuffer-attachable images; texture images and renderbuffer images.
// If an image of a texture object is attached to a framebuffer, OpenGL performs "render to texture".
// And if an image of a renderbuffer object is attached to a framebuffer, then OpenGL performs "offscreen rendering".
// Blitting:
// glDrawBuffers
// gl_DrawBuffers
// glReadBuffer
// glBlitFramebuffer
// gl_BlitFramebuffer
// *************************************************************
// m_size.x = w;
@@ -61,7 +69,7 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
switch (m_type) {
case GSTexture::Offscreen:
//FIXME I not sure we need a pixel buffer object. It seems more a texture
// glGenBuffers(1, &m_texture_id);
// gl_GenBuffers(1, &m_texture_id);
// m_texture_target = GL_PIXEL_UNPACK_BUFFER;
// ASSERT(0);
// Note there is also a buffer texture!!!
@@ -83,15 +91,17 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
break;
}
// Extra buffer to handle various pixel transfer
glGenBuffers(1, &m_pbo_id);
gl_GenBuffers(1, &m_pbo_id);
uint msaa_level;
#if 0
uint32 msaa_level;
if (m_msaa) {
// FIXME which level of MSAA
msaa_level = 1;
} else {
msaa_level = 0;
}
#endif
// Allocate the buffer
switch (m_type) {
@@ -104,25 +114,21 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
ASSERT(0); // TODO Later
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
glBufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
gl_BufferData(GL_PIXEL_PACK_BUFFER, m_pbo_size, NULL, GL_STREAM_DRAW);
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
ASSERT(!m_msaa);
case GSTexture::DepthStencil:
case GSTexture::RenderTarget:
case GSTexture::Texture:
// FIXME: check the opensource driver
// Howto allocate the texture unit !!!
// In worst case the HW renderer seems to use 3 texture unit
// For the moment SW renderer only use 1 so don't bother
EnableUnit(0);
EnableUnit(3);
if (m_msaa) {
ASSERT(m_texture_target == GL_TEXTURE_2D_MULTISAMPLE);
// Require a recent GLEW and GL4.3
//glTexStorage2DMultisample(m_texture_target, msaa_level, m_format, m_size.x, m_size.y, false);
// Require a recent GL4.3 extension
//gl_TexStorage2DMultisample(m_texture_target, msaa_level, m_format, m_size.x, m_size.y, false);
} else {
glTexStorage2D(m_texture_target, 1, m_format, m_size.x, m_size.y);
gl_TexStorage2D(m_texture_target, 1, m_format, m_size.x, m_size.y);
}
break;
default: break;
@@ -131,16 +137,49 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint
GSTextureOGL::~GSTextureOGL()
{
glDeleteBuffers(1, &m_pbo_id);
/* Unbind the texture from our local state */
for (uint32 i = 0; i < 7; i++)
if (g_state_texture_id[i] == m_texture_id)
g_state_texture_id[i] = 0;
gl_DeleteBuffers(1, &m_pbo_id);
glDeleteTextures(1, &m_texture_id);
}
void GSTextureOGL::Attach(GLenum attachment)
{
//fprintf(stderr, "format %d,%x\n", m_type, m_format);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
switch(attachment) {
case GL_COLOR_ATTACHMENT0:
if (g_color0 != m_texture_id) {
g_color0 = m_texture_id;
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
}
break;
case GL_COLOR_ATTACHMENT1:
if (g_color1 != m_texture_id) {
g_color1 = m_texture_id;
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
}
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
if (g_depth != m_texture_id) {
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
g_depth = m_texture_id;
}
break;
default:
gl_FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
break;
}
// FIXME DEBUG
//fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
//fprintf(stderr, "FB status %x\n", gl_CheckFramebufferStatus(GL_FRAMEBUFFER));
}
void GSTextureOGL::AttachRead(GLenum attachment)
{
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
glReadBuffer(attachment);
}
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
@@ -150,35 +189,53 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
// FIXME warning order of the y axis
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
EnableUnit(0);
EnableUnit(4);
// pitch could be different of width*element_size
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
// FIXME : it crash on colin mcrae rally 3 (others game too) when the size is 16
//fprintf(stderr, "Texture %dx%d with a pitch of %d\n", m_size.x, m_size.y, pitch >>2);
//fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
if (m_format == GL_RGBA8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
else if (m_format == GL_R16UI)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED_INTEGER, GL_R16UI, data);
else if (m_format == GL_R8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED, GL_R8, data);
else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
ASSERT(0);
// pitch is in byte wherease GL_UNPACK_ROW_LENGTH is in pixel
GLenum format;
GLenum type;
switch (m_format) {
case GL_RGBA8:
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
break;
case GL_R16UI:
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>1);
format = GL_RED;
type = GL_UNSIGNED_SHORT;
break;
case GL_R8:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
format = GL_RED;
type = GL_UNSIGNED_BYTE;
break;
default:
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
ASSERT(0);
}
#if 0
//if (m_size.x != 16)
if (r.width() > 16 && r.height() > 16)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
else {
fprintf(stderr, "skip texture upload\n");
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return false;
#ifdef _LINUX
if (GLLoader::fglrx_buggy_driver) {
// FIXME : it crash on colin mcrae rally 3 (others game too) when the texture is small
//if ((pitch >> 2) == 32 || r.width() < 32 || r.height() < 32) {
if ((r.width() < 32) || (pitch == 128 && r.width() == 32)) {
#ifdef ENABLE_OGL_DEBUG
fprintf(stderr, "Skip Texture %dx%d with a pitch of %d pixel. Type %x\n", m_size.x, m_size.y, pitch >>2, m_format);
fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
#endif
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return false;
}
}
#endif
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), format, type, data);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return true;
@@ -196,23 +253,20 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
#endif
}
void GSTextureOGL::EnableUnit(uint unit)
void GSTextureOGL::EnableUnit(uint32 unit)
{
if (!IsBackbuffer()) {
// FIXME
// Howto allocate the texture unit !!!
// In worst case the HW renderer seems to use 3 texture unit
// For the moment SW renderer only use 1 so don't bother
if (g_state_texture_unit != unit) {
g_state_texture_unit = unit;
glActiveTexture(GL_TEXTURE0 + unit);
// When you change the texture unit, texture must be rebinded
g_state_texture_id = m_texture_id;
glBindTexture(m_texture_target, m_texture_id);
} else if (g_state_texture_id != m_texture_id) {
g_state_texture_id = m_texture_id;
glBindTexture(m_texture_target, m_texture_id);
}
/* Not a real texture */
if (IsBackbuffer()) {
return;
}
if (g_state_texture_unit != unit) {
gl_ActiveTexture(GL_TEXTURE0 + unit);
g_state_texture_unit = unit;
}
if (g_state_texture_id[unit] != m_texture_id) {
g_state_texture_id[unit] = m_texture_id;
glBindTexture(m_texture_target, m_texture_id);
}
}
@@ -223,42 +277,44 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
// Set m.pitch <- size of a row
// I think in opengl we need to copy back the data to the RAM: glReadPixels — read a block of pixels from the frame buffer
//
// glMapBuffer — map a buffer object's data store
// gl_MapBuffer — map a buffer object's data store
// Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER
if (m_type == GSTexture::Offscreen) {
// Bind the texture to the read framebuffer to avoid any disturbance
EnableUnit(0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
EnableUnit(5);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
// FIXME It might be possible to only read a subrange of the texture based on r object
// Load the PBO with the data
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo_id);
if (m_format == GL_RGBA8) {
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, 0);
m.pitch = m_size.x * 4;
} else if (m_format == GL_R16UI) {
glPixelStorei(GL_PACK_ALIGNMENT, 2);
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 0);
m.pitch = m_size.x * 2;
} else if (m_format == GL_R8) {
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, m_size.x, m_size.y, GL_RED, GL_UNSIGNED_BYTE, 0);
m.pitch = m_size.x;
} else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
ASSERT(0);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// Give access from the CPU
m.bits = (uint8*) glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, m_pbo_size, GL_MAP_READ_BIT);
m.pitch = m_size.x;
m.bits = (uint8*) gl_MapBufferRange(GL_PIXEL_PACK_BUFFER, 0, m_pbo_size, GL_MAP_READ_BIT);
if ( m.bits ) {
return true;
} else {
fprintf(stderr, "bad mapping of the pbo\n");
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
return false;
}
}
@@ -285,8 +341,8 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
void GSTextureOGL::Unmap()
{
if (m_type == GSTexture::Offscreen) {
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
gl_UnmapBuffer(GL_PIXEL_PACK_BUFFER);
gl_BindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
}
@@ -404,22 +460,20 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
// for us
if (IsBackbuffer()) {
//glReadBuffer(GL_BACK);
//glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
//gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glReadPixels(0, 0, m_size.x, m_size.y, GL_RGBA, GL_UNSIGNED_BYTE, image);
} else if(IsDss()) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
//EnableUnit(0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_texture_target, m_texture_id, 0);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_texture_target, m_texture_id, 0);
glReadPixels(0, 0, m_size.x, m_size.y, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} else {
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
EnableUnit(0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
EnableUnit(6);
gl_FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture_target, m_texture_id, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
if (m_format == GL_RGBA8)
@@ -437,7 +491,7 @@ bool GSTextureOGL::Save(const string& fn, bool dds)
status = false;
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
if (status) Save(fn, image, pitch);

Some files were not shown because too many files have changed in this diff Show More