Browse Source

dx9 occlusion queries

David Rose 18 years ago
parent
commit
9d16c5bf23

+ 3 - 3
panda/src/display/graphicsEngine.cxx

@@ -67,9 +67,9 @@ PStatCollector GraphicsEngine::_cull_setup_pcollector("Cull:Setup");
 PStatCollector GraphicsEngine::_cull_sort_pcollector("Cull:Sort");
 PStatCollector GraphicsEngine::_draw_pcollector("Draw");
 PStatCollector GraphicsEngine::_sync_pcollector("Draw:Sync");
-PStatCollector GraphicsEngine::_flip_pcollector("Draw:Flip");
-PStatCollector GraphicsEngine::_flip_begin_pcollector("Draw:Flip:Begin");
-PStatCollector GraphicsEngine::_flip_end_pcollector("Draw:Flip:End");
+PStatCollector GraphicsEngine::_flip_pcollector("Wait:Flip");
+PStatCollector GraphicsEngine::_flip_begin_pcollector("Wait:Flip:Begin");
+PStatCollector GraphicsEngine::_flip_end_pcollector("Wait:Flip:End");
 PStatCollector GraphicsEngine::_transform_states_pcollector("TransformStates");
 PStatCollector GraphicsEngine::_transform_states_unused_pcollector("TransformStates:Unused");
 PStatCollector GraphicsEngine::_render_states_pcollector("RenderStates");

+ 3 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -70,6 +70,9 @@ PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive
 PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
 PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
 
+PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector("Wait:Occlusion");
+
+
 PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
 
 TypeHandle GraphicsStateGuardian::_type_handle;

+ 1 - 0
panda/src/display/graphicsStateGuardian.h

@@ -437,6 +437,7 @@ public:
   static PStatCollector _draw_primitive_pcollector;
   static PStatCollector _clear_pcollector;
   static PStatCollector _flush_pcollector;
+  static PStatCollector _wait_occlusion_pcollector;
 
 private:
   class LightInfo {

+ 2 - 0
panda/src/dxgsg9/Sources.pp

@@ -27,6 +27,7 @@
     dxTextureContext9.h dxTextureContext9.I \
     dxGeomMunger9.h dxGeomMunger9.I \
     dxGraphicsDevice9.h \
+    dxOcclusionQueryContext9.h dxOcclusionQueryContext9.I \
     dxShaderContext9.h \
     vertexElementArray.h
     
@@ -41,6 +42,7 @@
     wdxGraphicsWindow9.cxx \
     wdxGraphicsBuffer9.cxx \
     dxShaderContext9.cxx \
+    dxOcclusionQueryContext9.cxx \
     vertexElementArray.cxx
 
 #end lib_target

+ 3 - 1
panda/src/dxgsg9/config_dxgsg9.cxx

@@ -21,6 +21,7 @@
 #include "dxTextureContext9.h"
 #include "dxVertexBufferContext9.h"
 #include "dxIndexBufferContext9.h"
+#include "dxOcclusionQueryContext9.h"
 #include "dxShaderContext9.h"
 #include "dxGeomMunger9.h"
 #include "graphicsPipeSelection.h"
@@ -224,7 +225,8 @@ init_libdxgsg9() {
   DXTextureContext9::init_type();
   DXVertexBufferContext9::init_type();
   DXIndexBufferContext9::init_type();
-  CLP(ShaderContext)::init_type();
+  DXOcclusionQueryContext9::init_type();
+  DXShaderContext9::init_type();
   DXGeomMunger9::init_type();
 
   wdxGraphicsPipe9::init_type();

+ 81 - 5
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -58,6 +58,7 @@
 #include "config_gobj.h"
 #include "dxVertexBufferContext9.h"
 #include "dxIndexBufferContext9.h"
+#include "dxOcclusionQueryContext9.h"
 #include "pStatTimer.h"
 #include "pStatCollector.h"
 #include "wdxGraphicsBuffer9.h"
@@ -345,7 +346,7 @@ release_texture(TextureContext *tc) {
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
-ShaderContext *CLP(GraphicsStateGuardian)::
+ShaderContext *DXGraphicsStateGuardian9::
 prepare_shader(ShaderExpansion *se) {
 #ifdef HAVE_CG
   CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
@@ -359,7 +360,7 @@ prepare_shader(ShaderExpansion *se) {
 //       Access: Public, Virtual
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 release_shader(ShaderContext *sc) {
   CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
   delete gsc;
@@ -667,6 +668,76 @@ release_index_buffer(IndexBufferContext *ibc) {
   delete dibc;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian9::begin_occlusion_query
+//       Access: Public, Virtual
+//  Description: Begins a new occlusion query.  After this call, you
+//               may call begin_draw_primitives() and
+//               draw_triangles()/draw_whatever() repeatedly.
+//               Eventually, you should call end_occlusion_query()
+//               before the end of the frame; that will return a new
+//               OcclusionQueryContext object that will tell you how
+//               many pixels represented by the bracketed geometry
+//               passed the depth test.
+//
+//               It is not valid to call begin_occlusion_query()
+//               between another begin_occlusion_query()
+//               .. end_occlusion_query() sequence.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian9::
+begin_occlusion_query() {
+  nassertv(_supports_occlusion_query);
+  nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
+
+  IDirect3DQuery9 *query;
+  HRESULT hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
+  if (FAILED(hr)) {
+    dxgsg9_cat.warning()
+      << "Occlusion query failed.\n";
+    return;
+  }
+  
+  PT(DXOcclusionQueryContext9) queryobj = new DXOcclusionQueryContext9(query);
+
+  if (dxgsg9_cat.is_debug()) {
+    dxgsg9_cat.debug()
+      << "beginning occlusion query " << query << "\n";
+  }
+
+  query->Issue(D3DISSUE_BEGIN);
+  _current_occlusion_query = queryobj;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian9::end_occlusion_query
+//       Access: Public, Virtual
+//  Description: Ends a previous call to begin_occlusion_query().
+//               This call returns the OcclusionQueryContext object
+//               that will (eventually) report the number of pixels
+//               that passed the depth test between the call to
+//               begin_occlusion_query() and end_occlusion_query().
+////////////////////////////////////////////////////////////////////
+PT(OcclusionQueryContext) DXGraphicsStateGuardian9::
+end_occlusion_query() {
+  if (_current_occlusion_query == (OcclusionQueryContext *)NULL) {
+    return NULL;
+  }
+
+  PT(OcclusionQueryContext) result = _current_occlusion_query;
+
+  IDirect3DQuery9 *query = DCAST(DXOcclusionQueryContext9, result)->_query;
+    
+  if (dxgsg9_cat.is_debug()) {
+    dxgsg9_cat.debug()
+      << "ending occlusion query " << query << "\n";
+  }
+
+  _current_occlusion_query = NULL;
+  query->Issue(D3DISSUE_END);
+
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::make_geom_munger
 //       Access: Public, Virtual
@@ -2479,6 +2550,10 @@ reset() {
 
   _supports_depth_bias = ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0);
 
+  // Test for occlusion query support
+  hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL);
+  _supports_occlusion_query = !FAILED(hr);
+
   if (dxgsg9_cat.is_debug()) {
     dxgsg9_cat.debug()
       << "\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
@@ -2511,6 +2586,7 @@ reset() {
       << "\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
       << "\nsupports_stencil_wrap = " << _supports_stencil_wrap
       << "\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
+      << "\nsupports_occlusion_query = " << _supports_occlusion_query
       << "\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
       << "\nDirectX SDK version " DIRECTX_SDK_VERSION
       << "\n";
@@ -2954,7 +3030,7 @@ do_issue_alpha_test() {
 //       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 do_issue_shader() {
 
   DBG_SH3  dxgsg9_cat.debug ( ) << "SHADER: do_issue_shader\n"; DBG_E
@@ -3605,7 +3681,7 @@ do_issue_material() {
 //       Access: Protected
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 do_issue_texture() {
   DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
 
@@ -3634,7 +3710,7 @@ do_issue_texture() {
 //       Access: Private
 //  Description:
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 disable_standard_texture_bindings() {
   // Disable the texture stages that are no longer used.
   for (int i = 0; i < _num_active_texture_stages; i++) {

+ 4 - 1
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -102,6 +102,9 @@ public:
                           const GeomPrimitivePipelineReader *reader);
   virtual void release_index_buffer(IndexBufferContext *ibc);
 
+  virtual void begin_occlusion_query();
+  virtual PT(OcclusionQueryContext) end_occlusion_query();
+
   virtual PT(GeomMunger) make_geom_munger(const RenderState *state,
                                           Thread *current_thread);
 
@@ -384,7 +387,7 @@ private:
   friend class wdxGraphicsBuffer9;
   friend class DXVertexBufferContext9;
   friend class DXIndexBufferContext9;
-  friend class CLP(ShaderContext);
+  friend class DXShaderContext9;
 };
 
 #include "dxGraphicsStateGuardian9.I"

+ 27 - 0
panda/src/dxgsg9/dxOcclusionQueryContext9.I

@@ -0,0 +1,27 @@
+// Filename: dxOcclusionQueryContext9.I
+// Created by:  drose (04Jun07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXOcclusionQueryContext9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE DXOcclusionQueryContext9::
+DXOcclusionQueryContext9(IDirect3DQuery9 *query) : _query(query) {
+}

+ 102 - 0
panda/src/dxgsg9/dxOcclusionQueryContext9.cxx

@@ -0,0 +1,102 @@
+// Filename: dxOcclusionQueryContext9.cxx
+// Created by:  drose (04Jun07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxOcclusionQueryContext9.h"
+#include "dxGraphicsStateGuardian9.h"
+#include "pnotify.h"
+#include "dcast.h"
+#include "pStatTimer.h"
+
+TypeHandle DXOcclusionQueryContext9::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLOcclusionQueryContext::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXOcclusionQueryContext9::
+~DXOcclusionQueryContext9() {
+  _query->Release();
+  _query = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLOcclusionQueryContext::is_answer_ready
+//       Access: Public, Virtual
+//  Description: Returns true if the query's answer is ready, false
+//               otherwise.  If this returns false, the application
+//               must continue to poll until it returns true.
+//
+//               It is only valid to call this from the draw thread.
+////////////////////////////////////////////////////////////////////
+bool DXOcclusionQueryContext9::
+is_answer_ready() const {
+  DWORD result;
+  HRESULT hr = _query->GetData(&result, sizeof(result), 0);
+  return (hr != S_FALSE);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLOcclusionQueryContext::waiting_for_answer
+//       Access: Public, Virtual
+//  Description: Requests the graphics engine to expedite the pending
+//               answer--the application is now waiting until the
+//               answer is ready.
+//
+//               It is only valid to call this from the draw thread.
+////////////////////////////////////////////////////////////////////
+void DXOcclusionQueryContext9::
+waiting_for_answer() {
+  DWORD result;
+  PStatTimer timer(DXGraphicsStateGuardian9::_wait_occlusion_pcollector);
+  HRESULT hr = _query->GetData(&result, sizeof(result), D3DGETDATA_FLUSH);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLOcclusionQueryContext::get_num_fragments
+//       Access: Public, Virtual
+//  Description: Returns the number of fragments (pixels) of the
+//               specified geometry that passed the depth test.
+//               If is_answer_ready() did not return true, this
+//               function may block before it returns.
+//
+//               It is only valid to call this from the draw thread.
+////////////////////////////////////////////////////////////////////
+int DXOcclusionQueryContext9::
+get_num_fragments() const {
+  DWORD result;
+  HRESULT hr = _query->GetData(&result, sizeof(result), 0);
+  if (hr == S_OK) {
+    // The answer is ready now.
+    return result;
+  }
+
+  {
+    // The answer is not ready; this call will block.
+    PStatTimer timer(DXGraphicsStateGuardian9::_wait_occlusion_pcollector);
+    hr = _query->GetData(&result, sizeof(result), D3DGETDATA_FLUSH);
+  }
+
+  if (hr != S_OK) {
+    // Some failure, e.g. devicelost.  Return a nonzero value as a
+    // worst-case answer.
+    return 1;
+  }
+
+  return result;
+}

+ 64 - 0
panda/src/dxgsg9/dxOcclusionQueryContext9.h

@@ -0,0 +1,64 @@
+// Filename: dxOcclusionQueryContext9.h
+// Created by:  drose (04Jun07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXOCCLUSIONQUERYCONTEXT9_H
+#define DXOCCLUSIONQUERYCONTEXT9_H
+
+#include "pandabase.h"
+#include "occlusionQueryContext.h"
+#include "deletedChain.h"
+
+class GraphicsStateGuardian;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXOcclusionQueryContext9
+// Description :
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX DXOcclusionQueryContext9 : public OcclusionQueryContext {
+public:
+  INLINE DXOcclusionQueryContext9(IDirect3DQuery9 *query);
+  virtual ~DXOcclusionQueryContext9();
+  ALLOC_DELETED_CHAIN(DXOcclusionQueryContext9);
+
+  virtual bool is_answer_ready() const;
+  virtual void waiting_for_answer();
+  virtual int get_num_fragments() const;
+
+  IDirect3DQuery9 *_query;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    OcclusionQueryContext::init_type();
+    register_type(_type_handle, CLASSPREFIX_QUOTED "OcclusionQueryContext",
+                  OcclusionQueryContext::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "dxOcclusionQueryContext9.I"
+
+#endif

+ 1 - 0
panda/src/dxgsg9/dxgsg9_composite1.cxx

@@ -8,5 +8,6 @@
 #include "wdxGraphicsPipe9.cxx"
 #include "wdxGraphicsWindow9.cxx"
 #include "dxGraphicsDevice9.cxx"
+#include "dxOcclusionQueryContext9.cxx"
 #include "wdxGraphicsBuffer9.cxx"
 #include "vertexElementArray.cxx"

+ 0 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -64,7 +64,6 @@ PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:T
 PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
 PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
 PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
-PStatCollector CLP(GraphicsStateGuardian)::_wait_occlusion_pcollector("Wait:Occlusion");
 
 // The following noop functions are assigned to the corresponding
 // glext function pointers in the class, in case the functions are not

+ 0 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -473,7 +473,6 @@ public:
   static PStatCollector _primitive_batches_display_list_pcollector;
   static PStatCollector _vertices_display_list_pcollector;
   static PStatCollector _vertices_immediate_pcollector;
-  static PStatCollector _wait_occlusion_pcollector;
 
 public:
   virtual TypeHandle get_type() const {

+ 2 - 1
panda/src/glstuff/glOcclusionQueryContext_src.cxx

@@ -76,6 +76,7 @@ is_answer_ready() const {
 ////////////////////////////////////////////////////////////////////
 void CLP(OcclusionQueryContext)::
 waiting_for_answer() {
+  PStatTimer timer(GraphicsStateGuardian::_wait_occlusion_pcollector);
   GLP(Flush)();
 }
 
@@ -101,7 +102,7 @@ get_num_fragments() const {
     glgsg->_glGetQueryObjectuiv(_index, GL_QUERY_RESULT, &result);
   } else {
     // The answer is not ready; this call will block.
-    PStatTimer timer(glgsg->_wait_occlusion_pcollector);
+    PStatTimer timer(GraphicsStateGuardian::_wait_occlusion_pcollector);
     glgsg->_glGetQueryObjectuiv(_index, GL_QUERY_RESULT, &result);
   }
 

+ 3 - 4
panda/src/pstatclient/pStatProperties.cxx

@@ -114,7 +114,9 @@ static TimeCollectorProperties time_properties[] = {
   { 1, "Wait:Clock Wait",                  { 0.2, 0.8, 0.2 } },
   { 1, "Wait:Clock Wait:Sleep",            { 0.9, 0.4, 0.8 } },
   { 1, "Wait:Clock Wait:Spin",             { 0.2, 0.8, 1.0 } },
-  { 0, "Wait:Mutex block",                 { 0.5, 0.0, 1.0 } },
+  { 1, "Wait:Flip",                        { 1.0, 0.6, 0.3 } },
+  { 1, "Wait:Flip:Begin",                  { 0.3, 0.3, 0.9 } },
+  { 1, "Wait:Flip:End",                    { 0.9, 0.3, 0.6 } },
   { 1, "App",                              { 0.0, 0.4, 0.8 },  1.0 / 30.0 },
   { 1, "App:Collisions",                   { 1.0, 0.5, 0.0 } },
   { 1, "App:Collisions:Reset",             { 0.0, 0.0, 0.5 } },
@@ -146,9 +148,6 @@ static TimeCollectorProperties time_properties[] = {
   { 1, "Draw:Clear",                       { 0.0, 0.8, 0.6 } },
   { 1, "Draw:Flush",                       { 0.9, 0.2, 0.7 } },
   { 1, "Draw:Sync",                        { 0.5, 0.7, 0.7 } },
-  { 1, "Draw:Flip",                        { 1.0, 0.6, 0.3 } },
-  { 1, "Draw:Flip:Begin",                  { 0.3, 0.3, 0.9 } },
-  { 1, "Draw:Flip:End",                    { 0.9, 0.3, 0.6 } },
   { 0, "Draw:Transfer data",               { 0.8, 0.0, 0.6 } },
   { 0, "Draw:Transfer data:Vertex buffer", { 0.0, 0.1, 0.9 } },
   { 0, "Draw:Transfer data:Index buffer",  { 0.1, 0.9, 0.0 } },