dx9 occlusion queries

This commit is contained in:
David Rose 2007-06-04 17:20:51 +00:00
parent 8b83a2601a
commit 9d16c5bf23
15 changed files with 296 additions and 17 deletions

View File

@ -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");

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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();

View File

@ -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++) {

View File

@ -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"

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DXOcclusionQueryContext9::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DXOcclusionQueryContext9::
DXOcclusionQueryContext9(IDirect3DQuery9 *query) : _query(query) {
}

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#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;
}

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#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

View File

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

View File

@ -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

View File

@ -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 {

View File

@ -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);
}

View File

@ -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 } },