From bb8867fb77f8aef4b269ff1044ff095d89bad020 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 11 Feb 2012 21:09:35 +0000 Subject: [PATCH] move GSG::get_supports_render_texture() into GraphicsOutput to support render-to-texture on non-Windows platform. Also, further fixes to FBO render-to-texture. --- panda/src/display/graphicsOutput.cxx | 24 +++++++---- panda/src/display/graphicsOutput.h | 2 + panda/src/display/graphicsStateGuardian.I | 13 ------ panda/src/display/graphicsStateGuardian.cxx | 1 - panda/src/display/graphicsStateGuardian.h | 2 - panda/src/dxgsg8/dxGraphicsStateGuardian8.I | 13 ++++++ panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 1 + panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 2 + panda/src/dxgsg9/dxGraphicsStateGuardian9.I | 13 ++++++ panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 1 + panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 3 ++ panda/src/egldisplay/eglGraphicsPipe.cxx | 4 ++ panda/src/glstuff/glGraphicsBuffer_src.cxx | 43 ++++++++++++------- panda/src/glstuff/glGraphicsBuffer_src.h | 2 + panda/src/glxdisplay/glxGraphicsPipe.cxx | 4 ++ panda/src/wgldisplay/wglGraphicsBuffer.cxx | 19 ++++++++ panda/src/wgldisplay/wglGraphicsBuffer.h | 2 + panda/src/wgldisplay/wglGraphicsPipe.cxx | 2 +- .../src/wgldisplay/wglGraphicsStateGuardian.I | 12 ++++++ .../wgldisplay/wglGraphicsStateGuardian.cxx | 7 +-- .../src/wgldisplay/wglGraphicsStateGuardian.h | 4 +- 21 files changed, 130 insertions(+), 44 deletions(-) diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 80e7bbac3d..b3b8fff90e 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -365,15 +365,10 @@ add_render_texture(Texture *tex, RenderTextureMode mode, tex->set_size_padded(get_x_size(), get_y_size()); if (mode == RTM_bind_or_copy) { - // Binding is not supported or it is disabled, so just fall back - // to copy instead. - if (!support_render_texture) { + if (!support_render_texture || !get_supports_render_texture()) { + // Binding is not supported or it is disabled, so just fall back + // to copy instead. mode = RTM_copy_texture; - } else { - nassertv(_gsg != NULL); - if (!_gsg->get_supports_render_texture()) { - mode = RTM_copy_texture; - } } } @@ -1128,6 +1123,19 @@ void GraphicsOutput:: unshare_depth_buffer() { } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::get_supports_render_texture +// Access: Published, Virtual +// Description: Returns true if this particular GraphicsOutput can +// render directly into a texture, or false if it must +// always copy-to-texture at the end of each frame to +// achieve this effect. +//////////////////////////////////////////////////////////////////// +bool GraphicsOutput:: +get_supports_render_texture() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::flip_ready // Access: Public, Virtual diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 6e972797d8..a0222e8368 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -213,6 +213,8 @@ PUBLISHED: virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual void unshare_depth_buffer(); + virtual bool get_supports_render_texture() const; + public: // These are not intended to be called directly by the user. virtual bool flip_ready() const; diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 7edaf68c17..65fb416357 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -584,19 +584,6 @@ get_supports_generate_mipmap() const { return _supports_generate_mipmap; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_supports_render_texture -// Access: Published -// Description: Returns true if this particular GSG can render -// directly into a texture, or false if it must always -// copy-to-texture at the end of each frame to achieve -// this effect. -//////////////////////////////////////////////////////////////////// -INLINE bool GraphicsStateGuardian:: -get_supports_render_texture() const { - return _supports_render_texture; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_supports_depth_texture // Access: Published diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 35ad920432..c465a417e2 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -210,7 +210,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, // Similarly with these capabilities flags. _supports_multisample = false; _supports_generate_mipmap = false; - _supports_render_texture = false; _supports_depth_texture = false; _supports_depth_stencil = false; _supports_shadow_filter = false; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 463540397f..5654a7c7a6 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -139,7 +139,6 @@ PUBLISHED: INLINE bool get_copy_texture_inverted() const; virtual bool get_supports_multisample() const; INLINE bool get_supports_generate_mipmap() const; - INLINE bool get_supports_render_texture() const; INLINE bool get_supports_depth_texture() const; INLINE bool get_supports_depth_stencil() const; INLINE bool get_supports_shadow_filter() const; @@ -478,7 +477,6 @@ protected: bool _copy_texture_inverted; bool _supports_multisample; bool _supports_generate_mipmap; - bool _supports_render_texture; bool _supports_depth_texture; bool _supports_depth_stencil; bool _supports_shadow_filter; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I index aad030845a..dde43ecddb 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I @@ -144,3 +144,16 @@ get_safe_buffer_start() { return _safe_buffer_start; } + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::get_supports_render_texture +// Access: Published +// Description: Returns true if this particular GSG can render +// from a wdxGraphicsBuffer8 directly into a texture, or +// false if it must always copy-to-texture at the end of +// each frame to achieve this effect. +//////////////////////////////////////////////////////////////////// +INLINE bool DXGraphicsStateGuardian8:: +get_supports_render_texture() const { + return _supports_render_texture; +} diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 53d01bc9c0..b344e9964d 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -96,6 +96,7 @@ DXGraphicsStateGuardian8(GraphicsEngine *engine, GraphicsPipe *pipe) : _vertex_blending_enabled = false; _overlay_windows_supported = false; _tex_stats_retrieval_impossible = false; + _supports_render_texture = false; _active_vbuffer = NULL; _active_ibuffer = NULL; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 765bfd23ad..4116089220 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -122,6 +122,7 @@ public: virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); LPDIRECT3DDEVICE8 get_d3d_device(); + INLINE bool get_supports_render_texture() const; static bool get_gamma_table(void); static bool static_set_gamma(bool restore, PN_stdfloat gamma); @@ -225,6 +226,7 @@ protected: HRESULT _last_testcooplevel_result; bool _vertex_blending_enabled; + bool _supports_render_texture; RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation bool _auto_rescale_normal; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.I b/panda/src/dxgsg9/dxGraphicsStateGuardian9.I index 35b3b7ea4c..f6d2e0391f 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.I +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.I @@ -213,3 +213,16 @@ set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value) return hr; } + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::get_supports_render_texture +// Access: Published +// Description: Returns true if this particular GSG can render +// from a wdxGraphicsBuffer9 directly into a texture, or +// false if it must always copy-to-texture at the end of +// each frame to achieve this effect. +//////////////////////////////////////////////////////////////////// +INLINE bool DXGraphicsStateGuardian9:: +get_supports_render_texture() const { + return _supports_render_texture; +} diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 0851573d34..96bdb0e446 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -115,6 +115,7 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) : _vertex_blending_enabled = false; _overlay_windows_supported = false; _tex_stats_retrieval_impossible = false; + _supports_render_texture = false; _active_ibuffer = NULL; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 2c1dfc5ece..c9c0df9fd9 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -157,6 +157,8 @@ public: INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); + INLINE bool get_supports_render_texture() const; + static bool get_gamma_table(void); static bool static_set_gamma(bool restore, PN_stdfloat gamma); bool set_gamma(PN_stdfloat gamma); @@ -269,6 +271,7 @@ protected: HRESULT _last_testcooplevel_result; bool _vertex_blending_enabled; + bool _supports_render_texture; RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation bool _auto_rescale_normal; diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index dcf41e8b8d..cc9d44969c 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -232,11 +232,15 @@ make_output(const string &name, bool support_rtt; support_rtt = false; + /* + Currently, no support for eglGraphicsBuffer render-to-texture. if (eglgsg) { support_rtt = eglgsg -> get_supports_render_texture() && support_render_texture; } + */ + // First thing to try: an eglGraphicsWindow if (retry == 0) { diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index ef6ab469ba..4a14b97102 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -158,14 +158,12 @@ begin_frame(FrameMode mode, Thread *current_thread) { } } - if (_needs_rebuild) { - rebuild_bitplanes(); + rebuild_bitplanes(); - if (_needs_rebuild) { - // If we still need rebuild, something went wrong with - // rebuild_bitplanes(). - return false; - } + if (_needs_rebuild) { + // If we still need rebuild, something went wrong with + // rebuild_bitplanes(). + return false; } } @@ -237,12 +235,13 @@ rebuild_bitplanes() { return; } - if (!_needs_rebuild) { - return; - } - CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); + + if (!_needs_rebuild) { + glgsg->bind_fbo(_fbo[0]); + return; + } // Calculate bitplane size. This can be larger than the buffer. if (_creation_flags & GraphicsPipe::BF_size_track_host) { @@ -290,10 +289,6 @@ rebuild_bitplanes() { continue; } - if (tex->get_texture_type() == Texture::TT_cube_map) { - any_cube_maps = true; - } - // If I can't find an appropriate slot, or if there's // already a texture bound to this slot, then punt // this texture. @@ -301,8 +296,12 @@ rebuild_bitplanes() { ((CData *)cdata.p())->_textures[i]._rtm_mode = RTM_copy_texture; continue; } + // Assign the texture to this slot. attach[plane] = tex; + if (tex->get_texture_type() == Texture::TT_cube_map) { + any_cube_maps = true; + } } } @@ -1018,6 +1017,20 @@ unshare_depth_buffer() { } } +//////////////////////////////////////////////////////////////////// +// Function: glGraphicsBuffer::get_supports_render_texture +// Access: Published, Virtual +// Description: Returns true if this particular GraphicsOutput can +// render directly into a texture, or false if it must +// always copy-to-texture at the end of each frame to +// achieve this effect. +//////////////////////////////////////////////////////////////////// +bool CLP(GraphicsBuffer):: +get_supports_render_texture() const { + // FBO-based buffers, by their nature, can always bind-to-texture. + return true; +} + //////////////////////////////////////////////////////////////////// // Function: glGraphicsBuffer::register_shared_depth_buffer // Access: Public diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index 9f970ed624..ffcf27f5c5 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -77,6 +77,8 @@ public: virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual void unshare_depth_buffer(); + virtual bool get_supports_render_texture() const; + void register_shared_depth_buffer(GraphicsOutput *graphics_output); void unregister_shared_depth_buffer(GraphicsOutput *graphics_output); diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index f745a66274..f7c9e92e68 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/panda/src/glxdisplay/glxGraphicsPipe.cxx @@ -95,11 +95,15 @@ make_output(const string &name, bool support_rtt; support_rtt = false; + /* + Currently, no support for glxGraphicsBuffer render-to-texture. if (glxgsg) { support_rtt = glxgsg -> get_supports_render_texture() && support_render_texture; } + */ + // First thing to try: a glxGraphicsWindow if (retry == 0) { diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 07e7443021..273aae5462 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -253,6 +253,25 @@ process_events() { } } +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsBuffer::get_supports_render_texture +// Access: Published, Virtual +// Description: Returns true if this particular GraphicsOutput can +// render directly into a texture, or false if it must +// always copy-to-texture at the end of each frame to +// achieve this effect. +//////////////////////////////////////////////////////////////////// +bool wglGraphicsBuffer:: +get_supports_render_texture() const { + if (_gsg == (GraphicsStateGuardian *)NULL) { + return false; + } + + wglGraphicsStateGuardian *wglgsg; + DCAST_INTO_R(wglgsg, _gsg, false); + return wglgsg->get_supports_wgl_render_texture(); +} + //////////////////////////////////////////////////////////////////// // Function: wglGraphicsBuffer::close_buffer // Access: Protected, Virtual diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index e1845a8b07..128d877331 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.h +++ b/panda/src/wgldisplay/wglGraphicsBuffer.h @@ -53,6 +53,8 @@ public: virtual void process_events(); + virtual bool get_supports_render_texture() const; + protected: virtual void close_buffer(); virtual bool open_buffer(); diff --git a/panda/src/wgldisplay/wglGraphicsPipe.cxx b/panda/src/wgldisplay/wglGraphicsPipe.cxx index 73ce3383b9..8020f2f56e 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.cxx +++ b/panda/src/wgldisplay/wglGraphicsPipe.cxx @@ -126,7 +126,7 @@ make_output(const string &name, support_rtt = false; if (wglgsg) { support_rtt = - wglgsg -> get_supports_render_texture() && + wglgsg -> get_supports_wgl_render_texture() && support_render_texture; } diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.I b/panda/src/wgldisplay/wglGraphicsStateGuardian.I index 3b27a4fb2d..7c652f1123 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.I +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.I @@ -100,3 +100,15 @@ get_twindow_dc() { return _twindow_dc; } +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsStateGuardian::get_supports_wgl_render_texture +// Access: Published +// Description: Returns true if this particular GSG can render +// from a wglGraphicsBuffer directly into a texture, or +// false if it must always copy-to-texture at the end of +// each frame to achieve this effect. +//////////////////////////////////////////////////////////////////// +INLINE bool wglGraphicsStateGuardian:: +get_supports_wgl_render_texture() const { + return _supports_wgl_render_texture; +} diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index dcb99cee3c..9850ecc961 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -45,6 +45,7 @@ wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, _supports_pbuffer = false; _supports_pixel_format = false; _supports_wgl_multisample = false; + _supports_wgl_render_texture = false; get_gamma_table(); atexit(atexit_function); @@ -518,9 +519,9 @@ reset() { _supports_wgl_multisample = has_extension("WGL_ARB_multisample"); - _supports_render_texture = has_extension("WGL_ARB_render_texture"); + _supports_wgl_render_texture = has_extension("WGL_ARB_render_texture"); - if (_supports_render_texture) { + if (_supports_wgl_render_texture) { _wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress("wglBindTexImageARB"); _wglReleaseTexImageARB = @@ -532,7 +533,7 @@ reset() { _wglSetPbufferAttribARB == NULL) { wgldisplay_cat.error() << "Driver claims to support WGL_ARB_render_texture, but does not define all functions.\n"; - _supports_render_texture = false; + _supports_wgl_render_texture = false; } } } diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index 4c6d0a79a2..e8fe61177a 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -47,6 +47,7 @@ public: virtual void reset(); INLINE HDC get_twindow_dc(); + INLINE bool get_supports_wgl_render_texture() const; static bool get_gamma_table(void); static bool static_set_gamma(bool restore, PN_stdfloat gamma); @@ -54,6 +55,7 @@ public: void restore_gamma(); static void atexit_function(void); + protected: virtual void get_extra_extensions(); virtual void *do_get_extension_func(const char *prefix, const char *name); @@ -84,7 +86,6 @@ private: FrameBufferProperties _pre_pfnum_properties; int _pre_pfnum; - bool _made_context; HGLRC _context; @@ -112,6 +113,7 @@ public: bool _supports_wgl_multisample; + bool _supports_wgl_render_texture; PFNWGLBINDTEXIMAGEARBPROC _wglBindTexImageARB; PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB; PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB;