diff --git a/res/gamedata/shaders/gl/accum_sun_far.ps b/res/gamedata/shaders/gl/accum_sun_far.ps index 0cbd77753be..c3db12d5490 100644 Binary files a/res/gamedata/shaders/gl/accum_sun_far.ps and b/res/gamedata/shaders/gl/accum_sun_far.ps differ diff --git a/res/gamedata/shaders/gl/accum_sun_far_msaa.ps b/res/gamedata/shaders/gl/accum_sun_far_msaa.ps index a074523cf85..47202351fee 100644 Binary files a/res/gamedata/shaders/gl/accum_sun_far_msaa.ps and b/res/gamedata/shaders/gl/accum_sun_far_msaa.ps differ diff --git a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps index 22216c9b517..2db07e0f5c7 100644 Binary files a/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps and b/res/gamedata/shaders/gl/accum_volumetric_sun_msaa0.ps differ diff --git a/res/gamedata/shaders/gl/copy.ps b/res/gamedata/shaders/gl/copy.ps index 39bc549e171..0a862763ff7 100644 Binary files a/res/gamedata/shaders/gl/copy.ps and b/res/gamedata/shaders/gl/copy.ps differ diff --git a/res/gamedata/shaders/gl/copy_p.ps b/res/gamedata/shaders/gl/copy_p.ps index a48a5910873..bc53d62c0e4 100644 Binary files a/res/gamedata/shaders/gl/copy_p.ps and b/res/gamedata/shaders/gl/copy_p.ps differ diff --git a/res/gamedata/shaders/gl/depth_downs.ps b/res/gamedata/shaders/gl/depth_downs.ps index 3cb386cb92b..2a5516f8c2f 100644 Binary files a/res/gamedata/shaders/gl/depth_downs.ps and b/res/gamedata/shaders/gl/depth_downs.ps differ diff --git a/res/gamedata/shaders/gl/iostructs/p_aa_aa_sun.h b/res/gamedata/shaders/gl/iostructs/p_aa_aa_sun.h index b03dd7f46f5..5010fefface 100644 --- a/res/gamedata/shaders/gl/iostructs/p_aa_aa_sun.h +++ b/res/gamedata/shaders/gl/iostructs/p_aa_aa_sun.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif layout(location = TEXCOORD0) in float2 p_aa_AA_sun_tc ; // TEXCOORD0; layout(location = TEXCOORD1) in float2 p_aa_AA_sun_unused ; // TEXCOORD1; diff --git a/res/gamedata/shaders/gl/iostructs/p_accum.h b/res/gamedata/shaders/gl/iostructs/p_accum.h index b6d69d6dee3..5fe8af2418b 100644 --- a/res/gamedata/shaders/gl/iostructs/p_accum.h +++ b/res/gamedata/shaders/gl/iostructs/p_accum.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif layout(location = TEXCOORD0) in float4 p_accum_omni_tc ; // TEXCOORD0; diff --git a/res/gamedata/shaders/gl/iostructs/p_bumped.h b/res/gamedata/shaders/gl/iostructs/p_bumped.h index 870dd42d66d..8006246bbaa 100644 --- a/res/gamedata/shaders/gl/iostructs/p_bumped.h +++ b/res/gamedata/shaders/gl/iostructs/p_bumped.h @@ -4,12 +4,6 @@ out vec4 SV_Target1; #ifndef GBUFFER_OPTIMIZATION out vec4 SV_Target2; #endif -#ifdef EXTEND_F_DEFFER -out int gl_SampleMask[]; -#endif -#ifdef MSAA_ALPHATEST_DX10_1_ATOC -in vec4 gl_FragCoord; -#endif #if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI) layout(location = TEXCOORD0) in float4 p_bumped_tcdh ; // TEXCOORD0; // Texture coordinates, w=sun_occlusion @@ -62,6 +56,6 @@ void main() SV_Target2 = O.C; #endif #ifdef EXTEND_F_DEFFER - gl_SampleMask[0] = O.mask; + gl_SampleMask[0] = int(O.mask); #endif } diff --git a/res/gamedata/shaders/gl/iostructs/p_combine.h b/res/gamedata/shaders/gl/iostructs/p_combine.h index 1a196e5e93d..9a51b47edf3 100644 --- a/res/gamedata/shaders/gl/iostructs/p_combine.h +++ b/res/gamedata/shaders/gl/iostructs/p_combine.h @@ -3,10 +3,6 @@ out vec4 SV_Target0; out vec4 SV_Target1; in vec4 gl_FragCoord; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif - struct _input { #ifdef USE_VTF diff --git a/res/gamedata/shaders/gl/iostructs/p_dumb.h b/res/gamedata/shaders/gl/iostructs/p_dumb.h index ef0378ee272..95cbe82776e 100644 --- a/res/gamedata/shaders/gl/iostructs/p_dumb.h +++ b/res/gamedata/shaders/gl/iostructs/p_dumb.h @@ -1,4 +1,3 @@ - out vec4 SV_Target; float4 _main (); diff --git a/res/gamedata/shaders/gl/iostructs/p_flat.h b/res/gamedata/shaders/gl/iostructs/p_flat.h index 2066d3afd0d..6186249e7d9 100644 --- a/res/gamedata/shaders/gl/iostructs/p_flat.h +++ b/res/gamedata/shaders/gl/iostructs/p_flat.h @@ -4,12 +4,6 @@ out vec4 SV_Target1; #ifndef GBUFFER_OPTIMIZATION out vec4 SV_Target2; #endif -#ifdef EXTEND_F_DEFFER -out int gl_SampleMask[]; -#endif -#ifdef MSAA_ALPHATEST_DX10_1_ATOC -in vec4 gl_FragCoord; -#endif #if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI) layout(location = TEXCOORD0) in float4 p_flat_tcdh ; // TEXCOORD0; // Texture coordinates, w=sun_occlusion @@ -58,6 +52,6 @@ void main() SV_Target2 = O.C; #endif #ifdef EXTEND_F_DEFFER - gl_SampleMask[0] = O.mask; + gl_SampleMask[0] = int(O.mask); #endif } diff --git a/res/gamedata/shaders/gl/iostructs/p_lod.h b/res/gamedata/shaders/gl/iostructs/p_lod.h index 47e2874e24f..b1d8645f551 100644 --- a/res/gamedata/shaders/gl/iostructs/p_lod.h +++ b/res/gamedata/shaders/gl/iostructs/p_lod.h @@ -5,13 +5,7 @@ out vec4 SV_Target1; #ifndef GBUFFER_OPTIMIZATION out vec4 SV_Target2; #endif // GBUFFER_OPTIMIZATION -#ifdef EXTEND_F_DEFFER -out int gl_SampleMask[]; -#endif // EXTEND_F_DEFFER -#ifdef MSAA_ALPHATEST_DX10_1_ATOC -in vec4 gl_FragCoord; -#endif // MSAA_ALPHATEST_DX10_1_ATOC -#endif // #endif +#endif // #endif struct v2p { @@ -52,7 +46,6 @@ void main() #else f_deffer O = _main (I); #endif // MSAA_ALPHATEST_DX10_1_ATOC - #endif // ATOC SV_Target0 = O.position; @@ -63,6 +56,6 @@ void main() SV_Target2 = O.C; #endif // GBUFFER_OPTIMIZATION #ifdef EXTEND_F_DEFFER - gl_SampleMask[0] = O.mask; + gl_SampleMask[0] = int(O.mask); #endif } diff --git a/res/gamedata/shaders/gl/iostructs/p_naa_aa_combine.h b/res/gamedata/shaders/gl/iostructs/p_naa_aa_combine.h index 236bdb6c674..02f0c04859e 100644 --- a/res/gamedata/shaders/gl/iostructs/p_naa_aa_combine.h +++ b/res/gamedata/shaders/gl/iostructs/p_naa_aa_combine.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif // GBUFFER_OPTIMIZATION -#ifdef USE_MSAA -out float gl_FragDepth; -#endif struct c2_out { diff --git a/res/gamedata/shaders/gl/iostructs/p_particle_deffer.h b/res/gamedata/shaders/gl/iostructs/p_particle_deffer.h index 93d9e0057d2..fdf81ca5ffe 100644 --- a/res/gamedata/shaders/gl/iostructs/p_particle_deffer.h +++ b/res/gamedata/shaders/gl/iostructs/p_particle_deffer.h @@ -1,15 +1,6 @@ out vec4 SV_Target0; out vec4 SV_Target1; -#ifndef GBUFFER_OPTIMIZATION -out vec4 SV_Target2; -#endif -#ifdef EXTEND_F_DEFFER -out int gl_SampleMask[]; -#endif -#ifdef MSAA_ALPHATEST_DX10_1_ATOC -in vec4 gl_FragCoord; -#endif struct p_particle { @@ -33,7 +24,7 @@ layout(location = TEXCOORD4) in float2 p_flat_lmh ; // TEXCOORD4; // lm-hemi #endif #ifdef MSAA_ALPHATEST_DX10_1_ATOC -f_deffer _main ( p_particle II, float4 pos2d ); +f_deffer _main ( p_particle II, float2 pos2d ); #else // MSAA_ALPHATEST_DX10_1_ATOC f_deffer _main ( p_particle II ); #endif // MSAA_ALPHATEST_DX10_1_ATOC @@ -66,6 +57,6 @@ void main() SV_Target2 = O.C; #endif #ifdef EXTEND_F_DEFFER - gl_SampleMask[0] = O.mask; + gl_SampleMask[0] = int(O.mask); #endif } diff --git a/res/gamedata/shaders/gl/iostructs/p_rain_apply.h b/res/gamedata/shaders/gl/iostructs/p_rain_apply.h index 0baaf163ebc..415d32e50da 100644 --- a/res/gamedata/shaders/gl/iostructs/p_rain_apply.h +++ b/res/gamedata/shaders/gl/iostructs/p_rain_apply.h @@ -1,14 +1,11 @@ out vec4 SV_Target; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif layout(location = TEXCOORD0) in float2 p_rain_tc ; // TEXCOORD0; layout(location = TEXCOORD1) in float2 p_rain_tcJ ; // TEXCOORD1; #ifdef MSAA_OPTIMIZATION -float4 _main ( float2 tc, float2 tcJ, uint iSample ); +float4 _main ( float2 tc, float2 tcJ, int iSample ); #else float4 _main ( float2 tc, float2 tcJ ); #endif diff --git a/res/gamedata/shaders/gl/iostructs/p_rain_patch.h b/res/gamedata/shaders/gl/iostructs/p_rain_patch.h index 91cfd604ce3..90ab08787bf 100644 --- a/res/gamedata/shaders/gl/iostructs/p_rain_patch.h +++ b/res/gamedata/shaders/gl/iostructs/p_rain_patch.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif layout(location = TEXCOORD0) in float2 p_rain_tc ; // TEXCOORD0; layout(location = TEXCOORD1) in float2 p_rain_tcJ ; // TEXCOORD1; @@ -19,7 +13,7 @@ float4 _main ( float2 tc, float2 tcJ, float4 Color, float4 pos2d ); #endif #else #ifdef MSAA_OPTIMIZATION -float4 _main ( float2 tc, float2 tcJ, uint iSample ); +float4 _main ( float2 tc, float2 tcJ, int iSample ); #else float4 _main ( float2 tc, float2 tcJ ); #endif diff --git a/res/gamedata/shaders/gl/iostructs/p_ssao_calc.h b/res/gamedata/shaders/gl/iostructs/p_ssao_calc.h index 12dbd2d115f..9c432f7b11e 100644 --- a/res/gamedata/shaders/gl/iostructs/p_ssao_calc.h +++ b/res/gamedata/shaders/gl/iostructs/p_ssao_calc.h @@ -1,10 +1,6 @@ out vec4 SV_Target; in vec4 gl_FragCoord; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif - struct _input { #ifdef USE_VTF diff --git a/res/gamedata/shaders/gl/iostructs/p_tl_sun.h b/res/gamedata/shaders/gl/iostructs/p_tl_sun.h index 0522a886d1e..c3b6f1ff0bc 100644 --- a/res/gamedata/shaders/gl/iostructs/p_tl_sun.h +++ b/res/gamedata/shaders/gl/iostructs/p_tl_sun.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif layout(location = TEXCOORD0) in float2 p_TL_Tex0 ; // TEXCOORD0; layout(location = COLOR) in float4 p_TL_Color ; // COLOR; diff --git a/res/gamedata/shaders/gl/iostructs/p_volume.h b/res/gamedata/shaders/gl/iostructs/p_volume.h index 42619d4a063..4c9fb2c61f7 100644 --- a/res/gamedata/shaders/gl/iostructs/p_volume.h +++ b/res/gamedata/shaders/gl/iostructs/p_volume.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif layout(location = TEXCOORD0) in float4 p_volume_tc ; // TEXCOORD0; #ifdef USE_SJITTER diff --git a/res/gamedata/shaders/gl/iostructs/p_volume_sun.h b/res/gamedata/shaders/gl/iostructs/p_volume_sun.h index cd918c95014..655bfb90b3c 100644 --- a/res/gamedata/shaders/gl/iostructs/p_volume_sun.h +++ b/res/gamedata/shaders/gl/iostructs/p_volume_sun.h @@ -1,11 +1,5 @@ out vec4 SV_Target; -#ifdef GBUFFER_OPTIMIZATION -in vec4 gl_FragCoord; -#endif // GBUFFER_OPTIMIZATION -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif // MSAA_OPTIMIZATION layout(location = TEXCOORD0) in float4 p_volume_tc; // TEXCOORD0; #ifdef USE_SJITTER diff --git a/res/gamedata/shaders/gl/iostructs/p_volumetric.h b/res/gamedata/shaders/gl/iostructs/p_volumetric.h index 488e1aea985..15f7e1a61a7 100644 --- a/res/gamedata/shaders/gl/iostructs/p_volumetric.h +++ b/res/gamedata/shaders/gl/iostructs/p_volumetric.h @@ -1,8 +1,6 @@ out vec4 SV_Target; -#ifdef MSAA_OPTIMIZATION -in int gl_SampleID; -#endif + struct v2p { diff --git a/res/gamedata/shaders/gl/mark_msaa_edges.ps b/res/gamedata/shaders/gl/mark_msaa_edges.ps index 34383fd00cd..d94e64414d4 100644 Binary files a/res/gamedata/shaders/gl/mark_msaa_edges.ps and b/res/gamedata/shaders/gl/mark_msaa_edges.ps differ diff --git a/res/gamedata/shaders/gl/rain_apply_gloss.ps b/res/gamedata/shaders/gl/rain_apply_gloss.ps index c4129747305..da8adfd68b7 100644 Binary files a/res/gamedata/shaders/gl/rain_apply_gloss.ps and b/res/gamedata/shaders/gl/rain_apply_gloss.ps differ diff --git a/res/gamedata/shaders/gl/rain_apply_normal.ps b/res/gamedata/shaders/gl/rain_apply_normal.ps index 3d7dcc9201f..3604bc5c512 100644 Binary files a/res/gamedata/shaders/gl/rain_apply_normal.ps and b/res/gamedata/shaders/gl/rain_apply_normal.ps differ diff --git a/res/gamedata/shaders/gl/shadow.h b/res/gamedata/shaders/gl/shadow.h index 036b8662471..5a47822349a 100644 --- a/res/gamedata/shaders/gl/shadow.h +++ b/res/gamedata/shaders/gl/shadow.h @@ -574,13 +574,12 @@ bool cheap_reject( float3 tc, inout bool full_light ) float4 plane1 = sm_minmax_gather( tc.xy, int2( 1,-1 ) ); float4 plane2 = sm_minmax_gather( tc.xy, int2( -1, 1 ) ); float4 plane3 = sm_minmax_gather( tc.xy, int2( 1, 1 ) ); - bool plane = all( greaterThanEqual( plane0, float4(0.0) )) && all(greaterThanEqual( plane1, float4(0.0) )) && all(greaterThanEqual( plane2, float4(0.0) )) && all(greaterThanEqual( plane3, float4(0.0) ) ); - + bool plane = all(greaterThanEqual( plane0, float4(0.0) )) && all(greaterThanEqual( plane1, float4(0.0) )) && all(greaterThanEqual( plane2, float4(0.0) )) && all(greaterThanEqual( plane3, float4(0.0) )); if( !plane ) // if there are no proper plane equations in the support region { - bool no_plane = all(lessThan( plane0, float4(0.0) )) && all(lessThan( plane1, float4(0.0) )) && all(lessThan( plane2, float4(0.0) )) && all(lessThan( plane3, float4(0.0) ) ); + bool no_plane = all(lessThan( plane0, float4(0.0) )) && all(lessThan( plane1, float4(0.0) )) && all(lessThan( plane2, float4(0.0) )) && all(lessThan( plane3, float4(0.0) )); float4 z = float4( tc.z - 0.0005 ); - bool reject = all( greaterThan( z, -plane0 )) && all(greaterThan( z, -plane1 )) && all(greaterThan( z, -plane2 )) && all(greaterThan( z, -plane3 ) ); + bool reject = all(greaterThan( z, -plane0 )) && all(greaterThan( z, -plane1 )) && all(greaterThan( z, -plane2 )) && all(greaterThan( z, -plane3 )); if( no_plane && reject ) { full_light = false; diff --git a/res/gamedata/shaders/gl/shared/waterconfig.h b/res/gamedata/shaders/gl/shared/waterconfig.h index 5f83a17d0aa..891790d9aa4 100644 --- a/res/gamedata/shaders/gl/shared/waterconfig.h +++ b/res/gamedata/shaders/gl/shared/waterconfig.h @@ -1,7 +1,6 @@ #ifndef _WATERCONFIG_H #define _WATERCONFIG_H -//настройки для: (1) //waterdistortion //waterdistortion2 @@ -20,7 +19,7 @@ //////////////////////////////////////////////////////////////////////////////// -- waters clear //////////////////////////////////////////////////////////////////////////////// -настройки для: + waterdistortion waterdistortion2 //////////////////////////////////////////////////////////////////////////////// @@ -32,7 +31,7 @@ #define W_DISTORT_AMP_1 (-1.75) //(-0.30) #define W_DISTORT_POWER (1.0) //(1.0) //////////////////////////////////////////////////////////////////////////////// -настройки для: + waterdistortion waterdistortion //////////////////////////////////////////////////////////////////////////////// diff --git a/res/gamedata/shaders/gl/ssao_blur.ps b/res/gamedata/shaders/gl/ssao_blur.ps index 7c29131226a..b525d9d641d 100644 Binary files a/res/gamedata/shaders/gl/ssao_blur.ps and b/res/gamedata/shaders/gl/ssao_blur.ps differ diff --git a/res/gamedata/shaders/gl/ssao_hdao.ps b/res/gamedata/shaders/gl/ssao_hdao.ps index 5fc325a8f78..77f27418e8c 100644 Binary files a/res/gamedata/shaders/gl/ssao_hdao.ps and b/res/gamedata/shaders/gl/ssao_hdao.ps differ diff --git a/src/Layers/xrRender/R_Backend.h b/src/Layers/xrRender/R_Backend.h index 9ab2b11c0fd..1e1226f526b 100644 --- a/src/Layers/xrRender/R_Backend.h +++ b/src/Layers/xrRender/R_Backend.h @@ -97,9 +97,12 @@ class ECORE_API CBackend ID3DRenderTargetView* pRT[4]; ID3DDepthStencilView* pZB; #elif defined(USE_OGL) + // TODO make it valid(?), set target as GL_NONE + ref_rt ref_invalid{}; + GLuint pFB; - GLuint pRT[4]; - GLuint pZB; + ref_rt* pRT[4] = {&ref_invalid, &ref_invalid, &ref_invalid, &ref_invalid}; + ref_rt* pZB = &ref_invalid; #else # error No graphics API selected or enabled! #endif @@ -274,13 +277,25 @@ class ECORE_API CBackend IC void set_ZB(ID3DDepthStencilView* ZB); IC ID3DRenderTargetView* get_RT(u32 ID = 0); IC ID3DDepthStencilView* get_ZB(); + IC void unset_RT(u32 ID) + { + set_RT(nullptr, ID); + } #elif defined(USE_OGL) IC void set_FB(GLuint FB = 0); - IC void set_RT(GLuint RT, u32 ID = 0); - IC void set_ZB(GLuint ZB); + IC void set_RT(const ref_rt& RT, u32 ID); + IC void unset_RT(u32 ID); + IC void set_ZB(const ref_rt& ZB); + IC void unset_ZB(); IC GLuint get_FB(); - IC GLuint get_RT(u32 ID = 0); - IC GLuint get_ZB(); + IC ref_rt& get_RT(u32 ID = 0); + IC ref_rt& get_ZB(); + + IC void ClearZB(const ref_rt& zb, float depth); + IC void ClearZB(const ref_rt& zb, float depth, u8 stencil); + IC bool ClearZBRect(const ref_rt& zb, float depth, size_t numRects, const Irect* rects); + IC bool ClearRTRect(const ref_rt& rt, const Fcolor& color, size_t numRects, const Irect* rects); + IC void ClearRT(ref_rt& rt, const Fcolor& color); #else # error No graphics API selected or enabled! #endif @@ -293,40 +308,17 @@ class ECORE_API CBackend IC bool ClearRTRect(ID3DRenderTargetView* rt, const Fcolor& color, size_t numRects, const Irect* rects); IC bool ClearZBRect(ID3DDepthStencilView* zb, float depth, size_t numRects, const Irect* rects); -#elif defined(USE_OGL) - IC void ClearRT(GLuint rt, const Fcolor& color); - - IC void ClearZB(GLuint zb, float depth); - IC void ClearZB(GLuint zb, float depth, u8 stencil); - - IC bool ClearRTRect(GLuint rt, const Fcolor& color, size_t numRects, const Irect* rects); - IC bool ClearZBRect(GLuint zb, float depth, size_t numRects, const Irect* rects); -#else -# error No graphics API selected or enabled! -#endif - ICF void ClearRT(ref_rt& rt, const Fcolor& color) { ClearRT(rt->pRT, color); } - ICF bool ClearRTRect(ref_rt& rt, const Fcolor& color, size_t numRects, const Irect* rects) - { - return ClearRTRect(rt->pRT, color, numRects, rects); - } - -#if defined(USE_OGL) - ICF void ClearZB(ref_rt& zb, float depth) { ClearZB(zb->pRT, depth);} - ICF void ClearZB(ref_rt& zb, float depth, u8 stencil) { ClearZB(zb->pRT, depth, stencil);} - ICF bool ClearZBRect(ref_rt& zb, float depth, size_t numRects, const Irect* rects) - { - return ClearZBRect(zb->pRT, depth, numRects, rects); - } -#elif defined(USE_DX11) ICF void ClearZB(ref_rt& zb, float depth) { ClearZB(zb->pZRT[context_id], depth); } ICF void ClearZB(ref_rt& zb, float depth, u8 stencil) { ClearZB(zb->pZRT[context_id], depth, stencil); } ICF bool ClearZBRect(ref_rt& zb, float depth, size_t numRects, const Irect* rects) { return ClearZBRect(zb->pZRT[context_id], depth, numRects, rects); } -#else -# error No graphics API selected or enabled! + ICF bool ClearRTRect(ref_rt& rt, const Fcolor& color, size_t numRects, const Irect* rects) + { + return ClearRTRect(rt->pRT, color, numRects, rects); + } #endif IC void set_Constants(R_constant_table* C); diff --git a/src/Layers/xrRender/R_Backend_DBG.cpp b/src/Layers/xrRender/R_Backend_DBG.cpp index 0f5dc039207..11511dae3fe 100644 --- a/src/Layers/xrRender/R_Backend_DBG.cpp +++ b/src/Layers/xrRender/R_Backend_DBG.cpp @@ -52,7 +52,7 @@ void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, u32 vcnt, u16* pIdx, RImplementation.Index.Unlock(count); } set_Geometry(vs_L); - set_RT(RImplementation.Target->get_base_rt()); + set_RT(RImplementation.Target->get_base_rt(), 0); RImplementation.rmNormal(RCache); set_Stencil(FALSE); Render(T, vBase, 0, vcnt, iBase, pcnt); @@ -70,7 +70,7 @@ void CBackend::dbg_Draw(D3DPRIMITIVETYPE T, FVF::L* pVerts, int pcnt) RImplementation.Vertex.Unlock(count, vs_L->vb_stride); } set_Geometry(vs_L); - set_RT(RImplementation.Target->get_base_rt()); + set_RT(RImplementation.Target->get_base_rt(), 0); RImplementation.rmFar(RCache); set_Stencil(FALSE); Render(T, vBase, pcnt); diff --git a/src/Layers/xrRender/R_Backend_Runtime.cpp b/src/Layers/xrRender/R_Backend_Runtime.cpp index 9167b4206ff..59662743807 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.cpp +++ b/src/Layers/xrRender/R_Backend_Runtime.cpp @@ -36,7 +36,7 @@ void CBackend::OnFrameBegin() #else set_FB(HW.pFB); #endif - set_RT(RImplementation.Target->get_base_rt()); + set_RT(RImplementation.Target->get_base_rt(), 0); set_ZB(RImplementation.Target->get_base_zb()); #endif diff --git a/src/Layers/xrRender/R_Backend_Runtime.h b/src/Layers/xrRender/R_Backend_Runtime.h index 90f54d5f0ab..2b77566f67b 100644 --- a/src/Layers/xrRender/R_Backend_Runtime.h +++ b/src/Layers/xrRender/R_Backend_Runtime.h @@ -60,27 +60,36 @@ IC const Fmatrix& CBackend::get_xform_view() { return xforms.get_V(); } IC const Fmatrix& CBackend::get_xform_project() { return xforms.get_P(); } #if defined(USE_DX11) IC ID3DRenderTargetView* CBackend::get_RT(u32 ID) -#elif defined(USE_OGL) -IC GLuint CBackend::get_RT(u32 ID) -#else -# error No graphics API selected or enabled! -#endif { VERIFY((ID >= 0) && (ID < 4)); return pRT[ID]; } - -#if defined(USE_DX11) -IC ID3DDepthStencilView* CBackend::get_ZB() #elif defined(USE_OGL) -IC GLuint CBackend::get_ZB() +IC ref_rt& CBackend::get_RT(u32 ID) +{ + VERIFY((ID >= 0) && (ID < 4)); + + return *pRT[ID]; +} #else # error No graphics API selected or enabled! #endif + +#if defined(USE_DX11) +IC ID3DDepthStencilView* CBackend::get_ZB() { return pZB; } +#elif defined(USE_OGL) +IC ref_rt& CBackend::get_ZB() +{ + return *pZB; +} +#else +# error No graphics API selected or enabled! +#endif + ICF void CBackend::set_States(SState* _state) { PGO(Msg("PGO:state_block")); diff --git a/src/Layers/xrRender/SH_RT.h b/src/Layers/xrRender/SH_RT.h index 0c174ab20d9..93d4898efa7 100644 --- a/src/Layers/xrRender/SH_RT.h +++ b/src/Layers/xrRender/SH_RT.h @@ -2,7 +2,10 @@ namespace xray::render::RENDER_NAMESPACE { -////////////////////////////////////////////////////////////////////////// +class CRT; +struct resptrcode_crt; +typedef resptr_core ref_rt; + class CRT : public xr_resource_named { public: @@ -25,7 +28,11 @@ class CRT : public xr_resource_named void set_slice_read(int slice); void set_slice_write(u32 context_id, int slice); +#ifdef USE_OGL + void resolve_into(ref_rt& destination) const; +#else void resolve_into(CRT& destination) const; // only RTs with same format supported +#endif public: #if defined(USE_DX11) @@ -63,7 +70,6 @@ struct resptrcode_crt : public resptr_base void create(LPCSTR Name, u32 w, u32 h, D3DFORMAT f, u32 SampleCount, u32 slices_num, Flags32 flags); void destroy() { _set(nullptr); } }; -typedef resptr_core ref_rt; /* // DX10 cut ////////////////////////////////////////////////////////////////////////// diff --git a/src/Layers/xrRender/blenders/blender_light_occq.cpp b/src/Layers/xrRender/blenders/blender_light_occq.cpp index 06eec0b3d9e..b0ab6bf0a40 100644 --- a/src/Layers/xrRender/blenders/blender_light_occq.cpp +++ b/src/Layers/xrRender/blenders/blender_light_occq.cpp @@ -42,9 +42,11 @@ void CBlender_light_occq::Compile(CBlender_Compile& C) C.r_Pass("stub_notransform_t", "dumb", false, FALSE, FALSE, FALSE); C.r_ColorWriteEnable(false, false, false, false); C.r_CullMode(D3DCULL_NONE); +#ifdef USE_DX11 if (RImplementation.o.msaa) C.r_Stencil(TRUE, D3DCMP_ALWAYS, 0x00, 0x7E, D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO); else +#endif { // Clear all bits except the last one C.r_Stencil(TRUE, D3DCMP_ALWAYS, 0x00, 0xFE, D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO, D3DSTENCILOP_ZERO); diff --git a/src/Layers/xrRender/dxEnvironmentRender.cpp b/src/Layers/xrRender/dxEnvironmentRender.cpp index d99d741cd87..6382fc788c8 100644 --- a/src/Layers/xrRender/dxEnvironmentRender.cpp +++ b/src/Layers/xrRender/dxEnvironmentRender.cpp @@ -264,9 +264,9 @@ void dxEnvironmentRender::RenderSky(CEnvironment& env) #ifdef USE_OGL // Sun must be rendered to generic0 only as it is done in DX if (!RImplementation.o.msaa) - RImplementation.Target->u_setrt(RCache, RImplementation.Target->rt_Generic_0, nullptr, nullptr, RImplementation.Target->rt_Base_Depth); + RImplementation.Target->u_setrtzb(RCache, RImplementation.Target->rt_Generic_0, RImplementation.Target->rt_Base_Depth); else - RImplementation.Target->u_setrt(RCache, RImplementation.Target->rt_Generic_0_r, nullptr, nullptr, RImplementation.Target->rt_MSAADepth); + RImplementation.Target->u_setrtzb(RCache, RImplementation.Target->rt_Generic_0_r, RImplementation.Target->rt_MSAADepth); #endif // USE_OGL // Sun @@ -288,9 +288,9 @@ void dxEnvironmentRender::RenderSky(CEnvironment& env) #ifdef USE_OGL // set low/hi RTs for clouds if (!RImplementation.o.msaa) - RImplementation.Target->u_setrt(RCache, RImplementation.Target->rt_Generic_0, RImplementation.Target->rt_Generic_1, nullptr, RImplementation.Target->rt_Base_Depth); + RImplementation.Target->u_setrtzb(RCache, RImplementation.Target->rt_Generic_0, RImplementation.Target->rt_Generic_1, RImplementation.Target->rt_Base_Depth); else - RImplementation.Target->u_setrt(RCache, RImplementation.Target->rt_Generic_0_r, RImplementation.Target->rt_Generic_1_r, nullptr, RImplementation.Target->rt_MSAADepth); + RImplementation.Target->u_setrtzb(RCache, RImplementation.Target->rt_Generic_0_r, RImplementation.Target->rt_Generic_1_r, RImplementation.Target->rt_MSAADepth); #endif // USE_OGL } diff --git a/src/Layers/xrRender/r__dsgraph_render.cpp b/src/Layers/xrRender/r__dsgraph_render.cpp index bebaf084036..9e93e182cf4 100644 --- a/src/Layers/xrRender/r__dsgraph_render.cpp +++ b/src/Layers/xrRender/r__dsgraph_render.cpp @@ -270,20 +270,22 @@ void R_dsgraph_structure::render_hud_ui() #if RENDER != R_R1 // Targets, use accumulator for temporary storage - const ref_rt rt_null; - cmd_list.set_RT(0, 1); - cmd_list.set_RT(0, 2); + cmd_list.unset_RT( 1); + cmd_list.unset_RT( 2); auto zb = RImplementation.Target->rt_Base_Depth; #if (RENDER == R_R3) || (RENDER == R_R4) || (RENDER==R_GL) if (RImplementation.o.msaa) zb = RImplementation.Target->rt_MSAADepth; #endif - +#ifdef USE_OGL + RImplementation.Target->u_setrtzb(cmd_list, RImplementation.o.albedo_wo ? RImplementation.Target->rt_Accumulator : RImplementation.Target->rt_Color, zb); +#else RImplementation.Target->u_setrt(cmd_list, RImplementation.o.albedo_wo ? RImplementation.Target->rt_Accumulator : RImplementation.Target->rt_Color, - rt_null, rt_null, zb); + nullptr, nullptr, zb); #endif // RENDER!=R_R1 +#endif levelHud->RenderActiveItemUI(); } diff --git a/src/Layers/xrRender/r__pixel_calculator.cpp b/src/Layers/xrRender/r__pixel_calculator.cpp index 9a7ce49ce23..5a1f7d20389 100644 --- a/src/Layers/xrRender/r__pixel_calculator.cpp +++ b/src/Layers/xrRender/r__pixel_calculator.cpp @@ -16,11 +16,12 @@ void r_pixel_calculator::begin() rt.create("$user$pixel_calculator_rt", rt_dimensions, rt_dimensions, HW.Caps.fTarget); zb.create("$user$pixel_calculator_zb", rt_dimensions, rt_dimensions, HW.Caps.fDepth, 1, { CRT::CreateSurface }); - RCache.set_RT(rt->pRT); #ifdef USE_DX11 + RCache.set_RT(rt->pRT); RCache.set_ZB(zb->pZRT[RCache.context_id]); #elif defined(USE_OGL) - RCache.set_ZB(zb->pRT); + RCache.set_RT(rt, 0); + RCache.set_ZB(zb); #endif R_ASSERT(Device.RenderBegin()); @@ -30,7 +31,7 @@ void r_pixel_calculator::end() { Device.RenderEnd(); - RCache.set_RT(RImplementation.Target->get_base_rt()); + RCache.set_RT(RImplementation.Target->get_base_rt(), 0); RCache.set_ZB(RImplementation.Target->get_base_zb()); zb = nullptr; diff --git a/src/Layers/xrRenderGL/glBufferUtils.cpp b/src/Layers/xrRenderGL/glBufferUtils.cpp index 0889426e5ae..4dd6ceba442 100644 --- a/src/Layers/xrRenderGL/glBufferUtils.cpp +++ b/src/Layers/xrRenderGL/glBufferUtils.cpp @@ -386,7 +386,7 @@ void VertexStreamBuffer::Destroy() return; glDeleteBuffers(1, &m_DeviceBuffer); - m_DeviceBuffer = 0; + m_DeviceBuffer = GL_NONE; } void* VertexStreamBuffer::Map(size_t offset, size_t size, bool flush /*= false*/) @@ -435,7 +435,7 @@ void IndexStreamBuffer::Destroy() return; glDeleteBuffers(1, &m_DeviceBuffer); - m_DeviceBuffer = 0; + m_DeviceBuffer = GL_NONE; } void* IndexStreamBuffer::Map(size_t offset, size_t size, bool flush /*= false*/) diff --git a/src/Layers/xrRenderGL/glHW.cpp b/src/Layers/xrRenderGL/glHW.cpp index 5e37a01d4e5..95ecfbf7648 100644 --- a/src/Layers/xrRenderGL/glHW.cpp +++ b/src/Layers/xrRenderGL/glHW.cpp @@ -125,6 +125,7 @@ void CHW::CreateDevice(SDL_Window* hWnd) if (glDebugMessageCallback) { CHK_GL(glEnable(GL_DEBUG_OUTPUT)); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); CHK_GL(glDebugMessageCallback((GLDEBUGPROC)OnDebugCallback, nullptr)); } #endif // DEBUG @@ -152,7 +153,9 @@ void CHW::CreateDevice(SDL_Window* hWnd) void CHW::DestroyDevice() { CHK_GL(glDeleteFramebuffers(1, &pFB)); - pFB = 0; + CHK_GL(glDeleteFramebuffers(1, &pResolveFB)); + pFB = GL_NONE; + pResolveFB = GL_NONE; const auto context = SDL_GL_GetCurrentContext(); if (context == m_context) @@ -170,7 +173,9 @@ void CHW::Reset() ZoneScoped; CHK_GL(glDeleteFramebuffers(1, &pFB)); + CHK_GL(glDeleteFramebuffers(1, &pResolveFB)); pFB = 0; + pResolveFB = 0; UpdateViews(); UpdateVSync(); @@ -224,9 +229,16 @@ int CHW::MakeContextCurrent(IRender::RenderContext context) const void CHW::UpdateViews() { - // Create the default framebuffer + /* + * mainly for resolve multisample fbo to simple fbo + */ + glGenFramebuffers(1, &pResolveFB); + CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, pResolveFB)); + glObjectLabel(GL_FRAMEBUFFER, pResolveFB, -1, "pResolveFBO"); + glGenFramebuffers(1, &pFB); CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, pFB)); + glObjectLabel(GL_FRAMEBUFFER, pFB, -1, "mainFBO"); BackBufferCount = 1; } diff --git a/src/Layers/xrRenderGL/glHW.h b/src/Layers/xrRenderGL/glHW.h index c0251c2f51b..a090078c0bc 100644 --- a/src/Layers/xrRenderGL/glHW.h +++ b/src/Layers/xrRenderGL/glHW.h @@ -52,6 +52,7 @@ class CHW u32 CurrentBackBuffer{}; GLuint pFB{}; + GLuint pResolveFB{}; SDL_Window* m_window{}; diff --git a/src/Layers/xrRenderGL/glR_Backend_Runtime.h b/src/Layers/xrRenderGL/glR_Backend_Runtime.h index fc37884139c..74625b7b108 100644 --- a/src/Layers/xrRenderGL/glR_Backend_Runtime.h +++ b/src/Layers/xrRenderGL/glR_Backend_Runtime.h @@ -23,37 +23,67 @@ IC void CBackend::set_FB(GLuint FB) PGO(Msg("PGO:set_FB")); pFB = FB; CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, pFB)); + + //nullptr is unset, but its actually unknown after switching FBO + std::fill(std::begin(pRT), std::end(pRT), &ref_invalid); + pZB = &ref_invalid; } } -IC void CBackend::set_RT(GLuint RT, u32 ID) +IC void CBackend::set_RT(const ref_rt& RT, u32 ID) { - if (RT != pRT[ID]) + VERIFY(RT != ref_invalid); + + if (!pRT[ID] || RT != *pRT[ID]) { PGO(Msg("PGO:setRT")); stat.target_rt++; - pRT[ID] = RT; - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ID, GL_TEXTURE_2D, RT, 0)); + pRT[ID] = const_cast(&RT); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ID, RT->target, RT->pRT, 0)); + } +} + +IC void CBackend::unset_RT(u32 ID) +{ + if (pRT[ID]) + { + PGO(Msg("PGO:unsetRT")); + stat.target_rt++; + pRT[ID] = nullptr; + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ID, GL_TEXTURE_2D, GL_NONE, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ID, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, 0)); } } -IC void CBackend::set_ZB(GLuint ZB) +IC void CBackend::set_ZB(const ref_rt& ZB) { - if (ZB != pZB) + VERIFY(ZB != ref_invalid); + + if (!pZB || ZB != *pZB) { PGO(Msg("PGO:setZB")); stat.target_zb++; - pZB = ZB; - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, ZB, 0)); + pZB = const_cast(&ZB); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, ZB->target, ZB->pZRT, 0)); } } -IC void CBackend::ClearRT(GLuint rt, const Fcolor& color) +IC void CBackend::unset_ZB() { - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt, 0)); + if (pZB) + { + PGO(Msg("PGO:setZB")); + stat.target_zb++; + pZB = nullptr; + //@TODO: track what texture we used + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, GL_NONE, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, 0)); + } +} + +IC void CBackend::ClearRT(ref_rt& rt, const Fcolor& color) +{ + set_RT(rt, 0); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClearColor(color.r, color.g, color.b, color.a); @@ -61,11 +91,9 @@ IC void CBackend::ClearRT(GLuint rt, const Fcolor& color) CHK_GL(glClear(GL_COLOR_BUFFER_BIT)); } -IC void CBackend::ClearZB(GLuint zb, float depth) +IC void CBackend::ClearZB(const ref_rt& zb, float depth) { - VERIFY(pZB == zb); // do not allow to clear unbound depth - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, zb, 0)); + set_ZB(zb); glDepthMask(GL_TRUE); glClearDepthf(depth); @@ -73,11 +101,9 @@ IC void CBackend::ClearZB(GLuint zb, float depth) CHK_GL(glClear(GL_DEPTH_BUFFER_BIT)); } -IC void CBackend::ClearZB(GLuint zb, float depth, u8 stencil) +IC void CBackend::ClearZB(const ref_rt& zb, float depth, u8 stencil) { - VERIFY(pZB == zb); // do not allow to clear unbound depth - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, zb, 0)); + set_ZB(zb); glDepthMask(GL_TRUE); glClearDepthf(depth); @@ -88,10 +114,9 @@ IC void CBackend::ClearZB(GLuint zb, float depth, u8 stencil) CHK_GL(glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); } -IC bool CBackend::ClearRTRect(GLuint rt, const Fcolor& color, size_t numRects, const Irect* rects) +IC bool CBackend::ClearRTRect(const ref_rt& rt, const Fcolor& color, size_t numRects, const Irect* rects) { - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt, 0)); + set_RT(rt, 0); CHK_GL(glEnable(GL_SCISSOR_TEST)); @@ -116,11 +141,9 @@ IC bool CBackend::ClearRTRect(GLuint rt, const Fcolor& color, size_t numRects, c return true; } -IC bool CBackend::ClearZBRect(GLuint zb, float depth, size_t numRects, const Irect* rects) +IC bool CBackend::ClearZBRect(const ref_rt& zb, float depth, size_t numRects, const Irect* rects) { - // TODO: OGL: Implement support for multi-sampled render targets - CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, zb, 0)); - + set_ZB(zb); CHK_GL(glEnable(GL_SCISSOR_TEST)); for (size_t i = 0; i < numRects; ++i, ++rects) @@ -491,6 +514,7 @@ IC void CBackend::set_Constants(R_constant_table* C) if (Cs->handler) Cs->handler->setup(*this, &*Cs); } +//@TODO: get rid of unused ref_rt's void CBackend::set_pass_targets(const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& zb) { if (_1) @@ -511,10 +535,23 @@ void CBackend::set_pass_targets(const ref_rt& _1, const ref_rt& _2, const ref_rt (GLenum)(_3 ? GL_COLOR_ATTACHMENT2 : GL_NONE) }; - set_RT(_1 ? _1->pRT : 0, 0); - set_RT(_2 ? _2->pRT : 0, 1); - set_RT(_3 ? _3->pRT : 0, 2); - set_ZB(zb ? zb->pZRT : 0); + if (_1) + set_RT(_1, 0); + else + unset_RT(0); + + if (_2) + set_RT(_2, 1); + else + unset_RT(1); + if (_3) + set_RT(_3 , 2); + else + unset_RT(2); + if (zb) + set_ZB(zb); + else + unset_ZB(); [[maybe_unused]] GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); VERIFY(status == GL_FRAMEBUFFER_COMPLETE); diff --git a/src/Layers/xrRenderGL/glSH_RT.cpp b/src/Layers/xrRenderGL/glSH_RT.cpp index 5d967334bbc..61845c5ebcd 100644 --- a/src/Layers/xrRenderGL/glSH_RT.cpp +++ b/src/Layers/xrRenderGL/glSH_RT.cpp @@ -52,6 +52,7 @@ void CRT::create(LPCSTR Name, u32 w, u32 h, D3DFORMAT f, u32 SampleCount /*= 1*/ target = (SampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; glGenTextures(1, &pRT); CHK_GL(glBindTexture(target, pRT)); + glObjectLabel(GL_TEXTURE, pRT, -1, Name); if (SampleCount > 1) CHK_GL(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SampleCount, glTextureUtils::ConvertTextureFormat(fmt), w, h, GL_FALSE)); @@ -85,21 +86,43 @@ void CRT::reset_end() create(cName.c_str(), dwWidth, dwHeight, fmt, sampleCount, { dwFlags }); } -void CRT::resolve_into(CRT& destination) const +void CRT::resolve_into(ref_rt& destination) const { - glReadBuffer(GL_COLOR_ATTACHMENT0); - glDrawBuffer(GL_COLOR_ATTACHMENT1); - - constexpr GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; - RCache.set_RT(pRT, 0); - RCache.set_RT(destination.pRT, 1); - - [[maybe_unused]] GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - VERIFY(status == GL_FRAMEBUFFER_COMPLETE); - CHK_GL(glDrawBuffers(std::size(buffers), buffers)); - - CHK_GL(glBlitFramebuffer(0, 0, dwWidth, dwHeight, 0, 0, destination.dwWidth, destination.dwHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST)); + PIX_EVENT(resolve_into); + + auto actualFB = RCache.get_FB(); + RCache.set_FB(HW.pResolveFB); + //CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, HW.pResolveFB)); + CHK_GL(glDisable(GL_DEPTH_TEST)); + CHK_GL(glDisable(GL_STENCIL_TEST)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, pRT, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_NONE, GL_NONE, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_NONE, GL_NONE, 0)); + CHK_GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0)); + VERIFY(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + //Resolve Screen + RCache.set_FB(actualFB); + //CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, actualFB)); + CHK_GL(glDisable(GL_DEPTH_TEST)); + CHK_GL(glDisable(GL_STENCIL_TEST)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destination->target, destination->pRT, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_NONE, GL_NONE, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_NONE, GL_NONE, 0)); + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_NONE, GL_NONE, 0)); + VERIFY(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + //CHK_GL(glBindFramebuffer(GL_FRAMEBUFFER, HW.pResolveFB)); + RCache.set_FB(HW.pResolveFB); // hm??? + + CHK_GL(glBindFramebuffer(GL_READ_FRAMEBUFFER, HW.pResolveFB)); + CHK_GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, actualFB)); + + CHK_GL(glBlitFramebuffer(0, 0, dwWidth, dwHeight, 0, 0, destination->dwWidth, destination->dwHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST)); + + CHK_GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE, 0)); + + RCache.set_FB(actualFB); } void resptrcode_crt::create(LPCSTR Name, u32 w, u32 h, D3DFORMAT f, u32 SampleCount /*= 1*/, u32 slices_num /*=1*/, Flags32 flags /*= {}*/) diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget.h b/src/Layers/xrRenderPC_GL/gl_rendertarget.h index fe05b0c1e90..6101442eb54 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget.h +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget.h @@ -220,16 +220,18 @@ class CRenderTarget void accum_volumetric_geom_create(); void accum_volumetric_geom_destroy(); - GLuint get_base_rt() { return rt_Base[HW.CurrentBackBuffer]->pRT; } - GLuint get_base_zb() { return rt_Base_Depth->pZRT; } + [[nodiscard]] ref_rt& get_base_rt() { return rt_Base[HW.CurrentBackBuffer]; } + [[nodiscard]] const ref_rt& get_base_zb() const { return rt_Base_Depth; } - void u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb); - void u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _zb); - void u_setrt(CBackend& cmd_list, u32 W, u32 H, GLuint _1, GLuint _2, GLuint _3, GLuint zb); - void u_setrt(CBackend& cmd_list, u32 W, u32 H, GLuint _1, GLuint _2, GLuint _3, const ref_rt& _zb) - { - u_setrt(cmd_list, W, H, _1, _2, _3, _zb ? _zb->pZRT : 0); - } +private: + template + void u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb); +public: + void u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb); + void u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _zb); + void u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _zb); + void u_setrt_(CBackend& cmd_list, const ref_rt& _1); + void u_set_zb(CBackend& cmd_list, const ref_rt& _zb); void u_stencil_optimize(CBackend& cmd_list, eStencilOptimizeMode eSOM = SO_Light); void u_compute_texgen_screen(CBackend& cmd_list, Fmatrix& dest); diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_accum_direct.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_accum_direct.cpp index b740a257096..03a4ec16d06 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_accum_direct.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_accum_direct.cpp @@ -4,12 +4,11 @@ namespace xray::render::RENDER_NAMESPACE { -////////////////////////////////////////////////////////////////////////// // tables to calculate view-frustum bounds in world space // note: D3D uses [0..1] range for Z namespace accum_direct { -static Fvector3 corners[8] = +static const Fvector3 corners[8] = { { -1, -1, 0.7f }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, 0.7f }, @@ -17,7 +16,7 @@ static Fvector3 corners[8] = { +1, -1, +1 }, { +1, -1, 0.7f } }; -static u16 facetable[16][3] = +static const u16 facetable[16][3] = { { 3, 2, 1 }, { 3, 1, 0 }, @@ -96,41 +95,14 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; Fvector dir = L_dir; dir.normalize().mul(-_sqrt(intensity + EPS)); - RCache.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker + ref_shader shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + RCache.set_Element(shader_accum_mask->E[SE_MASK_DIRECT]); // masker RCache.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.f); - // if (stencil>=1 && aref_pass) stencil = light_id - // Done in blender! - // RCache.set_ColorWriteEnable (FALSE ); - if (!RImplementation.o.msaa) - { - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel rendering // checked Holger - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, + D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - // per sample rendering - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_mask_msaa[0]->E[SE_MASK_DIRECT]); // masker - RCache.set_CullMode(CULL_NONE); - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - } } // recalculate d_Z, to perform depth-clipping @@ -228,10 +200,6 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) // Fill vertex buffer FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - //pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); pv++; - //pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); pv++; - //pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); pv++; - //pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); pv++; pv->set(-1, -1, d_Z, d_W, C, 0, 0, 0, 0); pv++; pv->set(-1, 1, d_Z, d_W, C, 0, 1, 0, scale_X); @@ -244,7 +212,8 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) RCache.set_Geometry(g_combine_2UV); // setup - RCache.set_Element(s_accum_direct->E[uiElementIndex]); + ref_shader shader_accum_direct = RImplementation.o.msaa ? s_accum_direct_msaa[0] : s_accum_direct; + RCache.set_Element(shader_accum_direct->E[uiElementIndex]); RCache.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); RCache.set_c("m_shadow", m_shadow); @@ -270,60 +239,10 @@ void CRenderTarget::accum_direct(CBackend& cmd_list, u32 sub_phase) Device.mFullTransform.transform(center_pt); zMax = center_pt.z; - // TODO: DX11: Check if DX11 has analog for NV DBT - // if (u_DBT_enable(zMin,zMax)) { - // z-test always - // RCache.set_ZFunc(D3DCMP_ALWAYS); - // HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - // } - - // Fetch4 : enable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET4 MAKEFOURCC('G','E','T','4') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 ); - // } - - // setup stencil - if (!RImplementation.o.msaa) - { - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_direct_msaa[0]->E[uiElementIndex]); - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0xff, 0x00); - RCache.set_CullMode(CULL_NONE); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - } - - // Fetch4 : disable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET1 MAKEFOURCC('G','E','T','1') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1 ); - // } - - // TODO: DX11: Check if DX11 has analog for NV DBT - // disable depth bounds - // u_DBT_disable (); + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - // Igor: draw volumetric here - // if (ps_r2_ls_flags.test(R2FLAG_SUN_SHAFTS)) + // Draw volumetric here if (RImplementation.o.advancedpp && (ps_r_sun_shafts > 0)) accum_direct_volumetric(sub_phase, Offset, m_shadow); } @@ -389,41 +308,13 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; Fvector dir = L_dir; dir.normalize().mul(-_sqrt(intensity + EPS)); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker + ref_shader shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_DIRECT]); // masker cmd_list.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.f); - // if (stencil>=1 && aref_pass) stencil = light_id - // Done in blender! - // RCache.set_ColorWriteEnable (FALSE ); - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel rendering // checked Holger - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample rendering - if (RImplementation.o.msaa_opt) - { - cmd_list.set_Element(s_accum_mask_msaa[0]->E[SE_MASK_DIRECT]); // masker - cmd_list.set_CullMode(CULL_NONE); - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - } + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, + D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); + cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } // recalculate d_Z, to perform depth-clipping @@ -444,22 +335,8 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat cmd_list.set_CullMode(CULL_CCW); //****************************************************************** cmd_list.set_ColorWriteEnable(); - // texture adjustment matrix - // float fTexelOffs = (.5f / float(RImplementation.o.smapsize)); - // float fRange = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_scale:ps_r2_sun_depth_far_scale; - // float fBias = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias; - // Fmatrix m_TexelAdjust = - //{ - // 0.5f, 0.0f, 0.0f, 0.0f, - // 0.0f, 0.5f, 0.0f, 0.0f, - // 0.0f, 0.0f, 0.5f * fRange, 0.0f, - // 0.5f + fTexelOffs, 0.5f + fTexelOffs, 0.5f + fBias, 1.0f - //}; float fRange = (SE_SUN_NEAR == sub_phase) ? ps_r2_sun_depth_near_scale : ps_r2_sun_depth_far_scale; - // float fBias = (SE_SUN_NEAR==sub_phase)?ps_r2_sun_depth_near_bias:ps_r2_sun_depth_far_bias; - // TODO: DX11: Remove this when fix inverse culling for far region - // float fBias = (SE_SUN_NEAR==sub_phase)?(-ps_r2_sun_depth_near_bias):ps_r2_sun_depth_far_bias; - Fmatrix m_TexelAdjust = + const Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, @@ -558,7 +435,8 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat cmd_list.set_Geometry(g_combine_cuboid); // setup - cmd_list.set_Element(s_accum_direct->E[uiElementIndex]); + ref_shader shader_accum_direct = RImplementation.o.msaa ? s_accum_direct_msaa[0] : s_accum_direct; + cmd_list.set_Element(shader_accum_direct->E[uiElementIndex]); cmd_list.set_c("m_texgen", m_Texgen); cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); @@ -600,20 +478,6 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat Device.mFullTransform.transform(center_pt); zMax = center_pt.z; - // TODO: DX11: Check if DX11 has analog for NV DBT - // if (u_DBT_enable(zMin,zMax)) { - // z-test always - // RCache.set_ZFunc(D3DCMP_ALWAYS); - // HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - // } - - // Fetch4 : enable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET4 MAKEFOURCC('G','E','T','4') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 ); - // } - // Enable Z function only for near and middle cascades, the far one is restricted by only stencil. if ((SE_SUN_NEAR == sub_phase || SE_SUN_MIDDLE == sub_phase)) cmd_list.set_ZFunc(D3DCMP_GREATEREQUAL); @@ -631,59 +495,10 @@ void CRenderTarget::accum_direct_cascade(CBackend& cmd_list, u32 sub_phase, Fmat st_pass = D3DSTENCILOP_KEEP; } - // setup stencil - if (!RImplementation.o.msaa) - { - // RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00); - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, st_mask, - D3DSTENCILOP_KEEP, st_pass, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - } - else - { - // per pixel - // RCache.set_Stencil (TRUE,D3DCMP_EQUAL,dwLightMarkerID,0xff,0x00); - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, st_mask, - D3DSTENCILOP_KEEP, st_pass, D3DSTENCILOP_KEEP); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - - // per sample - if (RImplementation.o.msaa_opt) - { - cmd_list.set_Element(s_accum_direct_msaa[0]->E[uiElementIndex]); - - if ((SE_SUN_NEAR == sub_phase || SE_SUN_MIDDLE == sub_phase)) - cmd_list.set_ZFunc(D3DCMP_GREATEREQUAL); - else if (!ps_r2_ls_flags_ext.is(R2FLAGEXT_SUN_ZCULLING)) - cmd_list.set_ZFunc(D3DCMP_ALWAYS); - else - cmd_list.set_ZFunc(D3DCMP_LESS); - - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0xff, st_mask, - D3DSTENCILOP_KEEP, st_pass, D3DSTENCILOP_KEEP); - cmd_list.set_CullMode(CULL_NONE); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - } + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, st_mask,D3DSTENCILOP_KEEP, st_pass, D3DSTENCILOP_KEEP); + cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - // Fetch4 : disable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET1 MAKEFOURCC('G','E','T','1') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1 ); - // } - - // TODO: DX11: Check if DX11 has analog for NV DBT - // disable depth bounds - // u_DBT_disable (); - - // Igor: draw volumetric here - // if (ps_r2_ls_flags.test(R2FLAG_SUN_SHAFTS)) + // Draw volumetric here if (RImplementation.o.advancedpp && (ps_r_sun_shafts > 0) && sub_phase == SE_SUN_FAR) accum_direct_volumetric(sub_phase, Offset, m_shadow); } @@ -695,7 +510,7 @@ void CRenderTarget::accum_direct_blend(CBackend& cmd_list) // blend-copy if (!RImplementation.o.fp16_blend) { - u_setrt(RCache, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); + u_setrtzb(RCache, rt_Accumulator, rt_MSAADepth); // TODO: DX11: remove half pixel offset // Common calc for quad-rendering @@ -710,10 +525,6 @@ void CRenderTarget::accum_direct_blend(CBackend& cmd_list) // Fill vertex buffer FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - //pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y, p0.x, p1.y); pv++; - //pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y, p0.x, p0.y); pv++; - //pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y, p1.x, p1.y); pv++; - //pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y, p1.x, p0.y); pv++; pv->set(-1, -1, d_Z, d_W, C, 0, 0, 0, 0); pv++; pv->set(-1, 1, d_Z, d_W, C, 0, 1, 0, 1); @@ -724,31 +535,10 @@ void CRenderTarget::accum_direct_blend(CBackend& cmd_list) pv++; RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); RCache.set_Geometry(g_combine_2UV); - RCache.set_Element(s_accum_mask->E[SE_MASK_ACCUM_2D]); - if (!RImplementation.o.msaa) - { - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_mask_msaa[0]->E[SE_MASK_ACCUM_2D]); - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else // checked Holger - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - } + ref_shader shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + RCache.set_Element(shader_accum_mask->E[SE_MASK_ACCUM_2D]); // masker + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } // dwLightMarkerID += 2; increment_light_marker(RCache); @@ -764,7 +554,7 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) return; } phase_accumulator(RCache); - u_setrt(RCache, rt_Generic_0_r, nullptr, nullptr, rt_MSAADepth); + u_setrtzb(RCache, rt_Generic_0_r, rt_MSAADepth); // *** assume accumulator setted up *** light* fuckingsun = (light*)RImplementation.Lights.sun._get(); @@ -811,41 +601,12 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) float intensity = 0.3f * fuckingsun->color.r + 0.48f * fuckingsun->color.g + 0.22f * fuckingsun->color.b; Fvector dir = L_dir; dir.normalize().mul(-_sqrt(intensity + EPS)); - RCache.set_Element(s_accum_mask->E[SE_MASK_DIRECT]); // masker + ref_shader shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + RCache.set_Element(shader_accum_mask->E[SE_MASK_DIRECT]); // masker RCache.set_c("Ldynamic_dir", dir.x, dir.y, dir.z, 0.f); - // if (stencil>=1 && aref_pass) stencil = light_id - // Done in blender! - // RCache.set_ColorWriteEnable (FALSE ); - if (!RImplementation.o.msaa) - { - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_mask_msaa[0]->E[SE_MASK_DIRECT]); // masker - RCache.set_Stencil(TRUE, D3DCMP_LESS, dwLightMarkerID, 0x81, 0x7f, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - RCache.set_CullMode(CULL_NONE); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, - D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); - } + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE, D3DSTENCILOP_KEEP); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } // recalculate d_Z, to perform depth-clipping @@ -860,7 +621,7 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) // Perform lighting { - u_setrt(RCache, rt_Generic_0_r, nullptr, nullptr, rt_MSAADepth); // ensure RT is set + u_setrtzb(RCache, rt_Generic_0_r, rt_MSAADepth); // ensure RT is set RCache.set_CullMode(CULL_NONE); RCache.set_ColorWriteEnable(); @@ -906,10 +667,6 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) // Fill vertex buffer FVF::TL2uv* pv = (FVF::TL2uv*)RImplementation.Vertex.Lock(4, g_combine_2UV->vb_stride, Offset); - //pv->set (EPS, float(_h+EPS), d_Z, d_W, C, p0.x, p1.y, j0.x, j1.y); pv++; - //pv->set (EPS, EPS, d_Z, d_W, C, p0.x, p0.y, j0.x, j0.y); pv++; - //pv->set (float(_w+EPS), float(_h+EPS), d_Z, d_W, C, p1.x, p1.y, j1.x, j1.y); pv++; - //pv->set (float(_w+EPS), EPS, d_Z, d_W, C, p1.x, p0.y, j1.x, j0.y); pv++; pv->set(-1, -1, d_Z, d_W, C, 0, 0, 0, 0); pv++; pv->set(-1, 1, d_Z, d_W, C, 0, 1, 0, scale_X); @@ -922,39 +679,16 @@ void CRenderTarget::accum_direct_f(CBackend& cmd_list, u32 sub_phase) RCache.set_Geometry(g_combine_2UV); // setup - RCache.set_Element(s_accum_direct->E[sub_phase]); + ref_shader shader_accum_direct = RImplementation.o.msaa ? s_accum_direct_msaa[0] : s_accum_direct; + RCache.set_Element(shader_accum_direct->E[sub_phase]); RCache.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); RCache.set_c("m_shadow", m_shadow); - if (!RImplementation.o.msaa) - { - // setup stencil - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample // checked Holger - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_direct_msaa[0]->E[sub_phase]); - RCache.set_CullMode(CULL_NONE); - RCache.set_Stencil(TRUE, D3DCMP_LESS, dwLightMarkerID | 0x80, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - } + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - // Igor: draw volumetric here + // Draw volumetric here // accum_direct_volumetric (sub_phase, Offset); } } @@ -1061,36 +795,13 @@ void CRenderTarget::accum_direct_lum(CBackend& cmd_list) RCache.set_Geometry(g_aa_AA); // setup - RCache.set_Element(s_accum_direct->E[SE_SUN_LUMINANCE]); + ref_shader shader_accum_direct = RImplementation.o.msaa ? s_accum_direct_msaa[0] : s_accum_direct; + RCache.set_Element(shader_accum_direct->E[SE_SUN_LUMINANCE]); RCache.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); RCache.set_c("Ldynamic_color", L_clr.x, L_clr.y, L_clr.z, L_spec); - if (!RImplementation.o.msaa) - { - // setup stencil - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - // per pixel - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_direct_msaa[0]->E[SE_SUN_LUMINANCE]); - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0xff, 0x00); - RCache.set_CullMode(CULL_NONE); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - } + RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } void CRenderTarget::accum_direct_volumetric(u32 sub_phase, const u32 Offset, const Fmatrix& mShadow) @@ -1111,11 +822,11 @@ void CRenderTarget::accum_direct_volumetric(u32 sub_phase, const u32 Offset, con RCache.set_ColorWriteEnable(); - ref_selement Element = s_accum_direct_volumetric->E[0]; + ref_selement Element = RImplementation.o.msaa ? s_accum_direct_volumetric_msaa[0]->E[0] : s_accum_direct_volumetric->E[0]; - const bool useMinMaxSMThisFrame = use_minmax_sm_this_frame(); + const bool useMinMaxSMThisFrame = !RImplementation.o.msaa && use_minmax_sm_this_frame(); // if ( (sub_phase==SE_SUN_NEAR) && use_minmax_sm_this_frame()) - if (useMinMaxSMThisFrame) + if (useMinMaxSMThisFrame && !RImplementation.o.msaa) Element = s_accum_direct_volumetric_minmax->E[0]; // Assume everything was recalculated before this call by accum_direct @@ -1154,7 +865,7 @@ void CRenderTarget::accum_direct_volumetric(u32 sub_phase, const u32 Offset, con float _h = float(Device.dwHeight); float o_w = (.5f / _w); float o_h = (.5f / _h); - Fmatrix m_TexelAdjust = + const Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, @@ -1176,10 +887,7 @@ void CRenderTarget::accum_direct_volumetric(u32 sub_phase, const u32 Offset, con } else { - if (RImplementation.o.oldshadowcascades) - zMin = ps_r2_sun_near; - else - zMin = 0; /////***************************************************************************************** + zMin = RImplementation.o.oldshadowcascades ? ps_r2_sun_near : 0; zMax = ps_r2_sun_far; } @@ -1194,81 +902,17 @@ void CRenderTarget::accum_direct_volumetric(u32 sub_phase, const u32 Offset, con Device.mFullTransform.transform(center_pt); zMax = center_pt.z; - // TODO: DX11: Check if DX11 has analog for NV DBT - // if (u_DBT_enable(zMin,zMax)) { - // z-test always - // RCache.set_ZFunc(D3DCMP_ALWAYS); - // HW.pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - // } - // else { - // TODO: DX11: Implement via different passes if (SE_SUN_NEAR == sub_phase) RCache.set_ZFunc(D3DCMP_GREATER); else RCache.set_ZFunc(D3DCMP_ALWAYS); } - // Fetch4 : enable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET4 MAKEFOURCC('G','E','T','4') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 ); - // } - - // setup stencil: we have to draw to both lit and unlit pixels - // RCache.set_Stencil (TRUE,D3DCMP_LESSEQUAL,dwLightMarkerID,0xff,0x00); - // if( ! RImplementation.o.msaa ) - { - if (RImplementation.o.oldshadowcascades) - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - else - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); - } - /*else - { - // per pixel + if (RImplementation.o.oldshadowcascades) RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - - // per sample - if (RImplementation.o.msaa_opt) - { - RCache.set_Element(s_accum_direct_volumetric_msaa[0]->E[0]); - RCache.set_Stencil(TRUE, D3DCMP_ALWAYS, 0xff, 0xff, 0xff); - if (SE_SUN_NEAR == sub_phase) - RCache.set_ZFunc(D3DCMP_GREATER); - else - RCache.set_ZFunc(D3DCMP_LESSEQUAL); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) - { - RCache.set_Element(s_accum_direct_volumetric_msaa[i]->E[0]); - StateManager.SetSampleMask(u32(1) << i); - RCache.set_Stencil(TRUE, D3DCMP_ALWAYS, 0xff, 0xff, 0xff); - if (SE_SUN_NEAR == sub_phase) - RCache.set_ZFunc(D3DCMP_GREATER); - else - RCache.set_ZFunc(D3DCMP_LESSEQUAL); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - StateManager.SetSampleMask(0xffffffff); - } - RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - }*/ - - // Fetch4 : disable - // if (RImplementation.o.HW_smap_FETCH4) { - //. we hacked the shader to force smap on S0 - //# define FOURCC_GET1 MAKEFOURCC('G','E','T','1') - // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET1 ); - // } - - // TODO: DX11: Check if DX11 has analog for NV DBT - // disable depth bounds - // u_DBT_disable (); + else + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 8, 0, 16); } } } // namespace xray::render::RENDER_NAMESPACE diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp index 5591f5f19e6..d39c48f342d 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_phase_combine.cpp @@ -46,10 +46,10 @@ void CRenderTarget::phase_combine() // low/hi RTs { - // Clear to zero + // TODO Clear both at once RCache.ClearRT(rt_Generic_0_r, {}); RCache.ClearRT(rt_Generic_1_r, {}); - u_setrt(RCache, rt_Generic_0_r, rt_Generic_1_r, nullptr, rt_MSAADepth); + u_setrtzb(RCache, rt_Generic_0_r, rt_Generic_1_r, rt_MSAADepth); } RCache.set_CullMode(CULL_NONE); RCache.set_Stencil(FALSE); @@ -142,28 +142,6 @@ void CRenderTarget::phase_combine() sundir.set(L_dir.x, L_dir.y, L_dir.z, 0); } - /* - // Fill VB - //float _w = float(Device.dwWidth); - //float _h = float(Device.dwHeight); - //p0.set (.5f/_w, .5f/_h); - //p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); - //p0.set (.5f/_w, .5f/_h); - //p1.set ((_w+.5f)/_w, (_h+.5f)/_h ); - - // Fill vertex buffer - Fvector4* pv = (Fvector4*) RImplementation.Vertex.Lock (4,g_combine_VP->vb_stride,Offset); - //pv->set (hclip(EPS, _w), hclip(_h+EPS, _h), p0.x, p1.y); pv++; - //pv->set (hclip(EPS, _w), hclip(EPS, _h), p0.x, p0.y); pv++; - //pv->set (hclip(_w+EPS, _w), hclip(_h+EPS, _h), p1.x, p1.y); pv++; - //pv->set (hclip(_w+EPS, _w), hclip(EPS, _h), p1.x, p0.y); pv++; - pv->set (-1, 1, 0, 1); pv++; - pv->set (-1, -1, 0, 0); pv++; - pv->set (1, 1, 1, 1); pv++; - pv->set (1, -1, 1, 0); pv++; - RImplementation.Vertex.Unlock (4,g_combine_VP->vb_stride); - */ - // Fill VB float scale_X = float(Device.dwWidth) / float(TEX_jitter); float scale_Y = float(Device.dwHeight) / float(TEX_jitter); @@ -181,10 +159,8 @@ void CRenderTarget::phase_combine() RImplementation.Vertex.Unlock(4, g_combine->vb_stride); // Draw - if (!RImplementation.o.msaa) - RCache.set_Element(s_combine->E[0]); - else - RCache.set_Element(s_combine_msaa[0]->E[0]); + ref_shader shader_combine = RImplementation.o.msaa ? s_combine_msaa[0] : s_combine; + RCache.set_Element(shader_combine->E[0]); RCache.set_Geometry(g_combine); RCache.set_c("m_v2w", Device.mInvView); @@ -199,27 +175,16 @@ void CRenderTarget::phase_combine() RCache.set_c("ssao_noise_tile_factor", fSSAONoise); RCache.set_c("ssao_kernel_size", fSSAOKernelSize); - if (!RImplementation.o.msaa) - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - else - { - if (RImplementation.o.msaa_opt) - { - RCache.set_Stencil(TRUE, D3DCMP_EQUAL, 0x81, 0x81, 0); - RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); - } - else - { - VERIFY(!"Only optimized MSAA is supported in OpenGL"); - } - RCache.set_Stencil(FALSE, D3DCMP_EQUAL, 0x01, 0xff, 0); - } + // bit0 & bit7 nothing + // TODO bit7 represent nothing too, check why + RCache.set_Stencil(TRUE, D3DCMP_NOTEQUAL, 0, 0x7F); + RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } // Forward rendering { PIX_EVENT(Forward_rendering); - u_setrt(RCache, rt_Generic_0_r, nullptr, nullptr, rt_MSAADepth); // LDR RT + u_setrtzb(RCache, rt_Generic_0_r, rt_MSAADepth); // LDR RT RCache.set_CullMode(CULL_CCW); RCache.set_Stencil(FALSE); RCache.set_ColorWriteEnable(); @@ -240,16 +205,16 @@ void CRenderTarget::phase_combine() if (RImplementation.o.msaa) { - // we need to resolve rt_Generic_1_r into rt_Generic_1 - rt_Generic_0_r->resolve_into(*rt_Generic_0); - rt_Generic_1_r->resolve_into(*rt_Generic_1); + // we need to resolve rt_Generic_1_r multisample into rt_Generic_1 single-sampled + rt_Generic_0_r->resolve_into(rt_Generic_0); + rt_Generic_1_r->resolve_into(rt_Generic_1); } // for msaa we need a resolved color buffer - Holger phase_bloom(); // HDR RT invalidated here // RImplementation.rmNormal(); - // u_setrt(rt_Generic_1,0,0,get_base_zb()); + // u_setrtzb(RCache, rt_Generic_1, get_base_zb()); // Distortion filter auto& dsgraph = RImplementation.get_imm_context(); @@ -260,7 +225,7 @@ void CRenderTarget::phase_combine() if (bDistort) { PIX_EVENT(render_distort_objects); - u_setrt(RCache, rt_Generic_1_r, nullptr, nullptr, rt_MSAADepth); // Now RT is a distortion mask + u_setrtzb(RCache, rt_Generic_1_r, rt_MSAADepth); // Now RT is a distortion mask RCache.ClearRT(rt_Generic_1_r, color_rgba(127, 127, 0, 127)); RCache.set_CullMode(CULL_CCW); RCache.set_Stencil(FALSE); @@ -284,16 +249,16 @@ void CRenderTarget::phase_combine() if (RImplementation.o.msaa) { if (PP_Complex) - u_setrt(RCache, rt_Generic, nullptr, nullptr, rt_Base_Depth); // LDR RT + u_setrtzb(RCache, rt_Generic, rt_Base_Depth); // LDR RT else - u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, get_base_zb()); + u_setrtzb(RCache, get_base_rt(), get_base_zb()); } else { if (PP_Complex) - u_setrt(RCache, rt_Color, nullptr, nullptr, rt_Base_Depth); // LDR RT + u_setrtzb(RCache, rt_Color, rt_Base_Depth); // LDR RT else - u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, get_base_zb()); + u_setrtzb(RCache, get_base_rt(), get_base_zb()); } //. u_setrt ( Device.dwWidth,Device.dwHeight, get_base_rt(), NULL, NULL, get_base_zb()); RCache.set_CullMode(CULL_NONE); @@ -367,21 +332,14 @@ void CRenderTarget::phase_combine() vDofKernel.set(0.5f / Device.dwWidth, 0.5f / Device.dwHeight); vDofKernel.mul(ps_r2_dof_kernel_size); + // we operate here on a single-sampled fbo // Draw COLOR - if (!RImplementation.o.msaa) - { - if (ps_r2_ls_flags.test(R2FLAG_AA)) - RCache.set_Element(s_combine->E[bDistort ? 3 : 1]); // look at blender_combine.cpp - else - RCache.set_Element(s_combine->E[bDistort ? 4 : 2]); // look at blender_combine.cpp - } + ref_shader shader_combine = RImplementation.o.msaa ? s_combine_msaa[0] : s_combine; + if (ps_r2_ls_flags.test(R2FLAG_AA)) + RCache.set_Element(shader_combine->E[bDistort ? 3 : 1]); // look at blender_combine.cpp else - { - if (ps_r2_ls_flags.test(R2FLAG_AA)) - RCache.set_Element(s_combine_msaa[0]->E[bDistort ? 3 : 1]); // look at blender_combine.cpp - else - RCache.set_Element(s_combine_msaa[0]->E[bDistort ? 4 : 2]); // look at blender_combine.cpp - } + RCache.set_Element(shader_combine->E[bDistort ? 4 : 2]); // look at blender_combine.cpp + RCache.set_c("e_barrier", ps_r2_aa_barier.x, ps_r2_aa_barier.y, ps_r2_aa_barier.z, 0.f); RCache.set_c("e_weights", ps_r2_aa_weight.x, ps_r2_aa_weight.y, ps_r2_aa_weight.z, 0.f); RCache.set_c("e_kernel", ps_r2_aa_kernel, ps_r2_aa_kernel, ps_r2_aa_kernel, 0.f); @@ -530,10 +488,7 @@ void CRenderTarget::phase_combine() void CRenderTarget::phase_wallmarks() { - // Targets - RCache.set_RT(0, 2); - RCache.set_RT(0, 1); - u_setrt(RCache, rt_Color, nullptr, nullptr, rt_MSAADepth); + u_setrtzb(RCache, rt_Color, rt_MSAADepth); // Stencil - draw only where stencil >= 0x1 RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); RCache.set_CullMode(CULL_CCW); @@ -546,7 +501,7 @@ void CRenderTarget::phase_combine_volumetric() u32 Offset = 0; // TODO: DX11: Remove half pixel offset here - u_setrt(RCache, rt_Generic_0_r, rt_Generic_1_r, nullptr, rt_MSAADepth); + u_setrtzb(RCache, rt_Generic_0_r, rt_Generic_1_r, rt_MSAADepth); // Sets limits to both render targets RCache.set_ColorWriteEnable(D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); diff --git a/src/Layers/xrRenderPC_GL/gl_rendertarget_u_set_rt.cpp b/src/Layers/xrRenderPC_GL/gl_rendertarget_u_set_rt.cpp index 34ffdfad2b5..1d0634bfd7b 100644 --- a/src/Layers/xrRenderPC_GL/gl_rendertarget_u_set_rt.cpp +++ b/src/Layers/xrRenderPC_GL/gl_rendertarget_u_set_rt.cpp @@ -2,192 +2,119 @@ namespace xray::render::RENDER_NAMESPACE { -void CRenderTarget::u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb) + +void CRenderTarget::u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb) { - dwWidth[cmd_list.context_id] = 0; - dwHeight[cmd_list.context_id] = 0; + u_setrtzb(cmd_list, _1, _2, _3, _zb); +} + +void CRenderTarget::u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _zb) +{ + u_setrtzb(cmd_list, _1, _2, nullptr, _zb); +} +void CRenderTarget::u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _zb) +{ + u_setrtzb(cmd_list, _1, nullptr, nullptr, _zb); +} + +void CRenderTarget::u_setrt_(CBackend& cmd_list, const ref_rt& _1) +{ + u_setrtzb(cmd_list, _1, nullptr, nullptr, nullptr); +} + +void CRenderTarget::u_set_zb(CBackend& cmd_list, const ref_rt& _zb) +{ + u_setrtzb(cmd_list, nullptr, nullptr, nullptr, _zb); +} + +template +void CRenderTarget::u_setrtzb(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _3, const ref_rt& _zb) +{ + VERIFY(cmd_list.context_id < R__NUM_CONTEXTS); + GLuint _target = 0; GLenum buffers[3] = {GL_NONE, GL_NONE, GL_NONE}; cmd_list.set_FB(HW.pFB); - if (_1) + if constexpr (has1) { + VERIFY(_1); dwWidth[cmd_list.context_id] = _1->dwWidth; dwHeight[cmd_list.context_id] = _1->dwHeight; - - buffers[0] = GL_COLOR_ATTACHMENT0; - cmd_list.set_RT(_1->pRT, 0); + _target = _1->target; } - else + else if constexpr (has2) { - cmd_list.set_RT(GL_NONE, 0); + VERIFY(_2); + dwWidth[cmd_list.context_id] = _2->dwWidth; + dwHeight[cmd_list.context_id] = _2->dwHeight; + _target = _2->target; } - - if (_2) + else if constexpr (has3) { - if (dwWidth[cmd_list.context_id] && dwHeight[cmd_list.context_id]) - { - VERIFY(_2->dwWidth == dwWidth[cmd_list.context_id]); - VERIFY(_2->dwHeight == dwHeight[cmd_list.context_id]); - } - else - { - dwWidth[cmd_list.context_id] = _2->dwWidth; - dwHeight[cmd_list.context_id] = _2->dwHeight; - } - - buffers[1] = GL_COLOR_ATTACHMENT1; - cmd_list.set_RT(_2->pRT, 1); + VERIFY(_3); + dwWidth[cmd_list.context_id] = _3->dwWidth; + dwHeight[cmd_list.context_id] = _3->dwHeight; + _target = _3->target; } - else + else if constexpr (hasZB) { - cmd_list.set_RT(GL_NONE, 1); + dwWidth[cmd_list.context_id] = _zb->dwWidth; + dwHeight[cmd_list.context_id] = _zb->dwHeight; + _target = _zb->target; } - if (_3) - { - if (dwWidth[cmd_list.context_id] && dwHeight[cmd_list.context_id]) - { - VERIFY(_2->dwWidth == dwWidth[cmd_list.context_id]); - VERIFY(_2->dwHeight == dwHeight[cmd_list.context_id]); - } - else - { - dwWidth[cmd_list.context_id] = _3->dwWidth; - dwHeight[cmd_list.context_id] = _3->dwHeight; - } + VERIFY(dwWidth[cmd_list.context_id] != 0); + VERIFY(dwHeight[cmd_list.context_id] != 0); - buffers[2] = GL_COLOR_ATTACHMENT2; - cmd_list.set_RT(_3->pRT, 2); - } - else + if constexpr (has1) { - cmd_list.set_RT(GL_NONE, 2); - } + VERIFY(_1); - if (_zb) - { - if (dwWidth[cmd_list.context_id] && dwHeight[cmd_list.context_id]) - { - VERIFY(_zb->dwWidth == dwWidth[cmd_list.context_id]); - VERIFY(_zb->dwHeight == dwHeight[cmd_list.context_id]); - } - else - { - dwWidth[cmd_list.context_id] = _zb->dwWidth; - dwHeight[cmd_list.context_id] = _zb->dwHeight; - } - - cmd_list.set_ZB(_zb->pZRT); + buffers[0] = GL_COLOR_ATTACHMENT0; + cmd_list.set_RT(_1, 0); } else - { - cmd_list.set_ZB(GL_NONE); - } - - VERIFY(dwWidth != 0); - VERIFY(dwHeight != 0); + cmd_list.unset_RT(0); - [[maybe_unused]] GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - VERIFY(status == GL_FRAMEBUFFER_COMPLETE); - CHK_GL(glDrawBuffers(3, buffers)); -} - -void CRenderTarget::u_setrt(CBackend& cmd_list, const ref_rt& _1, const ref_rt& _2, const ref_rt& _zb) -{ - dwWidth[cmd_list.context_id] = 0; - dwHeight[cmd_list.context_id] = 0; - - GLenum buffers[3] = {GL_NONE, GL_NONE, GL_NONE}; - - cmd_list.set_FB(HW.pFB); - - if (_1) + if constexpr (has2) { - dwWidth[cmd_list.context_id] = _1->dwWidth; - dwHeight[cmd_list.context_id] = _1->dwHeight; + VERIFY(_2); + VERIFY(_2->dwWidth == dwWidth[cmd_list.context_id]); + VERIFY(_2->dwHeight == dwHeight[cmd_list.context_id]); + VERIFY(_2->target == _target); - buffers[0] = GL_COLOR_ATTACHMENT0; - cmd_list.set_RT(_1->pRT, 0); + buffers[1] = GL_COLOR_ATTACHMENT1; + cmd_list.set_RT(_2, 1); } else - { - cmd_list.set_RT(GL_NONE, 0); - } + cmd_list.unset_RT(1); - if (_2) + + if constexpr (has3) { - if (dwWidth[cmd_list.context_id] && dwHeight[cmd_list.context_id]) - { - VERIFY(_2->dwWidth == dwWidth[cmd_list.context_id]); - VERIFY(_2->dwHeight == dwHeight[cmd_list.context_id]); - } - else - { - dwWidth[cmd_list.context_id] = _2->dwWidth; - dwHeight[cmd_list.context_id] = _2->dwHeight; - } + VERIFY(_3); + VERIFY(_3->dwWidth == dwWidth[cmd_list.context_id]); + VERIFY(_3->dwHeight == dwHeight[cmd_list.context_id]); + VERIFY(_3->target == _target); - buffers[1] = GL_COLOR_ATTACHMENT1; - cmd_list.set_RT(_2->pRT, 1); + buffers[2] = GL_COLOR_ATTACHMENT2; + cmd_list.set_RT(_3, 2); } else - { - cmd_list.set_RT(GL_NONE, 1); - } + cmd_list.unset_RT( 2); - if (_zb) + if constexpr (hasZB) { - if (dwWidth[cmd_list.context_id] && dwHeight[cmd_list.context_id]) - { - VERIFY(_zb->dwWidth == dwWidth[cmd_list.context_id]); - VERIFY(_zb->dwHeight == dwHeight[cmd_list.context_id]); - } - else - { - dwWidth[cmd_list.context_id] = _zb->dwWidth; - dwHeight[cmd_list.context_id] = _zb->dwHeight; - } - - cmd_list.set_ZB(_zb->pZRT); + VERIFY(_zb); + VERIFY(_zb->dwWidth == dwWidth[cmd_list.context_id]); + cmd_list.set_ZB(_zb); } else - { - cmd_list.set_ZB(GL_NONE); - } - - VERIFY(dwWidth[cmd_list.context_id] != 0); - VERIFY(dwHeight[cmd_list.context_id] != 0); - - [[maybe_unused]] GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - VERIFY(status == GL_FRAMEBUFFER_COMPLETE); - CHK_GL(glDrawBuffers(2, buffers)); -} - -void CRenderTarget::u_setrt(CBackend& cmd_list, u32 W, u32 H, GLuint _1, GLuint _2, GLuint _3, GLuint zb) -{ - VERIFY(W != 0); - VERIFY(H != 0); - - dwWidth[cmd_list.context_id] = W; - dwHeight[cmd_list.context_id] = H; - - const GLenum buffers[3] = { - (GLenum)(_1 ? GL_COLOR_ATTACHMENT0 : GL_NONE), - (GLenum)(_2 ? GL_COLOR_ATTACHMENT1 : GL_NONE), - (GLenum)(_3 ? GL_COLOR_ATTACHMENT2 : GL_NONE) - }; - - cmd_list.set_FB(HW.pFB); - - cmd_list.set_RT(_1, 0); - cmd_list.set_RT(_2, 1); - cmd_list.set_RT(_3, 2); - cmd_list.set_ZB(zb); + cmd_list.unset_ZB(); - [[maybe_unused]] GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - VERIFY(status == GL_FRAMEBUFFER_COMPLETE); + VERIFY(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); CHK_GL(glDrawBuffers(3, buffers)); } } // namespace xray::render::RENDER_NAMESPACE diff --git a/src/Layers/xrRender_R2/r2.cpp b/src/Layers/xrRender_R2/r2.cpp index f377c694827..7f898154011 100644 --- a/src/Layers/xrRender_R2/r2.cpp +++ b/src/Layers/xrRender_R2/r2.cpp @@ -145,7 +145,7 @@ static bool must_enable_old_cascades() { IReader* accumSunNear = open_shader("accum_sun_near.ps"); R_ASSERT3(accumSunNear, "Can't open shader", "accum_sun_near.ps"); - do + while (accumSunNear != nullptr) { xr_string str(static_cast(accumSunNear->pointer()), accumSunNear->length()); @@ -172,7 +172,7 @@ static bool must_enable_old_cascades() { oldCascades = false; } - } while (false); + } FS.r_close(accumSunNear); } #endif @@ -421,10 +421,16 @@ void CRender::create() o.msaa_hybrid = ps_r2_ls_flags.test((u32)R3FLAG_USE_DX10_1); o.msaa_hybrid &= !o.msaa_opt && o.msaa && (HW.FeatureLevel >= D3D_FEATURE_LEVEL_10_1); #elif defined(USE_OGL) - // TODO: OGL: temporary disabled, need to fix it - o.msaa = false; - o.msaa_samples = 0; + o.msaa_samples = (1 << ps_r3_msaa); + o.msaa = o.msaa_samples > 1; + + if (!o.msaa) o.msaa_samples = 0; + // Important! DX10 related, for OpenGL same as o.msaa + // It's messing with shader predefines o.msaa_opt = o.msaa; + // DX related ? + o.gbuffer_opt = true; + // Important! DX10 related, for OpenGL always false o.msaa_hybrid = false; #else # error No graphics API selected or enabled! diff --git a/src/Layers/xrRender_R2/r2_R_render.cpp b/src/Layers/xrRender_R2/r2_R_render.cpp index 50c56c8cdbb..f45e5850d5b 100644 --- a/src/Layers/xrRender_R2/r2_R_render.cpp +++ b/src/Layers/xrRender_R2/r2_R_render.cpp @@ -23,18 +23,30 @@ void CRender::RenderMenu() // Main Render { +#ifdef USE_OGL + Target->u_setrtzb(RCache, Target->rt_Generic_0, Target->rt_Base_Depth); // LDR RT +#else Target->u_setrt(RCache, Target->rt_Generic_0, nullptr, nullptr, Target->rt_Base_Depth); // LDR RT +#endif g_pGamePersistent->OnRenderPPUI_main(); // PP-UI } // Distort { +#ifdef USE_OGL + Target->u_setrtzb(RCache, Target->rt_Generic_1, Target->rt_Base_Depth); // Now RT is a distortion mask +#else Target->u_setrt(RCache, Target->rt_Generic_1, nullptr, nullptr, Target->rt_Base_Depth); // Now RT is a distortion mask +#endif RCache.ClearRT(Target->rt_Generic_1, color_rgba(127, 127, 0, 127)); g_pGamePersistent->OnRenderPPUI_PP(); // PP-UI } // Actual Display +#ifdef USE_OGL + Target->u_setrtzb(RCache, Target->get_base_rt(), Target->get_base_zb()); +#else Target->u_setrt(RCache, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), 0, 0, Target->get_base_zb()); +#endif RCache.set_Shader(Target->s_menu); RCache.set_Geometry(Target->g_menu); @@ -94,7 +106,11 @@ void CRender::Render() // if (!(g_pGameLevel && g_hud) || bMenu) if (!g_pGameLevel || bMenu) { +#ifdef USE_OGL + Target->u_setrtzb(RCache, Target->get_base_rt(), 0, 0, Target->get_base_zb()); +#else Target->u_setrt(RCache, Device.dwWidth, Device.dwHeight, Target->get_base_rt(), 0, 0, Target->get_base_zb()); +#endif return; } @@ -207,7 +223,7 @@ void CRender::Render() #if defined(USE_DX11) dsgraph.cmd_list.set_ZB(Target->rt_MSAADepth->pZRT[dsgraph.cmd_list.context_id]); #elif defined(USE_OGL) - dsgraph.cmd_list.set_ZB(Target->rt_MSAADepth->pZRT); + dsgraph.cmd_list.set_ZB(Target->rt_MSAADepth); #endif } { @@ -262,10 +278,15 @@ void CRender::Render() if (split_the_scene_to_minimize_wait) { PIX_EVENT(DEFER_PART1_SPLIT); + //@TODO: REMOVE dead code // skybox can be drawn here if (false) { +#ifdef USE_OGL + Target->u_setrtzb(dsgraph.cmd_list, Target->rt_Generic_0_r, Target->rt_Generic_1_r, Target->rt_MSAADepth); +#else Target->u_setrt(dsgraph.cmd_list, Target->rt_Generic_0_r, Target->rt_Generic_1_r, nullptr, Target->rt_MSAADepth); +#endif dsgraph.cmd_list.set_CullMode(CULL_NONE); dsgraph.cmd_list.set_Stencil(FALSE); diff --git a/src/Layers/xrRender_R2/r2_rendertarget.cpp b/src/Layers/xrRender_R2/r2_rendertarget.cpp index af4e223b9e4..58fd1120a30 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget.cpp @@ -438,9 +438,13 @@ CRenderTarget::CRenderTarget() for (u32 i = 0; i < BoundSamples; ++i) { - // CBlender_accum_direct_volumetric_sun_msaa b_accum_direct_volumetric_sun_msaa{ "ISAMPLE", SAMPLE_DEFS[i] }; - // s_accum_direct_volumetric_msaa[i].create(&b_accum_direct_volumetric_sun_msaa, "r2" DELIMITER "accum_direct"); +#ifdef USE_OGL + CBlender_accum_direct_volumetric_sun_msaa b_accum_direct_volumetric_sun_msaa{ "ISAMPLE", SAMPLE_DEFS[i] }; + s_accum_direct_volumetric_msaa[i].create(&b_accum_direct_volumetric_sun_msaa, "r2" DELIMITER "accum_direct"); +#else s_accum_direct_volumetric_msaa[i].create(snames[i]); +#endif + manually_assign_texture(s_accum_direct_volumetric_msaa[i], "s_smap", smapTarget); } } @@ -639,7 +643,11 @@ CRenderTarget::CRenderTarget() rt_LUM_pool[it].create(name, 1, 1, D3DFMT_R32F); RCache.ClearRT(rt_LUM_pool[it], 0x7f7f7f7f); } +#ifdef USE_OGL + u_setrtzb(RCache, get_base_rt(), get_base_zb()); +#else u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, get_base_zb()); +#endif } // COMBINE diff --git a/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp b/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp index 4fe08c2a983..3da1c8c47ae 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_accum_reflected.cpp @@ -42,7 +42,7 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) 0.5f + o_w, 0.5f + o_h, 0.0f, 1.0f }; #elif defined(USE_OGL) - Fmatrix m_TexelAdjust = + const Fmatrix m_TexelAdjust = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, @@ -65,8 +65,12 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) L_dir.normalize(); { + ref_shader shader_accum_reflected = s_accum_reflected; +#ifdef USE_OGL + shader_accum_reflected = RImplementation.o.msaa ? s_accum_reflected_msaa[0] : shader_accum_reflected; +#endif // Lighting - cmd_list.set_Shader(s_accum_reflected); + cmd_list.set_Shader(shader_accum_reflected); // Constants cmd_list.set_c("Ldynamic_pos", L_pos.x, L_pos.y, L_pos.z, 1 / (L->range * L->range)); @@ -74,12 +78,8 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) cmd_list.set_c("direction", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("m_texgen", m_Texgen); - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else // checked Holger +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x81, 0x00); @@ -98,7 +98,6 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) } else // checked Holger { -# if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Shader(s_accum_reflected_msaa[i]); @@ -111,26 +110,30 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -# elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -# endif // USE_DX11 } } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); + draw_volume(cmd_list, L); + } } // blend-copy if (!RImplementation.o.fp16_blend) { + ref_shader shader_accum_mask = s_accum_mask; +#ifdef USE_OGL + shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : shader_accum_mask; + u_setrtzb(cmd_list, rt_Accumulator, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); +#endif + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_ACCUM_VOL]); cmd_list.set_c("m_texgen", m_Texgen); - if (!RImplementation.o.msaa) - { - // per pixel - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else // checked holger +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x81, 0x00); @@ -144,7 +147,6 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) } else // checked holger { -# if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_accum_mask_msaa[i]->E[SE_MASK_ACCUM_VOL]); @@ -153,17 +155,18 @@ void CRenderTarget::accum_reflected(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -# elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -# endif // USE_DX11 } -# if defined(USE_DX11) // XXX: not sure why this is needed. Just preserving original behaviour cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); -# endif // !USE_OGL + } + else +#endif + { + // per pixel + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); + draw_volume(cmd_list, L); } } - // u_DBT_disable(); } } // namespace xray::render::RENDER_NAMESPACE diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp index 592fd93fc7c..627a94cda6a 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_PP.cpp @@ -131,7 +131,12 @@ struct TL_2c3uv void CRenderTarget::phase_pp() { // combination/postprocess +#ifdef USE_OGL + u_setrtzb(RCache, get_base_rt(), get_base_zb()); +#else u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, get_base_zb()); +#endif + // Element 0 for for normal post-process // Element 4 for color map post-process bool bCMap = u_need_CM(); diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp index fdc736ec21d..3cbf6696180 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_accumulator.cpp @@ -7,11 +7,12 @@ void CRenderTarget::phase_accumulator(CBackend& cmd_list) // Targets if (dwAccumulatorClearMark == Device.dwFrame) { - // normal operation - setup - if (RImplementation.o.fp16_blend) - u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); - else - u_setrt(cmd_list, rt_Accumulator_temp, nullptr, nullptr, rt_MSAADepth); + auto& rt1 = RImplementation.o.fp16_blend ? rt_Accumulator : rt_Accumulator_temp; +#ifdef USE_OGL + u_setrtzb(cmd_list, rt1, rt_MSAADepth); +#else + u_setrt(cmd_list, rt1, nullptr, nullptr,rt_MSAADepth); +#endif } else { @@ -19,7 +20,11 @@ void CRenderTarget::phase_accumulator(CBackend& cmd_list) dwAccumulatorClearMark = Device.dwFrame; // clear +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Accumulator, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); +#endif // dwLightMarkerID = 5; // start from 5, increment in 2 units reset_light_marker(cmd_list); @@ -57,7 +62,11 @@ void CRenderTarget::phase_accumulator(CBackend& cmd_list) void CRenderTarget::phase_vol_accumulator(CBackend& cmd_list) { +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Generic_2, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Generic_2, nullptr, nullptr, rt_MSAADepth); +#endif if (!m_bHasActiveVolumetric) { diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp index ce0385e92e3..e6e043ce2d6 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_bloom.cpp @@ -80,7 +80,13 @@ void CRenderTarget::phase_bloom() u32 Offset; // Targets - u_setrt(RCache, rt_Bloom_1, 0, 0, 0); // No need for ZBuffer at all +#ifdef USE_OGL + u_setrt_(RCache, rt_Bloom_1); // No need for ZBuffer at all +#else + u_setrt(RCache, rt_Bloom_1, nullptr, nullptr, nullptr); // No need for ZBuffer at all +#endif + + // Clear - don't clear - it's stupid here :) // Stencil - disable @@ -249,12 +255,22 @@ void CRenderTarget::phase_bloom() RCache.set_Geometry(g_bloom_build); // P0 - u_setrt(RCache, rt_Bloom_2, 0, 0, 0); // No need for ZBuffer at all +#ifdef USE_OGL + u_setrt_(RCache, rt_Bloom_2); +#else + u_setrt(RCache, rt_Bloom_2, nullptr, nullptr, nullptr); // No need for ZBuffer at all +#endif + RCache.set_Element(s_bloom->E[3]); RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); // P1 - u_setrt(RCache, rt_Bloom_1, 0, 0, 0); // No need for ZBuffer at all +#ifdef USE_OGL + u_setrt_(RCache, rt_Bloom_1); +#else + u_setrt(RCache, rt_Bloom_1, nullptr, nullptr, nullptr); // No need for ZBuffer at all +#endif + RCache.set_Element(s_bloom->E[4]); RCache.Render(D3DPT_TRIANGLELIST, Offset, 0, 4, 0, 2); } @@ -385,7 +401,11 @@ void CRenderTarget::phase_bloom() Fvector4 w0, w1; float kernel = ps_r2_ls_bloom_kernel_g; CalcGauss_wave(w0, w1, kernel, kernel / 3.f, ps_r2_ls_bloom_kernel_scale); - u_setrt(RCache, rt_Bloom_2, 0, 0, 0); // No need for ZBuffer at all +#ifdef USE_OGL + u_setrt_(RCache, rt_Bloom_2); // No need for ZBuffer at all +#else + u_setrt(RCache, rt_Bloom_2, nullptr, nullptr, nullptr); // No need for ZBuffer at all +#endif RCache.set_Element(s_bloom->E[1]); RCache.set_ca("weight", 0, w0); RCache.set_ca("weight", 1, w1); @@ -517,7 +537,11 @@ void CRenderTarget::phase_bloom() Fvector4 w0, w1; float kernel = ps_r2_ls_bloom_kernel_g * float(Device.dwHeight) / float(Device.dwWidth); CalcGauss_wave(w0, w1, kernel, kernel / 3.f, ps_r2_ls_bloom_kernel_scale); - u_setrt(RCache, rt_Bloom_1, 0, 0, 0); // No need for ZBuffer at all +#ifdef USE_OGL + u_setrt_(RCache, rt_Bloom_1); // No need for ZBuffer at all +#else + u_setrt(RCache, rt_Bloom_1, nullptr, nullptr, nullptr); // No need for ZBuffer at all +#endif RCache.set_Element(s_bloom->E[2]); RCache.set_ca("weight", 0, w0); RCache.set_ca("weight", 1, w1); diff --git a/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp b/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp index e67b2f16565..7f9f527499f 100644 --- a/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp +++ b/src/Layers/xrRender_R2/r2_rendertarget_phase_luminance.cpp @@ -40,7 +40,11 @@ void CRenderTarget::phase_luminance() RCache.set_Z(false); // 000: Perform LUM-SAT, pass 0, 256x256 => 64x64 - u_setrt(RCache, rt_LUM_64, 0, 0, 0); +#ifdef USE_OGL + u_setrt_(RCache, rt_LUM_64); +#else + u_setrt(RCache, rt_LUM_64, nullptr, nullptr, nullptr); +#endif { float ts = 64; float _w = float(BLOOM_size_X); @@ -119,7 +123,11 @@ void CRenderTarget::phase_luminance() } // 111: Perform LUM-SAT, pass 1, 64x64 => 8x8 - u_setrt(RCache, rt_LUM_8, 0, 0, 0); +#ifdef USE_OGL + u_setrt_(RCache, rt_LUM_8); +#else + u_setrt(RCache, rt_LUM_8, nullptr, nullptr, nullptr); +#endif { // Build filter-kernel float _ts = 8; @@ -180,7 +188,11 @@ void CRenderTarget::phase_luminance() // 222: Perform LUM-SAT, pass 2, 8x8 => 1x1 u32 gpu_id = Device.dwFrame % HW.Caps.iGPUNum; - u_setrt(RCache, rt_LUM_pool[gpu_id * 2 + 1], 0, 0, 0); +#ifdef USE_OGL + u_setrt_(RCache, rt_LUM_pool[gpu_id * 2 + 1]); +#else + u_setrt(RCache, rt_LUM_pool[gpu_id * 2 + 1], nullptr, nullptr, nullptr); +#endif { // Build filter-kernel float _ts = 1; diff --git a/src/Layers/xrRender_R2/r3_rendertarget_accum_point.cpp b/src/Layers/xrRender_R2/r3_rendertarget_accum_point.cpp index bb03fb7659f..5badc97329e 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_accum_point.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_accum_point.cpp @@ -6,14 +6,23 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) { phase_accumulator(cmd_list); RImplementation.Stats.l_visible++; - - ref_shader shader = L->s_point; + ref_shader shader; + ref_shader shader_accum_mask; +#ifdef USE_OGL + shader = RImplementation.o.msaa ? L->s_point_msaa[0] : L->s_point; + shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + if (!shader) + shader = RImplementation.o.msaa ? s_accum_point_msaa[0]: s_accum_point; +#else + shader = L->s_point; + shader_accum_mask = s_accum_mask; ref_shader* shader_msaa = L->s_point_msaa; if (!shader) { shader = s_accum_point; shader_msaa = s_accum_point_msaa; } +#endif // Common Fvector L_pos; @@ -37,34 +46,38 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) // *** similar to "Carmack's reverse", but assumes convex, non intersecting objects, // *** thus can cope without stencil clear with 127 lights // *** in practice, 'cause we "clear" it back to 0x1 it usually allows us to > 200 lights :) - cmd_list.set_Element(s_accum_mask->E[SE_MASK_POINT]); // masker + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_POINT]); // masker // Done in blender! // RCache.set_ColorWriteEnable (FALSE); // backfaces: if (1<=stencil && zfail) stencil = light_id cmd_list.set_CullMode(CULL_CW); - if (!RImplementation.o.msaa) +#ifdef USE_DX11 + if (RImplementation.o.msaa) { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } else +#endif { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0x7f, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } draw_volume(cmd_list, L); // frontfaces: if (1<=stencil && zfail) stencil = 0x1 cmd_list.set_CullMode(CULL_CCW); - if (!RImplementation.o.msaa) +#ifdef USE_DX11 + if (RImplementation.o.msaa) { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0x7f, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } else +#endif { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0x7f, 0x7f, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } draw_volume(cmd_list, L); @@ -123,12 +136,8 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) cmd_list.set_CullMode(CULL_CW); // back // Render if (light_id <= stencil && z-pass) - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else // checked Holger +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); @@ -138,13 +147,12 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) if (RImplementation.o.msaa_opt) { cmd_list.set_Element(shader_msaa[0]->E[_id]); - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID | 0x80, 0xff, 0x00); + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); cmd_list.set_CullMode(D3DCULL_CW); draw_volume(cmd_list, L); } else // checked Holger { -#if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(shader_msaa[i]->E[_id]); @@ -154,15 +162,15 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); } - + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); + draw_volume(cmd_list, L); + } // Fetch4 : disable // if (RImplementation.o.HW_smap_FETCH4) { //. we hacked the shader to force smap on S0 @@ -174,15 +182,15 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) // blend-copy if (!RImplementation.o.fp16_blend) { +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Accumulator, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); +#endif + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_ACCUM_VOL]); cmd_list.set_c("m_texgen", m_Texgen); - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else // checked Holger +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel cmd_list.set_CullMode(D3DCULL_CW); @@ -198,7 +206,6 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) } else // checked Holger { -#if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_accum_mask_msaa[i]->E[SE_MASK_ACCUM_VOL]); @@ -208,14 +215,15 @@ void CRenderTarget::accum_point(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); + draw_volume(cmd_list, L); + } } cmd_list.set_Scissor(0); diff --git a/src/Layers/xrRender_R2/r3_rendertarget_accum_spot.cpp b/src/Layers/xrRender_R2/r3_rendertarget_accum_spot.cpp index 374f2183698..92f70b64d12 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_accum_spot.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_accum_spot.cpp @@ -13,7 +13,24 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) // *** assume accumulator already setup *** // ***************************** Mask by stencil ************************************* ref_shader shader; + ref_shader shader_accum_mask; +#ifdef USE_OGL + shader_accum_mask = RImplementation.o.msaa ? s_accum_mask_msaa[0] : s_accum_mask; + if (IRender_Light::OMNIPART == L->flags.type) + { + shader = RImplementation.o.msaa ? L->s_point_msaa[0] : L->s_point; + if (!shader) + shader = RImplementation.o.msaa ? s_accum_point_msaa[0] : s_accum_point; + } + else + { + shader = RImplementation.o.msaa ? L->s_spot_msaa[0] : L->s_spot; + if (!shader) + shader = RImplementation.o.msaa ? s_accum_spot_msaa[0] : s_accum_spot; + } +#else ref_shader* shader_msaa; + shader_accum_mask = s_accum_mask; if (IRender_Light::OMNIPART == L->flags.type) { shader = L->s_point; @@ -34,6 +51,7 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) shader_msaa = s_accum_spot_msaa; } } +#endif { // setup xform @@ -49,32 +67,36 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) // *** in practice, 'cause we "clear" it back to 0x1 it usually allows us to > 200 lights :) // Done in blender! // cmd_list.set_ColorWriteEnable (FALSE); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_SPOT]); // masker + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_SPOT]); // masker // backfaces: if (stencil>=1 && zfail) stencil = light_id cmd_list.set_CullMode(CULL_CW); - if (!RImplementation.o.msaa) +#ifdef USE_DX11 + if (RImplementation.o.msaa) { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } else +#endif { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0x7f, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0x01, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } draw_volume(cmd_list, L); // frontfaces: if (stencil>=light_id && zfail) stencil = 0x1 cmd_list.set_CullMode(CULL_CCW); - if (!RImplementation.o.msaa) +#ifdef USE_DX11 + if (RImplementation.o.msaa) { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0x7f, 0x7f, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } else +#endif { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0x7f, 0x7f, + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0xff, D3DSTENCILOP_KEEP, D3DSTENCILOP_KEEP, D3DSTENCILOP_REPLACE); } draw_volume(cmd_list, L); @@ -211,13 +233,8 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) //# define FOURCC_GET4 MAKEFOURCC('G','E','T','4') // HW.pDevice->SetSamplerState ( 0, D3DSAMP_MIPMAPLODBIAS, FOURCC_GET4 ); // } - - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel cmd_list.set_Element(shader->E[_id]); @@ -235,7 +252,7 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) } else // checked Holger { -#ifdef USE_DX11 + for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(shader_msaa[i]->E[_id]); @@ -245,14 +262,19 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); } + else + { + cmd_list.set_Stencil(TRUE, D3DCMP_LESSEQUAL, dwLightMarkerID, 0xff, 0x00); +#else + { + // TODO Investigate: without it there are light artefacts ? + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); +#endif + draw_volume(cmd_list, L); + } // Fetch4 : disable // if (RImplementation.o.HW_smap_FETCH4) { @@ -265,16 +287,16 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) // blend-copy if (!RImplementation.o.fp16_blend) { +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Accumulator, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); - cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); +#endif + cmd_list.set_Element(shader_accum_mask->E[SE_MASK_ACCUM_VOL]); cmd_list.set_c("m_texgen", m_Texgen); cmd_list.set_c("m_texgen_J", m_Texgen_J); - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); - draw_volume(cmd_list, L); - } - else // checked Holger +#ifdef USE_DX11 + if (RImplementation.o.msaa) // checked Holger { // per pixel cmd_list.set_Element(s_accum_mask->E[SE_MASK_ACCUM_VOL]); @@ -289,7 +311,6 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) } else // checked Holger { -#ifdef USE_DX11 for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_accum_mask_msaa[i]->E[SE_MASK_ACCUM_VOL]); @@ -298,14 +319,15 @@ void CRenderTarget::accum_spot(CBackend& cmd_list, light* L) draw_volume(cmd_list, L); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, dwLightMarkerID, 0xff, 0x00); + draw_volume(cmd_list, L); + } } cmd_list.set_Scissor(0); diff --git a/src/Layers/xrRender_R2/r3_rendertarget_create_minmaxSM.cpp b/src/Layers/xrRender_R2/r3_rendertarget_create_minmaxSM.cpp index cfe6534b3eb..fdc351ee82c 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_create_minmaxSM.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_create_minmaxSM.cpp @@ -20,7 +20,11 @@ void CRenderTarget::create_minmax_SM(CBackend& cmd_list) pv++; RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); //u_setrt (rt_smap_depth_minmax_temp,NULL,NULL,NULL); - u_setrt(cmd_list, rt_smap_depth_minmax, 0, 0, 0); +#ifdef USE_OGL + u_setrt_(cmd_list, rt_smap_depth_minmax); +#else + u_setrt(cmd_list, rt_smap_depth_minmax, nullptr, nullptr, nullptr); +#endif cmd_list.set_Element(s_create_minmax_sm->E[0]); cmd_list.set_Geometry(g_combine_2UV); cmd_list.set_Stencil(FALSE, D3DCMP_ALWAYS, 0x80, 0xFF, 0x80, diff --git a/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp b/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp index 7c8cb889020..3de2856ac3b 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_draw_rain.cpp @@ -234,10 +234,18 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) // Use for intermediate results // Patch normal +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Accumulator, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Accumulator, nullptr, nullptr, rt_MSAADepth); +#endif // u_setrt (rt_Normal,NULL,NULL,get_base_zb()); - cmd_list.set_Element(s_rain->E[1]); + ref_shader shader_rain = s_rain; +#ifdef USE_OGL + shader_rain = RImplementation.o.msaa ? s_rain_msaa[0] : s_rain; +#endif + cmd_list.set_Element(shader_rain->E[1]); cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("WorldX", W_dirX.x, W_dirX.y, W_dirX.z, 0.f); cmd_list.set_c("WorldZ", W_dirZ.x, W_dirZ.y, W_dirZ.z, 0.f); @@ -245,12 +253,8 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) cmd_list.set_c("m_sunmask", m_clouds_shadow); cmd_list.set_c("RainDensity", fRainFactor, 0.f, 0.f, 0.f); cmd_list.set_c("RainFallof", ps_r3_dyn_wet_surf_near, ps_r3_dyn_wet_surf_far, 0.f, 0.f); - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); - } - else +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel execution cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x81, 0); @@ -273,7 +277,6 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) } else { -#if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_rain_msaa[i]->E[0]); @@ -290,16 +293,17 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); + cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); + } // Apply normal - cmd_list.set_Element(s_rain->E[2]); + cmd_list.set_Element(shader_rain->E[2]); cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("m_shadow", m_shadow); cmd_list.set_c("m_sunmask", m_clouds_shadow); @@ -308,20 +312,24 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) { // Do this in blender! // StateManager.SetColorWriteEnable( D3D_COLOR_WRITE_ENABLE_RED | D3D_COLOR_WRITE_ENABLE_GREEN | D3D_COLOR_WRITE_ENABLE_BLUE ); +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Normal, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Normal, nullptr, nullptr, rt_MSAADepth); +#endif } else { // StateManager.SetColorWriteEnable( D3D_COLOR_WRITE_ENABLE_RED | D3D_COLOR_WRITE_ENABLE_GREEN ); +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Position, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Position, nullptr, nullptr, rt_MSAADepth); +#endif } - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); - } - else +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel execution cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x81, 0); @@ -337,7 +345,6 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) } else { -#if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_rain_msaa[i]->E[1]); @@ -347,30 +354,36 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); + cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); + } // Apply gloss - cmd_list.set_Element(s_rain->E[3]); +#ifdef USE_DX11 + cmd_list.set_Element(shader_rain->E[3]); +#else + // TODO Should be resolved in blender + cmd_list.set_Element(shader_rain->E[RImplementation.o.msaa ? 2 : 3]); +#endif cmd_list.set_c("Ldynamic_dir", L_dir.x, L_dir.y, L_dir.z, 0.f); cmd_list.set_c("m_shadow", m_shadow); cmd_list.set_c("m_sunmask", m_clouds_shadow); // It is restored automatically by a set_Element call // StateManager.SetColorWriteEnable( D3D_COLOR_WRITE_ENABLE_ALL ); +#ifdef USE_OGL + u_setrtzb(cmd_list, rt_Color, rt_MSAADepth); +#else u_setrt(cmd_list, rt_Color, nullptr, nullptr, rt_MSAADepth); +#endif - if (!RImplementation.o.msaa) - { - cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); - cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); - } - else +#ifdef USE_DX11 + if (RImplementation.o.msaa) { // per pixel execution cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x81, 0); @@ -385,7 +398,6 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) } else { -#if defined(USE_DX11) for (u32 i = 0; i < RImplementation.o.msaa_samples; ++i) { cmd_list.set_Element(s_rain_msaa[i]->E[2]); @@ -394,13 +406,14 @@ void CRenderTarget::draw_rain(CBackend& cmd_list, light& RainSetup) cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); } cmd_list.StateManager.SetSampleMask(0xffffffff); -#elif defined(USE_OGL) - VERIFY(!"Only optimized MSAA is supported in OpenGL"); -#else -# error No graphics API selected or enabled! -#endif } } + else +#endif + { + cmd_list.set_Stencil(TRUE, D3DCMP_EQUAL, 0x01, 0x01, 0); + cmd_list.Render(D3DPT_TRIANGLELIST, Offset, 0, 3, 0, 1); + } // TODO: DX11: Check if DX11 has analog for NV DBT // disable depth bounds diff --git a/src/Layers/xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp b/src/Layers/xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp index 43a4faaeda7..81fc6910b8e 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_mark_msaa_edges.cpp @@ -32,10 +32,10 @@ void CRenderTarget::mark_msaa_edges() # error No graphics API selected or enabled! #endif RImplementation.Vertex.Unlock(4, g_combine_2UV->vb_stride); -#if defined(USE_DX11) // XXX: remove this difference +#ifdef USE_OGL + u_set_zb(RCache, rt_MSAADepth); +#else u_setrt(RCache, nullptr, nullptr, nullptr, rt_MSAADepth); -#elif defined(USE_OGL) - u_setrt(RCache, Device.dwWidth, Device.dwHeight, 0, 0, 0, rt_MSAADepth->pZRT); #endif RCache.set_Element(s_mark_msaa_edges->E[0]); RCache.set_Geometry(g_combine_2UV); diff --git a/src/Layers/xrRender_R2/r3_rendertarget_phase_occq.cpp b/src/Layers/xrRender_R2/r3_rendertarget_phase_occq.cpp index 8159a5f9c65..ad94e72490b 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_phase_occq.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_phase_occq.cpp @@ -4,10 +4,16 @@ namespace xray::render::RENDER_NAMESPACE { void CRenderTarget::phase_occq() { +#ifdef USE_OGL + auto rt1 = RImplementation.o.msaa ? rt_Generic_0_r : get_base_rt(); + auto zb = RImplementation.o.msaa ? rt_MSAADepth : rt_Base_Depth; + u_setrtzb(RCache, rt1, zb); +#else if (!RImplementation.o.msaa) u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, rt_MSAADepth); else u_setrt(RCache, Device.dwWidth, Device.dwHeight, 0, 0, 0, rt_MSAADepth); +#endif RCache.set_Shader(s_occq); RCache.set_CullMode(CULL_CCW); RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); diff --git a/src/Layers/xrRender_R2/r3_rendertarget_phase_scene.cpp b/src/Layers/xrRender_R2/r3_rendertarget_phase_scene.cpp index 7f4b4733b33..f628ac7089a 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_phase_scene.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_phase_scene.cpp @@ -21,27 +21,39 @@ void CRenderTarget::phase_scene_prepare() if (RImplementation.o.advancedpp && (ps_r2_ls_flags.test(R2FLAG_SOFT_PARTICLES | R2FLAG_DOF) || ((ps_r_sun_shafts > 0) && (fValue >= 0.0001)) || (ps_r_ssao > 0))) { +#ifdef USE_DX11 // TODO: DX11: Check if we need to set RT here. u_setrt(RCache, Device.dwWidth, Device.dwHeight, rt_Position->pRT, 0, 0, rt_MSAADepth); +#else + /* TODO investigate: it should be rt_Normal, (maybe) rt_Color(albedo) and rt_MSAADepth + * rt_Position should be always single-sampled */ + u_setrtzb(RCache, rt_Position,rt_MSAADepth); +#endif const Fcolor color{}; // black RCache.ClearRT(rt_Position, color); // RCache.ClearRT(rt_Normal, color); // RCache.ClearRT(rt_Color, color); + //@TODO: do we need this if ? if (!RImplementation.o.msaa) RCache.ClearZB(get_base_zb(), 1.0f, 0); else { + // TODO Clear all at once RCache.ClearRT(rt_Color, color); RCache.ClearRT(rt_Accumulator, color); RCache.ClearZB(rt_MSAADepth, 1.0f, 0); - RCache.ClearZB(get_base_zb(), 1.0f, 0); + //RCache.ClearZB(get_base_zb(), 1.0f, 0); rt_MSAADepth != get_base_zb() } } else { // TODO: DX11: Check if we need to set RT here. +#ifdef USE_OGL + u_setrtzb(RCache, get_base_rt(),rt_MSAADepth); +#else u_setrt(RCache, Device.dwWidth, Device.dwHeight, get_base_rt(), 0, 0, rt_MSAADepth); +#endif RCache.ClearZB(rt_MSAADepth, 1.0f, 0); } @@ -54,6 +66,11 @@ void CRenderTarget::phase_scene_prepare() void CRenderTarget::phase_scene_begin() { // Targets, use accumulator for temporary storage +#ifdef USE_OGL + // TODO Investigate should be color always + auto& _2 = RImplementation.o.albedo_wo ? rt_Accumulator : rt_Color; + u_setrtzb(RCache, rt_Position, _2, rt_MSAADepth); +#else if (!RImplementation.o.gbuffer_opt) { if (RImplementation.o.albedo_wo) @@ -69,6 +86,7 @@ void CRenderTarget::phase_scene_begin() u_setrt(RCache, rt_Position, rt_Color, rt_MSAADepth); // else u_setrt (rt_Position, rt_Color, rt_Normal, rt_MSAADepth); } +#endif // Stencil - write 0x1 at pixel pos RCache.set_Stencil( @@ -98,7 +116,12 @@ void CRenderTarget::phase_scene_end() return; // transfer from "rt_Accumulator" into "rt_Color" +#ifdef USE_OGL + u_setrtzb(RCache, rt_Color, rt_MSAADepth); +#else u_setrt(RCache, rt_Color, nullptr, nullptr, rt_MSAADepth); +#endif + RCache.set_CullMode(CULL_NONE); RCache.set_Stencil(TRUE, D3DCMP_LESSEQUAL, 0x01, 0xff, 0x00); // stencil should be >= 1 if (RImplementation.o.nvstencil) diff --git a/src/Layers/xrRender_R2/r3_rendertarget_phase_smap_D.cpp b/src/Layers/xrRender_R2/r3_rendertarget_phase_smap_D.cpp index f95d8f3e488..01c67186ce4 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_phase_smap_D.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_phase_smap_D.cpp @@ -6,7 +6,11 @@ void CRenderTarget::phase_smap_direct(CBackend& cmd_list, light *L, u32 sub_phas { if (sub_phase == SE_SUN_RAIN_SMAP) { +#ifdef USE_OGL + u_set_zb(cmd_list, rt_smap_rain); +#else u_setrt(cmd_list, nullptr, nullptr, nullptr, rt_smap_rain); +#endif cmd_list.ClearZB(rt_smap_rain, 1.0f); cmd_list.SetViewport({0, 0, rt_smap_rain->dwWidth, rt_smap_rain->dwHeight, 0.0, 1.0}); } diff --git a/src/Layers/xrRender_R2/r3_rendertarget_phase_ssao.cpp b/src/Layers/xrRender_R2/r3_rendertarget_phase_ssao.cpp index 188a003d3df..54e2423b446 100644 --- a/src/Layers/xrRender_R2/r3_rendertarget_phase_ssao.cpp +++ b/src/Layers/xrRender_R2/r3_rendertarget_phase_ssao.cpp @@ -10,7 +10,12 @@ void CRenderTarget::phase_ssao() RCache.ClearRT(rt_ssao_temp, {}); // low/hi RTs +#ifdef USE_OGL + u_setrt_(RCache, rt_ssao_temp); +#else u_setrt(RCache, rt_ssao_temp, nullptr, nullptr, nullptr /*rt_MSAADepth*/); +#endif + RCache.set_Stencil(FALSE); @@ -102,7 +107,12 @@ void CRenderTarget::phase_downsamp() // Fvector2 p0,p1; u32 Offset = 0; +#ifdef USE_OGL + u_setrt_(RCache, rt_half_depth); +#else u_setrt(RCache, rt_half_depth, nullptr, nullptr, nullptr /*rt_MSAADepth*/); +#endif + RCache.ClearRT(rt_half_depth, {}); // black u32 w = Device.dwWidth; u32 h = Device.dwHeight;