mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
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:
Vendored
+443
-4
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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}")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -393,4 +393,4 @@ GSAdapter::GSAdapter(const D3DADAPTER_IDENTIFIER9 &desc_d3d9)
|
||||
#endif
|
||||
#ifdef _LINUX
|
||||
// TODO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+421
-513
File diff suppressed because it is too large
Load Diff
+18
-24
@@ -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
|
||||
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user