diff --git a/3rdparty/GL/glext.h b/3rdparty/GL/glext.h index 6e5e6a1118..09400215ba 100644 --- a/3rdparty/GL/glext.h +++ b/3rdparty/GL/glext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2007-2010 The Khronos Group Inc. +** Copyright (c) 2007-2011 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -29,9 +29,9 @@ extern "C" { */ /* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated $Date: 2010-12-09 02:15:08 -0800 (Thu, 09 Dec 2010) $ */ +/* glext.h last updated $Date: 2011-08-08 00:34:29 -0700 (Mon, 08 Aug 2011) $ */ /* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 67 +#define GL_GLEXT_VERSION 72 /* Function declaration macros - to move into glplatform.h */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) @@ -1047,6 +1047,124 @@ extern "C" { /* reuse GL_UNDEFINED_VERTEX */ #endif +#ifndef GL_VERSION_4_2 +/* Reuse tokens from ARB_base_instance (none) */ +/* Reuse tokens from ARB_shading_language_420pack (none) */ +/* Reuse tokens from ARB_transform_feedback_instanced (none) */ +/* Reuse tokens from ARB_compressed_texture_pixel_storage */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE */ +/* reuse GL_PACK_COMPRESSED_BLOCK_WIDTH */ +/* reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT */ +/* reuse GL_PACK_COMPRESSED_BLOCK_DEPTH */ +/* reuse GL_PACK_COMPRESSED_BLOCK_SIZE */ +/* Reuse tokens from ARB_conservative_depth (none) */ +/* Reuse tokens from ARB_internalformat_query */ +/* reuse GL_NUM_SAMPLE_COUNTS */ +/* Reuse tokens from ARB_map_buffer_alignment */ +/* reuse GL_MIN_MAP_BUFFER_ALIGNMENT */ +/* Reuse tokens from ARB_shader_atomic_counters */ +/* reuse GL_ATOMIC_COUNTER_BUFFER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_BINDING */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_START */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_SIZE */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */ +/* reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_VERTEX_ATOMIC_COUNTERS */ +/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */ +/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */ +/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS */ +/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS */ +/* reuse GL_MAX_COMBINED_ATOMIC_COUNTERS */ +/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */ +/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */ +/* reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */ +/* reuse GL_UNSIGNED_INT_ATOMIC_COUNTER */ +/* Reuse tokens from ARB_shader_image_load_store */ +/* reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT */ +/* reuse GL_ELEMENT_ARRAY_BARRIER_BIT */ +/* reuse GL_UNIFORM_BARRIER_BIT */ +/* reuse GL_TEXTURE_FETCH_BARRIER_BIT */ +/* reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT */ +/* reuse GL_COMMAND_BARRIER_BIT */ +/* reuse GL_PIXEL_BUFFER_BARRIER_BIT */ +/* reuse GL_TEXTURE_UPDATE_BARRIER_BIT */ +/* reuse GL_BUFFER_UPDATE_BARRIER_BIT */ +/* reuse GL_FRAMEBUFFER_BARRIER_BIT */ +/* reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT */ +/* reuse GL_ATOMIC_COUNTER_BARRIER_BIT */ +/* reuse GL_ALL_BARRIER_BITS */ +/* reuse GL_MAX_IMAGE_UNITS */ +/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */ +/* reuse GL_IMAGE_BINDING_NAME */ +/* reuse GL_IMAGE_BINDING_LEVEL */ +/* reuse GL_IMAGE_BINDING_LAYERED */ +/* reuse GL_IMAGE_BINDING_LAYER */ +/* reuse GL_IMAGE_BINDING_ACCESS */ +/* reuse GL_IMAGE_1D */ +/* reuse GL_IMAGE_2D */ +/* reuse GL_IMAGE_3D */ +/* reuse GL_IMAGE_2D_RECT */ +/* reuse GL_IMAGE_CUBE */ +/* reuse GL_IMAGE_BUFFER */ +/* reuse GL_IMAGE_1D_ARRAY */ +/* reuse GL_IMAGE_2D_ARRAY */ +/* reuse GL_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_INT_IMAGE_1D */ +/* reuse GL_INT_IMAGE_2D */ +/* reuse GL_INT_IMAGE_3D */ +/* reuse GL_INT_IMAGE_2D_RECT */ +/* reuse GL_INT_IMAGE_CUBE */ +/* reuse GL_INT_IMAGE_BUFFER */ +/* reuse GL_INT_IMAGE_1D_ARRAY */ +/* reuse GL_INT_IMAGE_2D_ARRAY */ +/* reuse GL_INT_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_INT_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_1D */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D */ +/* reuse GL_UNSIGNED_INT_IMAGE_3D */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_RECT */ +/* reuse GL_UNSIGNED_INT_IMAGE_CUBE */ +/* reuse GL_UNSIGNED_INT_IMAGE_BUFFER */ +/* reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_MAX_IMAGE_SAMPLES */ +/* reuse GL_IMAGE_BINDING_FORMAT */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */ +/* reuse GL_MAX_VERTEX_IMAGE_UNIFORMS */ +/* reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */ +/* reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */ +/* reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS */ +/* reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS */ +/* reuse GL_MAX_COMBINED_IMAGE_UNIFORMS */ +/* Reuse tokens from ARB_shading_language_packing (none) */ +/* Reuse tokens from ARB_texture_storage */ +/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */ +#endif + #ifndef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 @@ -2140,6 +2258,143 @@ extern "C" { #ifndef GL_ARB_shader_stencil_export #endif +#ifndef GL_ARB_base_instance +#endif + +#ifndef GL_ARB_shading_language_420pack +#endif + +#ifndef GL_ARB_transform_feedback_instanced +#endif + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#endif + +#ifndef GL_ARB_conservative_depth +#endif + +#ifndef GL_ARB_internalformat_query +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#endif + +#ifndef GL_ARB_map_buffer_alignment +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#endif + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +#ifndef GL_ARB_shader_image_load_store +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#endif + +#ifndef GL_ARB_shading_language_packing +#endif + +#ifndef GL_ARB_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#endif + #ifndef GL_EXT_abgr #define GL_ABGR_EXT 0x8000 #endif @@ -5032,6 +5287,32 @@ extern "C" { #define GL_SKIP_DECODE_EXT 0x8A4A #endif +#ifndef GL_NV_texture_multisample +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +#endif + +#ifndef GL_AMD_blend_minmax_factor +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D +#endif + +#ifndef GL_AMD_sample_positions +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#endif + +#ifndef GL_EXT_x11_sync_object +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +#endif + +#ifndef GL_AMD_multi_draw_indirect +#endif + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#endif + /*************************************************************/ @@ -5891,7 +6172,7 @@ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, #ifndef GL_VERSION_4_1 #define GL_VERSION_4_1 1 -/* OpenGL 4.1 also reuses entry points from these extensions: */ +/* OpenGL 4.1 reuses entry points from these extensions: */ /* ARB_ES2_compatibility */ /* ARB_get_program_binary */ /* ARB_separate_shader_objects */ @@ -5900,6 +6181,22 @@ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, /* ARB_viewport_array */ #endif +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 +/* OpenGL 4.2 reuses entry points from these extensions: */ +/* ARB_base_instance */ +/* ARB_shading_language_420pack (no entry points) */ +/* ARB_transform_feedback_instanced */ +/* ARB_compressed_texture_pixel_storage (no entry points) */ +/* ARB_conservative_depth (no entry points) */ +/* ARB_internalformat_query */ +/* ARB_map_buffer_alignment (no entry points) */ +/* ARB_shader_atomic_counters */ +/* ARB_shader_image_load_store */ +/* ARB_shading_language_packing (no entry points) */ +/* ARB_texture_storage */ +#endif + #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #ifdef GL_GLEXT_PROTOTYPES @@ -6825,6 +7122,10 @@ typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); #endif +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 +#endif + #ifndef GL_ARB_texture_rgb10_a2ui #define GL_ARB_texture_rgb10_a2ui 1 #endif @@ -7331,6 +7632,92 @@ typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint locati #define GL_ARB_shader_stencil_export 1 #endif +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); +#endif + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 +#endif + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei primcount); +GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); +#endif + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 +#endif + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 +#endif + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 +#endif + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +#endif + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +#endif + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 +#endif + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #endif @@ -11041,6 +11428,58 @@ typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, cons #define GL_EXT_texture_sRGB_decode 1 #endif +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#endif + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 +#endif + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); +#endif + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#endif + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride); +#endif + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_EXT_framebuffer_multisample_blit_scaled 1 +#endif + #ifdef __cplusplus } diff --git a/cmake/FindEGL.cmake b/cmake/FindEGL.cmake index e54dfadf2b..ea9bb76db1 100644 --- a/cmake/FindEGL.cmake +++ b/cmake/FindEGL.cmake @@ -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}) diff --git a/linux_various/glsl2h.pl b/linux_various/glsl2h.pl index b5d96c805f..9d26116048 100755 --- a/linux_various/glsl2h.pl +++ b/linux_various/glsl2h.pl @@ -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 = < +#include +#include +#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; +} diff --git a/plugins/GSdx/GPURenderer.cpp b/plugins/GSdx/GPURenderer.cpp index e1e41ed585..a8efccf665 100644 --- a/plugins/GSdx/GPURenderer.cpp +++ b/plugins/GSdx/GPURenderer.cpp @@ -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); } diff --git a/plugins/GSdx/GPURenderer.h b/plugins/GSdx/GPURenderer.h index ffffc72091..93c23f17fd 100644 --- a/plugins/GSdx/GPURenderer.h +++ b/plugins/GSdx/GPURenderer.h @@ -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); diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index b17a4b3f95..698af7c639 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -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 #include @@ -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) { diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index 830591abb8..37f7bcdd30 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -393,4 +393,4 @@ GSAdapter::GSAdapter(const D3DADAPTER_IDENTIFIER9 &desc_d3d9) #endif #ifdef _LINUX // TODO -#endif \ No newline at end of file +#endif diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index e280fbd92c..171c8ced93 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -19,12 +19,14 @@ * */ +#include "stdafx.h" #include "GSDeviceOGL.h" #include "res/convert.h" #include "res/interlace.h" #include "res/merge.h" #include "res/shadeboost.h" +#include "res/fxaa.h" // TODO performance cost to investigate // Texture attachment/glDrawBuffer. For the moment it set every draw and potentially multiple time (first time in clear, second time in rendering) @@ -33,6 +35,11 @@ //#define LOUD_DEBUGGING //#define PRINT_FRAME_NUMBER //#define ONLY_LINES +#if 0 +#ifdef _DEBUG +#define ENABLE_OGL_STENCIL_DEBUG +#endif +#endif static uint32 g_draw_count = 0; static uint32 g_frame_count = 1; @@ -49,8 +56,6 @@ GSDeviceOGL::GSDeviceOGL() , m_fbo(0) , m_fbo_read(0) , m_vb_sr(NULL) - , m_srv_changed(false) - , m_ss_changed(false) { m_msaa = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_MSAA", 0) : 0; @@ -61,7 +66,7 @@ GSDeviceOGL::GSDeviceOGL() memset(&m_state, 0, sizeof(m_state)); // Reset the debug file - #ifdef OGL_DEBUG + #ifdef ENABLE_OGL_DEBUG FILE* f = fopen("Debug.txt","w"); fclose(f); #endif @@ -73,69 +78,75 @@ GSDeviceOGL::~GSDeviceOGL() delete (m_vb_sr); // Clean m_merge_obj - for (uint i = 0; i < 2; i++) -#ifndef DISABLE_GL41_SSO - glDeleteProgram(m_merge_obj.ps[i]); -#else - glDeleteShader(m_merge_obj.ps[i]); -#endif + for (uint32 i = 0; i < 2; i++) + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_DeleteProgram(m_merge_obj.ps[i]); + else + gl_DeleteShader(m_merge_obj.ps[i]); delete (m_merge_obj.cb); delete (m_merge_obj.bs); // Clean m_interlace - for (uint i = 0; i < 2; i++) -#ifndef DISABLE_GL41_SSO - glDeleteProgram(m_interlace.ps[i]); -#else - glDeleteShader(m_interlace.ps[i]); -#endif + for (uint32 i = 0; i < 2; i++) + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_DeleteProgram(m_interlace.ps[i]); + else + gl_DeleteShader(m_interlace.ps[i]); delete (m_interlace.cb); // Clean m_convert -#ifndef DISABLE_GL41_SSO - glDeleteProgram(m_convert.vs); - for (uint i = 0; i < 2; i++) - glDeleteProgram(m_convert.ps[i]); -#else - glDeleteShader(m_convert.vs); - for (uint i = 0; i < 2; i++) - glDeleteShader(m_convert.ps[i]); -#endif - glDeleteSamplers(1, &m_convert.ln); - glDeleteSamplers(1, &m_convert.pt); + if (GLLoader::found_GL_ARB_separate_shader_objects) { + gl_DeleteProgram(m_convert.vs); + for (uint32 i = 0; i < 2; i++) + gl_DeleteProgram(m_convert.ps[i]); + } else { + gl_DeleteShader(m_convert.vs); + for (uint32 i = 0; i < 2; i++) + gl_DeleteShader(m_convert.ps[i]); + } + gl_DeleteSamplers(1, &m_convert.ln); + gl_DeleteSamplers(1, &m_convert.pt); delete m_convert.dss; delete m_convert.bs; + // Clean m_fxaa + delete m_fxaa.cb; + if (GLLoader::found_GL_ARB_separate_shader_objects) { + gl_DeleteProgram(m_fxaa.ps); + } else { + gl_DeleteShader(m_fxaa.ps); + } + // Clean m_date delete m_date.dss; delete m_date.bs; // Clean various opengl allocation -#ifndef DISABLE_GL41_SSO - glDeleteProgramPipelines(1, &m_pipeline); -#endif - glDeleteFramebuffers(1, &m_fbo); - glDeleteFramebuffers(1, &m_fbo_read); + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_DeleteProgramPipelines(1, &m_pipeline); + gl_DeleteFramebuffers(1, &m_fbo); + gl_DeleteFramebuffers(1, &m_fbo_read); // Delete HW FX delete m_vs_cb; delete m_ps_cb; - glDeleteSamplers(1, &m_rt_ss); + gl_DeleteSamplers(1, &m_palette_ss); delete m_vb; -#ifndef DISABLE_GL41_SSO - for (auto it = m_vs.begin(); it != m_vs.end() ; it++) glDeleteProgram(it->second); - for (auto it = m_gs.begin(); it != m_gs.end() ; it++) glDeleteProgram(it->second); - for (auto it = m_ps.begin(); it != m_ps.end() ; it++) glDeleteProgram(it->second); -#else - for (auto it = m_vs.begin(); it != m_vs.end() ; it++) glDeleteShader(it->second); - for (auto it = m_gs.begin(); it != m_gs.end() ; it++) glDeleteShader(it->second); - for (auto it = m_ps.begin(); it != m_ps.end() ; it++) glDeleteShader(it->second); + if (GLLoader::found_GL_ARB_separate_shader_objects) { + for (auto it = m_vs.begin(); it != m_vs.end() ; it++) gl_DeleteProgram(it->second); + for (auto it = m_gs.begin(); it != m_gs.end() ; it++) gl_DeleteProgram(it->second); + for (auto it = m_ps.begin(); it != m_ps.end() ; it++) gl_DeleteProgram(it->second); + } else { + for (auto it = m_vs.begin(); it != m_vs.end() ; it++) gl_DeleteShader(it->second); + for (auto it = m_gs.begin(); it != m_gs.end() ; it++) gl_DeleteShader(it->second); + for (auto it = m_ps.begin(); it != m_ps.end() ; it++) gl_DeleteShader(it->second); - for (auto it = m_single_prog.begin(); it != m_single_prog.end() ; it++) glDeleteProgram(it->second); - m_single_prog.clear(); -#endif - for (auto it = m_ps_ss.begin(); it != m_ps_ss.end() ; it++) glDeleteSamplers(1, &it->second); + for (auto it = m_single_prog.begin(); it != m_single_prog.end() ; it++) gl_DeleteProgram(it->second); + m_single_prog.clear(); + } + + for (auto it = m_ps_ss.begin(); it != m_ps_ss.end() ; it++) gl_DeleteSamplers(1, &it->second); m_vs.clear(); m_gs.clear(); m_ps.clear(); @@ -180,58 +191,11 @@ GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int form bool GSDeviceOGL::Create(GSWnd* wnd) { if (m_window == NULL) { - // FIXME...... - // GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes GL_INVALID_ENUM - // on GL 3.2 forward compatible context as soon as glewInit() is called. It also doesn't fetch - // the function pointers. The solution is for GLEW to use glGetStringi instead. - // The current version of GLEW is 1.9.0 but they still haven't corrected it. The only fix is to use glewExperimental for now : - //NOTE: I'm not sure experimental work on 1.6 ... - glewExperimental=true; - const int glew_ok = glewInit(); - if (glew_ok != GLEW_OK) - { - // FIXME:proper logging - fprintf(stderr, "Error: Failed to init glew :%s\n", glewGetErrorString(glew_ok)); - return false; - } - // Note: don't rely on glew to avoid to pull glew1.7 - // Instead we just copy/adapt the 10 lines of code - // if (!GLEW_VERSION_4_2) { - // fprintf(stderr, "4.2 is not supported!\n"); - // return false; - // } - const GLubyte* s; - s = glGetString(GL_VERSION); - if (s == NULL) return false; - fprintf(stderr, "Supported Opengl version: %s on GPU: %s. Vendor: %s\n", s, glGetString(GL_RENDERER), glGetString(GL_VENDOR)); - // Could be useful to detect the GPU vendor: - // if ( strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.") == 0 ) - - GLuint dot = 0; - while (s[dot] != '\0' && s[dot] != '.') dot++; - if (dot == 0) return false; - - GLuint major = s[dot-1]-'0'; - GLuint minor = s[dot+1]-'0'; - // Note: 4.2 crash on latest nvidia drivers! - // So only check 4.1 - // if ( (major < 4) || ( major == 4 && minor < 2 ) ) return false; - // if ( (major < 4) || ( major == 4 && minor < 1 ) ) return false; - if ( (major < 3) || ( major == 3 && minor < 3 ) ) { - fprintf(stderr, "OPENGL 3.3 is not supported\n"); - return false; - } - - if ( !glewIsSupported("GL_ARB_separate_shader_objects")) { - fprintf(stderr, "GL_ARB_separate_shader_objects is not supported\n"); - return false; - } - if ( !glewIsSupported("GL_ARB_shading_language_420pack")) { - fprintf(stderr, "GL_ARB_shading_language_420pack is not supported\n"); - //return false; - } + GLLoader::init_gl_function(); + if (!GLLoader::check_gl_version(3, 0)) return false; + if (!GLLoader::check_gl_supported_extension()) return false; } // FIXME disable it when code is ready @@ -242,13 +206,13 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** // Various object // **************************************************************** -#ifndef DISABLE_GL41_SSO - glGenProgramPipelines(1, &m_pipeline); - glBindProgramPipeline(m_pipeline); -#endif + if (GLLoader::found_GL_ARB_separate_shader_objects) { + gl_GenProgramPipelines(1, &m_pipeline); + gl_BindProgramPipeline(m_pipeline); + } - glGenFramebuffers(1, &m_fbo); - glGenFramebuffers(1, &m_fbo_read); + gl_GenFramebuffers(1, &m_fbo); + gl_GenFramebuffers(1, &m_fbo_read); // **************************************************************** // Vertex buffer state @@ -264,8 +228,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // convert // **************************************************************** CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs, convert_glsl); - CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs, convert_glsl); - for(uint i = 0; i < countof(m_convert.ps); i++) + for(uint32 i = 0; i < countof(m_convert.ps); i++) CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i], convert_glsl); // Note the following object are initialized to 0 so disabled. @@ -286,36 +249,9 @@ bool GSDeviceOGL::Create(GSWnd* wnd) hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); #endif - glGenSamplers(1, &m_convert.ln); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameterf(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX); - // FIXME: seems there is 2 possibility in opengl - // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - // glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_NONE); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); - // FIXME: need ogl extension sd.MaxAnisotropy = 16; - - glGenSamplers(1, &m_convert.pt); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // FIXME which value for GL_TEXTURE_MIN_LOD - glSamplerParameterf(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX); - // FIXME: seems there is 2 possibility in opengl - // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - // glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_NONE); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); - // FIXME: need ogl extension sd.MaxAnisotropy = 16; + CreateSampler(m_convert.ln, true, false, false); + CreateSampler(m_convert.pt, false, false, false); m_convert.dss = new GSDepthStencilOGL(); m_convert.bs = new GSBlendStateOGL(); @@ -325,7 +261,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** m_merge_obj.cb = new GSUniformBufferOGL(g_merge_cb_index, sizeof(MergeConstantBuffer)); - for(uint i = 0; i < countof(m_merge_obj.ps); i++) + for(uint32 i = 0; i < countof(m_merge_obj.ps); i++) CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i], merge_glsl); m_merge_obj.bs = new GSBlendStateOGL(); @@ -337,7 +273,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** m_interlace.cb = new GSUniformBufferOGL(g_interlace_cb_index, sizeof(InterlaceConstantBuffer)); - for(uint i = 0; i < countof(m_interlace.ps); i++) + for(uint32 i = 0; i < countof(m_interlace.ps); i++) CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i], interlace_glsl); // **************************************************************** // Shade boost @@ -347,11 +283,11 @@ bool GSDeviceOGL::Create(GSWnd* wnd) int ShadeBoost_Contrast = theApp.GetConfig("ShadeBoost_Contrast", 50); int ShadeBoost_Brightness = theApp.GetConfig("ShadeBoost_Brightness", 50); int ShadeBoost_Saturation = theApp.GetConfig("ShadeBoost_Saturation", 50); - std::string macro = format("#define SB_SATURATION %d\n", ShadeBoost_Saturation) + std::string shade_macro = format("#define SB_SATURATION %d\n", ShadeBoost_Saturation) + format("#define SB_BRIGHTNESS %d\n", ShadeBoost_Brightness) + format("#define SB_CONTRAST %d\n", ShadeBoost_Contrast); - CompileShaderFromSource("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, &m_shadeboost.ps, shadeboost_glsl, macro); + CompileShaderFromSource("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, &m_shadeboost.ps, shadeboost_glsl, shade_macro); // **************************************************************** // rasterization configuration @@ -383,37 +319,28 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // FIXME need to define FXAA_GLSL_130 for the shader // FIXME need to manually set the index... // FIXME need dofxaa interface too - // m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer)); - //CompileShaderFromSource("fxaa.fx", format("ps_main", i), GL_FRAGMENT_SHADER, &m_fxaa.ps, fxaa_glsl); + std::string fxaa_macro = "#define FXAA_GLSL_130 1\n"; + if (!GLLoader::found_only_gl30) { + // This extension become core on openGL4 + fxaa_macro += "#extension GL_ARB_gpu_shader5 : enable\n"; + fxaa_macro += "#define FXAA_GATHER4_ALPHA 1\n"; + } + m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer)); + CompileShaderFromSource("fxaa.fx", "ps_main", GL_FRAGMENT_SHADER, &m_fxaa.ps, fxaa_fx, fxaa_macro); // **************************************************************** - // date + // DATE // **************************************************************** m_date.dss = new GSDepthStencilOGL(); m_date.dss->EnableStencil(); m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE); - //memset(&dsd, 0, sizeof(dsd)); - //dsd.DepthEnable = false; - //dsd.StencilEnable = true; - //dsd.StencilReadMask = 1; - //dsd.StencilWriteMask = 1; - - //dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - //dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; - //dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - //dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - - //m_dev->CreateDepthStencilState(&dsd, &m_date.dss); - - // FIXME are the blend state really empty m_date.bs = new GSBlendStateOGL(); - //D3D11_BLEND_DESC blend; - - //memset(&blend, 0, sizeof(blend)); - - //m_dev->CreateBlendState(&blend, &m_date.bs); +#ifndef ENABLE_OGL_STENCIL_DEBUG + // Only keep stencil data + m_date.bs->SetMask(false, false, false, false); +#endif // **************************************************************** // HW renderer shader @@ -482,44 +409,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); #endif - // **************************************************************** - // The check of capability is done when context is created on openGL - // For the moment don't bother with extension, I just ask the most recent openGL version - // **************************************************************** -#if 0 - if(FAILED(hr)) return false; - - if(!SetFeatureLevel(level, true)) - { - return false; - } - - D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; - - hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); - - // msaa - - for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - uint32 quality[2] = {0, 0}; - - if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0 - && SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0) - { - m_msaa_desc.Count = i; - m_msaa_desc.Quality = std::min(quality[0] - 1, quality[1] - 1); - - if(i >= m_msaa) break; - } - } - - if(m_msaa_desc.Count == 1) - { - m_msaa = 0; - } -#endif - return true; } @@ -545,7 +434,7 @@ void GSDeviceOGL::SetVSync(bool enable) void GSDeviceOGL::Flip() { // FIXME: disable it when code is working - #ifdef OGL_DEBUG + #ifdef ENABLE_OGL_DEBUG CheckDebugLog(); #endif @@ -553,111 +442,48 @@ void GSDeviceOGL::Flip() #ifdef PRINT_FRAME_NUMBER fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count); +#endif +#if defined(ENABLE_OGL_DEBUG) || defined(PRINT_FRAME_NUMBER) g_frame_count++; #endif } -void GSDeviceOGL::DebugBB() -{ - bool dump_me = false; - uint32 start = theApp.GetConfig("debug_ogl_dump", 0); - uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); - if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; - - if (!dump_me) return; - - GLuint fbo_old = m_state.fbo; - OMSetFBO(m_fbo); - - GSVector2i size = m_backbuffer->GetSize(); - GSTexture* rt = CreateRenderTarget(size.x, size.y, false); - - static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); - - glBlitFramebuffer(0, 0, size.x, size.y, - 0, 0, size.x, size.y, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - - rt->Save(format("/tmp/out_f%d__d%d__bb.bmp", g_frame_count, g_draw_count)); - - delete rt; - OMSetFBO(fbo_old); -} - -void GSDeviceOGL::DebugInput() -{ - bool dump_me = false; - uint32 start = theApp.GetConfig("debug_ogl_dump", 0); - uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); - if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; - - if (!dump_me) return; - - for (auto i = 0 ; i < 3 ; i++) { - if (m_state.ps_srv[i] != NULL) { - m_state.ps_srv[i]->Save(format("/tmp/in_f%d__d%d__%d.bmp", g_frame_count, g_draw_count, i)); - } - } - //if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/target_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); - //if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_in_%d.bmp", g_draw_count)); - - fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count); - fprintf(stderr, "vs: %d ; gs: %d ; ps: %d\n", m_state.vs, m_state.gs, m_state.ps); - m_state.vb->debug(); - m_state.bs->debug(); - m_state.dss->debug(); -} - -void GSDeviceOGL::DebugOutput() -{ - CheckDebugLog(); - - bool dump_me = false; - uint32 start = theApp.GetConfig("debug_ogl_dump", 0); - uint32 length = theApp.GetConfig("debug_ogl_dump_length", 5); - if ( (start != 0 && g_frame_count >= start && g_frame_count < (start + length)) ) dump_me = true; - - if (!dump_me) return; - - if (m_state.rtv == m_backbuffer) { - m_state.rtv->Save(format("/tmp/out_f%d__d%d__back.bmp", g_frame_count, g_draw_count)); - } else { - if (m_state.rtv != NULL) m_state.rtv->Save(format("/tmp/out_f%d__d%d__tex.bmp", g_frame_count, g_draw_count)); - } - if (m_state.dsv != NULL) m_state.dsv->Save(format("/tmp/ds_out_%d.bmp", g_draw_count)); - - fprintf(stderr, "\n"); - //DebugBB(); -} - -#ifdef DISABLE_GL42 static void set_uniform_buffer_binding(GLuint prog, GLchar* name, GLuint binding) { GLuint index; - index = glGetUniformBlockIndex(prog, name); + index = gl_GetUniformBlockIndex(prog, name); if (index != GL_INVALID_INDEX) { - glUniformBlockBinding(prog, index, binding); + gl_UniformBlockBinding(prog, index, binding); + } +} + +static void set_sampler_uniform_binding(GLuint prog, GLchar* name, GLuint binding) { + GLint loc = gl_GetUniformLocation(prog, name); + if (loc != -1) { + if (GLLoader::found_GL_ARB_separate_shader_objects) { + gl_ProgramUniform1i(prog, loc, binding); + } else { + gl_Uniform1i(loc, binding); + } } } -#endif -#ifdef DISABLE_GL41_SSO GLuint GSDeviceOGL::link_prog() { - GLuint single_prog = glCreateProgram(); - if (m_state.vs) glAttachShader(single_prog, m_state.vs); - if (m_state.ps) glAttachShader(single_prog, m_state.ps); - if (m_state.gs) glAttachShader(single_prog, m_state.gs); + GLuint single_prog = gl_CreateProgram(); + if (m_state.vs) gl_AttachShader(single_prog, m_state.vs); + if (m_state.ps) gl_AttachShader(single_prog, m_state.ps); + if (m_state.gs) gl_AttachShader(single_prog, m_state.gs); - glLinkProgram(single_prog); + gl_LinkProgram(single_prog); GLint status; - glGetProgramiv(single_prog, GL_LINK_STATUS, &status); + gl_GetProgramiv(single_prog, GL_LINK_STATUS, &status); if (!status) { GLint log_length = 0; - glGetProgramiv(single_prog, GL_INFO_LOG_LENGTH, &log_length); + gl_GetProgramiv(single_prog, GL_INFO_LOG_LENGTH, &log_length); if (log_length > 0) { char* log = new char[log_length]; - glGetProgramInfoLog(single_prog, log_length, NULL, log); + gl_GetProgramInfoLog(single_prog, log_length, NULL, log); fprintf(stderr, "%s", log); delete[] log; } @@ -665,52 +491,64 @@ GLuint GSDeviceOGL::link_prog() } #if 0 - if (m_state.vs) glDetachShader(single_prog, m_state.vs); - if (m_state.ps) glDetachShader(single_prog, m_state.ps); - if (m_state.gs) glDetachShader(single_prog, m_state.gs); + if (m_state.vs) gl_DetachShader(single_prog, m_state.vs); + if (m_state.ps) gl_DetachShader(single_prog, m_state.ps); + if (m_state.gs) gl_DetachShader(single_prog, m_state.gs); #endif return single_prog; } -#endif void GSDeviceOGL::BeforeDraw() { -#ifdef OGL_DEBUG - DebugInput(); -#endif + hash_map::iterator single_prog; -#ifdef DISABLE_GL41_SSO - // Note: shader are integer lookup pointer. They start from 1 and incr - // every time you create a new shader OR a new program. - uint64 sel = (uint64)m_state.vs << 40 | (uint64)m_state.gs << 20 | m_state.ps; - auto single_prog = m_single_prog.find(sel); - if (single_prog == m_single_prog.end()) { - m_single_prog[sel] = link_prog(); + + if (!GLLoader::found_GL_ARB_separate_shader_objects) { + // Note: shader are integer lookup pointer. They start from 1 and incr + // every time you create a new shader OR a new program. + uint64 sel = (uint64)m_state.vs << 40 | (uint64)m_state.gs << 20 | m_state.ps; single_prog = m_single_prog.find(sel); + if (single_prog == m_single_prog.end()) { + m_single_prog[sel] = link_prog(); + single_prog = m_single_prog.find(sel); + } + + gl_UseProgram(single_prog->second); } - glUseProgram(single_prog->second); + if (!GLLoader::found_GL_ARB_shading_language_420pack) { + if (GLLoader::found_GL_ARB_separate_shader_objects) { + set_uniform_buffer_binding(m_state.vs, "cb20", 20); + set_uniform_buffer_binding(m_state.ps, "cb21", 21); -#endif + set_uniform_buffer_binding(m_state.ps, "cb10", 10); + set_uniform_buffer_binding(m_state.ps, "cb11", 11); + set_uniform_buffer_binding(m_state.ps, "cb12", 12); + set_uniform_buffer_binding(m_state.ps, "cb13", 13); -#ifdef DISABLE_GL42 - set_uniform_buffer_binding(m_state.vs, "cb20", 20); - set_uniform_buffer_binding(m_state.ps, "cb21", 21); + set_sampler_uniform_binding(m_state.ps, "TextureSampler", 0); + set_sampler_uniform_binding(m_state.ps, "PaletteSampler", 1); + set_sampler_uniform_binding(m_state.ps, "RTCopySampler", 2); + } else { + set_uniform_buffer_binding(single_prog->second, "cb20", 20); + set_uniform_buffer_binding(single_prog->second, "cb21", 21); - set_uniform_buffer_binding(m_state.ps, "cb10", 10); - set_uniform_buffer_binding(m_state.ps, "cb11", 11); - set_uniform_buffer_binding(m_state.ps, "cb12", 12); - set_uniform_buffer_binding(m_state.ps, "cb13", 13); -#endif + set_uniform_buffer_binding(single_prog->second, "cb10", 10); + set_uniform_buffer_binding(single_prog->second, "cb11", 11); + set_uniform_buffer_binding(single_prog->second, "cb12", 12); + set_uniform_buffer_binding(single_prog->second, "cb13", 13); + + set_sampler_uniform_binding(single_prog->second, "TextureSampler", 0); + set_sampler_uniform_binding(single_prog->second, "PaletteSampler", 1); + set_sampler_uniform_binding(single_prog->second, "RTCopySampler", 2); + } + } } void GSDeviceOGL::AfterDraw() { -#ifdef OGL_DEBUG - DebugOutput(); -#endif -#if defined(OGL_DEBUG) || defined(PRINT_FRAME_NUMBER) +#if defined(ENABLE_OGL_DEBUG) || defined(PRINT_FRAME_NUMBER) g_draw_count++; #endif } @@ -740,23 +578,20 @@ void GSDeviceOGL::DrawIndexedPrimitive(int offset, int count) void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) { - GLuint fbo_old = m_state.fbo; + glDisable(GL_SCISSOR_TEST); if (static_cast(t)->IsBackbuffer()) { - // FIXME I really not sure OMSetFBO(0); - //glClearBufferfv(GL_COLOR, GL_LEFT, c.v); - glClearBufferfv(GL_COLOR, 0, c.v); - // code for the old interface - // glClearColor(c.x, c.y, c.z, c.w); - // glClear(GL_COLOR_BUFFER_BIT); + + // glDrawBuffer(GL_BACK); // this is the default when there is no FB + // 0 will select the first drawbuffer ie GL_BACK + gl_ClearBufferfv(GL_COLOR, 0, c.v); } else { - // FIXME1 I need to clarify this FBO attachment stuff - // I would like to avoid FBO for a basic clean operation OMSetFBO(m_fbo); static_cast(t)->Attach(GL_COLOR_ATTACHMENT0); - glClearBufferfv(GL_COLOR, 0, c.v); + + gl_ClearBufferfv(GL_COLOR, 0, c.v); } - OMSetFBO(fbo_old); + glEnable(GL_SCISSOR_TEST); } void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) @@ -767,37 +602,63 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) void GSDeviceOGL::ClearDepth(GSTexture* t, float c) { - GLuint fbo_old = m_state.fbo; - // FIXME I need to clarify this FBO attachment stuff - // I would like to avoid FBO for a basic clean operation OMSetFBO(m_fbo); static_cast(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT); - // FIXME can you clean depth and stencil separately - // XXX: glClear* depends on the scissor test!!! Disable it because the viewport - // could be smaller than the texture and we really want to clean all pixels. + glDisable(GL_SCISSOR_TEST); if (m_state.dss != NULL && m_state.dss->IsMaskEnable()) { - glClearBufferfv(GL_DEPTH, 0, &c); + gl_ClearBufferfv(GL_DEPTH, 0, &c); } else { glDepthMask(true); - glClearBufferfv(GL_DEPTH, 0, &c); + gl_ClearBufferfv(GL_DEPTH, 0, &c); glDepthMask(false); } glEnable(GL_SCISSOR_TEST); - OMSetFBO(fbo_old); } void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) { - GLuint fbo_old = m_state.fbo; - // FIXME I need to clarify this FBO attachment stuff - // I would like to avoid FBO for a basic clean operation OMSetFBO(m_fbo); static_cast(t)->Attach(GL_DEPTH_STENCIL_ATTACHMENT); GLint color = c; - // FIXME can you clean depth and stencil separately - glClearBufferiv(GL_STENCIL, 0, &color); - OMSetFBO(fbo_old); + + glDisable(GL_SCISSOR_TEST); + gl_ClearBufferiv(GL_STENCIL, 0, &color); + glEnable(GL_SCISSOR_TEST); +} + +void GSDeviceOGL::CreateSampler(GLuint& sampler, bool bilinear, bool tau, bool tav) +{ + gl_GenSamplers(1, &sampler); + if (bilinear) { + gl_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + gl_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + // FIXME ensure U -> S, V -> T and W->R + if (tau) + gl_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + else + gl_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + if (tav) + gl_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + else + gl_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + gl_SamplerParameteri(sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + // FIXME which value for GL_TEXTURE_MIN_LOD + gl_SamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, FLT_MAX); + + // FIXME: seems there is 2 possibility in opengl + // DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER; + // gl_SamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_NONE); + gl_SamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + gl_SamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); + // FIXME: need ogl extension sd.MaxAnisotropy = 16; } GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format) @@ -882,14 +743,37 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r) // FIXME: the extension was integrated in opengl 4.3 (now we need driver that support OGL4.3) // FIXME check those function work as expected // void CopyImageSubDataNV( - // uint srcName, enum srcTarget, int srcLevel, int srcX, int srcY, int srcZ, - // uint dstName, enum dstTarget, int dstLevel, int dstX, int dstY, int dstZ, + // uint32 srcName, enum srcTarget, int srcLevel, int srcX, int srcY, int srcZ, + // uint32 dstName, enum dstTarget, int dstLevel, int dstX, int dstY, int dstZ, // sizei width, sizei height, sizei depth); - glCopyImageSubDataNV( static_cast(st)->GetID(), static_cast(st)->GetTarget(), - 0, r.x, r.y, 0, - static_cast(dt)->GetID(), static_cast(dt)->GetTarget(), - 0, r.x, r.y, 0, - r.width(), r.height(), 1); + if (GLLoader::found_GL_NV_copy_image) { + gl_CopyImageSubDataNV( static_cast(st)->GetID(), static_cast(st)->GetTarget(), + 0, r.x, r.y, 0, + static_cast(dt)->GetID(), static_cast(dt)->GetTarget(), + 0, r.x, r.y, 0, + r.width(), r.height(), 1); + } else if (GLLoader::found_GL_ARB_copy_image) { + // Would need an update of GL definition. For the moment it isn't supported by driver anyway. +#if 0 + gl_CopyImageSubData( static_cast(st)->GetID(), static_cast(st)->GetTarget(), + 0, r.x, r.y, 0, + static_cast(dt)->GetID(), static_cast(dt)->GetTarget(), + 0, r.x, r.y, 0, + r.width(), r.height(), 1); +#endif + } else { + + GSTextureOGL* st_ogl = (GSTextureOGL*) st; + GSTextureOGL* dt_ogl = (GSTextureOGL*) dt; + + gl_BindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read); + + st_ogl->AttachRead(GL_COLOR_ATTACHMENT0); + dt_ogl->EnableUnit(6); + glCopyTexSubImage2D(dt_ogl->GetTarget(), 0, r.x, r.y, r.x, r.y, r.width(), r.height()); + + gl_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); + } #if 0 D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1}; @@ -937,10 +821,18 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, // ************************************ + // Original code from DX float left = dr.x * 2 / ds.x - 1.0f; - float top = 1.0f - dr.y * 2 / ds.y; float right = dr.z * 2 / ds.x - 1.0f; +#if 0 + float top = 1.0f - dr.y * 2 / ds.y; float bottom = 1.0f - dr.w * 2 / ds.y; +#else + // Opengl get some issues with the coordinate + // I flip top/bottom to fix scaling of the internal resolution + float top = -1.0f + dr.y * 2 / ds.y; + float bottom = -1.0f + dr.w * 2 / ds.y; +#endif // Flip y axis only when we render in the backbuffer // By default everything is render in the wrong order (ie dx). @@ -949,16 +841,16 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, // Only flipping the backbuffer is transparent (I hope)... GSVector4 flip_sr = sr; if (static_cast(dt)->IsBackbuffer()) { - flip_sr.y = 1.0f - sr.y; - flip_sr.w = 1.0f - sr.w; + flip_sr.y = sr.w; + flip_sr.w = sr.y; } GSVertexPT1 vertices[] = { - {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(flip_sr.x, flip_sr.y)}, - {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(flip_sr.z, flip_sr.y)}, - {GSVector4(left, top, 0.5f, 1.0f), GSVector2(flip_sr.x, flip_sr.w)}, - {GSVector4(right, top, 0.5f, 1.0f), GSVector2(flip_sr.z, flip_sr.w)}, + {GSVector4(left, top, 0.5f, 1.0f), GSVector2(flip_sr.x, flip_sr.y)}, + {GSVector4(right, top, 0.5f, 1.0f), GSVector2(flip_sr.z, flip_sr.y)}, + {GSVector4(left, bottom, 0.5f, 1.0f), GSVector2(flip_sr.x, flip_sr.w)}, + {GSVector4(right, bottom, 0.5f, 1.0f), GSVector2(flip_sr.z, flip_sr.w)}, }; //fprintf(stderr, "A:%fx%f B:%fx%f\n", left, top, bottom, right); //fprintf(stderr, "SR: %f %f %f %f\n", sr.x, sr.y, sr.z, sr.w); @@ -1037,6 +929,25 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin StretchRect(st, sr, dt, dr, m_interlace.ps[shader], linear); } +void GSDeviceOGL::DoFXAA(GSTexture* st, GSTexture* dt) +{ + GSVector2i s = dt->GetSize(); + + GSVector4 sr(0, 0, 1, 1); + GSVector4 dr(0, 0, s.x, s.y); + + FXAAConstantBuffer cb; + + // FIXME optimize: remove rcpFrameOpt. And reduce rcpFrame to vec2 + cb.rcpFrame = GSVector4(1.0f / s.x, 1.0f / s.y, 0.0f, 0.0f); + cb.rcpFrameOpt = GSVector4::zero(); + + SetUniformBuffer(m_fxaa.cb); + m_fxaa.cb->upload(&cb); + + StretchRect(st, sr, dt, dr, m_fxaa.ps, true); +} + void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt) { GSVector2i s = dt->GetSize(); @@ -1057,56 +968,59 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* st, GSTexture* dt) void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm) { +#ifdef ENABLE_OGL_STENCIL_DEBUG const GSVector2i& size = rt->GetSize(); + GSTexture* t = CreateRenderTarget(size.x, size.y, rt->IsMSAA()); +#else + GSTexture* t = NULL; +#endif + // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows - if(GSTexture* t = CreateRenderTarget(size.x, size.y, rt->IsMSAA())) - { - // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows + BeginScene(); - BeginScene(); + ClearStencil(ds, 0); - ClearStencil(ds, 0); + // om - // om + OMSetDepthStencilState(m_date.dss, 1); + OMSetBlendState(m_date.bs, 0); + OMSetRenderTargets(t, ds); - OMSetDepthStencilState(m_date.dss, 1); - OMSetBlendState(m_date.bs, 0); - OMSetRenderTargets(t, ds); + // ia - // ia + IASetVertexState(m_vb_sr); + IASetVertexBuffer(vertices, 4); + IASetPrimitiveTopology(GL_TRIANGLE_STRIP); - IASetVertexState(m_vb_sr); - IASetVertexBuffer(vertices, 4); - IASetPrimitiveTopology(GL_TRIANGLE_STRIP); + // vs - // vs + VSSetShader(m_convert.vs); - VSSetShader(m_convert.vs); + // gs - // gs + GSSetShader(0); - GSSetShader(0); + // ps - // ps + GSTexture* rt2 = rt->IsMSAA() ? Resolve(rt) : rt; - GSTexture* rt2 = rt->IsMSAA() ? Resolve(rt) : rt; + PSSetShaderResources(rt2, NULL); + PSSetSamplerState(m_convert.pt, 0); + PSSetShader(m_convert.ps[datm ? 2 : 3]); - PSSetShaderResources(rt2, NULL); - PSSetSamplerState(m_convert.pt, 0); - PSSetShader(m_convert.ps[datm ? 2 : 3]); + // - // + DrawPrimitive(); - DrawPrimitive(); + // - // + EndScene(); - EndScene(); +#ifdef ENABLE_OGL_STENCIL_DEBUG + Recycle(t); +#endif - Recycle(t); - - if(rt2 != rt) Recycle(rt2); - } + if(rt2 != rt) Recycle(rt2); } // copy a multisample texture to a non-texture multisample. On opengl you need 2 FBO with different level of @@ -1180,23 +1094,21 @@ void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology) void GSDeviceOGL::VSSetShader(GLuint vs) { - if(m_state.vs != vs) + if (m_state.vs != vs) { m_state.vs = vs; -#ifndef DISABLE_GL41_SSO - glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, vs); -#endif + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_UseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, vs); } } void GSDeviceOGL::GSSetShader(GLuint gs) { - if(m_state.gs != gs) + if (m_state.gs != gs) { m_state.gs = gs; -#ifndef DISABLE_GL41_SSO - glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, gs); -#endif + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_UseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, gs); } } @@ -1211,53 +1123,33 @@ void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr) { GSTextureOGL* srv = static_cast(sr); - if(m_state.ps_srv[i] != srv) + if (m_state.ps_srv[i] != srv) { m_state.ps_srv[i] = srv; - - m_srv_changed = true; + if (srv != NULL) + m_state.ps_srv[i]->EnableUnit(i); } } void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2) { - if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1) - //if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1 || m_state.ps_ss[2] != ss2) - { + if (m_state.ps_ss[0] != ss0) { m_state.ps_ss[0] = ss0; + gl_BindSampler(0, ss0); + } + if (m_state.ps_ss[1] != ss1) { m_state.ps_ss[1] = ss1; - //m_state.ps_ss[2] = ss2; - - m_ss_changed = true; + gl_BindSampler(1, ss1); } } void GSDeviceOGL::PSSetShader(GLuint ps) { - if(m_state.ps != ps) + if (m_state.ps != ps) { m_state.ps = ps; -#ifndef DISABLE_GL41_SSO - glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, ps); -#endif - } - -// Sampler and texture must be set at the same time -// 1/ select the texture unit -// glActiveTexture(GL_TEXTURE0 + 1); -// 2/ bind the texture -// glBindTexture(GL_TEXTURE_2D , brickTexture); -// 3/ sets the texture sampler in GLSL (could be useless with layout stuff) -// glUniform1i(brickSamplerId , 1); -// 4/ set the sampler state -// glBindSampler(1 , sampler); - if (m_srv_changed || m_ss_changed) { - for (uint i=0 ; i < 1; i++) { - if (m_state.ps_srv[i] != NULL) { - m_state.ps_srv[i]->EnableUnit(i); - glBindSampler(i, m_state.ps_ss[i]); - } - } + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_UseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, ps); } } @@ -1265,9 +1157,9 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer) { if (m_state.fbo != fbo) { m_state.fbo = fbo; - glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gl_BindFramebuffer(GL_FRAMEBUFFER, fbo); // FIXME DEBUG - //if (fbo) fprintf(stderr, "FB status %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + //if (fbo) fprintf(stderr, "FB status %x\n", gl_CheckFramebufferStatus(GL_FRAMEBUFFER)); } if (m_state.draw != buffer) { @@ -1279,23 +1171,17 @@ void GSDeviceOGL::OMSetFBO(GLuint fbo, GLenum buffer) void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref) { - if(m_state.dss != dss) { + if (m_state.dss != dss) { m_state.dss = dss; - m_state.sref = sref; dss->SetupDepth(); - dss->SetupStencil(sref); - - } else if (m_state.sref != sref) { - m_state.sref = sref; - - dss->SetupStencil(sref); + dss->SetupStencil(); } } void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf) { - if( m_state.bs != bs || (m_state.bf != bf && bs->HasConstantFactor()) ) + if ( m_state.bs != bs || (m_state.bf != bf && bs->HasConstantFactor()) ) { m_state.bs = bs; m_state.bf = bf; @@ -1306,39 +1192,41 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf) void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { - // Hum, need to separate 2 case, Render target fbo and render target backbuffer - // Or maybe blit final result to the backbuffer - m_state.rtv = static_cast(rt); - m_state.dsv = static_cast(ds); - - if (static_cast(rt)->IsBackbuffer()) { - assert(ds == NULL); // no depth-stencil without FBO - - OMSetFBO(0); - - } else { - assert(rt != NULL); // a render target must exists - - // FIXME DEBUG special case for GL_R16UI - if (rt->GetFormat() == GL_R16UI) { - OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT1); - static_cast(rt)->Attach(GL_COLOR_ATTACHMENT1); + if (rt == NULL || !static_cast(rt)->IsBackbuffer()) { + if (rt) { + // FIXME DEBUG special case for GL_R16UI + if (rt->GetFormat() == GL_R16UI) { + OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT1); + static_cast(rt)->Attach(GL_COLOR_ATTACHMENT1); + } else { + OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT0); + static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); + } } else { - OMSetFBO(m_fbo, GL_COLOR_ATTACHMENT0); - static_cast(rt)->Attach(GL_COLOR_ATTACHMENT0); + // Note: NULL rt is only used in DATE so far. Color writing is disabled + // on the blend setup + OMSetFBO(m_fbo, GL_NONE); } - if (ds != NULL) + // Note: it must be done after OMSetFBO + if (ds) static_cast(ds)->Attach(GL_DEPTH_STENCIL_ATTACHMENT); + + } else { + // Render in the backbuffer + OMSetFBO(0); } - if(m_state.viewport != rt->GetSize()) + + + GSVector2i size = rt ? rt->GetSize() : ds->GetSize(); + if(m_state.viewport != size) { - m_state.viewport = rt->GetSize(); - glViewport(0, 0, rt->GetWidth(), rt->GetHeight()); + m_state.viewport = size; + glViewport(0, 0, size.x, size.y); } - GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy(); + GSVector4i r = scissor ? *scissor : GSVector4i(size).zwxy(); if(!m_state.scissor.eq(r)) { @@ -1349,24 +1237,44 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const char* glsl_h_code, const std::string& macro_sel) { + // Not supported + if (type == GL_GEOMETRY_SHADER && !GLLoader::found_geometry_shader) { + *program = 0; + return; + } + // ***************************************************** // Build a header string // ***************************************************** // First select the version (must be the first line so we need to generate it -#ifdef DISABLE_GL41_SSO - #ifdef DISABLE_GL42 - std::string version = "#version 330\n#define DISABLE_GL42\n"; - #else - std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: require\n"; - #endif -#else - #ifdef DISABLE_GL42 - std::string version = "#version 330\n#extension GL_ARB_separate_shader_objects : require\n#define DISABLE_GL42\n"; - #else - std::string version = "#version 330\n#extension GL_ARB_shading_language_420pack: require\n#extension GL_ARB_separate_shader_objects : require\n"; - #endif + std::string version; + if (GLLoader::found_only_gl30) { + version = "#version 130\n"; + } else { + version = "#version 330\n"; + } + if (GLLoader::found_GL_ARB_shading_language_420pack) { + version += "#extension GL_ARB_shading_language_420pack: require\n"; + } else { + version += "#define DISABLE_GL42\n"; + } + if (GLLoader::found_GL_ARB_separate_shader_objects) { + version += "#extension GL_ARB_separate_shader_objects : require\n"; + // REMOVE ME: Emulate open source driver + //if (!GLLoader::found_GL_ARB_shading_language_420pack) { + // version += "#define NO_STRUCT 1\n"; + //} + } else { + if (GLLoader::found_only_gl30) + version += "#define DISABLE_SSO\n"; + } + if (GLLoader::found_only_gl30) { + version += "#extension GL_ARB_explicit_attrib_location : require\n"; + version += "#extension GL_ARB_uniform_buffer_object : require\n"; + } +#ifdef ENABLE_OGL_STENCIL_DEBUG + version += "#define ENABLE_OGL_STENCIL_DEBUG 1\n"; #endif - //std::string version = "#version 420\n"; // Allow to puts several shader in 1 files std::string shader_type; @@ -1380,7 +1288,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st case GL_FRAGMENT_SHADER: shader_type = "#define FRAGMENT_SHADER 1\n"; break; - default: assert(0); + default: ASSERT(0); } // Select the entry point ie the main function @@ -1427,7 +1335,10 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st char* source_str = (char*)malloc(source.size() + 1); if (failed_to_open_glsl) { - sources_array[1] = glsl_h_code; + if (glsl_h_code) + sources_array[1] = glsl_h_code; + else + sources_array[1] = '\0'; } else { sources_array[1] = source_str; source.copy(source_str, source.size(), 0); @@ -1435,62 +1346,66 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st } -#ifndef DISABLE_GL41_SSO -#if 0 - // Could be useful one day - const GLchar* ShaderSource[1]; - ShaderSource[0] = header.append(source).c_str(); - *program = glCreateShaderProgramv(type, 1, &ShaderSource[0]); -#else - *program = glCreateShaderProgramv(type, 2, sources_array); -#endif -#else - *program = glCreateShader(type); - glShaderSource(*program, 2, sources_array, NULL); - glCompileShader(*program); -#endif + if (GLLoader::found_GL_ARB_separate_shader_objects) { + #if 0 + // Could be useful one day + const GLchar* ShaderSource[1]; + ShaderSource[0] = header.append(source).c_str(); + *program = gl_CreateShaderProgramv(type, 1, &ShaderSource[0]); + #else + *program = gl_CreateShaderProgramv(type, 2, sources_array); + #endif + } else { + *program = gl_CreateShader(type); + gl_ShaderSource(*program, 2, sources_array, NULL); + gl_CompileShader(*program); + } free(source_str); free(header_str); free(sources_array); if (theApp.GetConfig("debug_ogl_shader", 1) == 1) { - // Print a nice debug log - fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program); - fprintf(stderr, "\n%s", macro_sel.c_str()); - GLint log_length = 0; -#ifndef DISABLE_GL41_SSO - glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); -#else - glGetShaderiv(*program, GL_INFO_LOG_LENGTH, &log_length); -#endif - if (log_length > 0) { + GLint status = false; + if (GLLoader::found_GL_ARB_separate_shader_objects) { + gl_GetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length); + gl_GetProgramiv(*program, GL_LINK_STATUS, &status); + } else { + gl_GetShaderiv(*program, GL_INFO_LOG_LENGTH, &log_length); + gl_GetShaderiv(*program, GL_COMPILE_STATUS, &status); + } + + if (log_length > 0 && !status) { + // Print a nice debug log + fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), *program); + fprintf(stderr, "\n%s", macro_sel.c_str()); + char* log = new char[log_length]; -#ifndef DISABLE_GL41_SSO - glGetProgramInfoLog(*program, log_length, NULL, log); -#else - glGetShaderInfoLog(*program, log_length, NULL, log); -#endif + if (GLLoader::found_GL_ARB_separate_shader_objects) + gl_GetProgramInfoLog(*program, log_length, NULL, log); + else + gl_GetShaderInfoLog(*program, log_length, NULL, log); + fprintf(stderr, "%s", log); + fprintf(stderr, "\n"); delete[] log; } - fprintf(stderr, "\n"); } } void GSDeviceOGL::CheckDebugLog() { - unsigned int count = 64; // max. num. of messages that will be read from the log + unsigned int count = 16; // max. num. of messages that will be read from the log int bufsize = 2048; - unsigned int* sources = new unsigned int[count]; - unsigned int* types = new unsigned int[count]; - unsigned int* ids = new unsigned int[count]; - unsigned int* severities = new unsigned int[count]; - int* lengths = new int[count]; + unsigned int sources[16] = {}; + unsigned int types[16] = {}; + unsigned int ids[16] = {}; + unsigned int severities[16] = {}; + int lengths[16] = {}; char* messageLog = new char[bufsize]; - unsigned int retVal = glGetDebugMessageLogARB(count, bufsize, sources, types, ids, severities, lengths, messageLog); + unsigned int retVal = gl_GetDebugMessageLogARB(count, bufsize, sources, types, ids, severities, lengths, messageLog); if(retVal > 0) { @@ -1502,13 +1417,6 @@ void GSDeviceOGL::CheckDebugLog() pos += lengths[i]; } } - - delete [] sources; - delete [] types; - delete [] ids; - delete [] severities; - delete [] lengths; - delete [] messageLog; } void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message) diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index b18deb0aae..59dca31593 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -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 m_vs; hash_map m_gs; hash_map 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 m_single_prog; GLuint link_prog(); -#endif - }; diff --git a/plugins/GSdx/GSLinuxDialog.cpp b/plugins/GSdx/GSLinuxDialog.cpp index c74b0cc823..c14707bf4b 100644 --- a/plugins/GSdx/GSLinuxDialog.cpp +++ b/plugins/GSdx/GSLinuxDialog.cpp @@ -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); diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 2c2d7a9b17..ee1ea5c7bb 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -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: diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index bfffd72404..394f489363 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -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]; -}; \ No newline at end of file +}; diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 0fe4dd2cb3..6dc4236f4f 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -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. diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 502f699d8e..aadc3fb4be 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -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: diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 92cc3881b0..2cc41a7ed0 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -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 s_tags; template 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; diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index 8e3b543083..3be6c82640 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -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); } diff --git a/plugins/GSdx/GSTextureOGL.cpp b/plugins/GSdx/GSTextureOGL.cpp index 88b31ce6f4..7036d96be6 100644 --- a/plugins/GSdx/GSTextureOGL.cpp +++ b/plugins/GSdx/GSTextureOGL.cpp @@ -19,10 +19,18 @@ * */ +#include "stdafx.h" #include #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); diff --git a/plugins/GSdx/GSTextureOGL.h b/plugins/GSdx/GSTextureOGL.h index 89ef0163d1..4a235b2ffc 100644 --- a/plugins/GSdx/GSTextureOGL.h +++ b/plugins/GSdx/GSTextureOGL.h @@ -28,7 +28,7 @@ class GSTextureOGL : public GSTexture private: GLenum m_texture_target; // texture target: 2D, rectangle etc... GLuint m_texture_id; // the texture id - uint m_pbo_id; + uint32 m_pbo_id; int m_pbo_size; GLuint m_fbo_read; @@ -42,8 +42,9 @@ class GSTextureOGL : public GSTexture bool Save(const string& fn, bool dds = false); void Save(const string& fn, const void* image, uint32 pitch); - void EnableUnit(uint unit); + void EnableUnit(uint32 unit); void Attach(GLenum attachment); + void AttachRead(GLenum attachment); bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); } bool IsDss() { return (m_type == GSTexture::DepthStencil); } diff --git a/plugins/GSdx/GSUniformBufferOGL.h b/plugins/GSdx/GSUniformBufferOGL.h index 281b5aa1e6..dedc037156 100644 --- a/plugins/GSdx/GSUniformBufferOGL.h +++ b/plugins/GSdx/GSUniformBufferOGL.h @@ -24,15 +24,15 @@ class GSUniformBufferOGL { GLuint buffer; // data object GLuint index; // GLSL slot - uint size; // size of the data + uint32 size; // size of the data const GLenum target; public: - GSUniformBufferOGL(GLuint index, uint size) : index(index) + GSUniformBufferOGL(GLuint index, uint32 size) : index(index) , size(size) ,target(GL_UNIFORM_BUFFER) { - glGenBuffers(1, &buffer); + gl_GenBuffers(1, &buffer); bind(); allocate(); attach(); @@ -40,28 +40,28 @@ public: void bind() { - glBindBuffer(target, buffer); + gl_BindBuffer(target, buffer); } void allocate() { - glBufferData(target, size, NULL, GL_STREAM_DRAW); + gl_BufferData(target, size, NULL, GL_STREAM_DRAW); } void attach() { - glBindBufferBase(target, index, buffer); + gl_BindBufferBase(target, index, buffer); } void upload(const void* src) { - uint32 flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; - uint8* dst = (uint8*) glMapBufferRange(target, 0, size, flags); - memcpy(dst, src, size); - glUnmapBuffer(target); + // glMapBufferRange allow to set various parameter but the call is + // synchronous whereas glBufferSubData could be asynchronous. + // TODO: investigate the extension ARB_invalidate_subdata + gl_BufferSubData(target, 0, size, src); } ~GSUniformBufferOGL() { - glDeleteBuffers(1, &buffer); + gl_DeleteBuffers(1, &buffer); } }; diff --git a/plugins/GSdx/GSVertexArrayOGL.h b/plugins/GSdx/GSVertexArrayOGL.h index 5f24698ef6..8c1f83ad57 100644 --- a/plugins/GSdx/GSVertexArrayOGL.h +++ b/plugins/GSdx/GSVertexArrayOGL.h @@ -47,12 +47,12 @@ class GSBufferOGL { , m_limit(0) , m_target(target) { - glGenBuffers(1, &m_buffer); + gl_GenBuffers(1, &m_buffer); // Opengl works best with 1-4MB buffer. m_default_size = 2 * 1024 * 1024 / m_stride; } - ~GSBufferOGL() { glDeleteBuffers(1, &m_buffer); } + ~GSBufferOGL() { gl_DeleteBuffers(1, &m_buffer); } void allocate() { allocate(m_default_size); } @@ -60,12 +60,12 @@ class GSBufferOGL { { m_start = 0; m_limit = new_limit; - glBufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW); + gl_BufferData(m_target, m_limit * m_stride, NULL, GL_STREAM_DRAW); } void bind() { - glBindBuffer(m_target, m_buffer); + gl_BindBuffer(m_target, m_buffer); } void upload(const void* src, uint32 count) @@ -81,9 +81,9 @@ class GSBufferOGL { } bool Map(void** pointer, uint32 count ) { -#ifdef OGL_DEBUG +#ifdef ENABLE_OGL_DEBUG GLint b_size = -1; - glGetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); + gl_GetBufferParameteriv(m_target, GL_BUFFER_SIZE, &b_size); if (b_size <= 0) return false; #endif @@ -112,9 +112,9 @@ class GSBufferOGL { } // Upload the data to the buffer - *pointer = (uint8*) glMapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); + *pointer = (uint8*) gl_MapBufferRange(m_target, m_stride*m_start, m_stride*m_count, map_flags); //fprintf(stderr, "Map %x from %d to %d\n", *pointer, m_start, m_start+m_count); -#ifdef OGL_DEBUG +#ifdef ENABLE_OGL_DEBUG if (*pointer == NULL) { fprintf(stderr, "CRITICAL ERROR map failed for vb!!!\n"); return false; @@ -123,7 +123,7 @@ class GSBufferOGL { return true; } - void Unmap() { glUnmapBuffer(m_target); } + void Unmap() { gl_UnmapBuffer(m_target); } void EndScene() { @@ -138,12 +138,12 @@ class GSBufferOGL { void Draw(GLenum mode, GLint basevertex) { - glDrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex); + gl_DrawElementsBaseVertex(mode, m_count, GL_UNSIGNED_INT, (void*)(m_start * m_stride), basevertex); } void Draw(GLenum mode, GLint basevertex, int offset, int count) { - glDrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex); + gl_DrawElementsBaseVertex(mode, count, GL_UNSIGNED_INT, (void*)((m_start + offset) * m_stride), basevertex); } size_t GetStart() { return m_start; } @@ -165,7 +165,7 @@ class GSVertexBufferStateOGL { public: GSVertexBufferStateOGL(size_t stride, GSInputLayoutOGL* layout, uint32 layout_nbr) { - glGenVertexArrays(1, &m_va); + gl_GenVertexArrays(1, &m_va); m_vb = new GSBufferOGL(GL_ARRAY_BUFFER, stride); m_ib = new GSBufferOGL(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32)); @@ -181,23 +181,23 @@ public: void bind() { - glBindVertexArray(m_va); + gl_BindVertexArray(m_va); m_vb->bind(); } void set_internal_format(GSInputLayoutOGL* layout, uint32 layout_nbr) { - for (uint i = 0; i < layout_nbr; i++) { + for (uint32 i = 0; i < layout_nbr; i++) { // Note this function need both a vertex array object and a GL_ARRAY_BUFFER buffer - glEnableVertexAttribArray(layout[i].index); + gl_EnableVertexAttribArray(layout[i].index); switch (layout[i].type) { case GL_UNSIGNED_SHORT: case GL_UNSIGNED_INT: - // Rule: when shader use integral (not normalized) you must use glVertexAttribIPointer (note the extra I) - glVertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset); + // Rule: when shader use integral (not normalized) you must use gl_VertexAttribIPointer (note the extra I) + gl_VertexAttribIPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].stride, layout[i].offset); break; default: - glVertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset); + gl_VertexAttribPointer(layout[i].index, layout[i].size, layout[i].type, layout[i].normalize, layout[i].stride, layout[i].offset); break; } } @@ -227,7 +227,7 @@ public: ~GSVertexBufferStateOGL() { - glDeleteVertexArrays(1, &m_va); + gl_DeleteVertexArrays(1, &m_va); delete m_vb; delete m_ib; } diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index 97ac519ae1..c52c87ffbc 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -20,466 +20,3 @@ */ #include "stdafx.h" -#include "GSdx.h" -#include "GSWnd.h" - -#ifdef _WINDOWS - -GSWnd::GSWnd() - : m_hWnd(NULL) - , m_managed(true) - , m_frame(true) -{ -} - -GSWnd::~GSWnd() -{ -} - -LRESULT CALLBACK GSWnd::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - GSWnd* wnd = NULL; - - if(message == WM_NCCREATE) - { - wnd = (GSWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams; - - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)wnd); - - wnd->m_hWnd = hWnd; - } - else - { - wnd = (GSWnd*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - } - - if(wnd == NULL) - { - return DefWindowProc(hWnd, message, wParam, lParam); - } - - return wnd->OnMessage(message, wParam, lParam); -} - -LRESULT GSWnd::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - switch(message) - { - case WM_CLOSE: - Hide(); - // DestroyWindow(m_hWnd); - return 0; - case WM_DESTROY: - // This kills the emulator when GS is closed, which *really* isn't desired behavior, - // especially in STGS mode (worked in MTGS mode since it only quit the thread, but even - // that wasn't needed). - //PostQuitMessage(0); - return 0; - default: - break; - } - - return DefWindowProc((HWND)m_hWnd, message, wParam, lParam); -} - -bool GSWnd::Create(const string& title, int w, int h) -{ - if(m_hWnd) return false; - - WNDCLASS wc; - - memset(&wc, 0, sizeof(wc)); - - wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wc.lpfnWndProc = WndProc; - wc.hInstance = theApp.GetModuleHandle(); - // TODO: wc.hIcon = ; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszClassName = "GSWnd"; - - if(!GetClassInfo(wc.hInstance, wc.lpszClassName, &wc)) - { - if(!RegisterClass(&wc)) - { - return false; - } - } - - DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_BORDER; - - GSVector4i r; - - GetWindowRect(GetDesktopWindow(), r); - - bool remote = !!GetSystemMetrics(SM_REMOTESESSION); - - if(w <= 0 || h <= 0 || remote) - { - w = r.width() / 3; - h = r.width() / 4; - - if(!remote) - { - w *= 2; - h *= 2; - } - } - - r.left = (r.left + r.right - w) / 2; - r.top = (r.top + r.bottom - h) / 2; - r.right = r.left + w; - r.bottom = r.top + h; - - AdjustWindowRect(r, style, FALSE); - - m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, r.left, r.top, r.width(), r.height(), NULL, NULL, wc.hInstance, (LPVOID)this); - - return m_hWnd != NULL; -} - -bool GSWnd::Attach(void* handle, bool managed) -{ - // TODO: subclass - - m_hWnd = (HWND)handle; - m_managed = managed; - - return true; -} - -void GSWnd::Detach() -{ - if(m_hWnd && m_managed) - { - // close the window, since it's under GSdx care. It's not taking messages anyway, and - // that means its big, ugly, and in the way. - - DestroyWindow(m_hWnd); - } - - m_hWnd = NULL; - m_managed = true; -} - -GSVector4i GSWnd::GetClientRect() -{ - GSVector4i r; - - ::GetClientRect(m_hWnd, r); - - return r; -} - -// Returns FALSE if the window has no title, or if th window title is under the strict -// management of the emulator. - -bool GSWnd::SetWindowText(const char* title) -{ - if(!m_managed) return false; - - ::SetWindowText(m_hWnd, title); - - return m_frame; -} - -void GSWnd::Show() -{ - if(!m_managed) return; - - SetForegroundWindow(m_hWnd); - ShowWindow(m_hWnd, SW_SHOWNORMAL); - UpdateWindow(m_hWnd); -} - -void GSWnd::Hide() -{ - if(!m_managed) return; - - ShowWindow(m_hWnd, SW_HIDE); -} - -void GSWnd::HideFrame() -{ - if(!m_managed) return; - - SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); - SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - SetMenu(m_hWnd, NULL); - - m_frame = false; -} - -#else - -GSWnd::GSWnd() - : m_window(NULL), m_Xwindow(0), m_XDisplay(NULL), m_ctx_attached(false), m_swapinterval(NULL) -{ -} - -GSWnd::~GSWnd() -{ - if (m_XDisplay) { - XCloseDisplay(m_XDisplay); - m_XDisplay = NULL; - } -} - -static bool ctxError = false; -static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) -{ - ctxError = true; - return 0; -} - -bool GSWnd::CreateContext(int major, int minor) -{ - if ( !m_XDisplay || !m_Xwindow ) - { - fprintf( stderr, "Wrong X11 display/window\n" ); - exit(1); - } - - // Get visual information - static int attrListDbl[] = - { - // GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X - // visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE. - GLX_X_RENDERABLE , True, - GLX_RED_SIZE , 8, - GLX_GREEN_SIZE , 8, - GLX_BLUE_SIZE , 8, - GLX_DEPTH_SIZE , 24, - GLX_DOUBLEBUFFER , True, - None - }; - - PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig"); - int fbcount = 0; - GLXFBConfig *fbc = glXChooseFBConfig(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl, &fbcount); - if (!fbc || fbcount < 1) return false; - - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); - if (!glXCreateContextAttribsARB) return false; - - // Install a dummy handler to handle gracefully (aka not segfault) the support of GL version - int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); - // Be sure the handler is installed - XSync( m_XDisplay, false); - - // Create a context - int context_attribs[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, major, - GLX_CONTEXT_MINOR_VERSION_ARB, minor, - // FIXME : Request a debug context to ease opengl development - // Note: don't support deprecated feature (pre openg 3.1) - //GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, - None - }; - - m_context = glXCreateContextAttribsARB(m_XDisplay, fbc[0], 0, true, context_attribs); - - // Don't forget to reinstall the older Handler - XSetErrorHandler(oldHandler); - - // Get latest error - XSync( m_XDisplay, false); - - if (!m_context || ctxError) { - fprintf(stderr, "Failed to create the opengl context. Check your drivers support openGL %d.%d. Hint: opensource drivers don't\n", major, minor ); - return false; - } - - return true; -} - -void GSWnd::AttachContext() -{ - if (!IsContextAttached()) { - //fprintf(stderr, "Attach the context\n"); - glXMakeCurrent(m_XDisplay, m_Xwindow, m_context); - m_ctx_attached = true; - } -} - -void GSWnd::DetachContext() -{ - if (IsContextAttached()) { - //fprintf(stderr, "Detach the context\n"); - glXMakeCurrent(m_XDisplay, None, NULL); - m_ctx_attached = false; - } -} - -void GSWnd::CheckContext() -{ - int glxMajorVersion, glxMinorVersion; - glXQueryVersion(m_XDisplay, &glxMajorVersion, &glxMinorVersion); - if (glXIsDirect(m_XDisplay, m_context)) - fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion); - else - fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It won't support properly opengl\n", glxMajorVersion, glxMinorVersion); -} - -bool GSWnd::Attach(void* handle, bool managed) -{ - m_Xwindow = *(Window*)handle; - m_managed = managed; - - m_renderer = theApp.GetConfig("renderer", 0) / 3; - assert(m_renderer != 2); - - m_XDisplay = XOpenDisplay(NULL); - - // Note: 4.2 crash on latest nvidia drivers! - if (!CreateContext(3, 3)) return false; - - AttachContext(); - - CheckContext(); - - PFNGLXSWAPINTERVALMESAPROC m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); - //PFNGLXSWAPINTERVALMESAPROC m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapInterval"); - - - return true; -} - -void GSWnd::Detach() -{ - // Actually the destructor is not called when there is only a GSclose/GSshutdown - // The window still need to be closed - DetachContext(); - if (m_context) glXDestroyContext(m_XDisplay, m_context); - - if (m_XDisplay) { - XCloseDisplay(m_XDisplay); - m_XDisplay = NULL; - } -} - -bool GSWnd::Create(const string& title, int w, int h) -{ - if(m_window != NULL) return false; - - if(w <= 0 || h <= 0) { - w = theApp.GetConfig("ModeWidth", 640); - h = theApp.GetConfig("ModeHeight", 480); - } - - m_managed = true; - - // note this part must be only executed when replaying .gs debug file - m_XDisplay = XOpenDisplay(NULL); - - int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_DEPTH_SIZE, 24, - None - }; - XVisualInfo* vi = glXChooseVisual(m_XDisplay, DefaultScreen(m_XDisplay), attrListDbl); - - /* create a color map */ - XSetWindowAttributes attr; - attr.colormap = XCreateColormap(m_XDisplay, RootWindow(m_XDisplay, vi->screen), - vi->visual, AllocNone); - attr.border_pixel = 0; - attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | - StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | - EnterWindowMask | LeaveWindowMask | FocusChangeMask ; - - // Create a window at the last position/size - m_Xwindow = XCreateWindow(m_XDisplay, RootWindow(m_XDisplay, vi->screen), - 0 , 0 , w, h, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask, &attr); - - XMapWindow (m_XDisplay, m_Xwindow); - XFree(vi); - - if (!CreateContext(3, 3)) return false; - - AttachContext(); - - return (m_Xwindow != 0); -} - -Display* GSWnd::GetDisplay() -{ - // note this part must be only executed when replaying .gs debug file - return m_XDisplay; -} - -GSVector4i GSWnd::GetClientRect() -{ - unsigned int h = 480; - unsigned int w = 640; - - unsigned int borderDummy; - unsigned int depthDummy; - Window winDummy; - int xDummy; - int yDummy; - - if (!m_XDisplay) m_XDisplay = XOpenDisplay(NULL); - XGetGeometry(m_XDisplay, m_Xwindow, &winDummy, &xDummy, &yDummy, &w, &h, &borderDummy, &depthDummy); - - return GSVector4i(0, 0, (int)w, (int)h); -} - -// Returns FALSE if the window has no title, or if th window title is under the strict -// management of the emulator. - -bool GSWnd::SetWindowText(const char* title) -{ - if (!m_managed) return true; - - XTextProperty prop; - - memset(&prop, 0, sizeof(prop)); - - char* ptitle = (char*)title; - if (XStringListToTextProperty(&ptitle, 1, &prop)) { - XSetWMName(m_XDisplay, m_Xwindow, &prop); - } - - XFree(prop.value); - XFlush(m_XDisplay); - - return true; -} - -void GSWnd::SetVSync(bool enable) -{ - // m_swapinterval uses an integer as parameter - // 0 -> disable vsync - // n -> wait n frame - if (m_swapinterval) m_swapinterval((int)enable); -} - -void GSWnd::Flip() -{ - glXSwapBuffers(m_XDisplay, m_Xwindow); -} - -void GSWnd::Show() -{ - XMapRaised(m_XDisplay, m_Xwindow); - XFlush(m_XDisplay); -} - -void GSWnd::Hide() -{ - XUnmapWindow(m_XDisplay, m_Xwindow); - XFlush(m_XDisplay); -} - -void GSWnd::HideFrame() -{ - // TODO -} - -#endif diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index 634bc5ce18..4b71b1a1b7 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -21,81 +21,37 @@ #pragma once +#include "stdafx.h" +#include "GSdx.h" #include "GSVector.h" -#ifdef _WINDOWS - class GSWnd { - HWND m_hWnd; - +protected: bool m_managed; // set true when we're attached to a 3rdparty window that's amanged by the emulator - bool m_frame; - - static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); public: - GSWnd(); - virtual ~GSWnd(); + GSWnd() : m_managed(false) {}; + virtual ~GSWnd() {}; - bool Create(const string& title, int w, int h); - bool Attach(void* handle, bool managed = true); - void Detach(); + virtual bool Create(const string& title, int w, int h) = 0; + virtual bool Attach(void* handle, bool managed = true) = 0; + virtual void Detach() = 0; bool IsManaged() const {return m_managed;} - void* GetDisplay() {return m_hWnd;} - void* GetHandle() {return m_hWnd;} - GSVector4i GetClientRect(); - bool SetWindowText(const char* title); + virtual void* GetDisplay() = 0; + virtual void* GetHandle() = 0; + virtual GSVector4i GetClientRect() = 0; + virtual bool SetWindowText(const char* title) = 0; + + virtual void AttachContext() {}; + virtual void DetachContext() {}; + + virtual void Show() = 0; + virtual void Hide() = 0; + virtual void HideFrame() = 0; + + virtual void Flip() {}; + virtual void SetVSync(bool enable) {}; - void Show(); - void Hide(); - void HideFrame(); }; - -#else - -#include - -class GSWnd -{ - void* m_window; - Window m_Xwindow; - Display* m_XDisplay; - - bool m_ctx_attached; - bool m_managed; - int m_renderer; - GLXContext m_context; - - PFNGLXSWAPINTERVALMESAPROC m_swapinterval; - -public: - GSWnd(); - virtual ~GSWnd(); - - bool Create(const string& title, int w, int h); - bool Attach(void* handle, bool managed = true); - void Detach(); - bool IsManaged() const {return m_managed;} - bool IsContextAttached() const { return m_ctx_attached; } - - Display* GetDisplay(); - void* GetHandle() {return (void*)m_Xwindow;} - GSVector4i GetClientRect(); - bool SetWindowText(const char* title); - - bool CreateContext(int major, int minor); - void AttachContext(); - void DetachContext(); - void CheckContext(); - - void Show(); - void Hide(); - void HideFrame(); - void Flip(); - void SetVSync(bool enable); -}; - -#endif diff --git a/plugins/GSdx/GSWndDX.cpp b/plugins/GSdx/GSWndDX.cpp new file mode 100644 index 0000000000..a748394531 --- /dev/null +++ b/plugins/GSdx/GSWndDX.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWndDX.h" + +#ifdef _WINDOWS +GSWndDX::GSWndDX() + : m_hWnd(NULL) + , m_frame(true) +{ +} + +GSWndDX::~GSWndDX() +{ +} + +LRESULT CALLBACK GSWndDX::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + GSWndDX* wnd = NULL; + + if(message == WM_NCCREATE) + { + wnd = (GSWndDX*)((LPCREATESTRUCT)lParam)->lpCreateParams; + + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)wnd); + + wnd->m_hWnd = hWnd; + } + else + { + wnd = (GSWndDX*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + } + + if(wnd == NULL) + { + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return wnd->OnMessage(message, wParam, lParam); +} + +LRESULT GSWndDX::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_CLOSE: + Hide(); + // DestroyWindow(m_hWnd); + return 0; + case WM_DESTROY: + // This kills the emulator when GS is closed, which *really* isn't desired behavior, + // especially in STGS mode (worked in MTGS mode since it only quit the thread, but even + // that wasn't needed). + //PostQuitMessage(0); + return 0; + default: + break; + } + + return DefWindowProc((HWND)m_hWnd, message, wParam, lParam); +} + +bool GSWndDX::Create(const string& title, int w, int h) +{ + if(m_hWnd) return false; + + WNDCLASS wc; + + memset(&wc, 0, sizeof(wc)); + + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = WndProc; + wc.hInstance = theApp.GetModuleHandle(); + // TODO: wc.hIcon = ; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszClassName = "GSWndDX"; + + if(!GetClassInfo(wc.hInstance, wc.lpszClassName, &wc)) + { + if(!RegisterClass(&wc)) + { + return false; + } + } + + DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_BORDER; + + GSVector4i r; + + GetWindowRect(GetDesktopWindow(), r); + + bool remote = !!GetSystemMetrics(SM_REMOTESESSION); + + if(w <= 0 || h <= 0 || remote) + { + w = r.width() / 3; + h = r.width() / 4; + + if(!remote) + { + w *= 2; + h *= 2; + } + } + + r.left = (r.left + r.right - w) / 2; + r.top = (r.top + r.bottom - h) / 2; + r.right = r.left + w; + r.bottom = r.top + h; + + AdjustWindowRect(r, style, FALSE); + + m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, r.left, r.top, r.width(), r.height(), NULL, NULL, wc.hInstance, (LPVOID)this); + + return m_hWnd != NULL; +} + +bool GSWndDX::Attach(void* handle, bool managed) +{ + // TODO: subclass + + m_hWnd = (HWND)handle; + m_managed = managed; + + return true; +} + +void GSWndDX::Detach() +{ + if(m_hWnd && m_managed) + { + // close the window, since it's under GSdx care. It's not taking messages anyway, and + // that means its big, ugly, and in the way. + + DestroyWindow(m_hWnd); + } + + m_hWnd = NULL; + m_managed = true; +} + +GSVector4i GSWndDX::GetClientRect() +{ + GSVector4i r; + + ::GetClientRect(m_hWnd, r); + + return r; +} + +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. + +bool GSWndDX::SetWindowText(const char* title) +{ + if(!m_managed) return false; + + ::SetWindowText(m_hWnd, title); + + return m_frame; +} + +void GSWndDX::Show() +{ + if(!m_managed) return; + + SetForegroundWindow(m_hWnd); + ShowWindow(m_hWnd, SW_SHOWNORMAL); + UpdateWindow(m_hWnd); +} + +void GSWndDX::Hide() +{ + if(!m_managed) return; + + ShowWindow(m_hWnd, SW_HIDE); +} + +void GSWndDX::HideFrame() +{ + if(!m_managed) return; + + SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); + SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + SetMenu(m_hWnd, NULL); + + m_frame = false; +} +#endif diff --git a/plugins/GSdx/GSWndDX.h b/plugins/GSdx/GSWndDX.h new file mode 100644 index 0000000000..02c5c93dbe --- /dev/null +++ b/plugins/GSdx/GSWndDX.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWnd.h" + +#ifdef _WINDOWS +class GSWndDX : public GSWnd +{ + HWND m_hWnd; + + bool m_frame; + + static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + +public: + GSWndDX(); + virtual ~GSWndDX(); + + bool Create(const string& title, int w, int h); + bool Attach(void* handle, bool managed = true); + void Detach(); + + void* GetDisplay() {return m_hWnd;} + void* GetHandle() {return m_hWnd;} + GSVector4i GetClientRect(); + bool SetWindowText(const char* title); + + void Show(); + void Hide(); + void HideFrame(); +}; +#endif diff --git a/plugins/GSdx/GSWndEGL.cpp b/plugins/GSdx/GSWndEGL.cpp new file mode 100644 index 0000000000..d36a30b66d --- /dev/null +++ b/plugins/GSdx/GSWndEGL.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWndEGL.h" + +// Need at least MESA 9.0 (plan for october/november 2012) +// So force the destiny to at least check the compilation +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#endif + +#if defined(_LINUX) && defined (EGL_API) +GSWndEGL::GSWndEGL() + : m_NativeWindow(0), m_NativeDisplay(NULL), m_ctx_attached(false) +{ +} + +bool GSWndEGL::CreateContext(int major, int minor) +{ + EGLConfig eglConfig; + EGLint numConfigs; + EGLint contextAttribs[] = + { + // Not yet supported by Radeon/Gallium +#if 0 + EGL_CONTEXT_MAJOR_VERSION_KHR, major, + EGL_CONTEXT_MINOR_VERSION_KHR, minor, + // Keep compatibility for old cruft + //EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, + // FIXME : Request a debug context to ease opengl development + EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, +#endif + EGL_NONE + }; + EGLint attrList[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_NONE + }; + + eglBindAPI(EGL_OPENGL_API); + + if ( !eglChooseConfig(m_eglDisplay, attrList, &eglConfig, 1, &numConfigs) ) + { + fprintf(stderr,"EGL: Failed to get a frame buffer config!\n"); + return EGL_FALSE; + } + + m_eglSurface = eglCreateWindowSurface(m_eglDisplay, eglConfig, m_NativeWindow, NULL); + if ( m_eglSurface == EGL_NO_SURFACE ) + { + fprintf(stderr,"EGL: Failed to get a window surface\n"); + return EGL_FALSE; + } + + m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs ); + if ( m_eglContext == EGL_NO_CONTEXT ) + { + fprintf(stderr,"EGL: Failed to create the context\n"); + fprintf(stderr,"EGL STATUS: %x\n", eglGetError()); + return EGL_FALSE; + } + + if ( !eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext) ) + { + return EGL_FALSE; + } + + return EGL_TRUE; +} + +void GSWndEGL::AttachContext() +{ + if (!IsContextAttached()) { + // The setting of the API is local to a thread. This function + // can be called from 2 threads. + eglBindAPI(EGL_OPENGL_API); + + //fprintf(stderr, "Attach the context\n"); + eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); + m_ctx_attached = true; + } +} + +void GSWndEGL::DetachContext() +{ + if (IsContextAttached()) { + //fprintf(stderr, "Detach the context\n"); + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + m_ctx_attached = false; + } +} + +void GSWndEGL::CheckContext() +{ + fprintf(stderr,"EGL: %s : %s\n", eglQueryString(m_eglDisplay, EGL_VENDOR) , eglQueryString(m_eglDisplay, EGL_VERSION) ); + fprintf(stderr,"EGL: extensions supported: %s\n", eglQueryString(m_eglDisplay, EGL_EXTENSIONS)); +} + +bool GSWndEGL::Attach(void* handle, bool managed) +{ + m_NativeWindow = *(Window*)handle; + m_managed = managed; + + m_NativeDisplay = XOpenDisplay(NULL); + if (!OpenEGLDisplay()) return false; + + // Note: 4.2 crash on latest nvidia drivers! + if (!CreateContext(3, 3)) return false; + + AttachContext(); + + CheckContext(); + + return true; +} + +void GSWndEGL::Detach() +{ + // Actually the destructor is not called when there is only a GSclose/GSshutdown + // The window still need to be closed + DetachContext(); + CloseEGLDisplay(); + + if (m_NativeDisplay) { + XCloseDisplay(m_NativeDisplay); + m_NativeDisplay = NULL; + } +} + +bool GSWndEGL::Create(const string& title, int w, int h) +{ + if(m_NativeWindow) return false; + + if(w <= 0 || h <= 0) { + w = theApp.GetConfig("ModeWidth", 640); + h = theApp.GetConfig("ModeHeight", 480); + } + + m_managed = true; + + // note this part must be only executed when replaying .gs debug file + m_NativeDisplay = XOpenDisplay(NULL); + if (!OpenEGLDisplay()) return false; + + m_NativeWindow = XCreateSimpleWindow(m_NativeDisplay, DefaultRootWindow(m_NativeDisplay), 0, 0, w, h, 0, 0, 0); + + XMapWindow (m_NativeDisplay, m_NativeWindow); + + if (!CreateContext(3, 3)) return false; + + AttachContext(); + + return (m_NativeWindow != 0); +} + +void* GSWndEGL::GetDisplay() +{ + // note this part must be only executed when replaying .gs debug file + return (void*)m_NativeDisplay; +} + +GSVector4i GSWndEGL::GetClientRect() +{ + unsigned int h = 480; + unsigned int w = 640; + + unsigned int borderDummy; + unsigned int depthDummy; + Window winDummy; + int xDummy; + int yDummy; + + if (!m_NativeDisplay) m_NativeDisplay = XOpenDisplay(NULL); + XGetGeometry(m_NativeDisplay, m_NativeWindow, &winDummy, &xDummy, &yDummy, &w, &h, &borderDummy, &depthDummy); + + return GSVector4i(0, 0, (int)w, (int)h); +} + +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. + +bool GSWndEGL::SetWindowText(const char* title) +{ + if (!m_managed) return true; + + XTextProperty prop; + + memset(&prop, 0, sizeof(prop)); + + char* ptitle = (char*)title; + if (XStringListToTextProperty(&ptitle, 1, &prop)) { + XSetWMName(m_NativeDisplay, m_NativeWindow, &prop); + } + + XFree(prop.value); + XFlush(m_NativeDisplay); + + return true; +} + +void GSWndEGL::SetVSync(bool enable) +{ + // 0 -> disable vsync + // n -> wait n frame + eglSwapInterval(m_eglDisplay, enable); +} + +void GSWndEGL::Flip() +{ + eglSwapBuffers(m_eglDisplay, m_eglSurface); +} + +void GSWndEGL::Show() +{ + XMapRaised(m_NativeDisplay, m_NativeWindow); + XFlush(m_NativeDisplay); +} + +void GSWndEGL::Hide() +{ + XUnmapWindow(m_NativeDisplay, m_NativeWindow); + XFlush(m_NativeDisplay); +} + +void GSWndEGL::HideFrame() +{ + // TODO +} + +void GSWndEGL::CloseEGLDisplay() +{ + eglTerminate(m_eglDisplay); +} + +EGLBoolean GSWndEGL::OpenEGLDisplay() +{ + // Create an EGL display from the native display + m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_NativeDisplay); + if ( m_eglDisplay == EGL_NO_DISPLAY ) return EGL_FALSE; + + if ( !eglInitialize(m_eglDisplay, NULL, NULL) ) return EGL_FALSE; + + return EGL_TRUE; +} + + +#endif diff --git a/plugins/GSdx/GSWndEGL.h b/plugins/GSdx/GSWndEGL.h new file mode 100644 index 0000000000..3c1a6f3eec --- /dev/null +++ b/plugins/GSdx/GSWndEGL.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWnd.h" + +#if defined(_LINUX) && defined (EGL_API) +#include +#include +#include + +class GSWndEGL : public GSWnd +{ + EGLNativeWindowType m_NativeWindow; + EGLNativeDisplayType m_NativeDisplay; + + EGLDisplay m_eglDisplay; + EGLSurface m_eglSurface; + EGLContext m_eglContext; + + bool m_ctx_attached; + + bool IsContextAttached() const { return m_ctx_attached; } + bool CreateContext(int major, int minor); + void CheckContext(); + + EGLBoolean OpenEGLDisplay(); + void CloseEGLDisplay(); + +public: + GSWndEGL(); + virtual ~GSWndEGL() {}; + + bool Create(const string& title, int w, int h); + bool Attach(void* handle, bool managed = true); + void Detach(); + + void* GetDisplay(); + void* GetHandle() {return (void*)m_NativeWindow;} + GSVector4i GetClientRect(); + bool SetWindowText(const char* title); + + void AttachContext(); + void DetachContext(); + + void Show(); + void Hide(); + void HideFrame(); + void Flip(); + void SetVSync(bool enable); +}; + +#endif diff --git a/plugins/GSdx/GSWndOGL.cpp b/plugins/GSdx/GSWndOGL.cpp new file mode 100644 index 0000000000..ce57287157 --- /dev/null +++ b/plugins/GSdx/GSWndOGL.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWndOGL.h" + +#ifdef _LINUX +GSWndOGL::GSWndOGL() + : m_NativeWindow(0), m_NativeDisplay(NULL), m_swapinterval(NULL), m_ctx_attached(false) +{ +} + +static bool ctxError = false; +static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) +{ + ctxError = true; + return 0; +} + +bool GSWndOGL::CreateContext(int major, int minor) +{ + if ( !m_NativeDisplay || !m_NativeWindow ) + { + fprintf( stderr, "Wrong X11 display/window\n" ); + exit(1); + } + + // Get visual information + static int attrListDbl[] = + { + // GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X + // visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE. + GLX_X_RENDERABLE , True, + GLX_RED_SIZE , 8, + GLX_GREEN_SIZE , 8, + GLX_BLUE_SIZE , 8, + GLX_DEPTH_SIZE , 24, + GLX_DOUBLEBUFFER , True, + None + }; + + PFNGLXCHOOSEFBCONFIGPROC glX_ChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig"); + int fbcount = 0; + GLXFBConfig *fbc = glX_ChooseFBConfig(m_NativeDisplay, DefaultScreen(m_NativeDisplay), attrListDbl, &fbcount); + if (!fbc || fbcount < 1) return false; + + PFNGLXCREATECONTEXTATTRIBSARBPROC glX_CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); + if (!glX_CreateContextAttribsARB) return false; + + // Install a dummy handler to handle gracefully (aka not segfault) the support of GL version + int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); + // Be sure the handler is installed + XSync( m_NativeDisplay, false); + + // Create a context + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, major, + GLX_CONTEXT_MINOR_VERSION_ARB, minor, + // FIXME : Request a debug context to ease opengl development + // Note: don't support deprecated feature (pre openg 3.1) + //GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; + + m_context = glX_CreateContextAttribsARB(m_NativeDisplay, fbc[0], 0, true, context_attribs); + + // Don't forget to reinstall the older Handler + XSetErrorHandler(oldHandler); + + // Get latest error + XSync( m_NativeDisplay, false); + + if (!m_context || ctxError) { + fprintf(stderr, "Failed to create the opengl context. Check your drivers support openGL %d.%d. Hint: opensource drivers don't\n", major, minor ); + return false; + } + + return true; +} + +void GSWndOGL::AttachContext() +{ + if (!IsContextAttached()) { + //fprintf(stderr, "Attach the context\n"); + glXMakeCurrent(m_NativeDisplay, m_NativeWindow, m_context); + m_ctx_attached = true; + } +} + +void GSWndOGL::DetachContext() +{ + if (IsContextAttached()) { + //fprintf(stderr, "Detach the context\n"); + glXMakeCurrent(m_NativeDisplay, None, NULL); + m_ctx_attached = false; + } +} + +void GSWndOGL::CheckContext() +{ + int glxMajorVersion, glxMinorVersion; + glXQueryVersion(m_NativeDisplay, &glxMajorVersion, &glxMinorVersion); + if (glXIsDirect(m_NativeDisplay, m_context)) + fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion); + else + fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It won't support properly opengl\n", glxMajorVersion, glxMinorVersion); +} + +bool GSWndOGL::Attach(void* handle, bool managed) +{ + m_NativeWindow = *(Window*)handle; + m_managed = managed; + + m_NativeDisplay = XOpenDisplay(NULL); + + // Note: 4.2 crash on latest nvidia drivers! +#ifdef OGL_FREE_DRIVER + if (!CreateContext(3, 0)) return false; +#else + if (!CreateContext(3, 3)) return false; +#endif + + AttachContext(); + + CheckContext(); + + m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); + //PFNGLXSWAPINTERVALMESAPROC m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapInterval"); + + + return true; +} + +void GSWndOGL::Detach() +{ + // Actually the destructor is not called when there is only a GSclose/GSshutdown + // The window still need to be closed + DetachContext(); + if (m_context) glXDestroyContext(m_NativeDisplay, m_context); + + if (m_NativeDisplay) { + XCloseDisplay(m_NativeDisplay); + m_NativeDisplay = NULL; + } +} + +bool GSWndOGL::Create(const string& title, int w, int h) +{ + if(m_NativeWindow) return false; + + if(w <= 0 || h <= 0) { + w = theApp.GetConfig("ModeWidth", 640); + h = theApp.GetConfig("ModeHeight", 480); + } + + m_managed = true; + + // note this part must be only executed when replaying .gs debug file + m_NativeDisplay = XOpenDisplay(NULL); + +#if 0 + int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_DEPTH_SIZE, 24, + None + }; + XVisualInfo* vi = glXChooseVisual(m_NativeDisplay, DefaultScreen(m_NativeDisplay), attrListDbl); + + /* create a color map */ + XSetWindowAttributes attr; + attr.colormap = XCreateColormap(m_NativeDisplay, RootWindow(m_NativeDisplay, vi->screen), + vi->visual, AllocNone); + attr.border_pixel = 0; + attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | + StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | + EnterWindowMask | LeaveWindowMask | FocusChangeMask ; + + // Create a window at the last position/size + m_NativeWindow = XCreateWindow(m_NativeDisplay, RootWindow(m_NativeDisplay, vi->screen), + 0 , 0 , w, h, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &attr); + + XFree(vi); +#else + m_NativeWindow = XCreateSimpleWindow(m_NativeDisplay, DefaultRootWindow(m_NativeDisplay), 0, 0, w, h, 0, 0, 0); +#endif + + XMapWindow (m_NativeDisplay, m_NativeWindow); + + + if (!CreateContext(3, 3)) return false; + + AttachContext(); + + CheckContext(); + + return (m_NativeWindow != 0); +} + +void* GSWndOGL::GetDisplay() +{ + // note this part must be only executed when replaying .gs debug file + return (void*)m_NativeDisplay; +} + +GSVector4i GSWndOGL::GetClientRect() +{ + unsigned int h = 480; + unsigned int w = 640; + + unsigned int borderDummy; + unsigned int depthDummy; + Window winDummy; + int xDummy; + int yDummy; + + if (!m_NativeDisplay) m_NativeDisplay = XOpenDisplay(NULL); + XGetGeometry(m_NativeDisplay, m_NativeWindow, &winDummy, &xDummy, &yDummy, &w, &h, &borderDummy, &depthDummy); + + return GSVector4i(0, 0, (int)w, (int)h); +} + +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. + +bool GSWndOGL::SetWindowText(const char* title) +{ + if (!m_managed) return true; + + XTextProperty prop; + + memset(&prop, 0, sizeof(prop)); + + char* ptitle = (char*)title; + if (XStringListToTextProperty(&ptitle, 1, &prop)) { + XSetWMName(m_NativeDisplay, m_NativeWindow, &prop); + } + + XFree(prop.value); + XFlush(m_NativeDisplay); + + return true; +} + +void GSWndOGL::SetVSync(bool enable) +{ + // m_swapinterval uses an integer as parameter + // 0 -> disable vsync + // n -> wait n frame + if (m_swapinterval) m_swapinterval((int)enable); +} + +void GSWndOGL::Flip() +{ + glXSwapBuffers(m_NativeDisplay, m_NativeWindow); +} + +void GSWndOGL::Show() +{ + XMapRaised(m_NativeDisplay, m_NativeWindow); + XFlush(m_NativeDisplay); +} + +void GSWndOGL::Hide() +{ + XUnmapWindow(m_NativeDisplay, m_NativeWindow); + XFlush(m_NativeDisplay); +} + +void GSWndOGL::HideFrame() +{ + // TODO +} + +#endif diff --git a/plugins/GSdx/GSWndOGL.h b/plugins/GSdx/GSWndOGL.h new file mode 100644 index 0000000000..a8da30ea86 --- /dev/null +++ b/plugins/GSdx/GSWndOGL.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWnd.h" + +#ifdef _LINUX +#include +#include + +class GSWndOGL : public GSWnd +{ + Window m_NativeWindow; + Display* m_NativeDisplay; + GLXContext m_context; + + bool m_ctx_attached; + + PFNGLXSWAPINTERVALMESAPROC m_swapinterval; + + bool IsContextAttached() const { return m_ctx_attached; } + bool CreateContext(int major, int minor); + void CheckContext(); + +public: + GSWndOGL(); + virtual ~GSWndOGL() {}; + + bool Create(const string& title, int w, int h); + bool Attach(void* handle, bool managed = true); + void Detach(); + + void* GetDisplay(); + void* GetHandle() {return (void*)m_NativeWindow;} + GSVector4i GetClientRect(); + bool SetWindowText(const char* title); + + void AttachContext(); + void DetachContext(); + + void Show(); + void Hide(); + void HideFrame(); + void Flip(); + void SetVSync(bool enable); +}; + +#endif diff --git a/plugins/GSdx/GSWndWGL.cpp b/plugins/GSdx/GSWndWGL.cpp new file mode 100644 index 0000000000..03f98dfdaf --- /dev/null +++ b/plugins/GSdx/GSWndWGL.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWndWGL.h" + +#ifdef _WINDOWS +GSWndWGL::GSWndWGL() + : m_NativeWindow(NULL), m_NativeDisplay(NULL), m_context(NULL), m_ctx_attached(false) +{ +} + +bool GSWndWGL::CreateContext(int major, int minor) +{ + if ( !m_NativeDisplay || !m_NativeWindow ) + { + fprintf( stderr, "Wrong display/window\n" ); + exit(1); + } + + // GL2 context are quite easy but we need GL3 which is another painful story... + if (!(m_context = wglCreateContext(m_NativeDisplay))) { + fprintf(stderr, "Failed to create a 2.0 context\n"); + return false; + } + + // FIXME test it + // Note: albeit every tutorial said that we need an opengl context to use the GL function wglCreateContextAttribsARB + // On linux it works without the extra temporary context, not sure the limitation still applied + if (major >= 3) { + AttachContext(); + + // Create a context + int context_attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, major, + WGL_CONTEXT_MINOR_VERSION_ARB, minor, + // FIXME : Request a debug context to ease opengl development + // Note: don't support deprecated feature (pre openg 3.1) + //GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + 0 + }; + + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + if (!wglCreateContextAttribsARB) { + fprintf(stderr, "Failed to init wglCreateContextAttribsARB function pointer\n"); + return false; + } + + HGLRC context30 = wglCreateContextAttribsARB(m_NativeDisplay, NULL, context_attribs); + if (!context30) { + fprintf(stderr, "Failed to create a 3.x context\n"); + return false; + } + + DetachContext(); + wglDeleteContext(m_context); + + m_context = context30; + fprintf(stderr, "3.x GL context successfully created\n"); + } + + return true; +} + +void GSWndWGL::AttachContext() +{ + if (!IsContextAttached()) { + wglMakeCurrent(m_NativeDisplay, m_context); + m_ctx_attached = true; + } +} + +void GSWndWGL::DetachContext() +{ + if (IsContextAttached()) { + wglMakeCurrent(NULL, NULL); + m_ctx_attached = false; + } +} + +//TODO: DROP ??? +void GSWndWGL::CheckContext() +{ +#if 0 + int glxMajorVersion, glxMinorVersion; + glXQueryVersion(m_NativeDisplay, &glxMajorVersion, &glxMinorVersion); + if (glXIsDirect(m_NativeDisplay, m_context)) + fprintf(stderr, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion); + else + fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It won't support properly opengl\n", glxMajorVersion, glxMinorVersion); +#endif +} + +bool GSWndWGL::Attach(void* handle, bool managed) +{ + m_NativeWindow = (HWND)handle; + m_managed = managed; + + if (!OpenWGLDisplay()) return false; + + if (!CreateContext(3, 3)) return false; + + AttachContext(); + + CheckContext(); + + // TODO + //m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); + //PFNGLXSWAPINTERVALMESAPROC m_swapinterval = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapInterval"); + + UpdateWindow(m_NativeWindow); + + return true; +} + +void GSWndWGL::Detach() +{ + // Actually the destructor is not called when there is only a GSclose/GSshutdown + // The window still need to be closed + DetachContext(); + + if (m_context) wglDeleteContext(m_context); + m_context = NULL; + + CloseWGLDisplay(); +} + +bool GSWndWGL::OpenWGLDisplay() +{ + GLuint PixelFormat; // Holds The Results After Searching For A Match + PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be + + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 32, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // 8bit Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 24, // 24Bit Z-Buffer (Depth Buffer) + 8, // 8bit Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + if (!(m_NativeDisplay = GetDC(m_NativeWindow))) + { + MessageBox(NULL, "(1) Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return false; + } + + if (!(PixelFormat = ChoosePixelFormat(m_NativeDisplay, &pfd))) + { + MessageBox(NULL, "(2) Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return false; + } + + if (!SetPixelFormat(m_NativeDisplay, PixelFormat, &pfd)) + { + MessageBox(NULL, "(3) Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return false; + } + + return true; +} + +void GSWndWGL::CloseWGLDisplay() +{ + if (m_NativeDisplay && !ReleaseDC(m_NativeWindow, m_NativeDisplay)) // Are We Able To Release The DC + { + MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + } + m_NativeDisplay = NULL; // Set DC To NULL +} + +//TODO: GSopen 1 => Drop? +bool GSWndWGL::Create(const string& title, int w, int h) +{ +#if 0 + if(m_NativeWindow) return false; + + if(w <= 0 || h <= 0) { + w = theApp.GetConfig("ModeWidth", 640); + h = theApp.GetConfig("ModeHeight", 480); + } + + m_managed = true; + + // note this part must be only executed when replaying .gs debug file + m_NativeDisplay = XOpenDisplay(NULL); + + int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_DEPTH_SIZE, 24, + None + }; + XVisualInfo* vi = glXChooseVisual(m_NativeDisplay, DefaultScreen(m_NativeDisplay), attrListDbl); + + /* create a color map */ + XSetWindowAttributes attr; + attr.colormap = XCreateColormap(m_NativeDisplay, RootWindow(m_NativeDisplay, vi->screen), + vi->visual, AllocNone); + attr.border_pixel = 0; + attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | + StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | + EnterWindowMask | LeaveWindowMask | FocusChangeMask ; + + // Create a window at the last position/size + m_NativeWindow = XCreateWindow(m_NativeDisplay, RootWindow(m_NativeDisplay, vi->screen), + 0 , 0 , w, h, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &attr); + + XMapWindow (m_NativeDisplay, m_NativeWindow); + XFree(vi); + + if (!CreateContext(3, 3)) return false; + + AttachContext(); + + return (m_NativeWindow != 0); +#else + return false; +#endif +} + +//Same as DX +GSVector4i GSWndWGL::GetClientRect() +{ + GSVector4i r; + + ::GetClientRect(m_NativeWindow, r); + + return r; +} + +//TODO: check extensions supported or not +//FIXME : extension allocation +void GSWndWGL::SetVSync(bool enable) +{ + // m_swapinterval uses an integer as parameter + // 0 -> disable vsync + // n -> wait n frame + //if (m_swapinterval) m_swapinterval((int)enable); + // wglSwapIntervalEXT(!enable); + +} + +void GSWndWGL::Flip() +{ + SwapBuffers(m_NativeDisplay); +} + +void GSWndWGL::Show() +{ +} + +void GSWndWGL::Hide() +{ +} + +void GSWndWGL::HideFrame() +{ +} + +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. + +bool GSWndWGL::SetWindowText(const char* title) +{ + return false; +} + + +#endif diff --git a/plugins/GSdx/GSWndWGL.h b/plugins/GSdx/GSWndWGL.h new file mode 100644 index 0000000000..77251f8deb --- /dev/null +++ b/plugins/GSdx/GSWndWGL.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007-2012 Gabest + * http://www.gabest.org + * + * 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 "GSWnd.h" + +#ifdef _WINDOWS + +class GSWndWGL : public GSWnd +{ + HWND m_NativeWindow; + HDC m_NativeDisplay; + HGLRC m_context; + + bool m_ctx_attached; + + //PFNGLXSWAPINTERVALMESAPROC m_swapinterval; + + bool IsContextAttached() const { return m_ctx_attached; } + bool CreateContext(int major, int minor); + void CheckContext(); + + void CloseWGLDisplay(); + bool OpenWGLDisplay(); + +public: + GSWndWGL(); + virtual ~GSWndWGL() {}; + + bool Create(const string& title, int w, int h); + bool Attach(void* handle, bool managed = true); + void Detach(); + + void* GetDisplay() {return m_NativeWindow;} + void* GetHandle() {return m_NativeWindow;} + GSVector4i GetClientRect(); + bool SetWindowText(const char* title); + + void AttachContext(); + void DetachContext(); + + void Show(); + void Hide(); + void HideFrame(); + void Flip(); + void SetVSync(bool enable); +}; + +#endif diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index e3f7e6860b..0140a42b39 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -120,10 +120,8 @@ GSdxApp::GSdxApp() #endif m_gs_renderers.push_back(GSSetting(10, "Null", "Software")); m_gs_renderers.push_back(GSSetting(11, "Null", "Null")); -#ifdef _LINUX m_gs_renderers.push_back(GSSetting(12, "OpenGL", "Hardware")); m_gs_renderers.push_back(GSSetting(13, "OpenGL", "Software")); -#endif m_gs_interlace.push_back(GSSetting(0, "None", "")); m_gs_interlace.push_back(GSSetting(1, "Weave tff", "saw-tooth")); @@ -172,6 +170,16 @@ GSdxApp::GSdxApp() } #ifdef _LINUX +void GSdxApp::ReloadConfig() +{ + auto file = m_configuration_map.find("inifile"); + if (file == m_configuration_map.end()) return; + + // A map was built so reload it + m_configuration_map.clear(); + BuildConfigurationMap(file->second.c_str()); +} + void GSdxApp::BuildConfigurationMap(const char* lpFileName) { // Check if the map was already built diff --git a/plugins/GSdx/GSdx.h b/plugins/GSdx/GSdx.h index c517785b0d..f7f49a4a1b 100644 --- a/plugins/GSdx/GSdx.h +++ b/plugins/GSdx/GSdx.h @@ -41,6 +41,8 @@ public: #endif #ifdef _LINUX void BuildConfigurationMap(const char* lpFileName); + void ReloadConfig(); + size_t GetPrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName); bool WritePrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName); int GetPrivateProfileInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName); diff --git a/plugins/GSdx/GSdx.vcxproj b/plugins/GSdx/GSdx.vcxproj index babb34c27b..4289cf4322 100644 --- a/plugins/GSdx/GSdx.vcxproj +++ b/plugins/GSdx/GSdx.vcxproj @@ -438,6 +438,7 @@ + @@ -460,6 +461,7 @@ + @@ -536,6 +538,7 @@ + @@ -601,12 +604,15 @@ + + + @@ -618,6 +624,8 @@ + + Create Create @@ -1562,6 +1570,7 @@ + @@ -1587,6 +1596,7 @@ + @@ -1607,6 +1617,7 @@ + @@ -1617,21 +1628,27 @@ + + + + + + diff --git a/plugins/GSdx/GSdx.vcxproj.filters b/plugins/GSdx/GSdx.vcxproj.filters index 2875a069e4..7712fb7c28 100644 --- a/plugins/GSdx/GSdx.vcxproj.filters +++ b/plugins/GSdx/GSdx.vcxproj.filters @@ -60,6 +60,9 @@ Source Files + + Source Files + Source Files @@ -108,6 +111,9 @@ Source Files + + Source Files + Source Files @@ -135,6 +141,9 @@ Source Files + + Source Files + Source Files @@ -144,6 +153,9 @@ Source Files + + Source Files + Source Files @@ -153,6 +165,9 @@ Source Files + + Source Files + Source Files @@ -177,6 +192,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -249,6 +270,9 @@ Baseclasses + + Source Files + Source Files @@ -314,6 +338,9 @@ + + Header Files + Header Files @@ -353,6 +380,9 @@ Header Files + + Header Files + Header Files @@ -407,6 +437,9 @@ Header Files + + Header Files + Header Files @@ -437,6 +470,9 @@ Header Files + + Header Files + Header Files @@ -446,6 +482,9 @@ Header Files + + Header Files + Header Files @@ -455,6 +494,9 @@ Header Files + + Header Files + Header Files @@ -464,6 +506,9 @@ Header Files + + Header Files + Header Files @@ -479,6 +524,12 @@ Header Files + + Header Files + + + Header Files + Header Files diff --git a/plugins/GSdx/GSdx_vs11.vcxproj b/plugins/GSdx/GSdx_vs11.vcxproj index ffb8784255..988ebb8919 100644 --- a/plugins/GSdx/GSdx_vs11.vcxproj +++ b/plugins/GSdx/GSdx_vs11.vcxproj @@ -566,6 +566,7 @@ + @@ -588,6 +589,7 @@ + @@ -678,6 +680,7 @@ + @@ -755,12 +758,15 @@ + + + @@ -773,6 +779,8 @@ + + Create Create @@ -1905,6 +1913,7 @@ + @@ -1930,6 +1939,7 @@ + @@ -1950,6 +1960,7 @@ + @@ -1960,21 +1971,27 @@ + + + + + + @@ -2037,4 +2054,4 @@ - \ No newline at end of file + diff --git a/plugins/GSdx/GSdx_vs11.vcxproj.filters b/plugins/GSdx/GSdx_vs11.vcxproj.filters index 2875a069e4..7712fb7c28 100644 --- a/plugins/GSdx/GSdx_vs11.vcxproj.filters +++ b/plugins/GSdx/GSdx_vs11.vcxproj.filters @@ -60,6 +60,9 @@ Source Files + + Source Files + Source Files @@ -108,6 +111,9 @@ Source Files + + Source Files + Source Files @@ -135,6 +141,9 @@ Source Files + + Source Files + Source Files @@ -144,6 +153,9 @@ Source Files + + Source Files + Source Files @@ -153,6 +165,9 @@ Source Files + + Source Files + Source Files @@ -177,6 +192,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -249,6 +270,9 @@ Baseclasses + + Source Files + Source Files @@ -314,6 +338,9 @@ + + Header Files + Header Files @@ -353,6 +380,9 @@ Header Files + + Header Files + Header Files @@ -407,6 +437,9 @@ Header Files + + Header Files + Header Files @@ -437,6 +470,9 @@ Header Files + + Header Files + Header Files @@ -446,6 +482,9 @@ Header Files + + Header Files + Header Files @@ -455,6 +494,9 @@ Header Files + + Header Files + Header Files @@ -464,6 +506,9 @@ Header Files + + Header Files + Header Files @@ -479,6 +524,12 @@ Header Files + + Header Files + + + Header Files + Header Files diff --git a/plugins/GSdx/GSdx_vs2008.vcproj b/plugins/GSdx/GSdx_vs2008.vcproj index adfe022dd1..0b99690572 100644 --- a/plugins/GSdx/GSdx_vs2008.vcproj +++ b/plugins/GSdx/GSdx_vs2008.vcproj @@ -773,6 +773,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -861,6 +865,10 @@ RelativePath=".\GSDeviceNull.cpp" > + + @@ -1037,6 +1045,10 @@ RelativePath=".\GSRendererNull.cpp" > + + @@ -1177,6 +1189,10 @@ RelativePath=".\GSTexture9.cpp" > + + @@ -1189,6 +1205,10 @@ RelativePath=".\GSTextureCache9.cpp" > + + @@ -1201,6 +1221,10 @@ RelativePath=".\GSTextureFX9.cpp" > + + @@ -1237,6 +1261,14 @@ RelativePath=".\GSWnd.cpp" > + + + + @@ -1359,6 +1391,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -1459,6 +1495,10 @@ RelativePath=".\GSDeviceNull.h" > + + @@ -1539,6 +1579,10 @@ RelativePath=".\GSRendererNull.h" > + + @@ -1579,6 +1623,10 @@ RelativePath=".\GSTexture9.h" > + + @@ -1591,6 +1639,10 @@ RelativePath=".\GSTextureCache9.h" > + + @@ -1611,6 +1663,10 @@ RelativePath=".\GSThread.h" > + + @@ -1623,6 +1679,10 @@ RelativePath=".\GSVertex.h" > + + @@ -1643,6 +1703,14 @@ RelativePath=".\GSWnd.h" > + + + + diff --git a/plugins/GSdx/config.h b/plugins/GSdx/config.h index de278d120e..727931513d 100644 --- a/plugins/GSdx/config.h +++ b/plugins/GSdx/config.h @@ -36,8 +36,10 @@ //#define DISABLE_DATE -// Set manually uniform buffer index -//#define DISABLE_GL42 +#define ENABLE_OGL_MT_HACK // OpenGL doesn't allow to access the same bound context from multiple threads. This hack changes context binding for GSreadFIFO* access +#ifdef _DEBUG +#define ENABLE_OGL_DEBUG // Create a debug context and check opengl command status. Allow also to dump various textures/states. +#endif -// Debug: use single program for all shaders. -//#define DISABLE_GL41_SSO +// Allow to create only a 3.0 context for opensource driver +//#define OGL_FREE_DRIVER diff --git a/plugins/GSdx/linux_replay.cpp b/plugins/GSdx/linux_replay.cpp index acfceb6794..d6de2f73ed 100644 --- a/plugins/GSdx/linux_replay.cpp +++ b/plugins/GSdx/linux_replay.cpp @@ -19,43 +19,55 @@ */ #include "stdafx.h" - -EXPORT_C GSsetSettingsDir(const char* dir); -EXPORT_C GSReplay(char* lpszCmdLine, int renderer); - +#include void help() { fprintf(stderr, "Loader gs file\n"); - fprintf(stderr, "ARG1 Ini directory\n"); + fprintf(stderr, "ARG1 GSdx plugin\n"); fprintf(stderr, "ARG2 .gs file\n"); + fprintf(stderr, "ARG3 Ini directory\n"); exit(1); } int main ( int argc, char *argv[] ) { - if ( argc == 3) { - GSsetSettingsDir(argv[1]); - GSReplay(argv[2], 12); - } else if ( argc == 2) { + if (argc < 3) help(); + + void *handle = dlopen(argv[1], RTLD_LAZY|RTLD_GLOBAL); + if (handle == NULL) { + fprintf(stderr, "Failed to open plugin %s\n", argv[1]); + help(); + } + + __attribute__((stdcall)) void (*GSsetSettingsDir_ptr)(const char*); + __attribute__((stdcall)) void (*GSReplay_ptr)(char*, int); + + *(void**)(&GSsetSettingsDir_ptr) = dlsym(handle, "GSsetSettingsDir"); + *(void**)(&GSReplay_ptr) = dlsym(handle, "GSReplay"); + + if ( argc == 4) { + (void)GSsetSettingsDir_ptr(argv[3]); + } else if ( argc == 3) { #ifdef XDG_STD - std::string home("HOME"); - char * val = getenv( home.c_str() ); - if (val == NULL) { - fprintf(stderr, "Failed to get the home dir\n"); - help(); - } + char *val = getenv("HOME"); + if (val == NULL) { + dlclose(handle); + fprintf(stderr, "Failed to get the home dir\n"); + help(); + } - std::string ini_dir(val); - ini_dir += "/.config/pcsx2/inis"; + std::string ini_dir(val); + ini_dir += "/.config/pcsx2/inis"; - GSsetSettingsDir(ini_dir.c_str()); - GSReplay(argv[1], 12); + GSsetSettingsDir_ptr(ini_dir.c_str()); #else - fprintf(stderr, "default ini dir only supported on XDG\n"); - help(); + fprintf(stderr, "default ini dir only supported on XDG\n"); + dlclose(handle); + help(); #endif - } else - help(); + } + GSReplay_ptr(argv[2], 12); + dlclose(handle); } diff --git a/plugins/GSdx/res/convert.glsl b/plugins/GSdx/res/convert.glsl index 38b234c709..e2040e28a0 100644 --- a/plugins/GSdx/res/convert.glsl +++ b/plugins/GSdx/res/convert.glsl @@ -9,11 +9,13 @@ struct vertex_basic #ifdef VERTEX_SHADER +#if __VERSION__ > 140 out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; }; +#endif layout(location = 0) in vec4 POSITION; layout(location = 1) in vec2 TEXCOORD0; @@ -26,75 +28,75 @@ layout(location = 1) in vec2 TEXCOORD0; // smooth, the default, means to do perspective-correct interpolation. // // The centroid qualifier only matters when multisampling. If this qualifier is not present, then the value is interpolated to the pixel's center, anywhere in the pixel, or to one of the pixel's samples. This sample may lie outside of the actual primitive being rendered, since a primitive can cover only part of a pixel's area. The centroid qualifier is used to prevent this; the interpolation point must fall within both the pixel's area and the primitive's area. +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) out vertex_basic VSout; +#define VSout_p (VSout.p) +#define VSout_t (VSout.t) +#else +#ifdef DISABLE_SSO +out vec4 SHADERp; +out vec2 SHADERt; +#else +layout(location = 0) out vec4 SHADERp; +layout(location = 1) out vec2 SHADERt; +#endif +#define VSout_p SHADERp +#define VSout_t SHADERt +#endif void vs_main() { - VSout.p = POSITION; - VSout.t = TEXCOORD0; + VSout_p = POSITION; + VSout_t = TEXCOORD0; gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position } #endif -#ifdef GEOMETRY_SHADER -in gl_PerVertex { - vec4 gl_Position; - float gl_PointSize; - float gl_ClipDistance[]; -} gl_in[]; - -out gl_PerVertex { - vec4 gl_Position; - float gl_PointSize; - float gl_ClipDistance[]; -}; - -// FIXME -// AMD Driver bug again !!!! -//layout(location = 0) in vertex GSin[]; -in vertex_basic GSin[]; - -layout(location = 0) out vertex_basic GSout; -layout(triangles) in; -layout(triangle_strip, max_vertices = 3) out; - -void gs_main() -{ - for(int i = 0; i < gl_in.length(); i++) { - gl_Position = gl_in[i].gl_Position; - GSout = GSin[i]; - EmitVertex(); - } - EndPrimitive(); -} -#endif - #ifdef FRAGMENT_SHADER // NOTE: pixel can be clip with "discard" +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) in vertex_basic PSin; +#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec2 SHADERt; +#else +layout(location = 0) in vec4 SHADERp; +layout(location = 1) in vec2 SHADERt; +#endif +#define PSin_p SHADERp +#define PSin_t SHADERt +#endif layout(location = 0) out vec4 SV_Target0; layout(location = 1) out uint SV_Target1; +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +#else layout(binding = 0) uniform sampler2D TextureSampler; +#endif vec4 sample_c() { - return texture(TextureSampler, PSin.t ); + return texture(TextureSampler, PSin_t ); } -vec4 ps_crt(uint i) -{ - vec4 mask[4] = - { +uniform vec4 mask[4] = vec4[4] +( vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(1, 1, 1, 0) - }; +); + +vec4 ps_crt(uint i) +{ return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f); } @@ -125,7 +127,7 @@ void ps_main7() void ps_main5() // triangular { - highp uvec4 p = uvec4(PSin.p); + highp uvec4 p = uvec4(PSin_p); vec4 c = ps_crt(((p.x + ((p.y >> 1u) & 1u) * 3u) >> 1u) % 3u); @@ -134,27 +136,35 @@ void ps_main5() // triangular void ps_main6() // diagonal { - uvec4 p = uvec4(PSin.p); + uvec4 p = uvec4(PSin_p); vec4 c = ps_crt((p.x + (p.y % 3u)) % 3u); SV_Target0 = c; } +// Used for DATE (stencil) void ps_main2() { - if((sample_c().a - 128.0f / 255) < 0) // >= 0x80 pass + if((sample_c().a - 127.5f / 255) < 0) // >= 0x80 pass discard; - SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f); +#ifdef ENABLE_OGL_STENCIL_DEBUG + SV_Target0 = vec4(1.0f, 0.0f, 0.0f, 1.0f); +#endif } + +// Used for DATE (stencil) void ps_main3() { - if((127.95f / 255 - sample_c().a) <0) // < 0x80 pass (== 0x80 should not pass) + if((127.5f / 255 - sample_c().a) < 0) // < 0x80 pass (== 0x80 should not pass) discard; - SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f); +#ifdef ENABLE_OGL_STENCIL_DEBUG + SV_Target0 = vec4(1.0f, 0.0f, 0.0f, 1.0f); +#endif } + void ps_main4() { // FIXME mod and fmod are different when value are negative diff --git a/plugins/GSdx/res/convert.h b/plugins/GSdx/res/convert.h index 66379bd16d..f366e1bfed 100644 --- a/plugins/GSdx/res/convert.h +++ b/plugins/GSdx/res/convert.h @@ -25,7 +25,7 @@ #include "stdafx.h" -extern const char* convert_glsl = +static const char* convert_glsl = "//#version 420 // Keep it for editor detection\n" "\n" "struct vertex_basic\n" @@ -37,11 +37,13 @@ extern const char* convert_glsl = "\n" "#ifdef VERTEX_SHADER\n" "\n" + "#if __VERSION__ > 140\n" "out gl_PerVertex {\n" " vec4 gl_Position;\n" " float gl_PointSize;\n" " float gl_ClipDistance[];\n" "};\n" + "#endif\n" "\n" "layout(location = 0) in vec4 POSITION;\n" "layout(location = 1) in vec2 TEXCOORD0;\n" @@ -54,75 +56,75 @@ extern const char* convert_glsl = "// smooth, the default, means to do perspective-correct interpolation.\n" "//\n" "// The centroid qualifier only matters when multisampling. If this qualifier is not present, then the value is interpolated to the pixel's center, anywhere in the pixel, or to one of the pixel's samples. This sample may lie outside of the actual primitive being rendered, since a primitive can cover only part of a pixel's area. The centroid qualifier is used to prevent this; the interpolation point must fall within both the pixel's area and the primitive's area.\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) out vertex_basic VSout;\n" + "#define VSout_p (VSout.p)\n" + "#define VSout_t (VSout.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "out vec4 SHADERp;\n" + "out vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) out vec4 SHADERp;\n" + "layout(location = 1) out vec2 SHADERt;\n" + "#endif\n" + "#define VSout_p SHADERp\n" + "#define VSout_t SHADERt\n" + "#endif\n" "\n" "void vs_main()\n" "{\n" - " VSout.p = POSITION;\n" - " VSout.t = TEXCOORD0;\n" + " VSout_p = POSITION;\n" + " VSout_t = TEXCOORD0;\n" " gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position\n" "}\n" "\n" "#endif\n" "\n" - "#ifdef GEOMETRY_SHADER\n" - "in gl_PerVertex {\n" - " vec4 gl_Position;\n" - " float gl_PointSize;\n" - " float gl_ClipDistance[];\n" - "} gl_in[];\n" - "\n" - "out gl_PerVertex {\n" - " vec4 gl_Position;\n" - " float gl_PointSize;\n" - " float gl_ClipDistance[];\n" - "};\n" - "\n" - "// FIXME\n" - "// AMD Driver bug again !!!!\n" - "//layout(location = 0) in vertex GSin[];\n" - "in vertex_basic GSin[];\n" - "\n" - "layout(location = 0) out vertex_basic GSout;\n" - "layout(triangles) in;\n" - "layout(triangle_strip, max_vertices = 3) out;\n" - "\n" - "void gs_main()\n" - "{\n" - " for(int i = 0; i < gl_in.length(); i++) {\n" - " gl_Position = gl_in[i].gl_Position;\n" - " GSout = GSin[i];\n" - " EmitVertex();\n" - " }\n" - " EndPrimitive();\n" - "}\n" - "#endif\n" - "\n" "#ifdef FRAGMENT_SHADER\n" "// NOTE: pixel can be clip with \"discard\"\n" "\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) in vertex_basic PSin;\n" + "#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 1) in vec2 SHADERt;\n" + "#endif\n" + "#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#endif\n" "\n" "layout(location = 0) out vec4 SV_Target0;\n" "layout(location = 1) out uint SV_Target1;\n" "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "#else\n" "layout(binding = 0) uniform sampler2D TextureSampler;\n" + "#endif\n" "\n" "vec4 sample_c()\n" "{\n" - " return texture(TextureSampler, PSin.t );\n" + " return texture(TextureSampler, PSin_t );\n" "}\n" "\n" - "vec4 ps_crt(uint i)\n" - "{\n" - " vec4 mask[4] =\n" - " {\n" + "uniform vec4 mask[4] = vec4[4]\n" + "(\n" " vec4(1, 0, 0, 0),\n" " vec4(0, 1, 0, 0),\n" " vec4(0, 0, 1, 0),\n" " vec4(1, 1, 1, 0)\n" - " };\n" + ");\n" "\n" + "\n" + "vec4 ps_crt(uint i)\n" + "{\n" " return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);\n" "}\n" "\n" @@ -153,7 +155,7 @@ extern const char* convert_glsl = "\n" "void ps_main5() // triangular\n" "{\n" - " highp uvec4 p = uvec4(PSin.p);\n" + " highp uvec4 p = uvec4(PSin_p);\n" "\n" " vec4 c = ps_crt(((p.x + ((p.y >> 1u) & 1u) * 3u) >> 1u) \% 3u);\n" "\n" @@ -162,27 +164,35 @@ extern const char* convert_glsl = "\n" "void ps_main6() // diagonal\n" "{\n" - " uvec4 p = uvec4(PSin.p);\n" + " uvec4 p = uvec4(PSin_p);\n" "\n" " vec4 c = ps_crt((p.x + (p.y \% 3u)) \% 3u);\n" "\n" " SV_Target0 = c;\n" "}\n" "\n" + "// Used for DATE (stencil)\n" "void ps_main2()\n" "{\n" - " if((sample_c().a - 128.0f / 255) < 0) // >= 0x80 pass\n" + " if((sample_c().a - 127.5f / 255) < 0) // >= 0x80 pass\n" " discard;\n" "\n" - " SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n" + "#ifdef ENABLE_OGL_STENCIL_DEBUG\n" + " SV_Target0 = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n" + "#endif\n" "}\n" + "\n" + "// Used for DATE (stencil)\n" "void ps_main3()\n" "{\n" - " if((127.95f / 255 - sample_c().a) <0) // < 0x80 pass (== 0x80 should not pass)\n" + " if((127.5f / 255 - sample_c().a) < 0) // < 0x80 pass (== 0x80 should not pass)\n" " discard;\n" "\n" - " SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n" + "#ifdef ENABLE_OGL_STENCIL_DEBUG\n" + " SV_Target0 = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n" + "#endif\n" "}\n" + "\n" "void ps_main4()\n" "{\n" " // FIXME mod and fmod are different when value are negative\n" diff --git a/plugins/GSdx/res/fxaa.fx b/plugins/GSdx/res/fxaa.fx index 450aea1d8d..1df17eba28 100644 --- a/plugins/GSdx/res/fxaa.fx +++ b/plugins/GSdx/res/fxaa.fx @@ -1,8 +1,13 @@ -#ifdef SHADER_MODEL // make safe to include in resource file to enforce dependency +#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130) // make safe to include in resource file to enforce dependency + +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif #define FXAA_PC 1 -#define FXAA_QUALITY__SUBPIX 0.0 +#define FXAA_QUALITY_SUBPIX 0.0 +#ifdef SHADER_MODEL #if SHADER_MODEL >= 0x400 #if SHADER_MODEL >= 0x500 @@ -55,6 +60,51 @@ struct PS_OUTPUT float4 c : COLOR; }; +#endif +#endif + + +#if (FXAA_GLSL_130 == 1) +struct vertex_basic +{ + vec4 p; + vec2 t; +}; + +#ifdef DISABLE_GL42 +layout(std140) uniform cb13 +#else +layout(std140, binding = 13) uniform cb13 +#endif +{ + vec4 _rcpFrame; + vec4 _rcpFrameOpt; +}; + +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +#else +layout(binding = 0) uniform sampler2D TextureSampler; +#endif + +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) +layout(location = 0) in vertex_basic PSin; +#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec2 SHADERt; +#else +layout(location = 0) in vec4 SHADERp; +layout(location = 1) in vec2 SHADERt; +#endif +#define PSin_p SHADERp +#define PSin_t SHADERt +#endif + +layout(location = 0) out vec4 SV_Target0; + #endif /*============================================================================ @@ -87,9 +137,9 @@ Example, #define FXAA_PC 1 #define FXAA_HLSL_3 1 - #define FXAA_QUALITY__PRESET 12 - #define FXAA_QUALITY__EDGE_THRESHOLD (1.0/6.0) - #define FXAA_QUALITY__EDGE_THRESHOLD_MIN (1.0/12.0) + #define FXAA_QUALITY_PRESET 12 + #define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0) + #define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0) (2.) Then include this file, @@ -341,7 +391,7 @@ A. In the last opaque pass prior to FXAA, /*============================================================================ FXAA CONSOLE - TUNING KNOBS ============================================================================*/ -#ifndef FXAA_CONSOLE__EDGE_SHARPNESS +#ifndef FXAA_CONSOLE_EDGE_SHARPNESS // // Consoles the sharpness of edges. // @@ -354,17 +404,17 @@ A. In the last opaque pass prior to FXAA, // 2.0 is really soft (good for vector graphics inputs) // #if 1 - #define FXAA_CONSOLE__EDGE_SHARPNESS 8.0 + #define FXAA_CONSOLE_EDGE_SHARPNESS 8.0 #endif #if 0 - #define FXAA_CONSOLE__EDGE_SHARPNESS 4.0 + #define FXAA_CONSOLE_EDGE_SHARPNESS 4.0 #endif #if 0 - #define FXAA_CONSOLE__EDGE_SHARPNESS 2.0 + #define FXAA_CONSOLE_EDGE_SHARPNESS 2.0 #endif #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_CONSOLE__EDGE_THRESHOLD +#ifndef FXAA_CONSOLE_EDGE_THRESHOLD // // The minimum amount of local contrast required to apply algorithm. // The console setting has a different mapping than the quality setting. @@ -379,13 +429,13 @@ A. In the last opaque pass prior to FXAA, // 0.25 leaves more aliasing, and is sharper // #if 1 - #define FXAA_CONSOLE__EDGE_THRESHOLD 0.125 + #define FXAA_CONSOLE_EDGE_THRESHOLD 0.125 #else - #define FXAA_CONSOLE__EDGE_THRESHOLD 0.25 + #define FXAA_CONSOLE_EDGE_THRESHOLD 0.25 #endif #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_CONSOLE__EDGE_THRESHOLD_MIN +#ifndef FXAA_CONSOLE_EDGE_THRESHOLD_MIN // // Trims the algorithm from processing darks. // The console setting has a different mapping than the quality setting. @@ -395,13 +445,13 @@ A. In the last opaque pass prior to FXAA, // This does not apply to PS3. // PS3 was simplified to avoid more shader instructions. // - #define FXAA_CONSOLE__EDGE_THRESHOLD_MIN 0.05 + #define FXAA_CONSOLE_EDGE_THRESHOLD_MIN 0.05 #endif /*============================================================================ FXAA QUALITY - TUNING KNOBS ============================================================================*/ -#ifndef FXAA_QUALITY__EDGE_THRESHOLD +#ifndef FXAA_QUALITY_EDGE_THRESHOLD // // The minimum amount of local contrast required to apply algorithm. // @@ -411,10 +461,10 @@ A. In the last opaque pass prior to FXAA, // 1/8 - high quality (default) // 1/16 - overkill // - #define FXAA_QUALITY__EDGE_THRESHOLD (1.0/6.0) + #define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0) #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_QUALITY__EDGE_THRESHOLD_MIN +#ifndef FXAA_QUALITY_EDGE_THRESHOLD_MIN // // Trims the algorithm from processing darks. // @@ -422,10 +472,10 @@ A. In the last opaque pass prior to FXAA, // 1/16 - high quality // 1/12 - upper limit (default, the start of visible unfiltered edges) // - #define FXAA_QUALITY__EDGE_THRESHOLD_MIN (1.0/12.0) + #define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0) #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_QUALITY__SUBPIX +#ifndef FXAA_QUALITY_SUBPIX // // Choose the amount of sub-pixel aliasing removal. // @@ -433,10 +483,10 @@ A. In the last opaque pass prior to FXAA, // 3/4 - default amount of filtering // 1/2 - lower limit (sharper, less sub-pixel aliasing removal) // - #define FXAA_QUALITY__SUBPIX (3.0/4.0) + #define FXAA_QUALITY_SUBPIX (3.0/4.0) #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_QUALITY__PRESET +#ifndef FXAA_QUALITY_PRESET // // Choose the quality preset. // @@ -454,7 +504,7 @@ A. In the last opaque pass prior to FXAA, // _ = the lowest digit is directly related to performance // _ = the highest digit is directly related to style // - #define FXAA_QUALITY__PRESET 12 + #define FXAA_QUALITY_PRESET 12 #endif @@ -467,198 +517,198 @@ A. In the last opaque pass prior to FXAA, /*============================================================================ FXAA QUALITY - MEDIUM DITHER PRESETS ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 10) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 3.0 - #define FXAA_QUALITY__P2 12.0 +#if (FXAA_QUALITY_PRESET == 10) + #define FXAA_QUALITY_PS 3 + #define FXAA_QUALITY_P0 1.5 + #define FXAA_QUALITY_P1 3.0 + #define FXAA_QUALITY_P2 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 11) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 3.0 - #define FXAA_QUALITY__P3 12.0 +#if (FXAA_QUALITY_PRESET == 11) + #define FXAA_QUALITY_PS 4 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 3.0 + #define FXAA_QUALITY_P3 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 12) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 4.0 - #define FXAA_QUALITY__P4 12.0 +#if (FXAA_QUALITY_PRESET == 12) + #define FXAA_QUALITY_PS 5 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 4.0 + #define FXAA_QUALITY_P4 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 13) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 4.0 - #define FXAA_QUALITY__P5 12.0 +#if (FXAA_QUALITY_PRESET == 13) + #define FXAA_QUALITY_PS 6 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 4.0 + #define FXAA_QUALITY_P5 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 14) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 4.0 - #define FXAA_QUALITY__P6 12.0 +#if (FXAA_QUALITY_PRESET == 14) + #define FXAA_QUALITY_PS 7 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 4.0 + #define FXAA_QUALITY_P6 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 15) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 12.0 +#if (FXAA_QUALITY_PRESET == 15) + #define FXAA_QUALITY_PS 8 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 4.0 + #define FXAA_QUALITY_P7 12.0 #endif /*============================================================================ FXAA QUALITY - LOW DITHER PRESETS ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 20) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 2.0 - #define FXAA_QUALITY__P2 8.0 +#if (FXAA_QUALITY_PRESET == 20) + #define FXAA_QUALITY_PS 3 + #define FXAA_QUALITY_P0 1.5 + #define FXAA_QUALITY_P1 2.0 + #define FXAA_QUALITY_P2 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 21) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 8.0 +#if (FXAA_QUALITY_PRESET == 21) + #define FXAA_QUALITY_PS 4 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 22) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 8.0 +#if (FXAA_QUALITY_PRESET == 22) + #define FXAA_QUALITY_PS 5 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 23) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 8.0 +#if (FXAA_QUALITY_PRESET == 23) + #define FXAA_QUALITY_PS 6 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 24) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 3.0 - #define FXAA_QUALITY__P6 8.0 +#if (FXAA_QUALITY_PRESET == 24) + #define FXAA_QUALITY_PS 7 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 3.0 + #define FXAA_QUALITY_P6 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 25) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 8.0 +#if (FXAA_QUALITY_PRESET == 25) + #define FXAA_QUALITY_PS 8 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 4.0 + #define FXAA_QUALITY_P7 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 26) - #define FXAA_QUALITY__PS 9 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 4.0 - #define FXAA_QUALITY__P8 8.0 +#if (FXAA_QUALITY_PRESET == 26) + #define FXAA_QUALITY_PS 9 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 2.0 + #define FXAA_QUALITY_P7 4.0 + #define FXAA_QUALITY_P8 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 27) - #define FXAA_QUALITY__PS 10 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 4.0 - #define FXAA_QUALITY__P9 8.0 +#if (FXAA_QUALITY_PRESET == 27) + #define FXAA_QUALITY_PS 10 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 2.0 + #define FXAA_QUALITY_P7 2.0 + #define FXAA_QUALITY_P8 4.0 + #define FXAA_QUALITY_P9 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 28) - #define FXAA_QUALITY__PS 11 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 4.0 - #define FXAA_QUALITY__P10 8.0 +#if (FXAA_QUALITY_PRESET == 28) + #define FXAA_QUALITY_PS 11 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 2.0 + #define FXAA_QUALITY_P7 2.0 + #define FXAA_QUALITY_P8 2.0 + #define FXAA_QUALITY_P9 4.0 + #define FXAA_QUALITY_P10 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 29) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 +#if (FXAA_QUALITY_PRESET == 29) + #define FXAA_QUALITY_PS 12 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.5 + #define FXAA_QUALITY_P2 2.0 + #define FXAA_QUALITY_P3 2.0 + #define FXAA_QUALITY_P4 2.0 + #define FXAA_QUALITY_P5 2.0 + #define FXAA_QUALITY_P6 2.0 + #define FXAA_QUALITY_P7 2.0 + #define FXAA_QUALITY_P8 2.0 + #define FXAA_QUALITY_P9 2.0 + #define FXAA_QUALITY_P10 4.0 + #define FXAA_QUALITY_P11 8.0 #endif /*============================================================================ FXAA QUALITY - EXTREME QUALITY ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 39) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.0 - #define FXAA_QUALITY__P2 1.0 - #define FXAA_QUALITY__P3 1.0 - #define FXAA_QUALITY__P4 1.0 - #define FXAA_QUALITY__P5 1.5 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 +#if (FXAA_QUALITY_PRESET == 39) + #define FXAA_QUALITY_PS 12 + #define FXAA_QUALITY_P0 1.0 + #define FXAA_QUALITY_P1 1.0 + #define FXAA_QUALITY_P2 1.0 + #define FXAA_QUALITY_P3 1.0 + #define FXAA_QUALITY_P4 1.0 + #define FXAA_QUALITY_P5 1.5 + #define FXAA_QUALITY_P6 2.0 + #define FXAA_QUALITY_P7 2.0 + #define FXAA_QUALITY_P8 2.0 + #define FXAA_QUALITY_P9 2.0 + #define FXAA_QUALITY_P10 4.0 + #define FXAA_QUALITY_P11 8.0 #endif @@ -668,7 +718,7 @@ A. In the last opaque pass prior to FXAA, API PORTING ============================================================================*/ -#if FXAA_GLSL_120 +#if (FXAA_GLSL_120 == 1) // Requires, // #version 120 // And at least, @@ -704,7 +754,7 @@ A. In the last opaque pass prior to FXAA, #endif #endif /*--------------------------------------------------------------------------*/ -#if FXAA_GLSL_130 +#if (FXAA_GLSL_130 == 1) // Requires "#version 130" or better #define half float #define half2 vec2 @@ -747,7 +797,7 @@ A. In the last opaque pass prior to FXAA, #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) #endif /*--------------------------------------------------------------------------*/ -#if FXAA_HLSL_4 +#if (FXAA_HLSL_4 == 1) #define FxaaInt2 int2 #define FxaaFloat2 float2 #define FxaaFloat3 float3 @@ -761,7 +811,7 @@ A. In the last opaque pass prior to FXAA, #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) #endif /*--------------------------------------------------------------------------*/ -#if FXAA_HLSL_5 +#if (FXAA_HLSL_5 == 1) #define FxaaInt2 int2 #define FxaaFloat2 float2 #define FxaaFloat3 float3 @@ -779,823 +829,6 @@ A. In the last opaque pass prior to FXAA, -/*============================================================================ - - FXAA3 CONSOLE - 360 PIXEL SHADER - ------------------------------------------------------------------------------- -Might be some optimizations left here, -as of this latest change didn't have a PIX dump to verify if TEX bound. -============================================================================*/ -#if (FXAA_360 == 1) -/*--------------------------------------------------------------------------*/ -half4 FxaaPixelShader( - // {xy} = center of pixel - float2 pos, - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - float4 posPos, - // {rgb_} = color in linear or perceptual color space - // {___a} = alpha output is junk value - FxaaTex tex, - // This must be from a constant/uniform. - // {xy} = rcpFrame not used on PC version of FXAA Console - float2 rcpFrame, - // This must be from a constant/uniform. - // {x___} = 2.0/screenWidthInPixels - // {_y__} = 2.0/screenHeightInPixels - // {__z_} = 0.5/screenWidthInPixels - // {___w} = 0.5/screenHeightInPixels - float4 rcpFrameOpt -) { -/*--------------------------------------------------------------------------*/ - half4 lumaNwNeSwSe; - lumaNwNeSwSe.x = FxaaTexTop(tex, posPos.xy).w; - lumaNwNeSwSe.y = FxaaTexTop(tex, posPos.zy).w; - lumaNwNeSwSe.z = FxaaTexTop(tex, posPos.xw).w; - lumaNwNeSwSe.w = FxaaTexTop(tex, posPos.zw).w; -/*--------------------------------------------------------------------------*/ - half4 rgbyM = FxaaTexTop(tex, pos.xy); -/*--------------------------------------------------------------------------*/ - lumaNwNeSwSe.y += 1.0/384.0; -/*--------------------------------------------------------------------------*/ - half2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); - half2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); -/*--------------------------------------------------------------------------*/ - half lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); - half lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); -/*--------------------------------------------------------------------------*/ - half lumaMinM = min(lumaMin, rgbyM.w); - half lumaMaxM = max(lumaMax, rgbyM.w); - if((lumaMaxM - lumaMinM) < max(FXAA_CONSOLE__EDGE_THRESHOLD_MIN, lumaMax * FXAA_CONSOLE__EDGE_THRESHOLD)) return rgbyM; -/*--------------------------------------------------------------------------*/ - half2 dir; - dir.x = dot(lumaNwNeSwSe, float4(-1.0, -1.0, 1.0, 1.0)); - dir.y = dot(lumaNwNeSwSe, float4( 1.0, -1.0, 1.0,-1.0)); -/*--------------------------------------------------------------------------*/ - half2 dir1; - dir1 = normalize(dir.xy); -/*--------------------------------------------------------------------------*/ - half dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * FXAA_CONSOLE__EDGE_SHARPNESS; - half2 dir2; - dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); -/*--------------------------------------------------------------------------*/ - half4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * rcpFrameOpt.zw); - half4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * rcpFrameOpt.zw); - half4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * rcpFrameOpt.xy); - half4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * rcpFrameOpt.xy); -/*--------------------------------------------------------------------------*/ - half4 rgbyA = rgbyN1 * 0.5 + rgbyP1 * 0.5; - half4 rgbyB = rgbyN2 * 0.25 + rgbyP2 * 0.25 + rgbyA * 0.5; -/*--------------------------------------------------------------------------*/ - bool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); - if(twoTap) rgbyB.xyz = rgbyA.xyz; - return rgbyB; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - 360 PIXEL SHADER OPTIMIZED PROTOTYPE - ------------------------------------------------------------------------------- -This prototype optimized version thanks to suggestions from Andy Luedke. -Should be fully tex bound in all cases. -As of the FXAA 3.10 release I have not tested this code, -but at least the missing ";" was fixed. -If it does not work, please let me know so I can fix it. ------------------------------------------------------------------------------- -Extra requirements, -(1.) Different inputs: no posPos. -(2.) Different inputs: alias three samplers with different exp bias settings! -(3.) New constants: setup fxaaConst as described below. -============================================================================*/ -#if (FXAA_360_OPT == 1) -/*--------------------------------------------------------------------------*/ -[reduceTempRegUsage(4)] -float4 FxaaPixelShader( - // {xy} = center of pixel - float2 pos, - // Three samplers, - // texExpBias0 = exponent bias 0 - // texExpBiasNeg1 = exponent bias -1 - // texExpBiasNeg2 = exponent bias -2 - // {rgb_} = color in linear or perceptual color space - // {___a} = alpha output is junk value - uniform sampler2D texExpBias0, - uniform sampler2D texExpBiasNeg1, - uniform sampler2D texExpBiasNeg2, - // These must be in physical constant registers and NOT immedates - // Immedates will result in compiler un-optimizing - // width = screen width in pixels - // height = screen height in pixels - fxaaConstDir, // float4(1.0, -1.0, 0.25, -0.25); - fxaaConstInner, // float4(0.5/width, 0.5/height, -0.5/width, -0.5/height); - fxaaConstOuter // float4(8.0/width, 8.0/height, -4.0/width, -4.0/height); -) { -/*--------------------------------------------------------------------------*/ - float4 lumaNwNeSwSe; - asm { - tfetch2D lumaNwNeSwSe.w___, texExpBias0, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe._w__, texExpBias0, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.__w_, texExpBias0, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.___w, texExpBias0, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false - }; -/*--------------------------------------------------------------------------*/ - lumaNwNeSwSe.y += 1.0/384.0; - float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); - float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); - float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); - float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); -/*--------------------------------------------------------------------------*/ - float4 rgbyM = tex2Dlod(texExpBias0, float4(pos.xy, 0.0, 0.0)); - float4 lumaMinM = min(lumaMin, rgbyM.w); - float4 lumaMaxM = max(lumaMax, rgbyM.w); - if((lumaMaxM - lumaMinM) < max(FXAA_CONSOLE__EDGE_THRESHOLD_MIN, lumaMax * FXAA_CONSOLE__EDGE_THRESHOLD)) return rgbyM; -/*--------------------------------------------------------------------------*/ - float2 dir; - dir.x = dot(lumaNwNeSwSe, fxaaConstDir.yyxx); - dir.y = dot(lumaNwNeSwSe, fxaaConstDir.xyxy); - dir = normalize(dir); -/*--------------------------------------------------------------------------*/ - float4 dir1 = dir.xyxy * fxaaConstInner.xyzw; -/*--------------------------------------------------------------------------*/ - float4 dir2; - float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)); - dir2 = saturate(fxaaConstOuter.zzww * dir.xyxy / FXAA_CONSOLE__EDGE_SHARPNESS / dirAbsMinTimesC + 0.5); - dir2 = dir2 * fxaaConstOuter.xyxy + fxaaConstOuter.zwzw; -/*--------------------------------------------------------------------------*/ - float4 rgbyN1 = tex2Dlod(texExpBiasNeg1, float4(pos.xy + dir1.xy, 0.0, 0.0)); - float4 rgbyP1 = tex2Dlod(texExpBiasNeg1, float4(pos.xy + dir1.zw, 0.0, 0.0)); - float4 rgbyN2 = tex2Dlod(texExpBiasNeg2, float4(pos.xy + dir2.xy, 0.0, 0.0)); - float4 rgbyP2 = tex2Dlod(texExpBiasNeg2, float4(pos.xy + dir2.zw, 0.0, 0.0)); -/*--------------------------------------------------------------------------*/ - half4 rgbyA = rgbyN1 + rgbyP1; - half4 rgbyB = rgbyN2 + rgbyP2 * 0.5 + rgbyA; -/*--------------------------------------------------------------------------*/ - float4 rgbyR = ((rgbyB.w - lumaMax) > 0.0) ? rgbyA : rgbyB; - rgbyR = ((rgbyB.w - lumaMin) > 0.0) ? rgbyR : rgbyA; - return rgbyR; } -/*==========================================================================*/ -#endif - - - - -/*============================================================================ - - FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) - -============================================================================== -The code below does not exactly match the assembly. -I have a feeling that 12 cycles is possible, but was not able to get there. -Might have to increase register count to get full performance. -Note this shader does not use perspective interpolation. - -Use the following cgc options, - - --fenable-bx2 --fastmath --fastprecision --nofloatbindings - ------------------------------------------------------------------------------- - NVSHADERPERF OUTPUT ------------------------------------------------------------------------------- -For reference and to aid in debug, output of NVShaderPerf should match this, - -Shader to schedule: - 0: texpkb h0.w(TRUE), v5.zyxx, #0 - 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x - 4: texpkb h0.w(TRUE), v5.xwxx, #0 - 6: addh h0.z(TRUE), -h2, h0.w - 7: texpkb h1.w(TRUE), v5, #0 - 9: addh h0.x(TRUE), h0.z, -h1.w - 10: addh h3.w(TRUE), h0.z, h1 - 11: texpkb h2.w(TRUE), v5.zwzz, #0 - 13: addh h0.z(TRUE), h3.w, -h2.w - 14: addh h0.x(TRUE), h2.w, h0 - 15: nrmh h1.xz(TRUE), h0_n - 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| - 17: maxh h4.w(TRUE), h0, h1 - 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n - 19: movr r1.zw(TRUE), v4.xxxy - 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww - 22: minh h5.w(TRUE), h0, h1 - 23: texpkb h0(TRUE), r2.xzxx, #0 - 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 - 27: maxh h4.x(TRUE), h2.z, h2.w - 28: texpkb h1(TRUE), r0.zwzz, #0 - 30: addh_d2 h1(TRUE), h0, h1 - 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 33: texpkb h0(TRUE), r0, #0 - 35: minh h4.z(TRUE), h2, h2.w - 36: fenct TRUE - 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 39: texpkb h2(TRUE), r1, #0 - 41: addh_d2 h0(TRUE), h0, h2 - 42: maxh h2.w(TRUE), h4, h4.x - 43: minh h2.x(TRUE), h5.w, h4.z - 44: addh_d2 h0(TRUE), h0, h1 - 45: slth h2.x(TRUE), h0.w, h2 - 46: sgth h2.w(TRUE), h0, h2 - 47: movh h0(TRUE), h0 - 48: addx.c0 rc(TRUE), h2, h2.w - 49: movh h0(c0.NE.x), h1 - -IPU0 ------ Simplified schedule: -------- -Pass | Unit | uOp | PC: Op ------+--------+------+------------------------- - 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; - | | | - 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; - | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; - | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; - | | | - 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; - | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; - | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; - | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; - | | | - 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; - | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; - | | | - 5 | SCT1 | mov | 15: NRMh h1.xz, h0; - | SRB | nrm | 15: NRMh h1.xz, h0; - | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; - | SCB1 | max | 17: MAXh h4.w, h0, h1; - | | | - 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; - | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; - | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; - | SCB1 | min | 22: MINh h5.w, h0, h1; - | | | - 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; - | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; - | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; - | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; - | | | - 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; - | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; - | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; - | | | - 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; - | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; - | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; - | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; - | | | - 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; - | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; - | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; - | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; - | | | - 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; - | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; - | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; - | | | - 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; - | SCT1 | set | 46: SGTh h2.w, h0, h2; - | SCB0/1 | mul | 47: MOVh h0, h0; - | | | - 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; - | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; - -Pass SCT TEX SCB - 1: 0% 100% 25% - 2: 0% 100% 25% - 3: 0% 100% 50% - 4: 0% 100% 50% - 5: 0% 0% 50% - 6: 100% 0% 75% - 7: 0% 100% 75% - 8: 0% 100% 100% - 9: 0% 100% 25% - 10: 0% 100% 100% - 11: 50% 0% 100% - 12: 50% 0% 100% - 13: 25% 0% 100% - -MEAN: 17% 61% 67% - -Pass SCT0 SCT1 TEX SCB0 SCB1 - 1: 0% 0% 100% 0% 100% - 2: 0% 0% 100% 0% 100% - 3: 0% 0% 100% 100% 100% - 4: 0% 0% 100% 100% 100% - 5: 0% 0% 0% 100% 100% - 6: 100% 100% 0% 100% 100% - 7: 0% 0% 100% 100% 100% - 8: 0% 0% 100% 100% 100% - 9: 0% 0% 100% 0% 100% - 10: 0% 0% 100% 100% 100% - 11: 100% 100% 0% 100% 100% - 12: 100% 100% 0% 100% 100% - 13: 100% 0% 0% 100% 100% - -MEAN: 30% 23% 61% 76% 100% -Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 -Results 13 cycles, 3 r regs, 923,076,923 pixels/s -============================================================================*/ -#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) -/*--------------------------------------------------------------------------*/ -#pragma disablepc all -#pragma option O3 -#pragma option OutColorPrec=fp16 -#pragma texformat default RGBA8 -/*==========================================================================*/ -half4 FxaaPixelShader( - // {xy} = center of pixel - float2 pos, - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - float4 posPos, - // {rgb_} = color in linear or perceptual color space - // {___a} = luma in perceptual color space (not linear) - sampler2D tex, - // This must be from a constant/uniform. - // {xy} = rcpFrame not used on PS3 - float2 rcpFrame, - // This must be from a constant/uniform. - // {x___} = 2.0/screenWidthInPixels - // {_y__} = 2.0/screenHeightInPixels - // {__z_} = 0.5/screenWidthInPixels - // {___w} = 0.5/screenHeightInPixels - float4 rcpFrameOpt -) { -/*--------------------------------------------------------------------------*/ -// (1) - half4 dir; - half4 lumaNe = h4tex2Dlod(tex, half4(posPos.zy, 0, 0)); - lumaNe.w += half(1.0/512.0); - dir.x = -lumaNe.w; - dir.z = -lumaNe.w; -/*--------------------------------------------------------------------------*/ -// (2) - half4 lumaSw = h4tex2Dlod(tex, half4(posPos.xw, 0, 0)); - dir.x += lumaSw.w; - dir.z += lumaSw.w; -/*--------------------------------------------------------------------------*/ -// (3) - half4 lumaNw = h4tex2Dlod(tex, half4(posPos.xy, 0, 0)); - dir.x -= lumaNw.w; - dir.z += lumaNw.w; -/*--------------------------------------------------------------------------*/ -// (4) - half4 lumaSe = h4tex2Dlod(tex, half4(posPos.zw, 0, 0)); - dir.x += lumaSe.w; - dir.z -= lumaSe.w; -/*--------------------------------------------------------------------------*/ -// (5) - half4 dir1_pos; - dir1_pos.xy = normalize(dir.xyz).xz; - half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__EDGE_SHARPNESS); -/*--------------------------------------------------------------------------*/ -// (6) - half4 dir2_pos; - dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); - dir1_pos.zw = pos.xy; - dir2_pos.zw = pos.xy; - half4 temp1N; - temp1N.xy = dir1_pos.zw - dir1_pos.xy * rcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ -// (7) - temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); - half4 rgby1; - rgby1.xy = dir1_pos.zw + dir1_pos.xy * rcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ -// (8) - rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); - rgby1 = (temp1N + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (9) - half4 temp2N; - temp2N.xy = dir2_pos.zw - dir2_pos.xy * rcpFrameOpt.xy; - temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); -/*--------------------------------------------------------------------------*/ -// (10) - half4 rgby2; - rgby2.xy = dir2_pos.zw + dir2_pos.xy * rcpFrameOpt.xy; - rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); - rgby2 = (temp2N + rgby2) * 0.5; -/*--------------------------------------------------------------------------*/ -// (11) - // compilier moves these scalar ops up to other cycles - half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); - half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); - rgby2 = (rgby2 + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (12) - bool twoTapLt = rgby2.w < lumaMin; - bool twoTapGt = rgby2.w > lumaMax; -/*--------------------------------------------------------------------------*/ -// (13) - if(twoTapLt || twoTapGt) rgby2 = rgby1; -/*--------------------------------------------------------------------------*/ - return rgby2; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) - -============================================================================== -The code mostly matches the assembly. -I have a feeling that 14 cycles is possible, but was not able to get there. -Might have to increase register count to get full performance. -Note this shader does not use perspective interpolation. - -Use the following cgc options, - - --fenable-bx2 --fastmath --fastprecision --nofloatbindings - ------------------------------------------------------------------------------- - NVSHADERPERF OUTPUT ------------------------------------------------------------------------------- -For reference and to aid in debug, output of NVShaderPerf should match this, - -Shader to schedule: - 0: texpkb h0.w(TRUE), v5.zyxx, #0 - 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x - 4: texpkb h1.w(TRUE), v5.xwxx, #0 - 6: addh h0.x(TRUE), h1.w, -h2.y - 7: texpkb h2.w(TRUE), v5.zwzz, #0 - 9: minh h4.w(TRUE), h2.y, h2 - 10: maxh h5.x(TRUE), h2.y, h2.w - 11: texpkb h0.w(TRUE), v5, #0 - 13: addh h3.w(TRUE), -h0, h0.x - 14: addh h0.x(TRUE), h0.w, h0 - 15: addh h0.z(TRUE), -h2.w, h0.x - 16: addh h0.x(TRUE), h2.w, h3.w - 17: minh h5.y(TRUE), h0.w, h1.w - 18: nrmh h2.xz(TRUE), h0_n - 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| - 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w - 21: movr r1.zw(TRUE), v4.xxxy - 22: maxh h2.w(TRUE), h0, h1 - 23: fenct TRUE - 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz - 26: texpkb h0(TRUE), r0, #0 - 28: maxh h5.x(TRUE), h2.w, h5 - 29: minh h5.w(TRUE), h5.y, h4 - 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz - 32: texpkb h2(TRUE), r1, #0 - 34: addh_d2 h2(TRUE), h0, h2 - 35: texpkb h1(TRUE), v4, #0 - 37: maxh h5.y(TRUE), h5.x, h1.w - 38: minh h4.w(TRUE), h1, h5 - 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 41: texpkb h0(TRUE), r0, #0 - 43: addh_m8 h5.z(TRUE), h5.y, -h4.w - 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 46: texpkb h3(TRUE), r2, #0 - 48: addh_d2 h0(TRUE), h0, h3 - 49: addh_d2 h3(TRUE), h0, h2 - 50: movh h0(TRUE), h3 - 51: slth h3.x(TRUE), h3.w, h5.w - 52: sgth h3.w(TRUE), h3, h5.x - 53: addx.c0 rc(TRUE), h3.x, h3 - 54: slth.c0 rc(TRUE), h5.z, h5 - 55: movh h0(c0.NE.w), h2 - 56: movh h0(c0.NE.x), h1 - -IPU0 ------ Simplified schedule: -------- -Pass | Unit | uOp | PC: Op ------+--------+------+------------------------- - 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; - | | | - 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; - | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; - | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; - | | | - 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; - | SCB1 | min | 9: MINh h4.w, h2.---y, h2; - | | | - 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; - | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; - | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; - | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; - | | | - 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; - | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; - | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; - | | | - 6 | SCT1 | mov | 18: NRMh h2.xz, h0; - | SRB | nrm | 18: NRMh h2.xz, h0; - | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; - | | | - 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; - | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; - | SCB1 | max | 22: MAXh h2.w, h0, h1; - | | | - 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; - | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; - | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; - | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; - | SCB1 | min | 29: MINh h5.w, h5.---y, h4; - | | | - 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; - | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; - | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; - | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; - | | | - 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; - | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; - | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; - | SCB1 | min | 38: MINh h4.w, h1, h5; - | | | - 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; - | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; - | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; - | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; - | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; - | | | - 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; - | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; - | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; - | | | - 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; - | SCB0/1 | mul | 50: MOVh h0, h3; - | | | - 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; - | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; - | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; - | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; - | | | - 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; - | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; - -Pass SCT TEX SCB - 1: 0% 100% 25% - 2: 0% 100% 25% - 3: 0% 100% 50% - 4: 0% 100% 50% - 5: 50% 0% 25% - 6: 0% 0% 25% - 7: 100% 0% 25% - 8: 0% 100% 50% - 9: 0% 100% 100% - 10: 0% 100% 50% - 11: 0% 100% 75% - 12: 0% 100% 100% - 13: 100% 0% 100% - 14: 50% 0% 50% - 15: 100% 0% 100% - -MEAN: 26% 60% 56% - -Pass SCT0 SCT1 TEX SCB0 SCB1 - 1: 0% 0% 100% 100% 0% - 2: 0% 0% 100% 100% 0% - 3: 0% 0% 100% 100% 100% - 4: 0% 0% 100% 100% 100% - 5: 100% 100% 0% 100% 0% - 6: 0% 0% 0% 0% 100% - 7: 100% 100% 0% 0% 100% - 8: 0% 0% 100% 100% 100% - 9: 0% 0% 100% 100% 100% - 10: 0% 0% 100% 100% 100% - 11: 0% 0% 100% 100% 100% - 12: 0% 0% 100% 100% 100% - 13: 100% 100% 0% 100% 100% - 14: 100% 100% 0% 100% 100% - 15: 100% 100% 0% 100% 100% - -MEAN: 33% 33% 60% 86% 80% -Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 -Results 15 cycles, 3 r regs, 800,000,000 pixels/s -============================================================================*/ -#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) -/*--------------------------------------------------------------------------*/ -#pragma disablepc all -#pragma option O2 -#pragma option OutColorPrec=fp16 -#pragma texformat default RGBA8 -/*==========================================================================*/ -half4 FxaaPixelShader( - // {xy} = center of pixel - float2 pos, - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - float4 posPos, - // {rgb_} = color in linear or perceptual color space - // {___a} = luma in perceptual color space (not linear) - sampler2D tex, - // This must be from a constant/uniform. - // {xy} = rcpFrame not used on PS3 - float2 rcpFrame, - // This must be from a constant/uniform. - // {x___} = 2.0/screenWidthInPixels - // {_y__} = 2.0/screenHeightInPixels - // {__z_} = 0.5/screenWidthInPixels - // {___w} = 0.5/screenHeightInPixels - float4 rcpFrameOpt -) { -/*--------------------------------------------------------------------------*/ -// (1) - half4 rgbyNe = h4tex2Dlod(tex, half4(posPos.zy, 0, 0)); - half lumaNe = rgbyNe.w + half(1.0/512.0); -/*--------------------------------------------------------------------------*/ -// (2) - half4 lumaSw = h4tex2Dlod(tex, half4(posPos.xw, 0, 0)); - half lumaSwNegNe = lumaSw.w - lumaNe; -/*--------------------------------------------------------------------------*/ -// (3) - half4 lumaNw = h4tex2Dlod(tex, half4(posPos.xy, 0, 0)); - half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); - half lumaMinNwSw = min(lumaNw.w, lumaSw.w); -/*--------------------------------------------------------------------------*/ -// (4) - half4 lumaSe = h4tex2Dlod(tex, half4(posPos.zw, 0, 0)); - half dirZ = lumaNw.w + lumaSwNegNe; - half dirX = -lumaNw.w + lumaSwNegNe; -/*--------------------------------------------------------------------------*/ -// (5) - half3 dir; - dir.y = 0.0; - dir.x = lumaSe.w + dirX; - dir.z = -lumaSe.w + dirZ; - half lumaMinNeSe = min(lumaNe, lumaSe.w); -/*--------------------------------------------------------------------------*/ -// (6) - half4 dir1_pos; - dir1_pos.xy = normalize(dir).xz; - half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__EDGE_SHARPNESS); -/*--------------------------------------------------------------------------*/ -// (7) - half4 dir2_pos; - dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); - dir1_pos.zw = pos.xy; - dir2_pos.zw = pos.xy; - half lumaMaxNeSe = max(lumaNe, lumaSe.w); -/*--------------------------------------------------------------------------*/ -// (8) - half4 temp1N; - temp1N.xy = dir1_pos.zw - dir1_pos.xy * rcpFrameOpt.zw; - temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); - half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); - half lumaMin = min(lumaMinNwSw, lumaMinNeSe); -/*--------------------------------------------------------------------------*/ -// (9) - half4 rgby1; - rgby1.xy = dir1_pos.zw + dir1_pos.xy * rcpFrameOpt.zw; - rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); - rgby1 = (temp1N + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (10) - half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); - half lumaMaxM = max(lumaMax, rgbyM.w); - half lumaMinM = min(lumaMin, rgbyM.w); -/*--------------------------------------------------------------------------*/ -// (11) - half4 temp2N; - temp2N.xy = dir2_pos.zw - dir2_pos.xy * rcpFrameOpt.xy; - temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); - half4 rgby2; - rgby2.xy = dir2_pos.zw + dir2_pos.xy * rcpFrameOpt.xy; - half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__EDGE_THRESHOLD; -/*--------------------------------------------------------------------------*/ -// (12) - rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); - rgby2 = (temp2N + rgby2) * 0.5; -/*--------------------------------------------------------------------------*/ -// (13) - rgby2 = (rgby2 + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (14) - bool twoTapLt = rgby2.w < lumaMin; - bool twoTapGt = rgby2.w > lumaMax; - bool earlyExit = lumaRangeM < lumaMax; - bool twoTap = twoTapLt || twoTapGt; -/*--------------------------------------------------------------------------*/ -// (15) - if(twoTap) rgby2 = rgby1; - if(earlyExit) rgby2 = rgbyM; -/*--------------------------------------------------------------------------*/ - return rgby2; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - PC PIXEL SHADER - ------------------------------------------------------------------------------- -Using a modified version of the PS3 version here to best target old hardware. -============================================================================*/ -#if (FXAA_PC_CONSOLE == 1) -/*--------------------------------------------------------------------------*/ -half4 FxaaPixelShader( - // {xy} = center of pixel - float2 pos, - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - float4 posPos, - // {rgb_} = color in linear or perceptual color space - // {___a} = alpha output is junk value - FxaaTex tex, - // This must be from a constant/uniform. - // {xy} = rcpFrame not used on PC version of FXAA Console - float2 rcpFrame, - // This must be from a constant/uniform. - // {x___} = 2.0/screenWidthInPixels - // {_y__} = 2.0/screenHeightInPixels - // {__z_} = 0.5/screenWidthInPixels - // {___w} = 0.5/screenHeightInPixels - float4 rcpFrameOpt -) { -/*--------------------------------------------------------------------------*/ - half4 dir; - dir.y = 0.0; - half4 lumaNe = FxaaTexTop(tex, posPos.zy); - lumaNe.w += half(1.0/384.0); - dir.x = -lumaNe.w; - dir.z = -lumaNe.w; -/*--------------------------------------------------------------------------*/ - half4 lumaSw = FxaaTexTop(tex, posPos.xw); - dir.x += lumaSw.w; - dir.z += lumaSw.w; -/*--------------------------------------------------------------------------*/ - half4 lumaNw = FxaaTexTop(tex, posPos.xy); - dir.x -= lumaNw.w; - dir.z += lumaNw.w; -/*--------------------------------------------------------------------------*/ - half4 lumaSe = FxaaTexTop(tex, posPos.zw); - dir.x += lumaSe.w; - dir.z -= lumaSe.w; -/*==========================================================================*/ - #if (FXAA_EARLY_EXIT == 1) - half4 rgbyM = FxaaTexTop(tex, pos.xy); -/*--------------------------------------------------------------------------*/ - half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); - half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); -/*--------------------------------------------------------------------------*/ - half lumaMinM = min(lumaMin, rgbyM.w); - half lumaMaxM = max(lumaMax, rgbyM.w); -/*--------------------------------------------------------------------------*/ - if((lumaMaxM - lumaMinM) < max(FXAA_CONSOLE__EDGE_THRESHOLD_MIN, lumaMax * FXAA_CONSOLE__EDGE_THRESHOLD)) - #if (FXAA_DISCARD == 1) - FxaaDiscard; - #else - return rgbyM; - #endif - #endif -/*==========================================================================*/ - half4 dir1_pos; - dir1_pos.xy = normalize(dir.xyz).xz; - half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__EDGE_SHARPNESS); -/*--------------------------------------------------------------------------*/ - half4 dir2_pos; - dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); - dir1_pos.zw = pos.xy; - dir2_pos.zw = pos.xy; - half4 temp1N; - temp1N.xy = dir1_pos.zw - dir1_pos.xy * rcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ - temp1N = FxaaTexTop(tex, temp1N.xy); - half4 rgby1; - rgby1.xy = dir1_pos.zw + dir1_pos.xy * rcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ - rgby1 = FxaaTexTop(tex, rgby1.xy); - rgby1 = (temp1N + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ - half4 temp2N; - temp2N.xy = dir2_pos.zw - dir2_pos.xy * rcpFrameOpt.xy; - temp2N = FxaaTexTop(tex, temp2N.xy); -/*--------------------------------------------------------------------------*/ - half4 rgby2; - rgby2.xy = dir2_pos.zw + dir2_pos.xy * rcpFrameOpt.xy; - rgby2 = FxaaTexTop(tex, rgby2.xy); - rgby2 = (temp2N + rgby2) * 0.5; -/*--------------------------------------------------------------------------*/ - #if (FXAA_EARLY_EXIT == 0) - half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); - half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); - #endif - rgby2 = (rgby2 + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ - bool twoTapLt = rgby2.w < lumaMin; - bool twoTapGt = rgby2.w > lumaMax; -/*--------------------------------------------------------------------------*/ - if(twoTapLt || twoTapGt) rgby2 = rgby1; -/*--------------------------------------------------------------------------*/ - return rgby2; } -/*==========================================================================*/ -#endif - - - /*============================================================================ FXAA3 QUALITY - PC @@ -1655,9 +888,9 @@ float4 FxaaPixelShader( float minWN = min(lumaN, lumaW); float rangeMax = max(maxWN, maxESM); float rangeMin = min(minWN, minESM); - float rangeMaxScaled = rangeMax * FXAA_QUALITY__EDGE_THRESHOLD; + float rangeMaxScaled = rangeMax * FXAA_QUALITY_EDGE_THRESHOLD; float range = rangeMax - rangeMin; - float rangeMaxClamped = max(FXAA_QUALITY__EDGE_THRESHOLD_MIN, rangeMaxScaled); + float rangeMaxClamped = max(FXAA_QUALITY_EDGE_THRESHOLD_MIN, rangeMaxScaled); bool earlyExit = range < rangeMaxClamped; /*--------------------------------------------------------------------------*/ if(earlyExit) @@ -1727,11 +960,11 @@ float4 FxaaPixelShader( if( horzSpan) posB.y += lengthSign * 0.5; /*--------------------------------------------------------------------------*/ float2 posN; - posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; - posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + posN.x = posB.x - offNP.x * FXAA_QUALITY_P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY_P0; float2 posP; - posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; - posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + posP.x = posB.x + offNP.x * FXAA_QUALITY_P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY_P0; float subpixD = ((-2.0)*subpixC) + 3.0; float lumaEndN = FxaaTexTop(tex, posN).w; float subpixE = subpixC * subpixC; @@ -1747,11 +980,11 @@ float4 FxaaPixelShader( lumaEndP -= lumaNN * 0.5; bool doneN = abs(lumaEndN) >= gradientScaled; bool doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1; bool doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1; /*--------------------------------------------------------------------------*/ if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; @@ -1760,13 +993,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 3) + #if (FXAA_QUALITY_PS > 3) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1774,13 +1007,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 4) + #if (FXAA_QUALITY_PS > 4) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1788,13 +1021,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 5) + #if (FXAA_QUALITY_PS > 5) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1802,13 +1035,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 6) + #if (FXAA_QUALITY_PS > 6) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1816,13 +1049,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 7) + #if (FXAA_QUALITY_PS > 7) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1830,13 +1063,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 8) + #if (FXAA_QUALITY_PS > 8) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1844,13 +1077,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 9) + #if (FXAA_QUALITY_PS > 9) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1858,13 +1091,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 10) + #if (FXAA_QUALITY_PS > 10) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1872,13 +1105,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 11) + #if (FXAA_QUALITY_PS > 11) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1886,13 +1119,13 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 12) + #if (FXAA_QUALITY_PS > 12) if(doneNP) { if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w; if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w; @@ -1900,11 +1133,11 @@ float4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12; /*--------------------------------------------------------------------------*/ } #endif @@ -1953,7 +1186,7 @@ float4 FxaaPixelShader( bool goodSpan = directionN ? goodSpanN : goodSpanP; float subpixG = subpixF * subpixF; float pixelOffset = (dst * (-spanLengthRcp)) + 0.5; - float subpixH = subpixG * FXAA_QUALITY__SUBPIX; + float subpixH = subpixG * FXAA_QUALITY_SUBPIX; /*--------------------------------------------------------------------------*/ float pixelOffsetGood = goodSpan ? pixelOffset : 0.0; float pixelOffsetSubpix = max(pixelOffsetGood, subpixH); @@ -1968,6 +1201,7 @@ float4 FxaaPixelShader( /*==========================================================================*/ #endif +#ifdef SHADER_MODEL PS_OUTPUT ps_main(PS_INPUT input) { PS_OUTPUT output; @@ -1992,5 +1226,16 @@ PS_OUTPUT ps_main(PS_INPUT input) return output; } +#endif + +#if (FXAA_GLSL_130 == 1) +void ps_main() +{ + vec2 pos = PSin_t; + vec4 posPos = vec4(0.0, 0.0, 0.0, 0.0); + + SV_Target0 = FxaaPixelShader(pos, posPos, TextureSampler, _rcpFrame.xy, _rcpFrameOpt); +} +#endif #endif diff --git a/plugins/GSdx/res/fxaa.h b/plugins/GSdx/res/fxaa.h new file mode 100644 index 0000000000..d9cb8bbfbe --- /dev/null +++ b/plugins/GSdx/res/fxaa.h @@ -0,0 +1,1270 @@ +/* + * Copyright (C) 2011-2013 Gregory hainaut + * Copyright (C) 2007-2009 Gabest + * + * This file was generated by glsl2h.pl script + * + * 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 + +#include "stdafx.h" + +static const char* fxaa_fx = + "#if defined(SHADER_MODEL) || defined(FXAA_GLSL_130) // make safe to include in resource file to enforce dependency\n" + "\n" + "#ifndef FXAA_GLSL_130\n" + " #define FXAA_GLSL_130 0\n" + "#endif\n" + "\n" + "#define FXAA_PC 1\n" + "#define FXAA_QUALITY_SUBPIX 0.0\n" + "\n" + "#ifdef SHADER_MODEL\n" + "#if SHADER_MODEL >= 0x400\n" + "\n" + "#if SHADER_MODEL >= 0x500\n" + " #define FXAA_HLSL_5 1\n" + "#else \n" + " #define FXAA_HLSL_4 1\n" + "#endif\n" + "\n" + "Texture2D Texture;\n" + "SamplerState TextureSampler;\n" + "\n" + "cbuffer cb0\n" + "{\n" + " float4 _rcpFrame;\n" + " float4 _rcpFrameOpt;\n" + "};\n" + "\n" + "struct PS_INPUT\n" + "{\n" + " float4 p : SV_Position;\n" + " float2 t : TEXCOORD0;\n" + "};\n" + "\n" + "struct PS_OUTPUT\n" + "{\n" + " float4 c : SV_Target0;\n" + "};\n" + "\n" + "#elif SHADER_MODEL <= 0x300\n" + "\n" + "#define FXAA_HLSL_3 1\n" + "\n" + "sampler Texture : register(s0);\n" + "\n" + "float4 _rcpFrame : register(c0);\n" + "float4 _rcpFrameOpt : register(c1);\n" + "\n" + "struct PS_INPUT\n" + "{\n" + "#if SHADER_MODEL < 0x300\n" + " float4 p : TEXCOORD1;\n" + "#else\n" + " float4 p : VPOS;\n" + "#endif\n" + " float2 t : TEXCOORD0;\n" + "};\n" + "\n" + "struct PS_OUTPUT\n" + "{\n" + " float4 c : COLOR;\n" + "};\n" + "\n" + "#endif\n" + "#endif\n" + "\n" + "\n" + "#if (FXAA_GLSL_130 == 1)\n" + "struct vertex_basic\n" + "{\n" + " vec4 p;\n" + " vec2 t;\n" + "};\n" + "\n" + "#ifdef DISABLE_GL42\n" + "layout(std140) uniform cb13\n" + "#else\n" + "layout(std140, binding = 13) uniform cb13\n" + "#endif\n" + "{\n" + " vec4 _rcpFrame;\n" + " vec4 _rcpFrameOpt;\n" + "};\n" + "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "#else\n" + "layout(binding = 0) uniform sampler2D TextureSampler;\n" + "#endif\n" + "\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" + "layout(location = 0) in vertex_basic PSin;\n" + "#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 1) in vec2 SHADERt;\n" + "#endif\n" + "#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#endif\n" + "\n" + "layout(location = 0) out vec4 SV_Target0;\n" + "\n" + "#endif\n" + "\n" + "/*============================================================================\n" + "\n" + "\n" + " NVIDIA FXAA 3.10 by TIMOTHY LOTTES\n" + "\n" + "\n" + "------------------------------------------------------------------------------\n" + "COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.\n" + "------------------------------------------------------------------------------\n" + "TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED\n" + "*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS\n" + "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\n" + "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA\n" + "OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR\n" + "CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR\n" + "LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,\n" + "OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE\n" + "THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\n" + "DAMAGES.\n" + "\n" + "------------------------------------------------------------------------------\n" + " INTEGRATION CHECKLIST\n" + "------------------------------------------------------------------------------\n" + "(1.)\n" + "In the shader source,\n" + "setup defines for the desired configuration.\n" + "Example,\n" + "\n" + " #define FXAA_PC 1\n" + " #define FXAA_HLSL_3 1\n" + " #define FXAA_QUALITY_PRESET 12\n" + " #define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n" + " #define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n" + "\n" + "(2.)\n" + "Then include this file,\n" + "\n" + " #include \"Fxaa3.h\"\n" + "\n" + "(3.)\n" + "Then call the FXAA pixel shader from within your desired shader,\n" + "\n" + " return FxaaPixelShader(pos, posPos, tex, rcpFrame, rcpFrameOpt);\n" + "\n" + "(4.)\n" + "Insure pass prior to FXAA outputs RGBL.\n" + "See next section.\n" + "\n" + "(5.)\n" + "Setup engine to provide \"rcpFrame\" and \"rcpFrameOpt\" constants.\n" + "Not using constants will result in a performance loss.\n" + "\n" + " // {x_} = 1.0/screenWidthInPixels\n" + " // {_y} = 1.0/screenHeightInPixels\n" + " float2 rcpFrame\n" + "\n" + " // This must be from a constant/uniform.\n" + " // {x___} = 2.0/screenWidthInPixels\n" + " // {_y__} = 2.0/screenHeightInPixels\n" + " // {__z_} = 0.5/screenWidthInPixels\n" + " // {___w} = 0.5/screenHeightInPixels\n" + " float4 rcpFrameOpt\n" + "\n" + "(5.a.) \n" + "Optionally change to this for sharper FXAA Console,\n" + "\n" + " // This must be from a constant/uniform.\n" + " // {x___} = 2.0/screenWidthInPixels\n" + " // {_y__} = 2.0/screenHeightInPixels\n" + " // {__z_} = 0.333/screenWidthInPixels\n" + " // {___w} = 0.333/screenHeightInPixels\n" + " float4 rcpFrameOpt\n" + "\n" + "(6.)\n" + "Have FXAA vertex shader run as a full screen triangle,\n" + "and output \"pos\" and \"posPos\" such that inputs in the pixel shader provide,\n" + "\n" + " // {xy} = center of pixel\n" + " float2 pos,\n" + "\n" + " // {xy__} = upper left of pixel\n" + " // {__zw} = lower right of pixel\n" + " float4 posPos,\n" + "\n" + "(7.)\n" + "Insure the texture sampler used by FXAA is set to bilinear filtering.\n" + "\n" + "\n" + "------------------------------------------------------------------------------\n" + " INTEGRATION - RGBL AND COLORSPACE\n" + "------------------------------------------------------------------------------\n" + "FXAA3 requires RGBL as input.\n" + "\n" + "RGB should be LDR (low dynamic range).\n" + "Specifically do FXAA after tonemapping.\n" + "\n" + "RGB data as returned by a texture fetch can be linear or non-linear.\n" + "Note an \"sRGB format\" texture counts as linear,\n" + "because the result of a texture fetch is linear data.\n" + "Regular \"RGBA8\" textures in the sRGB colorspace are non-linear.\n" + "\n" + "Luma must be stored in the alpha channel prior to running FXAA.\n" + "This luma should be in a perceptual space (could be gamma 2.0).\n" + "Example pass before FXAA where output is gamma 2.0 encoded,\n" + "\n" + " color.rgb = ToneMap(color.rgb); // linear color output\n" + " color.rgb = sqrt(color.rgb); // gamma 2.0 color output\n" + " return color;\n" + "\n" + "To use FXAA,\n" + "\n" + " color.rgb = ToneMap(color.rgb); // linear color output\n" + " color.rgb = sqrt(color.rgb); // gamma 2.0 color output\n" + " color.a = dot(color.rgb, float3(0.299, 0.587, 0.114)); // compute luma\n" + " return color;\n" + "\n" + "Another example where output is linear encoded,\n" + "say for instance writing to an sRGB formated render target,\n" + "where the render target does the conversion back to sRGB after blending,\n" + "\n" + " color.rgb = ToneMap(color.rgb); // linear color output\n" + " return color;\n" + "\n" + "To use FXAA,\n" + "\n" + " color.rgb = ToneMap(color.rgb); // linear color output\n" + " color.a = sqrt(dot(color.rgb, float3(0.299, 0.587, 0.114))); // compute luma\n" + " return color;\n" + "\n" + "Getting luma correct is required for the algorithm to work correctly.\n" + "\n" + "\n" + "------------------------------------------------------------------------------\n" + " BEING LINEARLY CORRECT?\n" + "------------------------------------------------------------------------------\n" + "Applying FXAA to a framebuffer with linear RGB color will look worse.\n" + "This is very counter intuitive, but happends to be true in this case.\n" + "The reason is because dithering artifacts will be more visiable \n" + "in a linear colorspace.\n" + "\n" + "\n" + "------------------------------------------------------------------------------\n" + " COMPLEX INTEGRATION\n" + "------------------------------------------------------------------------------\n" + "Q. What if the engine is blending into RGB before wanting to run FXAA?\n" + "\n" + "A. In the last opaque pass prior to FXAA,\n" + " have the pass write out luma into alpha.\n" + " Then blend into RGB only.\n" + " FXAA should be able to run ok\n" + " assuming the blending pass did not any add aliasing.\n" + " This should be the common case for particles and common blending passes.\n" + "\n" + "============================================================================*/\n" + "\n" + "/*============================================================================\n" + "\n" + " INTEGRATION KNOBS\n" + "\n" + "============================================================================*/\n" + "//\n" + "// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).\n" + "// FXAA_360_OPT is a prototype for the new optimized 360 version.\n" + "//\n" + "// 1 = Use API.\n" + "// 0 = Don't use API.\n" + "//\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_PS3\n" + " #define FXAA_PS3 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_360\n" + " #define FXAA_360 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_360_OPT\n" + " #define FXAA_360_OPT 0\n" + "#endif\n" + "/*==========================================================================*/\n" + "#ifndef FXAA_PC\n" + " //\n" + " // FXAA Quality\n" + " // The high quality PC algorithm.\n" + " //\n" + " #define FXAA_PC 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_PC_CONSOLE\n" + " //\n" + " // The console algorithm for PC is included\n" + " // for developers targeting really low spec machines.\n" + " //\n" + " #define FXAA_PC_CONSOLE 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_GLSL_120\n" + " #define FXAA_GLSL_120 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_GLSL_130\n" + " #define FXAA_GLSL_130 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_HLSL_3\n" + " #define FXAA_HLSL_3 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_HLSL_4\n" + " #define FXAA_HLSL_4 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_HLSL_5\n" + " #define FXAA_HLSL_5 0\n" + "#endif\n" + "/*==========================================================================*/\n" + "#ifndef FXAA_EARLY_EXIT\n" + " //\n" + " // Controls algorithm's early exit path.\n" + " // On PS3 turning this on adds 2 cycles to the shader.\n" + " // On 360 turning this off adds 10ths of a millisecond to the shader.\n" + " // Turning this off on console will result in a more blurry image.\n" + " // So this defaults to on.\n" + " //\n" + " // 1 = On.\n" + " // 0 = Off.\n" + " //\n" + " #define FXAA_EARLY_EXIT 1\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_DISCARD\n" + " //\n" + " // Only valid for PC OpenGL currently.\n" + " //\n" + " // 1 = Use discard on pixels which don't need AA.\n" + " // For APIs which enable concurrent TEX+ROP from same surface.\n" + " // 0 = Return unchanged color on pixels which don't need AA.\n" + " //\n" + " #define FXAA_DISCARD 0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_FAST_PIXEL_OFFSET\n" + " //\n" + " // Used for GLSL 120 only.\n" + " //\n" + " // 1 = GL API supports fast pixel offsets\n" + " // 0 = do not use fast pixel offsets\n" + " //\n" + " #ifdef GL_EXT_gpu_shader4\n" + " #define FXAA_FAST_PIXEL_OFFSET 1\n" + " #endif\n" + " #ifdef GL_NV_gpu_shader5\n" + " #define FXAA_FAST_PIXEL_OFFSET 1\n" + " #endif\n" + " #ifdef GL_ARB_gpu_shader5\n" + " #define FXAA_FAST_PIXEL_OFFSET 1\n" + " #endif\n" + " #ifndef FXAA_FAST_PIXEL_OFFSET\n" + " #define FXAA_FAST_PIXEL_OFFSET 0\n" + " #endif\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_GATHER4_ALPHA\n" + " //\n" + " // 1 = API supports gather4 on alpha channel.\n" + " // 0 = API does not support gather4 on alpha channel.\n" + " //\n" + " #if (FXAA_HLSL_5 == 1)\n" + " #define FXAA_GATHER4_ALPHA 1\n" + " #endif\n" + " #ifdef GL_ARB_gpu_shader5\n" + " #define FXAA_GATHER4_ALPHA 1\n" + " #endif\n" + " #ifdef GL_NV_gpu_shader5\n" + " #define FXAA_GATHER4_ALPHA 1\n" + " #endif\n" + " #ifndef FXAA_GATHER4_ALPHA\n" + " #define FXAA_GATHER4_ALPHA 0\n" + " #endif\n" + "#endif\n" + "\n" + "/*============================================================================\n" + " FXAA CONSOLE - TUNING KNOBS\n" + "============================================================================*/\n" + "#ifndef FXAA_CONSOLE_EDGE_SHARPNESS\n" + " //\n" + " // Consoles the sharpness of edges.\n" + " //\n" + " // Due to the PS3 being ALU bound,\n" + " // there are only two safe values here: 4 and 8.\n" + " // These options use the shaders ability to a free *|/ by 4|8.\n" + " //\n" + " // 8.0 is sharper\n" + " // 4.0 is softer\n" + " // 2.0 is really soft (good for vector graphics inputs)\n" + " //\n" + " #if 1\n" + " #define FXAA_CONSOLE_EDGE_SHARPNESS 8.0\n" + " #endif\n" + " #if 0\n" + " #define FXAA_CONSOLE_EDGE_SHARPNESS 4.0\n" + " #endif\n" + " #if 0\n" + " #define FXAA_CONSOLE_EDGE_SHARPNESS 2.0\n" + " #endif\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_CONSOLE_EDGE_THRESHOLD\n" + " //\n" + " // The minimum amount of local contrast required to apply algorithm.\n" + " // The console setting has a different mapping than the quality setting.\n" + " //\n" + " // This only applies when FXAA_EARLY_EXIT is 1.\n" + " //\n" + " // Due to the PS3 being ALU bound,\n" + " // there are only two safe values here: 0.25 and 0.125.\n" + " // These options use the shaders ability to a free *|/ by 4|8.\n" + " //\n" + " // 0.125 leaves less aliasing, but is softer\n" + " // 0.25 leaves more aliasing, and is sharper\n" + " //\n" + " #if 1\n" + " #define FXAA_CONSOLE_EDGE_THRESHOLD 0.125\n" + " #else\n" + " #define FXAA_CONSOLE_EDGE_THRESHOLD 0.25\n" + " #endif\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_CONSOLE_EDGE_THRESHOLD_MIN\n" + " //\n" + " // Trims the algorithm from processing darks.\n" + " // The console setting has a different mapping than the quality setting.\n" + " //\n" + " // This only applies when FXAA_EARLY_EXIT is 1.\n" + " //\n" + " // This does not apply to PS3.\n" + " // PS3 was simplified to avoid more shader instructions.\n" + " //\n" + " #define FXAA_CONSOLE_EDGE_THRESHOLD_MIN 0.05\n" + "#endif\n" + "\n" + "/*============================================================================\n" + " FXAA QUALITY - TUNING KNOBS\n" + "============================================================================*/\n" + "#ifndef FXAA_QUALITY_EDGE_THRESHOLD\n" + " //\n" + " // The minimum amount of local contrast required to apply algorithm.\n" + " //\n" + " // 1/3 - too little\n" + " // 1/4 - low quality\n" + " // 1/6 - default\n" + " // 1/8 - high quality (default)\n" + " // 1/16 - overkill\n" + " //\n" + " #define FXAA_QUALITY_EDGE_THRESHOLD (1.0/6.0)\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_QUALITY_EDGE_THRESHOLD_MIN\n" + " //\n" + " // Trims the algorithm from processing darks.\n" + " //\n" + " // 1/32 - visible limit\n" + " // 1/16 - high quality\n" + " // 1/12 - upper limit (default, the start of visible unfiltered edges)\n" + " //\n" + " #define FXAA_QUALITY_EDGE_THRESHOLD_MIN (1.0/12.0)\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_QUALITY_SUBPIX\n" + " //\n" + " // Choose the amount of sub-pixel aliasing removal.\n" + " //\n" + " // 1 - upper limit (softer)\n" + " // 3/4 - default amount of filtering\n" + " // 1/2 - lower limit (sharper, less sub-pixel aliasing removal)\n" + " //\n" + " #define FXAA_QUALITY_SUBPIX (3.0/4.0)\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#ifndef FXAA_QUALITY_PRESET\n" + " //\n" + " // Choose the quality preset.\n" + " // \n" + " // OPTIONS\n" + " // -----------------------------------------------------------------------\n" + " // 10 to 15 - default medium dither (10=fastest, 15=highest quality)\n" + " // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)\n" + " // 39 - no dither, very expensive \n" + " //\n" + " // NOTES\n" + " // -----------------------------------------------------------------------\n" + " // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)\n" + " // 13 = about same speed as FXAA 3.9 and better than 12\n" + " // 23 = closest to FXAA 3.9 visually and performance wise\n" + " // _ = the lowest digit is directly related to performance\n" + " // _ = the highest digit is directly related to style\n" + " // \n" + " #define FXAA_QUALITY_PRESET 12\n" + "#endif\n" + "\n" + "\n" + "/*============================================================================\n" + "\n" + " FXAA QUALITY - PRESETS\n" + "\n" + "============================================================================*/\n" + "\n" + "/*============================================================================\n" + " FXAA QUALITY - MEDIUM DITHER PRESETS\n" + "============================================================================*/\n" + "#if (FXAA_QUALITY_PRESET == 10)\n" + " #define FXAA_QUALITY_PS 3\n" + " #define FXAA_QUALITY_P0 1.5\n" + " #define FXAA_QUALITY_P1 3.0\n" + " #define FXAA_QUALITY_P2 12.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 11)\n" + " #define FXAA_QUALITY_PS 4\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 3.0\n" + " #define FXAA_QUALITY_P3 12.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 12)\n" + " #define FXAA_QUALITY_PS 5\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 4.0\n" + " #define FXAA_QUALITY_P4 12.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 13)\n" + " #define FXAA_QUALITY_PS 6\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 4.0\n" + " #define FXAA_QUALITY_P5 12.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 14)\n" + " #define FXAA_QUALITY_PS 7\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 4.0\n" + " #define FXAA_QUALITY_P6 12.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 15)\n" + " #define FXAA_QUALITY_PS 8\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 4.0\n" + " #define FXAA_QUALITY_P7 12.0\n" + "#endif\n" + "\n" + "/*============================================================================\n" + " FXAA QUALITY - LOW DITHER PRESETS\n" + "============================================================================*/\n" + "#if (FXAA_QUALITY_PRESET == 20)\n" + " #define FXAA_QUALITY_PS 3\n" + " #define FXAA_QUALITY_P0 1.5\n" + " #define FXAA_QUALITY_P1 2.0\n" + " #define FXAA_QUALITY_P2 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 21)\n" + " #define FXAA_QUALITY_PS 4\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 22)\n" + " #define FXAA_QUALITY_PS 5\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 23)\n" + " #define FXAA_QUALITY_PS 6\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 24)\n" + " #define FXAA_QUALITY_PS 7\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 3.0\n" + " #define FXAA_QUALITY_P6 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 25)\n" + " #define FXAA_QUALITY_PS 8\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 4.0\n" + " #define FXAA_QUALITY_P7 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 26)\n" + " #define FXAA_QUALITY_PS 9\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 2.0\n" + " #define FXAA_QUALITY_P7 4.0\n" + " #define FXAA_QUALITY_P8 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 27)\n" + " #define FXAA_QUALITY_PS 10\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 2.0\n" + " #define FXAA_QUALITY_P7 2.0\n" + " #define FXAA_QUALITY_P8 4.0\n" + " #define FXAA_QUALITY_P9 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 28)\n" + " #define FXAA_QUALITY_PS 11\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 2.0\n" + " #define FXAA_QUALITY_P7 2.0\n" + " #define FXAA_QUALITY_P8 2.0\n" + " #define FXAA_QUALITY_P9 4.0\n" + " #define FXAA_QUALITY_P10 8.0\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_QUALITY_PRESET == 29)\n" + " #define FXAA_QUALITY_PS 12\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.5\n" + " #define FXAA_QUALITY_P2 2.0\n" + " #define FXAA_QUALITY_P3 2.0\n" + " #define FXAA_QUALITY_P4 2.0\n" + " #define FXAA_QUALITY_P5 2.0\n" + " #define FXAA_QUALITY_P6 2.0\n" + " #define FXAA_QUALITY_P7 2.0\n" + " #define FXAA_QUALITY_P8 2.0\n" + " #define FXAA_QUALITY_P9 2.0\n" + " #define FXAA_QUALITY_P10 4.0\n" + " #define FXAA_QUALITY_P11 8.0\n" + "#endif\n" + "\n" + "/*============================================================================\n" + " FXAA QUALITY - EXTREME QUALITY\n" + "============================================================================*/\n" + "#if (FXAA_QUALITY_PRESET == 39)\n" + " #define FXAA_QUALITY_PS 12\n" + " #define FXAA_QUALITY_P0 1.0\n" + " #define FXAA_QUALITY_P1 1.0\n" + " #define FXAA_QUALITY_P2 1.0\n" + " #define FXAA_QUALITY_P3 1.0\n" + " #define FXAA_QUALITY_P4 1.0\n" + " #define FXAA_QUALITY_P5 1.5\n" + " #define FXAA_QUALITY_P6 2.0\n" + " #define FXAA_QUALITY_P7 2.0\n" + " #define FXAA_QUALITY_P8 2.0\n" + " #define FXAA_QUALITY_P9 2.0\n" + " #define FXAA_QUALITY_P10 4.0\n" + " #define FXAA_QUALITY_P11 8.0\n" + "#endif\n" + "\n" + "\n" + "\n" + "/*============================================================================\n" + "\n" + " API PORTING\n" + "\n" + "============================================================================*/\n" + "#if (FXAA_GLSL_120 == 1)\n" + " // Requires,\n" + " // #version 120\n" + " // And at least,\n" + " // #extension GL_EXT_gpu_shader4 : enable\n" + " // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)\n" + " #define half float\n" + " #define half2 vec2\n" + " #define half3 vec3\n" + " #define half4 vec4\n" + " #define int2 ivec2\n" + " #define float2 vec2\n" + " #define float3 vec3\n" + " #define float4 vec4\n" + " #define FxaaInt2 ivec2\n" + " #define FxaaFloat2 vec2\n" + " #define FxaaFloat3 vec3\n" + " #define FxaaFloat4 vec4\n" + " #define FxaaDiscard discard\n" + " #define FxaaDot3(a, b) dot(a, b)\n" + " #define FxaaSat(x) clamp(x, 0.0, 1.0)\n" + " #define FxaaLerp(x,y,s) mix(x,y,s)\n" + " #define FxaaTex sampler2D\n" + " #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)\n" + " #if (FXAA_FAST_PIXEL_OFFSET == 1)\n" + " #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)\n" + " #else\n" + " #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)\n" + " #endif\n" + " #if (FXAA_GATHER4_ALPHA == 1)\n" + " // use #extension GL_ARB_gpu_shader5 : enable\n" + " #define FxaaTexAlpha4(t, p, r) textureGather(t, p, 3)\n" + " #define FxaaTexOffAlpha4(t, p, o, r) textureGatherOffset(t, p, o, 3)\n" + " #endif\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_GLSL_130 == 1)\n" + " // Requires \"#version 130\" or better\n" + " #define half float\n" + " #define half2 vec2\n" + " #define half3 vec3\n" + " #define half4 vec4\n" + " #define int2 ivec2\n" + " #define float2 vec2\n" + " #define float3 vec3\n" + " #define float4 vec4\n" + " #define FxaaInt2 ivec2\n" + " #define FxaaFloat2 vec2\n" + " #define FxaaFloat3 vec3\n" + " #define FxaaFloat4 vec4\n" + " #define FxaaDiscard discard\n" + " #define FxaaDot3(a, b) dot(a, b)\n" + " #define FxaaSat(x) clamp(x, 0.0, 1.0)\n" + " #define FxaaLerp(x,y,s) mix(x,y,s)\n" + " #define FxaaTex sampler2D\n" + " #define FxaaTexTop(t, p) textureLod(t, p, 0.0)\n" + " #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)\n" + " #if (FXAA_GATHER4_ALPHA == 1)\n" + " // use #extension GL_ARB_gpu_shader5 : enable\n" + " #define FxaaTexAlpha4(t, p, r) textureGather(t, p, 3)\n" + " #define FxaaTexOffAlpha4(t, p, o, r) textureGatherOffset(t, p, o, 3)\n" + " #endif\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1)\n" + " #define int2 float2\n" + " #define FxaaInt2 float2\n" + " #define FxaaFloat2 float2\n" + " #define FxaaFloat3 float3\n" + " #define FxaaFloat4 float4\n" + " #define FxaaDiscard clip(-1)\n" + " #define FxaaDot3(a, b) dot(a, b)\n" + " #define FxaaSat(x) saturate(x)\n" + " #define FxaaLerp(x,y,s) lerp(x,y,s)\n" + " #define FxaaTex sampler2D\n" + " #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))\n" + " #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_HLSL_4 == 1)\n" + " #define FxaaInt2 int2\n" + " #define FxaaFloat2 float2\n" + " #define FxaaFloat3 float3\n" + " #define FxaaFloat4 float4\n" + " #define FxaaDiscard clip(-1)\n" + " #define FxaaDot3(a, b) dot(a, b)\n" + " #define FxaaSat(x) saturate(x)\n" + " #define FxaaLerp(x,y,s) lerp(x,y,s)\n" + " struct FxaaTex { SamplerState smpl; Texture2D tex; };\n" + " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)\n" + " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)\n" + "#endif\n" + "/*--------------------------------------------------------------------------*/\n" + "#if (FXAA_HLSL_5 == 1)\n" + " #define FxaaInt2 int2\n" + " #define FxaaFloat2 float2\n" + " #define FxaaFloat3 float3\n" + " #define FxaaFloat4 float4\n" + " #define FxaaDiscard clip(-1)\n" + " #define FxaaDot3(a, b) dot(a, b)\n" + " #define FxaaSat(x) saturate(x)\n" + " #define FxaaLerp(x,y,s) lerp(x,y,s)\n" + " struct FxaaTex { SamplerState smpl; Texture2D tex; };\n" + " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)\n" + " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)\n" + " #define FxaaTexAlpha4(t, p, r) t.tex.GatherAlpha(t.smpl, p)\n" + " #define FxaaTexOffAlpha4(t, p, o, r) t.tex.GatherAlpha(t.smpl, p, o)\n" + "#endif\n" + "\n" + "\n" + "\n" + "/*============================================================================\n" + "\n" + " FXAA3 QUALITY - PC\n" + "\n" + "============================================================================*/\n" + "#if (FXAA_PC == 1)\n" + "/*--------------------------------------------------------------------------*/\n" + "float4 FxaaPixelShader(\n" + " // {xy} = center of pixel\n" + " float2 pos,\n" + " // {xyzw} = not used on FXAA3 Quality\n" + " float4 posPos,\n" + " // {rgb_} = color in linear or perceptual color space\n" + " // {___a} = luma in perceptual color space (not linear)\n" + " FxaaTex tex,\n" + " // This must be from a constant/uniform.\n" + " // {x_} = 1.0/screenWidthInPixels\n" + " // {_y} = 1.0/screenHeightInPixels\n" + " float2 rcpFrame,\n" + " // {xyzw} = not used on FXAA3 Quality\n" + " float4 rcpFrameOpt\n" + ") {\n" + "/*--------------------------------------------------------------------------*/\n" + " float2 posM;\n" + " posM.x = pos.x;\n" + " posM.y = pos.y;\n" + " #if (FXAA_GATHER4_ALPHA == 1)\n" + " #if (FXAA_DISCARD == 0)\n" + " float4 rgbyM = FxaaTexTop(tex, posM);\n" + " #define lumaM rgbyM.w\n" + " #endif\n" + " float4 luma4A = FxaaTexAlpha4(tex, posM, rcpFrame.xy);\n" + " float4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1), rcpFrame.xy);\n" + " #if (FXAA_DISCARD == 1)\n" + " #define lumaM luma4A.w\n" + " #endif\n" + " #define lumaE luma4A.z\n" + " #define lumaS luma4A.x\n" + " #define lumaSE luma4A.y\n" + " #define lumaNW luma4B.w\n" + " #define lumaN luma4B.z\n" + " #define lumaW luma4B.x\n" + " #else\n" + " float4 rgbyM = FxaaTexTop(tex, posM);\n" + " #define lumaM rgbyM.w\n" + " float lumaS = FxaaTexOff(tex, posM, FxaaInt2( 0, 1), rcpFrame.xy).w;\n" + " float lumaE = FxaaTexOff(tex, posM, FxaaInt2( 1, 0), rcpFrame.xy).w;\n" + " float lumaN = FxaaTexOff(tex, posM, FxaaInt2( 0,-1), rcpFrame.xy).w;\n" + " float lumaW = FxaaTexOff(tex, posM, FxaaInt2(-1, 0), rcpFrame.xy).w;\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " float maxSM = max(lumaS, lumaM);\n" + " float minSM = min(lumaS, lumaM);\n" + " float maxESM = max(lumaE, maxSM);\n" + " float minESM = min(lumaE, minSM);\n" + " float maxWN = max(lumaN, lumaW);\n" + " float minWN = min(lumaN, lumaW);\n" + " float rangeMax = max(maxWN, maxESM);\n" + " float rangeMin = min(minWN, minESM);\n" + " float rangeMaxScaled = rangeMax * FXAA_QUALITY_EDGE_THRESHOLD;\n" + " float range = rangeMax - rangeMin;\n" + " float rangeMaxClamped = max(FXAA_QUALITY_EDGE_THRESHOLD_MIN, rangeMaxScaled);\n" + " bool earlyExit = range < rangeMaxClamped;\n" + "/*--------------------------------------------------------------------------*/\n" + " if(earlyExit)\n" + " #if (FXAA_DISCARD == 1)\n" + " FxaaDiscard;\n" + " #else\n" + " return rgbyM;\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_GATHER4_ALPHA == 0)\n" + " float lumaNW = FxaaTexOff(tex, posM, FxaaInt2(-1,-1), rcpFrame.xy).w;\n" + " float lumaSE = FxaaTexOff(tex, posM, FxaaInt2( 1, 1), rcpFrame.xy).w;\n" + " float lumaNE = FxaaTexOff(tex, posM, FxaaInt2( 1,-1), rcpFrame.xy).w;\n" + " float lumaSW = FxaaTexOff(tex, posM, FxaaInt2(-1, 1), rcpFrame.xy).w;\n" + " #else\n" + " float lumaNE = FxaaTexOff(tex, posM, FxaaInt2(1, -1), rcpFrame.xy).w;\n" + " float lumaSW = FxaaTexOff(tex, posM, FxaaInt2(-1, 1), rcpFrame.xy).w;\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " float lumaNS = lumaN + lumaS;\n" + " float lumaWE = lumaW + lumaE;\n" + " float subpixRcpRange = 1.0/range;\n" + " float subpixNSWE = lumaNS + lumaWE;\n" + " float edgeHorz1 = (-2.0 * lumaM) + lumaNS;\n" + " float edgeVert1 = (-2.0 * lumaM) + lumaWE;\n" + "/*--------------------------------------------------------------------------*/\n" + " float lumaNESE = lumaNE + lumaSE;\n" + " float lumaNWNE = lumaNW + lumaNE;\n" + " float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;\n" + " float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;\n" + "/*--------------------------------------------------------------------------*/\n" + " float lumaNWSW = lumaNW + lumaSW;\n" + " float lumaSWSE = lumaSW + lumaSE;\n" + " float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);\n" + " float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);\n" + " float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;\n" + " float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;\n" + " float edgeHorz = abs(edgeHorz3) + edgeHorz4;\n" + " float edgeVert = abs(edgeVert3) + edgeVert4;\n" + "/*--------------------------------------------------------------------------*/\n" + " float subpixNWSWNESE = lumaNWSW + lumaNESE;\n" + " float lengthSign = rcpFrame.x;\n" + " bool horzSpan = edgeHorz >= edgeVert;\n" + " float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;\n" + "/*--------------------------------------------------------------------------*/\n" + " if(!horzSpan) lumaN = lumaW;\n" + " if(!horzSpan) lumaS = lumaE;\n" + " if(horzSpan) lengthSign = rcpFrame.y;\n" + " float subpixB = (subpixA * (1.0/12.0)) - lumaM;\n" + "/*--------------------------------------------------------------------------*/\n" + " float gradientN = lumaN - lumaM;\n" + " float gradientS = lumaS - lumaM;\n" + " float lumaNN = lumaN + lumaM;\n" + " float lumaSS = lumaS + lumaM;\n" + " bool pairN = abs(gradientN) >= abs(gradientS);\n" + " float gradient = max(abs(gradientN), abs(gradientS));\n" + " if(pairN) lengthSign = -lengthSign;\n" + " float subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);\n" + "/*--------------------------------------------------------------------------*/\n" + " float2 posB;\n" + " posB.x = posM.x;\n" + " posB.y = posM.y;\n" + " float2 offNP;\n" + " offNP.x = (!horzSpan) ? 0.0 : rcpFrame.x;\n" + " offNP.y = ( horzSpan) ? 0.0 : rcpFrame.y;\n" + " if(!horzSpan) posB.x += lengthSign * 0.5;\n" + " if( horzSpan) posB.y += lengthSign * 0.5;\n" + "/*--------------------------------------------------------------------------*/\n" + " float2 posN;\n" + " posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;\n" + " posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;\n" + " float2 posP;\n" + " posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;\n" + " posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;\n" + " float subpixD = ((-2.0)*subpixC) + 3.0;\n" + " float lumaEndN = FxaaTexTop(tex, posN).w;\n" + " float subpixE = subpixC * subpixC;\n" + " float lumaEndP = FxaaTexTop(tex, posP).w;\n" + "/*--------------------------------------------------------------------------*/\n" + " if(!pairN) lumaNN = lumaSS;\n" + " float gradientScaled = gradient * 1.0/4.0;\n" + " float lumaMM = lumaM - lumaNN * 0.5;\n" + " float subpixF = subpixD * subpixE;\n" + " bool lumaMLTZero = lumaMM < 0.0;\n" + "/*--------------------------------------------------------------------------*/\n" + " lumaEndN -= lumaNN * 0.5;\n" + " lumaEndP -= lumaNN * 0.5;\n" + " bool doneN = abs(lumaEndN) >= gradientScaled;\n" + " bool doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;\n" + " bool doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;\n" + "/*--------------------------------------------------------------------------*/\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 3)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 4)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 5)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 6)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 7)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 8)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 9)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 10)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 11)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;\n" + "/*--------------------------------------------------------------------------*/\n" + " #if (FXAA_QUALITY_PS > 12)\n" + " if(doneNP) {\n" + " if(!doneN) lumaEndN = FxaaTexTop(tex, posN.xy).w;\n" + " if(!doneP) lumaEndP = FxaaTexTop(tex, posP.xy).w;\n" + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;\n" + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;\n" + " doneN = abs(lumaEndN) >= gradientScaled;\n" + " doneP = abs(lumaEndP) >= gradientScaled;\n" + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;\n" + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;\n" + " doneNP = (!doneN) || (!doneP);\n" + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;\n" + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + " #endif\n" + "/*--------------------------------------------------------------------------*/\n" + " }\n" + "/*--------------------------------------------------------------------------*/\n" + " float dstN = posM.x - posN.x;\n" + " float dstP = posP.x - posM.x;\n" + " if(!horzSpan) dstN = posM.y - posN.y;\n" + " if(!horzSpan) dstP = posP.y - posM.y;\n" + "/*--------------------------------------------------------------------------*/\n" + " bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;\n" + " float spanLength = (dstP + dstN);\n" + " bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;\n" + " float spanLengthRcp = 1.0/spanLength;\n" + "/*--------------------------------------------------------------------------*/\n" + " bool directionN = dstN < dstP;\n" + " float dst = min(dstN, dstP);\n" + " bool goodSpan = directionN ? goodSpanN : goodSpanP;\n" + " float subpixG = subpixF * subpixF;\n" + " float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;\n" + " float subpixH = subpixG * FXAA_QUALITY_SUBPIX;\n" + "/*--------------------------------------------------------------------------*/\n" + " float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;\n" + " float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);\n" + " if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;\n" + " if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;\n" + " #if (FXAA_DISCARD == 1)\n" + " return FxaaTexTop(tex, posM);\n" + " #else\n" + " return float4(FxaaTexTop(tex, posM).xyz, lumaM);\n" + " #endif\n" + "}\n" + "/*==========================================================================*/\n" + "#endif\n" + "\n" + "#ifdef SHADER_MODEL\n" + "PS_OUTPUT ps_main(PS_INPUT input)\n" + "{\n" + " PS_OUTPUT output;\n" + "\n" + " float2 pos = input.t;\n" + " float4 posPos = (float4)0;\n" + "\n" + " FxaaTex tex;\n" + "\n" + " #if SHADER_MODEL >= 0x400\n" + "\n" + " tex.tex = Texture;\n" + " tex.smpl = TextureSampler;\n" + "\n" + " #else\n" + "\n" + " tex = Texture;\n" + "\n" + " #endif\n" + "\n" + " output.c = FxaaPixelShader(pos, posPos, tex, _rcpFrame.xy, _rcpFrameOpt);\n" + "\n" + " return output;\n" + "}\n" + "#endif\n" + "\n" + "#if (FXAA_GLSL_130 == 1)\n" + "void ps_main()\n" + "{\n" + " vec2 pos = PSin_t;\n" + " vec4 posPos = vec4(0.0, 0.0, 0.0, 0.0);\n" + "\n" + " SV_Target0 = FxaaPixelShader(pos, posPos, TextureSampler, _rcpFrame.xy, _rcpFrameOpt);\n" + "}\n" + "#endif\n" + "\n" + "#endif\n" + ; diff --git a/plugins/GSdx/res/interlace.glsl b/plugins/GSdx/res/interlace.glsl index 21b81af113..1bee5ff225 100644 --- a/plugins/GSdx/res/interlace.glsl +++ b/plugins/GSdx/res/interlace.glsl @@ -6,8 +6,22 @@ struct vertex_basic vec2 t; }; -#ifdef FRAGMENT_SHADER +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) in vertex_basic PSin; +#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec2 SHADERt; +#else +layout(location = 0) in vec4 SHADERp; +layout(location = 1) in vec2 SHADERt; +#endif +#define PSin_p SHADERp +#define PSin_t SHADERt +#endif +#ifdef FRAGMENT_SHADER layout(location = 0) out vec4 SV_Target0; @@ -21,15 +35,19 @@ layout(std140, binding = 11) uniform cb11 float hH; }; +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +#else layout(binding = 0) uniform sampler2D TextureSampler; +#endif // TODO ensure that clip (discard) is < 0 and not <= 0 ??? void ps_main0() { // I'm not sure it impact us but be safe to lookup texture before conditional if // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control - vec4 c = texture(TextureSampler, PSin.t); - if (fract(PSin.t.y * hH) - 0.5 < 0.0) + vec4 c = texture(TextureSampler, PSin_t); + if (fract(PSin_t.y * hH) - 0.5 < 0.0) discard; SV_Target0 = c; @@ -39,8 +57,8 @@ void ps_main1() { // I'm not sure it impact us but be safe to lookup texture before conditional if // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control - vec4 c = texture(TextureSampler, PSin.t); - if (0.5 - fract(PSin.t.y * hH) < 0.0) + vec4 c = texture(TextureSampler, PSin_t); + if (0.5 - fract(PSin_t.y * hH) < 0.0) discard; SV_Target0 = c; @@ -48,16 +66,16 @@ void ps_main1() void ps_main2() { - vec4 c0 = texture(TextureSampler, PSin.t - ZrH); - vec4 c1 = texture(TextureSampler, PSin.t); - vec4 c2 = texture(TextureSampler, PSin.t + ZrH); + vec4 c0 = texture(TextureSampler, PSin_t - ZrH); + vec4 c1 = texture(TextureSampler, PSin_t); + vec4 c2 = texture(TextureSampler, PSin_t + ZrH); SV_Target0 = (c0 + c1 * 2 + c2) / 4; } void ps_main3() { - SV_Target0 = texture(TextureSampler, PSin.t); + SV_Target0 = texture(TextureSampler, PSin_t); } #endif diff --git a/plugins/GSdx/res/interlace.h b/plugins/GSdx/res/interlace.h index ed21d59fe8..375676f5b1 100644 --- a/plugins/GSdx/res/interlace.h +++ b/plugins/GSdx/res/interlace.h @@ -25,7 +25,7 @@ #include "stdafx.h" -extern const char* interlace_glsl = +static const char* interlace_glsl = "//#version 420 // Keep it for editor detection\n" "\n" "struct vertex_basic\n" @@ -34,8 +34,22 @@ extern const char* interlace_glsl = " vec2 t;\n" "};\n" "\n" - "#ifdef FRAGMENT_SHADER\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) in vertex_basic PSin;\n" + "#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 1) in vec2 SHADERt;\n" + "#endif\n" + "#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#endif\n" + "#ifdef FRAGMENT_SHADER\n" "\n" "layout(location = 0) out vec4 SV_Target0;\n" "\n" @@ -49,15 +63,19 @@ extern const char* interlace_glsl = " float hH;\n" "};\n" "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "#else\n" "layout(binding = 0) uniform sampler2D TextureSampler;\n" + "#endif\n" "\n" "// TODO ensure that clip (discard) is < 0 and not <= 0 ???\n" "void ps_main0()\n" "{\n" " // I'm not sure it impact us but be safe to lookup texture before conditional if\n" " // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control\n" - " vec4 c = texture(TextureSampler, PSin.t);\n" - " if (fract(PSin.t.y * hH) - 0.5 < 0.0)\n" + " vec4 c = texture(TextureSampler, PSin_t);\n" + " if (fract(PSin_t.y * hH) - 0.5 < 0.0)\n" " discard;\n" "\n" " SV_Target0 = c;\n" @@ -67,8 +85,8 @@ extern const char* interlace_glsl = "{\n" " // I'm not sure it impact us but be safe to lookup texture before conditional if\n" " // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control\n" - " vec4 c = texture(TextureSampler, PSin.t);\n" - " if (0.5 - fract(PSin.t.y * hH) < 0.0)\n" + " vec4 c = texture(TextureSampler, PSin_t);\n" + " if (0.5 - fract(PSin_t.y * hH) < 0.0)\n" " discard;\n" "\n" " SV_Target0 = c;\n" @@ -76,16 +94,16 @@ extern const char* interlace_glsl = "\n" "void ps_main2()\n" "{\n" - " vec4 c0 = texture(TextureSampler, PSin.t - ZrH);\n" - " vec4 c1 = texture(TextureSampler, PSin.t);\n" - " vec4 c2 = texture(TextureSampler, PSin.t + ZrH);\n" + " vec4 c0 = texture(TextureSampler, PSin_t - ZrH);\n" + " vec4 c1 = texture(TextureSampler, PSin_t);\n" + " vec4 c2 = texture(TextureSampler, PSin_t + ZrH);\n" "\n" " SV_Target0 = (c0 + c1 * 2 + c2) / 4;\n" "}\n" "\n" "void ps_main3()\n" "{\n" - " SV_Target0 = texture(TextureSampler, PSin.t);\n" + " SV_Target0 = texture(TextureSampler, PSin_t);\n" "}\n" "\n" "#endif\n" diff --git a/plugins/GSdx/res/merge.glsl b/plugins/GSdx/res/merge.glsl index ed3ca36062..5fceebc7b2 100644 --- a/plugins/GSdx/res/merge.glsl +++ b/plugins/GSdx/res/merge.glsl @@ -6,8 +6,22 @@ struct vertex_basic vec2 t; }; -#ifdef FRAGMENT_SHADER +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) in vertex_basic PSin; +#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec2 SHADERt; +#else +layout(location = 0) in vec4 SHADERp; +layout(location = 1) in vec2 SHADERt; +#endif +#define PSin_p SHADERp +#define PSin_t SHADERt +#endif +#ifdef FRAGMENT_SHADER layout(location = 0) out vec4 SV_Target0; @@ -20,18 +34,22 @@ layout(std140, binding = 10) uniform cb10 vec4 BGColor; }; +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +#else layout(binding = 0) uniform sampler2D TextureSampler; +#endif void ps_main0() { - vec4 c = texture(TextureSampler, PSin.t); + vec4 c = texture(TextureSampler, PSin_t); c.a = min(c.a * 2, 1.0); SV_Target0 = c; } void ps_main1() { - vec4 c = texture(TextureSampler, PSin.t); + vec4 c = texture(TextureSampler, PSin_t); c.a = BGColor.a; SV_Target0 = c; } diff --git a/plugins/GSdx/res/merge.h b/plugins/GSdx/res/merge.h index a3012684bf..c593c64f91 100644 --- a/plugins/GSdx/res/merge.h +++ b/plugins/GSdx/res/merge.h @@ -25,7 +25,7 @@ #include "stdafx.h" -extern const char* merge_glsl = +static const char* merge_glsl = "//#version 420 // Keep it for editor detection\n" "\n" "struct vertex_basic\n" @@ -34,8 +34,22 @@ extern const char* merge_glsl = " vec2 t;\n" "};\n" "\n" - "#ifdef FRAGMENT_SHADER\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) in vertex_basic PSin;\n" + "#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 1) in vec2 SHADERt;\n" + "#endif\n" + "#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#endif\n" + "#ifdef FRAGMENT_SHADER\n" "\n" "layout(location = 0) out vec4 SV_Target0;\n" "\n" @@ -48,18 +62,22 @@ extern const char* merge_glsl = " vec4 BGColor;\n" "};\n" "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "#else\n" "layout(binding = 0) uniform sampler2D TextureSampler;\n" + "#endif\n" "\n" "void ps_main0()\n" "{\n" - " vec4 c = texture(TextureSampler, PSin.t);\n" + " vec4 c = texture(TextureSampler, PSin_t);\n" " c.a = min(c.a * 2, 1.0);\n" " SV_Target0 = c;\n" "}\n" "\n" "void ps_main1()\n" "{\n" - " vec4 c = texture(TextureSampler, PSin.t);\n" + " vec4 c = texture(TextureSampler, PSin_t);\n" " c.a = BGColor.a;\n" " SV_Target0 = c;\n" "}\n" diff --git a/plugins/GSdx/res/shadeboost.glsl b/plugins/GSdx/res/shadeboost.glsl index 006329ae80..8624b49d20 100644 --- a/plugins/GSdx/res/shadeboost.glsl +++ b/plugins/GSdx/res/shadeboost.glsl @@ -14,7 +14,21 @@ struct vertex_basic #ifdef FRAGMENT_SHADER +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) in vertex_basic PSin; +#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec2 SHADERt; +#else +layout(location = 0) in vec4 SHADERp; +layout(location = 1) in vec2 SHADERt; +#endif +#define PSin_p SHADERp +#define PSin_t SHADERt +#endif layout(location = 0) out vec4 SV_Target0; @@ -27,7 +41,11 @@ layout(std140, binding = 12) uniform cb12 vec4 BGColor; }; +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +#else layout(binding = 0) uniform sampler2D TextureSampler; +#endif // For all settings: 1.0 = 100% 0.5=50% 1.5 = 150% vec4 ContrastSaturationBrightness(vec4 color) @@ -57,7 +75,7 @@ vec4 ContrastSaturationBrightness(vec4 color) void ps_main() { - vec4 c = texture(TextureSampler, PSin.t); + vec4 c = texture(TextureSampler, PSin_t); SV_Target0 = ContrastSaturationBrightness(c); } diff --git a/plugins/GSdx/res/shadeboost.h b/plugins/GSdx/res/shadeboost.h index 172175c349..5890feea67 100644 --- a/plugins/GSdx/res/shadeboost.h +++ b/plugins/GSdx/res/shadeboost.h @@ -25,7 +25,7 @@ #include "stdafx.h" -extern const char* shadeboost_glsl = +static const char* shadeboost_glsl = "//#version 420 // Keep it for editor detection\n" "\n" "/*\n" @@ -42,7 +42,21 @@ extern const char* shadeboost_glsl = "\n" "#ifdef FRAGMENT_SHADER\n" "\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) in vertex_basic PSin;\n" + "#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec2 SHADERt;\n" + "#else\n" + "layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 1) in vec2 SHADERt;\n" + "#endif\n" + "#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#endif\n" "\n" "layout(location = 0) out vec4 SV_Target0;\n" "\n" @@ -55,7 +69,11 @@ extern const char* shadeboost_glsl = " vec4 BGColor;\n" "};\n" "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "#else\n" "layout(binding = 0) uniform sampler2D TextureSampler;\n" + "#endif\n" "\n" "// For all settings: 1.0 = 100\% 0.5=50\% 1.5 = 150\% \n" "vec4 ContrastSaturationBrightness(vec4 color)\n" @@ -85,7 +103,7 @@ extern const char* shadeboost_glsl = "\n" "void ps_main()\n" "{\n" - " vec4 c = texture(TextureSampler, PSin.t);\n" + " vec4 c = texture(TextureSampler, PSin_t);\n" " SV_Target0 = ContrastSaturationBrightness(c);\n" "}\n" "\n" diff --git a/plugins/GSdx/res/tfx.glsl b/plugins/GSdx/res/tfx.glsl index e6f87aff26..6e2c0d09ae 100644 --- a/plugins/GSdx/res/tfx.glsl +++ b/plugins/GSdx/res/tfx.glsl @@ -46,7 +46,7 @@ struct vertex { - vec4 p; + //vec4 p; vec4 t; vec4 tp; vec4 c; @@ -61,13 +61,37 @@ layout(location = 4) in uint i_z; layout(location = 5) in uvec2 i_uv; layout(location = 6) in vec4 i_f; +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) out vertex VSout; +#define VSout_p (VSout.p) +#define VSout_t (VSout.t) +#define VSout_tp (VSout.tp) +#define VSout_c (VSout.c) +#else +#ifdef DISABLE_SSO +//out vec4 SHADERp; +out vec4 SHADERt; +out vec4 SHADERtp; +out vec4 SHADERc; +#else +//layout(location = 0) out vec4 SHADERp; +layout(location = 0) out vec4 SHADERt; +layout(location = 1) out vec4 SHADERtp; +layout(location = 2) out vec4 SHADERc; +#endif +//#define VSout_p SHADERp +#define VSout_t SHADERt +#define VSout_tp SHADERtp +#define VSout_c SHADERc +#endif +#if __VERSION__ > 140 out gl_PerVertex { invariant vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; }; +#endif #ifdef DISABLE_GL42 layout(std140) uniform cb20 @@ -106,10 +130,10 @@ void vs_main() final_p.z = log2(1.0f + float(z)) / 32.0f; } - VSout.p = final_p; + //VSout_p = final_p; gl_Position = final_p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position #if VS_RTCOPY - VSout.tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5; + VSout_tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5; #endif @@ -117,25 +141,25 @@ void vs_main() { if(VS_FST != 0) { - //VSout.t.xy = i_t * TextureScale; - VSout.t.xy = i_uv * TextureScale; - VSout.t.w = 1.0f; + //VSout_t.xy = i_t * TextureScale; + VSout_t.xy = i_uv * TextureScale; + VSout_t.w = 1.0f; } else { - //VSout.t.xy = i_t; - VSout.t.xy = i_st; - VSout.t.w = i_q; + //VSout_t.xy = i_t; + VSout_t.xy = i_st; + VSout_t.w = i_q; } } else { - VSout.t.xy = vec2(0.0f, 0.0f); - VSout.t.w = 1.0f; + VSout_t.xy = vec2(0.0f, 0.0f); + VSout_t.w = 1.0f; } - VSout.c = i_c; - VSout.t.z = i_f.r; + VSout_c = i_c; + VSout_t.z = i_f.r; } #endif @@ -217,46 +241,50 @@ void gs_main() // right bottom => GSin[1]; vertex rb = GSin[1]; vertex lt = GSin[0]; + vec4 rb_p = gl_in[1].gl_Position; + vec4 lb_p = gl_in[1].gl_Position; + vec4 rt_p = gl_in[1].gl_Position; + vec4 lt_p = gl_in[0].gl_Position; - lt.p.z = rb.p.z; + lt_p.z = rb_p.z; lt.t.zw = rb.t.zw; #if GS_IIP == 0 lt.c = rb.c; #endif vertex lb = rb; - lb.p.x = lt.p.x; + lb_p.x = lt_p.x; lb.t.x = lt.t.x; vertex rt = rb; - rt.p.y = lt.p.y; + rt_p.y = lt_p.y; rt.t.y = lt.t.y; // Triangle 1 - gl_Position = lt.p; + gl_Position = lt_p; GSout = lt; EmitVertex(); - gl_Position = lb.p; + gl_Position = lb_p; GSout = lb; EmitVertex(); - gl_Position = rt.p; + gl_Position = rt_p; GSout = rt; EmitVertex(); EndPrimitive(); // Triangle 2 - gl_Position = lb.p; + gl_Position = lb_p; GSout = lb; EmitVertex(); - gl_Position = rt.p; + gl_Position = rt_p; GSout = rt; EmitVertex(); - gl_Position = rb.p; + gl_Position = rb_p; GSout = rb; EmitVertex(); @@ -269,15 +297,43 @@ void gs_main() #endif #ifdef FRAGMENT_SHADER +#if __VERSION__ > 140 && !(defined(NO_STRUCT)) layout(location = 0) in vertex PSin; +//#define PSin_p (PSin.p) +#define PSin_t (PSin.t) +#define PSin_tp (PSin.tp) +#define PSin_c (PSin.c) +#else +#ifdef DISABLE_SSO +in vec4 SHADERp; +in vec4 SHADERt; +in vec4 SHADERtp; +in vec4 SHADERc; +#else +//layout(location = 0) in vec4 SHADERp; +layout(location = 0) in vec4 SHADERt; +layout(location = 1) in vec4 SHADERtp; +layout(location = 2) in vec4 SHADERc; +#endif +//#define PSin_p SHADERp +#define PSin_t SHADERt +#define PSin_tp SHADERtp +#define PSin_c SHADERc +#endif // Same buffer but 2 colors for dual source blending layout(location = 0, index = 0) out vec4 SV_Target0; layout(location = 0, index = 1) out vec4 SV_Target1; +#ifdef DISABLE_GL42 +uniform sampler2D TextureSampler; +uniform sampler2D PaletteSampler; +uniform sampler2D RTCopySampler; +#else layout(binding = 0) uniform sampler2D TextureSampler; layout(binding = 1) uniform sampler2D PaletteSampler; layout(binding = 2) uniform sampler2D RTCopySampler; +#endif #ifdef DISABLE_GL42 layout(std140) uniform cb21 @@ -401,13 +457,12 @@ vec4 sample_4a(vec4 uv) { vec4 c; - // XXX - // I think .a is related to 8bit texture in alpha channel - // Opengl is only 8 bits on red channel. Not sure exactly of the impact - c.x = sample_c(uv.xy).a; - c.y = sample_c(uv.zy).a; - c.z = sample_c(uv.xw).a; - c.w = sample_c(uv.zw).a; + // Dx used the alpha channel. + // Opengl is only 8 bits on red channel. + c.x = sample_c(uv.xy).r; + c.y = sample_c(uv.zy).r; + c.z = sample_c(uv.xw).r; + c.w = sample_c(uv.zw).r; return c * 255./256 + 0.5/256; } @@ -470,14 +525,14 @@ vec4 sample_color(vec2 st, float q) if((PS_FMT & ~FMT_PAL) == FMT_24) { // FIXME GLSL any only support bvec so try to mix it with notEqual - bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) ); - t.a = ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f; + bvec3 rgb_check = notEqual( c[i].rgb, vec3(0.0f, 0.0f, 0.0f) ); + c[i].a = ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f; } else if((PS_FMT & ~FMT_PAL) == FMT_16) { // FIXME GLSL any only support bvec so try to mix it with notEqual - bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) ); - t.a = t.a >= 0.5 ? TA.y : ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f; + bvec3 rgb_check = notEqual( c[i].rgb, vec3(0.0f, 0.0f, 0.0f) ); + c[i].a = c[i].a >= 0.5 ? TA.y : ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f; } } @@ -543,7 +598,7 @@ vec4 tfx(vec4 t, vec4 c) void datst() { #if PS_DATE > 0 - float alpha = sample_rt(PSin.tp.xy).a; + float alpha = sample_rt(PSin_tp.xy).a; float alpha0x80 = 128. / 255; if (PS_DATE == 1 && alpha >= alpha0x80) @@ -613,13 +668,13 @@ vec4 ps_color() { datst(); - vec4 t = sample_color(PSin.t.xy, PSin.t.w); + vec4 t = sample_color(PSin_t.xy, PSin_t.w); - vec4 c = tfx(t, PSin.c); + vec4 c = tfx(t, PSin_c); atst(c); - c = fog(c, PSin.t.z); + c = fog(c, PSin_t.z); if (PS_COLCLIP == 2) { diff --git a/plugins/GSdx/res/tfx.h b/plugins/GSdx/res/tfx.h index 8f38c2c3e2..876c58f6c5 100644 --- a/plugins/GSdx/res/tfx.h +++ b/plugins/GSdx/res/tfx.h @@ -25,7 +25,7 @@ #include "stdafx.h" -extern const char* tfx_glsl = +static const char* tfx_glsl = "//#version 420 // Keep it for text editor detection\n" "\n" "// note lerp => mix\n" @@ -74,7 +74,7 @@ extern const char* tfx_glsl = "\n" "struct vertex\n" "{\n" - " vec4 p;\n" + " //vec4 p;\n" " vec4 t;\n" " vec4 tp;\n" " vec4 c;\n" @@ -89,13 +89,37 @@ extern const char* tfx_glsl = "layout(location = 5) in uvec2 i_uv;\n" "layout(location = 6) in vec4 i_f;\n" "\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) out vertex VSout;\n" + "#define VSout_p (VSout.p)\n" + "#define VSout_t (VSout.t)\n" + "#define VSout_tp (VSout.tp)\n" + "#define VSout_c (VSout.c)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "//out vec4 SHADERp;\n" + "out vec4 SHADERt;\n" + "out vec4 SHADERtp;\n" + "out vec4 SHADERc;\n" + "#else\n" + "//layout(location = 0) out vec4 SHADERp;\n" + "layout(location = 0) out vec4 SHADERt;\n" + "layout(location = 1) out vec4 SHADERtp;\n" + "layout(location = 2) out vec4 SHADERc;\n" + "#endif\n" + "//#define VSout_p SHADERp\n" + "#define VSout_t SHADERt\n" + "#define VSout_tp SHADERtp\n" + "#define VSout_c SHADERc\n" + "#endif\n" "\n" + "#if __VERSION__ > 140\n" "out gl_PerVertex {\n" " invariant vec4 gl_Position;\n" " float gl_PointSize;\n" " float gl_ClipDistance[];\n" "};\n" + "#endif\n" "\n" "#ifdef DISABLE_GL42\n" "layout(std140) uniform cb20\n" @@ -134,10 +158,10 @@ extern const char* tfx_glsl = " final_p.z = log2(1.0f + float(z)) / 32.0f;\n" " }\n" "\n" - " VSout.p = final_p;\n" + " //VSout_p = final_p;\n" " gl_Position = final_p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position\n" "#if VS_RTCOPY\n" - " VSout.tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5;\n" + " VSout_tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5;\n" "#endif\n" "\n" "\n" @@ -145,25 +169,25 @@ extern const char* tfx_glsl = " {\n" " if(VS_FST != 0)\n" " {\n" - " //VSout.t.xy = i_t * TextureScale;\n" - " VSout.t.xy = i_uv * TextureScale;\n" - " VSout.t.w = 1.0f;\n" + " //VSout_t.xy = i_t * TextureScale;\n" + " VSout_t.xy = i_uv * TextureScale;\n" + " VSout_t.w = 1.0f;\n" " }\n" " else\n" " {\n" - " //VSout.t.xy = i_t;\n" - " VSout.t.xy = i_st;\n" - " VSout.t.w = i_q;\n" + " //VSout_t.xy = i_t;\n" + " VSout_t.xy = i_st;\n" + " VSout_t.w = i_q;\n" " }\n" " }\n" " else\n" " {\n" - " VSout.t.xy = vec2(0.0f, 0.0f);\n" - " VSout.t.w = 1.0f;\n" + " VSout_t.xy = vec2(0.0f, 0.0f);\n" + " VSout_t.w = 1.0f;\n" " }\n" "\n" - " VSout.c = i_c;\n" - " VSout.t.z = i_f.r;\n" + " VSout_c = i_c;\n" + " VSout_t.z = i_f.r;\n" "}\n" "\n" "#endif\n" @@ -245,46 +269,50 @@ extern const char* tfx_glsl = " // right bottom => GSin[1];\n" " vertex rb = GSin[1];\n" " vertex lt = GSin[0];\n" + " vec4 rb_p = gl_in[1].gl_Position;\n" + " vec4 lb_p = gl_in[1].gl_Position;\n" + " vec4 rt_p = gl_in[1].gl_Position;\n" + " vec4 lt_p = gl_in[0].gl_Position;\n" "\n" - " lt.p.z = rb.p.z;\n" + " lt_p.z = rb_p.z;\n" " lt.t.zw = rb.t.zw;\n" "#if GS_IIP == 0\n" " lt.c = rb.c;\n" "#endif\n" "\n" " vertex lb = rb;\n" - " lb.p.x = lt.p.x;\n" + " lb_p.x = lt_p.x;\n" " lb.t.x = lt.t.x;\n" "\n" " vertex rt = rb;\n" - " rt.p.y = lt.p.y;\n" + " rt_p.y = lt_p.y;\n" " rt.t.y = lt.t.y;\n" "\n" " // Triangle 1\n" - " gl_Position = lt.p;\n" + " gl_Position = lt_p;\n" " GSout = lt;\n" " EmitVertex();\n" "\n" - " gl_Position = lb.p;\n" + " gl_Position = lb_p;\n" " GSout = lb;\n" " EmitVertex();\n" "\n" - " gl_Position = rt.p;\n" + " gl_Position = rt_p;\n" " GSout = rt;\n" " EmitVertex();\n" "\n" " EndPrimitive();\n" "\n" " // Triangle 2\n" - " gl_Position = lb.p;\n" + " gl_Position = lb_p;\n" " GSout = lb;\n" " EmitVertex();\n" "\n" - " gl_Position = rt.p;\n" + " gl_Position = rt_p;\n" " GSout = rt;\n" " EmitVertex();\n" "\n" - " gl_Position = rb.p;\n" + " gl_Position = rb_p;\n" " GSout = rb;\n" " EmitVertex();\n" "\n" @@ -297,15 +325,43 @@ extern const char* tfx_glsl = "#endif\n" "\n" "#ifdef FRAGMENT_SHADER\n" + "#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n" "layout(location = 0) in vertex PSin;\n" + "//#define PSin_p (PSin.p)\n" + "#define PSin_t (PSin.t)\n" + "#define PSin_tp (PSin.tp)\n" + "#define PSin_c (PSin.c)\n" + "#else\n" + "#ifdef DISABLE_SSO\n" + "in vec4 SHADERp;\n" + "in vec4 SHADERt;\n" + "in vec4 SHADERtp;\n" + "in vec4 SHADERc;\n" + "#else\n" + "//layout(location = 0) in vec4 SHADERp;\n" + "layout(location = 0) in vec4 SHADERt;\n" + "layout(location = 1) in vec4 SHADERtp;\n" + "layout(location = 2) in vec4 SHADERc;\n" + "#endif\n" + "//#define PSin_p SHADERp\n" + "#define PSin_t SHADERt\n" + "#define PSin_tp SHADERtp\n" + "#define PSin_c SHADERc\n" + "#endif\n" "\n" "// Same buffer but 2 colors for dual source blending\n" "layout(location = 0, index = 0) out vec4 SV_Target0;\n" "layout(location = 0, index = 1) out vec4 SV_Target1;\n" "\n" + "#ifdef DISABLE_GL42\n" + "uniform sampler2D TextureSampler;\n" + "uniform sampler2D PaletteSampler;\n" + "uniform sampler2D RTCopySampler;\n" + "#else\n" "layout(binding = 0) uniform sampler2D TextureSampler;\n" "layout(binding = 1) uniform sampler2D PaletteSampler;\n" "layout(binding = 2) uniform sampler2D RTCopySampler;\n" + "#endif\n" "\n" "#ifdef DISABLE_GL42\n" "layout(std140) uniform cb21\n" @@ -429,13 +485,12 @@ extern const char* tfx_glsl = "{\n" " vec4 c;\n" "\n" - " // XXX\n" - " // I think .a is related to 8bit texture in alpha channel\n" - " // Opengl is only 8 bits on red channel. Not sure exactly of the impact\n" - " c.x = sample_c(uv.xy).a;\n" - " c.y = sample_c(uv.zy).a;\n" - " c.z = sample_c(uv.xw).a;\n" - " c.w = sample_c(uv.zw).a;\n" + " // Dx used the alpha channel.\n" + " // Opengl is only 8 bits on red channel.\n" + " c.x = sample_c(uv.xy).r;\n" + " c.y = sample_c(uv.zy).r;\n" + " c.z = sample_c(uv.xw).r;\n" + " c.w = sample_c(uv.zw).r;\n" "\n" " return c * 255./256 + 0.5/256;\n" "}\n" @@ -498,14 +553,14 @@ extern const char* tfx_glsl = " if((PS_FMT & ~FMT_PAL) == FMT_24)\n" " {\n" " // FIXME GLSL any only support bvec so try to mix it with notEqual\n" - " bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) );\n" - " t.a = ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n" + " bvec3 rgb_check = notEqual( c[i].rgb, vec3(0.0f, 0.0f, 0.0f) );\n" + " c[i].a = ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n" " }\n" " else if((PS_FMT & ~FMT_PAL) == FMT_16)\n" " {\n" " // FIXME GLSL any only support bvec so try to mix it with notEqual\n" - " bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) );\n" - " t.a = t.a >= 0.5 ? TA.y : ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n" + " bvec3 rgb_check = notEqual( c[i].rgb, vec3(0.0f, 0.0f, 0.0f) );\n" + " c[i].a = c[i].a >= 0.5 ? TA.y : ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n" " }\n" " }\n" "\n" @@ -571,7 +626,7 @@ extern const char* tfx_glsl = "void datst()\n" "{\n" "#if PS_DATE > 0\n" - " float alpha = sample_rt(PSin.tp.xy).a;\n" + " float alpha = sample_rt(PSin_tp.xy).a;\n" " float alpha0x80 = 128. / 255;\n" "\n" " if (PS_DATE == 1 && alpha >= alpha0x80)\n" @@ -641,13 +696,13 @@ extern const char* tfx_glsl = "{\n" " datst();\n" "\n" - " vec4 t = sample_color(PSin.t.xy, PSin.t.w);\n" + " vec4 t = sample_color(PSin_t.xy, PSin_t.w);\n" "\n" - " vec4 c = tfx(t, PSin.c);\n" + " vec4 c = tfx(t, PSin_c);\n" "\n" " atst(c);\n" "\n" - " c = fog(c, PSin.t.z);\n" + " c = fog(c, PSin_t.z);\n" "\n" " if (PS_COLCLIP == 2)\n" " {\n" diff --git a/plugins/GSdx/stdafx.h b/plugins/GSdx/stdafx.h index cd4a62c7f5..d7d4c407ac 100644 --- a/plugins/GSdx/stdafx.h +++ b/plugins/GSdx/stdafx.h @@ -123,6 +123,11 @@ using namespace std; #ifdef _WINDOWS + #include + #include + #include + #include "GLLoader.h" + #include #include @@ -202,10 +207,9 @@ using namespace std; //#include //#include - #include #include - #include #include + #include "GLLoader.h" //using namespace __gnu_cxx; diff --git a/plugins/GSdx/vsprops/common.props b/plugins/GSdx/vsprops/common.props index 7ac9d55c40..eeb8133a91 100644 --- a/plugins/GSdx/vsprops/common.props +++ b/plugins/GSdx/vsprops/common.props @@ -14,12 +14,12 @@ Level4 ProgramDatabase 4996;4995;4324;4100;4101;4201;4556;%(DisableSpecificWarnings) - $(DXSDK_DIR)include;$(VTUNE_AMPLIFIER_XE_2013_DIR)include;%(AdditionalIncludeDirectories) + $(DXSDK_DIR)include;$(VTUNE_AMPLIFIER_XE_2013_DIR)include;$(SolutionDir)3rdparty;%(AdditionalIncludeDirectories) true - d3d11.lib;d3dx11.lib;d3d10_1.lib;d3dx10.lib;d3d9.lib;d3dx9.lib;dxgi.lib;dxguid.lib;winmm.lib;strmiids.lib;xinput.lib;%(AdditionalDependencies) - d3d9.dll;d3dx9_43.dll;d3d11.dll;d3dx11_43.dll;dxgi.dll;%(DelayLoadDLLs) + d3d11.lib;d3dx11.lib;d3d10_1.lib;d3dx10.lib;d3d9.lib;d3dx9.lib;dxgi.lib;dxguid.lib;winmm.lib;strmiids.lib;xinput.lib;opengl32.lib;%(AdditionalDependencies) + d3d9.dll;d3dx9_43.dll;d3d11.dll;d3dx11_43.dll;dxgi.dll;opengl32.dll;%(DelayLoadDLLs) true Windows false @@ -32,4 +32,4 @@ "$(SvnCommonDir)\vsprops\preBuild.cmd" "$(ProjectRootDir)" - \ No newline at end of file + diff --git a/plugins/GSdx/vsprops/common.vsprops b/plugins/GSdx/vsprops/common.vsprops index ab4c07482f..2919dbc907 100644 --- a/plugins/GSdx/vsprops/common.vsprops +++ b/plugins/GSdx/vsprops/common.vsprops @@ -9,7 +9,7 @@