Add depth buffer sharing.

This commit is contained in:
aignacio_sf 2008-02-13 01:08:36 +00:00
parent b6ea4ab8b2
commit 6dfe4ab030
6 changed files with 349 additions and 25 deletions

View File

@ -1218,3 +1218,24 @@ operator << (ostream &out, GraphicsOutput::FrameMode fm) {
return out << "(**invalid GraphicsOutput::FrameMode(" << (int)fm << ")**)";
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::share_depth_buffer
// Access: Published, Virtual
// Description: Will attempt to use the depth buffer of the input
// graphics_output. The buffer sizes must be exactly
// the same.
////////////////////////////////////////////////////////////////////
bool GraphicsOutput::
share_depth_buffer(GraphicsOutput *graphics_output) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::unshare_depth_buffer
// Access: Published, Virtual
// Description: Discontinue sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
unshare_depth_buffer() {
}

View File

@ -194,6 +194,9 @@ PUBLISHED:
NodePath get_texture_card();
virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer();
public:
// These are not intended to be called directly by the user.
INLINE bool flip_ready() const;

View File

@ -54,6 +54,9 @@ wdxGraphicsBuffer9(GraphicsPipe *pipe,
// same buffer we draw into.
_screenshot_buffer_type = _draw_buffer_type;
_shared_depth_buffer = 0;
_debug = 0;
if (_gsg) {
// save to GSG list to handle device lost issues
DXGraphicsStateGuardian9 *dxgsg;
@ -79,6 +82,29 @@ wdxGraphicsBuffer9::
dxgsg -> _graphics_buffer_list.remove(this);
}
// unshare shared depth buffer if any
this -> unshare_depth_buffer();
// unshare all buffers that are sharing this object's depth buffer
{
wdxGraphicsBuffer9 *graphics_buffer;
list <wdxGraphicsBuffer9 *>::iterator graphics_buffer_iterator;
graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) {
graphics_buffer = (*graphics_buffer_iterator);
if (graphics_buffer) {
// this call removes the entry from the list
graphics_buffer -> unshare_depth_buffer();
}
graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
}
}
if (_debug) {
printf ("wdxGraphicsBuffer9 destructor \n");
}
this -> close_buffer ( );
}
@ -147,7 +173,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsStateGuardian::save_bitplanes
// Function: wdxGraphicsBuffer9::save_bitplanes
// Access: Public
// Description: After rendering, d3d_device will need to be restored
// to its initial state. This function saves the state.
@ -170,7 +196,7 @@ save_bitplanes() {
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsStateGuardian::restore_bitplanes
// Function: wdxGraphicsBuffer9::restore_bitplanes
// Access: Public
// Description: After rendering, d3d_device will need to be restored
// to its initial state. This function restores the state.
@ -200,14 +226,13 @@ restore_bitplanes() {
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsStateGuardian::rebuild_bitplanes
// Function: wdxGraphicsBuffer9::rebuild_bitplanes
// Access: Public
// Description: If necessary, reallocates (or allocates) the
// bitplanes for the buffer.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer9::
rebuild_bitplanes() {
HRESULT hr;
Texture *color_tex = 0;
Texture *depth_tex = 0;
@ -300,30 +325,51 @@ rebuild_bitplanes() {
}
}
bool release_depth;
release_depth = true;
if (depth_tex_index < 0) {
// Maintain the backing depth surface.
if ((_depth_backing_store)&&
((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
_depth_backing_store->Release();
_depth_backing_store = NULL;
}
if (!_depth_backing_store) {
hr = _dxgsg -> _d3d_device ->
CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
_saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
false, &_depth_backing_store, NULL);
if (!SUCCEEDED(hr)) {
dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
if (_shared_depth_buffer) {
if (_shared_depth_buffer -> _depth_backing_store) {
if (_debug) {
printf ("SHARE DEPTH BUFFER\n");
}
depth_surf = _shared_depth_buffer -> _depth_backing_store;
release_depth = false;
}
}
depth_surf = _depth_backing_store;
if (depth_surf == 0) {
// Maintain the backing depth surface.
if ((_depth_backing_store)&&
((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
_depth_backing_store->Release();
_depth_backing_store = NULL;
}
if (!_depth_backing_store) {
hr = _dxgsg -> _d3d_device ->
CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
_saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
false, &_depth_backing_store, NULL);
if (!SUCCEEDED(hr)) {
dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
}
}
depth_surf = _depth_backing_store;
}
} else {
// Maintain the depth texture.
if (_depth_backing_store) {
_depth_backing_store->Release();
_depth_backing_store = NULL;
}
depth_tex = get_texture(depth_tex_index);
if (_shared_depth_buffer) {
depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index);
}
if (depth_tex == 0) {
depth_tex = get_texture(depth_tex_index);
}
depth_tex->set_x_size(bitplane_x);
depth_tex->set_y_size(bitplane_y);
depth_tex->set_format(Texture::F_depth_stencil);
@ -374,9 +420,13 @@ rebuild_bitplanes() {
if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
color_surf->Release();
}
if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
depth_surf->Release();
if (release_depth) {
if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
depth_surf->Release();
}
}
return true;
}
@ -558,3 +608,108 @@ process_1_event() {
// Call window_proc
DispatchMessage(&msg);
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::share_depth_buffer
// Access: Published
// Description: Will attempt to use the depth buffer of the input
// graphics_output. The buffer sizes must be exactly
// the same.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer9::
share_depth_buffer(GraphicsOutput *graphics_output) {
bool state;
wdxGraphicsBuffer9 *input_graphics_output;
state = false;
input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
if (this != input_graphics_output && input_graphics_output) {
state = true;
this -> unshare_depth_buffer();
if (_debug) {
printf ("share_depth_buffer\n");
}
// check buffer sizes
if (this -> get_x_size() != input_graphics_output -> get_x_size()) {
if (_debug) {
printf ("ERROR: share_depth_buffer: non matching width \n");
}
state = false;
}
if (this -> get_y_size() != input_graphics_output -> get_y_size()) {
if (_debug) {
printf ("ERROR: share_depth_buffer: non matching height \n");
}
state = false;
}
if (state) {
// let the input GraphicsOutput know that there is an object
// sharing its depth buffer
input_graphics_output -> register_shared_depth_buffer(this);
_shared_depth_buffer = input_graphics_output;
state = true;
}
}
return state;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::unshare_depth_buffer
// Access: Published
// Description: Discontinue sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9::
unshare_depth_buffer() {
if (_shared_depth_buffer) {
if (_debug) {
printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n");
}
// let the GraphicsOutput know that this object is no longer
// sharing its depth buffer
_shared_depth_buffer -> unregister_shared_depth_buffer(this);
_shared_depth_buffer = 0;
}
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::register_shared_depth_buffer
// Access: Public
// Description: Register/save who is sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9::
register_shared_depth_buffer(GraphicsOutput *graphics_output) {
wdxGraphicsBuffer9 *input_graphics_output;
input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
if (input_graphics_output) {
// add to list
_shared_depth_buffer_list.push_back(input_graphics_output);
}
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer
// Access: Public
// Description: Unregister who is sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9::
unregister_shared_depth_buffer(GraphicsOutput *graphics_output) {
wdxGraphicsBuffer9 *input_graphics_output;
input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
if (input_graphics_output) {
// remove from list
_shared_depth_buffer_list.remove(input_graphics_output);
}
}

View File

@ -51,6 +51,12 @@ public:
virtual void select_cube_map(int cube_map_index);
virtual void process_events();
virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer();
void register_shared_depth_buffer(GraphicsOutput *graphics_output);
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output);
protected:
virtual void close_buffer();
virtual bool open_buffer();
@ -72,6 +78,9 @@ private:
int _backing_sizex;
int _backing_sizey;
wdxGraphicsBuffer9 *_shared_depth_buffer;
list <wdxGraphicsBuffer9 *> _shared_depth_buffer_list;
public:
static TypeHandle get_class_type() {
return _type_handle;
@ -87,6 +96,7 @@ public:
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
bool _debug;
static TypeHandle _type_handle;
friend class DXGraphicsStateGuardian9;

View File

@ -46,6 +46,8 @@ CLP(GraphicsBuffer)(GraphicsPipe *pipe,
_rb[i] = 0;
_tex[i] = 0;
}
_shared_depth_buffer = 0;
}
////////////////////////////////////////////////////////////////////
@ -55,6 +57,24 @@ CLP(GraphicsBuffer)(GraphicsPipe *pipe,
////////////////////////////////////////////////////////////////////
CLP(GraphicsBuffer)::
~CLP(GraphicsBuffer)() {
// unshare shared depth buffer if any
this -> unshare_depth_buffer();
// unshare all buffers that are sharing this object's depth buffer
{
CLP(GraphicsBuffer) *graphics_buffer;
list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) {
graphics_buffer = (*graphics_buffer_iterator);
if (graphics_buffer) {
// this call removes the entry from the list
graphics_buffer -> unshare_depth_buffer();
}
graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
}
}
}
////////////////////////////////////////////////////////////////////
@ -336,7 +356,7 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
// If a renderbuffer is already attached to the slot, and it's
// the right size, then no update of this slot is needed.
if ((_rb[slot] != 0)&&(!rb_resize)) {
if (_shared_depth_buffer == 0 && (_rb[slot] != 0)&&(!rb_resize)) {
return;
}
@ -352,16 +372,33 @@ bind_slot(bool rb_resize, Texture **attach, RenderTexturePlane slot, GLenum atta
glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
_rb_size_x, _rb_size_y);
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
GLuint rb;
rb = _rb[slot];
if (_shared_depth_buffer) {
rb = _shared_depth_buffer -> _rb[slot];
}
glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, _rb[slot]);
GL_RENDERBUFFER_EXT, rb);
glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, _rb[slot]);
GL_RENDERBUFFER_EXT, rb);
} else {
glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
_rb_size_x, _rb_size_y);
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
GLuint rb;
rb = _rb[slot];
if (_shared_depth_buffer) {
rb = _shared_depth_buffer -> _rb[slot];
}
glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, _rb[slot]);
GL_RENDERBUFFER_EXT, rb);
}
} else {
glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA,
@ -577,3 +614,92 @@ close_buffer() {
_is_valid = false;
}
////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::share_depth_buffer
// Access: Published
// Description: Will attempt to use the depth buffer of the input
// graphics_output. The buffer sizes must be exactly
// the same.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsBuffer)::
share_depth_buffer(GraphicsOutput *graphics_output) {
bool state;
CLP(GraphicsBuffer) *input_graphics_output;
state = false;
input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
if (this != input_graphics_output && input_graphics_output) {
state = true;
this -> unshare_depth_buffer();
// check buffer sizes
if (this -> get_x_size() != input_graphics_output -> get_x_size()) {
GLCAT.error() << "share_depth_buffer: non matching width \n";
state = false;
}
if (this -> get_y_size() != input_graphics_output -> get_y_size()) {
GLCAT.error() << "share_depth_buffer: non matching height \n";
state = false;
}
if (state) {
// let the input GraphicsOutput know that there is an object
// sharing its depth buffer
input_graphics_output -> register_shared_depth_buffer(this);
_shared_depth_buffer = input_graphics_output;
state = true;
}
}
return state;
}
////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::unshare_depth_buffer
// Access: Published
// Description: Discontinue sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
unshare_depth_buffer() {
if (_shared_depth_buffer) {
// let the GraphicsOutput know that this object is no longer
// sharing its depth buffer
_shared_depth_buffer -> unregister_shared_depth_buffer(this);
_shared_depth_buffer = 0;
}
}
////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::register_shared_depth_buffer
// Access: Public
// Description: Register/save who is sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
register_shared_depth_buffer(GraphicsOutput *graphics_output) {
CLP(GraphicsBuffer) *input_graphics_output;
input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
if (input_graphics_output) {
// add to list
_shared_depth_buffer_list.push_back(input_graphics_output);
}
}
////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::unregister_shared_depth_buffer
// Access: Public
// Description: Unregister who is sharing the depth buffer.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
unregister_shared_depth_buffer(GraphicsOutput *graphics_output) {
CLP(GraphicsBuffer) *input_graphics_output;
input_graphics_output = DCAST (CLP(GraphicsBuffer), graphics_output);
if (input_graphics_output) {
// remove from list
_shared_depth_buffer_list.remove(input_graphics_output);
}
}

View File

@ -70,6 +70,12 @@ public:
virtual void select_cube_map(int cube_map_index);
virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer();
void register_shared_depth_buffer(GraphicsOutput *graphics_output);
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output);
protected:
virtual void close_buffer();
virtual bool open_buffer();
@ -89,6 +95,9 @@ private:
PT(Texture) _tex[RTP_COUNT];
GLuint _rb[RTP_COUNT];
GLenum _attach_point[RTP_COUNT];
CLP(GraphicsBuffer) *_shared_depth_buffer;
list <CLP(GraphicsBuffer) *> _shared_depth_buffer_list;
public:
static TypeHandle get_class_type() {