better pstats tracking of texture/vbuffer memory
This commit is contained in:
parent
c83ac68e90
commit
83a6c42496
|
|
@ -39,10 +39,6 @@
|
|||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage");
|
||||
PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
|
||||
PStatCollector GraphicsStateGuardian::_texture_count_pcollector("Prepared Textures");
|
||||
PStatCollector GraphicsStateGuardian::_active_texture_count_pcollector("Prepared Textures:Active");
|
||||
PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector("Vertex buffer switch:Vertex");
|
||||
PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector("Vertex buffer switch:Index");
|
||||
PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector("Draw:Transfer data:Vertex buffer");
|
||||
|
|
@ -51,15 +47,6 @@ PStatCollector GraphicsStateGuardian::_create_vertex_buffer_pcollector("Draw:Tra
|
|||
PStatCollector GraphicsStateGuardian::_create_index_buffer_pcollector("Draw:Transfer data:Create Index buffer");
|
||||
PStatCollector GraphicsStateGuardian::_load_texture_pcollector("Draw:Transfer data:Texture");
|
||||
PStatCollector GraphicsStateGuardian::_data_transferred_pcollector("Data transferred");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Vertex buffer size");
|
||||
PStatCollector GraphicsStateGuardian::_active_vertex_buffers_pcollector("Vertex buffer size:Active vertex");
|
||||
PStatCollector GraphicsStateGuardian::_active_index_buffers_pcollector("Vertex buffer size:Active index");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
|
||||
PStatCollector GraphicsStateGuardian::_used_texmem_pcollector("Texture memory:In use");
|
||||
PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager");
|
||||
PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector("Texture manager:Resident");
|
||||
PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector("Primitive batches");
|
||||
|
|
@ -964,11 +951,7 @@ prepare_lens() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
begin_frame() {
|
||||
// Now we know the GSG is the currently active context, so this is a
|
||||
// good time to release any textures or geoms that had been queued
|
||||
// up to release in the past frame, and load up any newly requested
|
||||
// textures.
|
||||
_prepared_objects->update(this);
|
||||
_prepared_objects->begin_frame(this);
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
// For Pstats to track our current texture memory usage, we have to
|
||||
|
|
@ -1005,6 +988,7 @@ begin_frame() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
begin_scene() {
|
||||
_prepared_objects->end_frame();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1879,7 +1863,6 @@ determine_light_color_scale() {
|
|||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::init_frame_pstats
|
||||
// Access: Protected
|
||||
|
|
@ -1889,16 +1872,7 @@ determine_light_color_scale() {
|
|||
void GraphicsStateGuardian::
|
||||
init_frame_pstats() {
|
||||
if (PStatClient::is_connected()) {
|
||||
_current_textures.clear();
|
||||
_current_geoms.clear();
|
||||
_current_vertex_buffers.clear();
|
||||
_current_index_buffers.clear();
|
||||
_active_texusage_pcollector.clear_level();
|
||||
_data_transferred_pcollector.clear_level();
|
||||
_active_geom_pcollector.clear_level();
|
||||
_active_geom_node_pcollector.clear_level();
|
||||
_active_vertex_buffers_pcollector.clear_level();
|
||||
_active_index_buffers_pcollector.clear_level();
|
||||
_vertex_buffer_switch_pcollector.clear_level();
|
||||
_index_buffer_switch_pcollector.clear_level();
|
||||
|
||||
|
|
@ -1918,114 +1892,6 @@ init_frame_pstats() {
|
|||
_texture_state_pcollector.clear_level();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_texture_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated texture has been applied
|
||||
// this frame, and thus must be present in current
|
||||
// texture memory. This function is only used to update
|
||||
// the PStats current_texmem collector; it gets compiled
|
||||
// out if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_texture_record(TextureContext *tc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (_current_textures.insert(tc).second) {
|
||||
_active_texusage_pcollector.add_level(tc->estimate_texture_memory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_geom_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated Geom has been drawn this
|
||||
// frame. This function is only used to update the
|
||||
// PStats active_geom collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_geom_record(GeomContext *gc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (gc != (GeomContext *)NULL && _current_geoms.insert(gc).second) {
|
||||
_active_geom_pcollector.add_level(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_vertex_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_vertex_buffers collector; it gets
|
||||
// compiled out if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_vertex_buffer_record(VertexBufferContext *vbc) {
|
||||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
if (PStatClient::is_connected()) {
|
||||
_vertex_buffer_switch_pcollector.add_level(1);
|
||||
if (_current_vertex_buffers.insert(vbc).second) {
|
||||
_active_vertex_buffers_pcollector.add_level(vbc->get_data()->get_data_size_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_index_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_index_buffers collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_index_buffer_record(IndexBufferContext *ibc) {
|
||||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
if (PStatClient::is_connected()) {
|
||||
_index_buffer_switch_pcollector.add_level(1);
|
||||
if (_current_index_buffers.insert(ibc).second) {
|
||||
_active_index_buffers_pcollector.add_level(ibc->get_data()->get_data_size_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_total_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been loaded
|
||||
// this frame. This function is only used to update the
|
||||
// PStats total_buffers collector; it gets
|
||||
// compiled out if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_total_buffer_record(VertexBufferContext *vbc) {
|
||||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
int delta = vbc->get_data()->get_data_size_bytes() - vbc->get_data_size_bytes();
|
||||
_total_buffers_pcollector.add_level(delta);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_total_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been loaded
|
||||
// this frame. This function is only used to update the
|
||||
// PStats total_buffers collector; it gets
|
||||
// compiled out if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_total_buffer_record(IndexBufferContext *ibc) {
|
||||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
int delta = ibc->get_data()->get_data_size_bytes() - ibc->get_data_size_bytes();
|
||||
_total_buffers_pcollector.add_level(delta);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DO_PSTATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -247,29 +247,7 @@ protected:
|
|||
INLINE void set_properties(const FrameBufferProperties &properties);
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
// These functions are used to update the active texture memory
|
||||
// usage record (and other frame-based measurements) in Pstats.
|
||||
void init_frame_pstats();
|
||||
void add_to_texture_record(TextureContext *tc);
|
||||
void add_to_geom_record(GeomContext *gc);
|
||||
void add_to_vertex_buffer_record(VertexBufferContext *vbc);
|
||||
void add_to_index_buffer_record(IndexBufferContext *ibc);
|
||||
void add_to_total_buffer_record(VertexBufferContext *vbc);
|
||||
void add_to_total_buffer_record(IndexBufferContext *ibc);
|
||||
|
||||
pset<TextureContext *> _current_textures;
|
||||
pset<GeomContext *> _current_geoms;
|
||||
pset<VertexBufferContext *> _current_vertex_buffers;
|
||||
pset<IndexBufferContext *> _current_index_buffers;
|
||||
#else
|
||||
INLINE void init_frame_pstats() { }
|
||||
INLINE void add_to_texture_record(TextureContext *) { }
|
||||
INLINE void add_to_geom_record(GeomContext *) { }
|
||||
INLINE void record_state_change(TypeHandle) { }
|
||||
INLINE void add_to_vertex_buffer_record(VertexBufferContext *) { }
|
||||
INLINE void add_to_index_buffer_record(IndexBufferContext *) { }
|
||||
INLINE void add_to_total_buffer_record(VertexBufferContext *) { };
|
||||
INLINE void add_to_total_buffer_record(IndexBufferContext *) { };
|
||||
#endif
|
||||
|
||||
static CPT(RenderState) get_unlit_state();
|
||||
|
|
@ -374,10 +352,6 @@ protected:
|
|||
|
||||
public:
|
||||
// Statistics
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _active_texusage_pcollector;
|
||||
static PStatCollector _texture_count_pcollector;
|
||||
static PStatCollector _active_texture_count_pcollector;
|
||||
static PStatCollector _vertex_buffer_switch_pcollector;
|
||||
static PStatCollector _index_buffer_switch_pcollector;
|
||||
static PStatCollector _load_vertex_buffer_pcollector;
|
||||
|
|
@ -386,15 +360,6 @@ public:
|
|||
static PStatCollector _create_index_buffer_pcollector;
|
||||
static PStatCollector _load_texture_pcollector;
|
||||
static PStatCollector _data_transferred_pcollector;
|
||||
static PStatCollector _total_geom_pcollector;
|
||||
static PStatCollector _active_geom_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
static PStatCollector _active_vertex_buffers_pcollector;
|
||||
static PStatCollector _active_index_buffers_pcollector;
|
||||
static PStatCollector _total_geom_node_pcollector;
|
||||
static PStatCollector _active_geom_node_pcollector;
|
||||
static PStatCollector _total_texmem_pcollector;
|
||||
static PStatCollector _used_texmem_pcollector;
|
||||
static PStatCollector _texmgrmem_total_pcollector;
|
||||
static PStatCollector _texmgrmem_resident_pcollector;
|
||||
static PStatCollector _primitive_batches_pcollector;
|
||||
|
|
|
|||
|
|
@ -147,11 +147,11 @@ DXGraphicsStateGuardian8::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TextureContext *DXGraphicsStateGuardian8::
|
||||
prepare_texture(Texture *tex) {
|
||||
DXTextureContext8 *dtc = new DXTextureContext8(tex);
|
||||
DXTextureContext8 *dtc = new DXTextureContext8(_prepared_objects, tex);
|
||||
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -178,30 +178,17 @@ apply_texture(int i, TextureContext *tc) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
add_to_texture_record(tc);
|
||||
#endif
|
||||
tc->set_active(true);
|
||||
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
|
||||
int dirty = dtc->get_dirty_flags();
|
||||
|
||||
// If the texture image has changed, or if its use of mipmaps has
|
||||
// changed, we need to re-create the image. Ignore other types of
|
||||
// changes, which aren't significant for DX.
|
||||
// changed, we need to re-create the image.
|
||||
|
||||
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
|
||||
// If this is *only* because of a mipmap change, issue a
|
||||
// warning--it is likely that this change is the result of an
|
||||
// error or oversight.
|
||||
if ((dirty & Texture::DF_image) == 0) {
|
||||
dxgsg8_cat.warning()
|
||||
<< *dtc->_texture << " has changed mipmap state.\n";
|
||||
}
|
||||
|
||||
if (!get_supports_compressed_texture_format(tc->_texture->get_ram_image_compression())) {
|
||||
if (dtc->was_modified()) {
|
||||
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
|
@ -209,13 +196,13 @@ apply_texture(int i, TextureContext *tc) {
|
|||
if (!dtc->create_texture(*_screen)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Texture *tex = tc->_texture;
|
||||
Texture *tex = tc->get_texture();
|
||||
Texture::WrapMode wrap_u, wrap_v, wrap_w;
|
||||
wrap_u = tex->get_wrap_u();
|
||||
wrap_v = tex->get_wrap_v();
|
||||
|
|
@ -303,7 +290,7 @@ release_texture(TextureContext *tc) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
VertexBufferContext *DXGraphicsStateGuardian8::
|
||||
prepare_vertex_buffer(GeomVertexArrayData *data) {
|
||||
DXVertexBufferContext8 *dvbc = new DXVertexBufferContext8(data);
|
||||
DXVertexBufferContext8 *dvbc = new DXVertexBufferContext8(_prepared_objects, data);
|
||||
return dvbc;
|
||||
}
|
||||
|
||||
|
|
@ -327,14 +314,13 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
if (dvbc->_vbuffer != NULL) {
|
||||
dvbc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
|
||||
_d3d_device->SetStreamSource
|
||||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_active_vbuffer = dvbc;
|
||||
_active_ibuffer = NULL;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
dvbc->set_active(true);
|
||||
|
||||
} else {
|
||||
_active_vbuffer = NULL;
|
||||
|
|
@ -349,8 +335,6 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
}
|
||||
|
||||
dvbc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
_active_vbuffer = NULL;
|
||||
}
|
||||
|
|
@ -360,7 +344,7 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_active_vbuffer = dvbc;
|
||||
_active_ibuffer = NULL;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
dvbc->set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +387,7 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *DXGraphicsStateGuardian8::
|
||||
prepare_index_buffer(GeomPrimitive *data) {
|
||||
DXIndexBufferContext8 *dibc = new DXIndexBufferContext8(data);
|
||||
DXIndexBufferContext8 *dibc = new DXIndexBufferContext8(_prepared_objects, data);
|
||||
return dibc;
|
||||
}
|
||||
|
||||
|
|
@ -423,12 +407,11 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
if (dibc->_ibuffer != NULL) {
|
||||
dibc->upload_data();
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
|
||||
_d3d_device->SetIndices(dibc->_ibuffer, 0);
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
dibc->set_active(true);
|
||||
|
||||
} else {
|
||||
_d3d_device->SetIndices(NULL, 0);
|
||||
|
|
@ -445,7 +428,6 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
dibc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
_active_ibuffer = NULL;
|
||||
}
|
||||
|
|
@ -453,7 +435,7 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
if (_active_ibuffer != dibc) {
|
||||
_d3d_device->SetIndices(dibc->_ibuffer, 0);
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
dibc->set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1396,7 +1378,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||
if (!dtc->create_texture(*_screen)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
return;
|
||||
}
|
||||
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
|
||||
|
|
@ -1415,7 +1397,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||
// If it's still the wrong size, it's because driver can't create size
|
||||
// that we want. In that case, there's no helping it, we have to give up.
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to copy to texture, texture is wrong size: " << *dtc->_texture << endl;
|
||||
<< "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
|
||||
SAFE_RELEASE(tex_level_0);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3435,7 +3417,7 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
|
|||
release_all_vertex_buffers();
|
||||
release_all_index_buffers();
|
||||
|
||||
_prepared_objects->update(this);
|
||||
_prepared_objects->begin_frame(this);
|
||||
|
||||
hr = _d3d_device->Reset(&_presentation_reset);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -3493,7 +3475,7 @@ check_cooperative_level() {
|
|||
_dx_is_ready = false;
|
||||
|
||||
// call this just in case
|
||||
_prepared_objects->update (this);
|
||||
_prepared_objects->begin_frame(this);
|
||||
|
||||
hr = reset_d3d_device(&_screen->_presentation_params);
|
||||
if (FAILED(hr)) {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ TypeHandle DXIndexBufferContext8::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXIndexBufferContext8::
|
||||
DXIndexBufferContext8(GeomPrimitive *data) :
|
||||
IndexBufferContext(data),
|
||||
DXIndexBufferContext8(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
||||
IndexBufferContext(pgo, data),
|
||||
_ibuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXIndexBufferContext8 : public IndexBufferContext {
|
||||
public:
|
||||
DXIndexBufferContext8(GeomPrimitive *data);
|
||||
DXIndexBufferContext8(PreparedGraphicsObjects *pgo, GeomPrimitive *data);
|
||||
virtual ~DXIndexBufferContext8();
|
||||
|
||||
void create_ibuffer(DXScreenData &scrn);
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ static const DWORD g_LowByteMask = 0x000000FF;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXTextureContext8::
|
||||
DXTextureContext8(Texture *tex) :
|
||||
TextureContext(tex) {
|
||||
DXTextureContext8(PreparedGraphicsObjects *pgo, Texture *tex) :
|
||||
TextureContext(pgo, tex) {
|
||||
|
||||
if (dxgsg8_cat.is_spam()) {
|
||||
dxgsg8_cat.spam()
|
||||
|
|
@ -59,7 +59,7 @@ DXTextureContext8::
|
|||
~DXTextureContext8() {
|
||||
if (dxgsg8_cat.is_spam()) {
|
||||
dxgsg8_cat.spam()
|
||||
<< "Deleting texture context for " << _texture->get_name() << "\n";
|
||||
<< "Deleting texture context for " << get_texture()->get_name() << "\n";
|
||||
}
|
||||
delete_texture();
|
||||
TextureContext::~TextureContext();
|
||||
|
|
@ -82,32 +82,31 @@ create_texture(DXScreenData &scrn) {
|
|||
D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
|
||||
bool needs_luminance = false;
|
||||
|
||||
nassertr(IS_VALID_PTR(_texture), false);
|
||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
||||
|
||||
delete_texture();
|
||||
|
||||
clear_dirty_flags(Texture::DF_image | Texture::DF_mipmap);
|
||||
mark_loaded();
|
||||
|
||||
// bpp indicates requested fmt, not texture fmt
|
||||
DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &num_alpha_bits);
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
|
||||
//PRINT_REFCNT(dxgsg8, scrn._d3d8);
|
||||
|
||||
DWORD orig_width = (DWORD)_texture->get_x_size();
|
||||
DWORD orig_height = (DWORD)_texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD)_texture->get_z_size();
|
||||
DWORD orig_width = (DWORD)get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD)get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD)get_texture()->get_z_size();
|
||||
|
||||
if ((_texture->get_format() == Texture::F_luminance_alpha)||
|
||||
(_texture->get_format() == Texture::F_luminance_alphamask) ||
|
||||
(_texture->get_format() == Texture::F_luminance)) {
|
||||
if ((get_texture()->get_format() == Texture::F_luminance_alpha)||
|
||||
(get_texture()->get_format() == Texture::F_luminance_alphamask) ||
|
||||
(get_texture()->get_format() == Texture::F_luminance)) {
|
||||
needs_luminance = true;
|
||||
}
|
||||
|
||||
if (num_alpha_bits > 0) {
|
||||
if (num_color_channels == 3) {
|
||||
dxgsg8_cat.error()
|
||||
<< "texture " << _texture->get_name()
|
||||
<< "texture " << get_texture()->get_name()
|
||||
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +144,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
DWORD filter_caps;
|
||||
|
||||
switch (_texture->get_texture_type()) {
|
||||
switch (get_texture()->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
||||
|
|
@ -239,15 +238,15 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (orig_width != target_width || orig_height != target_height ||
|
||||
orig_depth != target_depth) {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
||||
dxgsg8_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< "Reducing size of " << get_texture()->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
||||
<< " to " << target_width << "x" << target_height
|
||||
<< "x" << target_depth << "\n";
|
||||
} else {
|
||||
dxgsg8_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< "Reducing size of " << get_texture()->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height
|
||||
<< " to " << target_width << "x" << target_height << "\n";
|
||||
}
|
||||
|
|
@ -457,7 +456,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
// if we've gotten here, haven't found a match
|
||||
dxgsg8_cat.error()
|
||||
<< error_message << ": " << _texture->get_name() << endl
|
||||
<< error_message << ": " << get_texture()->get_name() << endl
|
||||
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
||||
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
||||
<< "; _supported_tex_formats_mask: 0x"
|
||||
|
|
@ -470,7 +469,7 @@ create_texture(DXScreenData &scrn) {
|
|||
found_matching_format:
|
||||
// We found a suitable format that matches the texture's format.
|
||||
|
||||
if (_texture->get_match_framebuffer_format()) {
|
||||
if (get_texture()->get_match_framebuffer_format()) {
|
||||
// Instead of creating a texture with the found format, we will
|
||||
// need to make one that exactly matches the framebuffer's
|
||||
// format. Look up what that format is.
|
||||
|
|
@ -505,7 +504,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
Texture::FilterType ft;
|
||||
|
||||
ft = _texture->get_magfilter();
|
||||
ft = get_texture()->get_magfilter();
|
||||
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
||||
// mipmap settings make no sense for magfilter
|
||||
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
||||
|
|
@ -519,10 +518,10 @@ create_texture(DXScreenData &scrn) {
|
|||
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
||||
ft = Texture::FT_nearest;
|
||||
}
|
||||
_texture->set_magfilter(ft);
|
||||
get_texture()->set_magfilter(ft);
|
||||
|
||||
// figure out if we are mipmapping this texture
|
||||
ft = _texture->get_minfilter();
|
||||
ft = get_texture()->get_minfilter();
|
||||
_has_mipmaps = false;
|
||||
|
||||
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
||||
|
|
@ -540,11 +539,11 @@ create_texture(DXScreenData &scrn) {
|
|||
if (ft != Texture::FT_linear_mipmap_linear) {
|
||||
dxgsg8_cat.spam()
|
||||
<< "Forcing trilinear mipmapping on DX texture ["
|
||||
<< _texture->get_name() << "]\n";
|
||||
<< get_texture()->get_name() << "]\n";
|
||||
}
|
||||
}
|
||||
ft = Texture::FT_linear_mipmap_linear;
|
||||
_texture->set_minfilter(ft);
|
||||
get_texture()->set_minfilter(ft);
|
||||
}
|
||||
|
||||
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
||||
|
|
@ -596,23 +595,23 @@ create_texture(DXScreenData &scrn) {
|
|||
break;
|
||||
}
|
||||
|
||||
_texture->set_minfilter(ft);
|
||||
get_texture()->set_minfilter(ft);
|
||||
|
||||
uint aniso_degree;
|
||||
|
||||
aniso_degree = 1;
|
||||
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
||||
aniso_degree = _texture->get_anisotropic_degree();
|
||||
aniso_degree = get_texture()->get_anisotropic_degree();
|
||||
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
||||
dx_force_anisotropic_filtering) {
|
||||
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
||||
}
|
||||
}
|
||||
_texture->set_anisotropic_degree(aniso_degree);
|
||||
get_texture()->set_anisotropic_degree(aniso_degree);
|
||||
|
||||
#ifdef _DEBUG
|
||||
dxgsg8_cat.spam()
|
||||
<< "create_texture: setting aniso degree for " << _texture->get_name()
|
||||
<< "create_texture: setting aniso degree for " << get_texture()->get_name()
|
||||
<< " to: " << aniso_degree << endl;
|
||||
#endif
|
||||
|
||||
|
|
@ -624,7 +623,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "create_texture: generating mipmaps for " << _texture->get_name()
|
||||
<< "create_texture: generating mipmaps for " << get_texture()->get_name()
|
||||
<< endl;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -634,7 +633,7 @@ create_texture(DXScreenData &scrn) {
|
|||
DWORD usage;
|
||||
D3DPOOL pool;
|
||||
|
||||
if (_texture->get_render_to_texture ()) {
|
||||
if (get_texture()->get_render_to_texture ()) {
|
||||
// REQUIRED
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
usage = D3DUSAGE_RENDERTARGET;
|
||||
|
|
@ -646,7 +645,7 @@ create_texture(DXScreenData &scrn) {
|
|||
usage = 0;
|
||||
}
|
||||
|
||||
switch (_texture->get_texture_type()) {
|
||||
switch (get_texture()->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
hr = scrn._d3d_device->CreateTexture
|
||||
|
|
@ -678,7 +677,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "create_texture: " << _texture->get_name()
|
||||
<< "create_texture: " << get_texture()->get_name()
|
||||
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
||||
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
||||
}
|
||||
|
|
@ -984,14 +983,14 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
HRESULT DXTextureContext8::
|
||||
fill_d3d_texture_pixels() {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
||||
return fill_d3d_volume_texture_pixels();
|
||||
}
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
CPTA_uchar image = get_texture()->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
|
|
@ -1003,13 +1002,13 @@ fill_d3d_texture_pixels() {
|
|||
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD orig_width = (DWORD) get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD) get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
int component_width = get_texture()->get_component_width();
|
||||
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
|
|
@ -1018,10 +1017,10 @@ fill_d3d_texture_pixels() {
|
|||
BYTE *pixels = NULL;
|
||||
|
||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||
pixels = image_pixels + di * _texture->get_expected_ram_page_size();
|
||||
pixels = image_pixels + di * get_texture()->get_expected_ram_page_size();
|
||||
mip_level_0 = NULL;
|
||||
|
||||
if (_texture->get_texture_type() == Texture::TT_cube_map) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
||||
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
||||
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)di, 0, &mip_level_0);
|
||||
} else {
|
||||
|
|
@ -1031,7 +1030,7 @@ fill_d3d_texture_pixels() {
|
|||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
@ -1085,7 +1084,7 @@ fill_d3d_texture_pixels() {
|
|||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_components = get_texture()->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
|
|
@ -1113,7 +1112,7 @@ fill_d3d_texture_pixels() {
|
|||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1131,7 +1130,7 @@ fill_d3d_texture_pixels() {
|
|||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1159,9 +1158,9 @@ fill_d3d_texture_pixels() {
|
|||
HRESULT DXTextureContext8::
|
||||
fill_d3d_volume_texture_pixels() {
|
||||
HRESULT hr = E_FAIL;
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
CPTA_uchar image = get_texture()->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
|
|
@ -1172,15 +1171,15 @@ fill_d3d_volume_texture_pixels() {
|
|||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
nassertr(_texture->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
|
||||
nassertr(get_texture()->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD orig_width = (DWORD) get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD) get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
int component_width = get_texture()->get_component_width();
|
||||
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
|
|
@ -1193,7 +1192,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
@ -1252,7 +1251,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_components = get_texture()->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * orig_depth * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
|
|
@ -1281,7 +1280,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1299,7 +1298,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXTextureContext8 : public TextureContext {
|
||||
public:
|
||||
DXTextureContext8(Texture *tex);
|
||||
DXTextureContext8(PreparedGraphicsObjects *pgo, Texture *tex);
|
||||
virtual ~DXTextureContext8();
|
||||
|
||||
bool create_texture(DXScreenData &scrn);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ TypeHandle DXVertexBufferContext8::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXVertexBufferContext8::
|
||||
DXVertexBufferContext8(GeomVertexArrayData *data) :
|
||||
VertexBufferContext(data),
|
||||
DXVertexBufferContext8(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
|
||||
VertexBufferContext(pgo, data),
|
||||
_vbuffer(NULL)
|
||||
{
|
||||
// Now fill in the FVF code.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXVertexBufferContext8 : public VertexBufferContext {
|
||||
public:
|
||||
DXVertexBufferContext8(GeomVertexArrayData *data);
|
||||
DXVertexBufferContext8(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data);
|
||||
virtual ~DXVertexBufferContext8();
|
||||
|
||||
void create_vbuffer(DXScreenData &scrn);
|
||||
|
|
|
|||
|
|
@ -190,11 +190,11 @@ DXGraphicsStateGuardian9::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TextureContext *DXGraphicsStateGuardian9::
|
||||
prepare_texture(Texture *tex) {
|
||||
DXTextureContext9 *dtc = new DXTextureContext9(tex);
|
||||
DXTextureContext9 *dtc = new DXTextureContext9(_prepared_objects, tex);
|
||||
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -221,9 +221,7 @@ apply_texture(int i, TextureContext *tc) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
add_to_texture_record(tc);
|
||||
#endif
|
||||
tc->set_active(true);
|
||||
|
||||
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||
|
||||
|
|
@ -232,24 +230,13 @@ apply_texture(int i, TextureContext *tc) {
|
|||
_lru -> access_page (dtc -> _lru_page);
|
||||
}
|
||||
|
||||
int dirty = dtc->get_dirty_flags();
|
||||
|
||||
// If the texture image has changed, or if its use of mipmaps has
|
||||
// changed, we need to re-create the image. Ignore other types of
|
||||
// changes, which aren't significant for DX.
|
||||
// changed, we need to re-create the image.
|
||||
|
||||
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
|
||||
// If this is *only* because of a mipmap change, issue a
|
||||
// warning--it is likely that this change is the result of an
|
||||
// error or oversight.
|
||||
if ((dirty & Texture::DF_image) == 0) {
|
||||
dxgsg9_cat.warning()
|
||||
<< *dtc->_texture << " has changed mipmap state.\n";
|
||||
}
|
||||
|
||||
if (!get_supports_compressed_texture_format(tc->_texture->get_ram_image_compression())) {
|
||||
if (dtc->was_modified()) {
|
||||
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *dtc->_texture << " is stored in an unsupported compressed format.\n";
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
|
@ -257,13 +244,13 @@ apply_texture(int i, TextureContext *tc) {
|
|||
if (!dtc->create_texture(*_screen)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Texture *tex = tc->_texture;
|
||||
Texture *tex = tc->get_texture();
|
||||
Texture::WrapMode wrap_u, wrap_v, wrap_w;
|
||||
|
||||
DWORD address_u;
|
||||
|
|
@ -388,7 +375,7 @@ release_shader(ShaderContext *sc) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
VertexBufferContext *DXGraphicsStateGuardian9::
|
||||
prepare_vertex_buffer(GeomVertexArrayData *data) {
|
||||
DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(data, *(this -> _screen));
|
||||
DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(_prepared_objects, data, *(this -> _screen));
|
||||
return dvbc;
|
||||
}
|
||||
|
||||
|
|
@ -427,7 +414,6 @@ apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context
|
|||
if (dvbc->_vbuffer != NULL) {
|
||||
dvbc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
|
||||
set_stream_source = true;
|
||||
|
|
@ -446,7 +432,6 @@ apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context
|
|||
|
||||
dvbc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dvbc);
|
||||
dvbc->mark_loaded();
|
||||
_active_vbuffer = NULL;
|
||||
}
|
||||
|
|
@ -467,7 +452,7 @@ apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context
|
|||
}
|
||||
_active_vbuffer = dvbc;
|
||||
_active_ibuffer = NULL;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
dvbc->set_active(true);
|
||||
}
|
||||
|
||||
if ((dvbc->_fvf != _last_fvf)) {
|
||||
|
|
@ -558,7 +543,7 @@ apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context
|
|||
}
|
||||
_active_vbuffer = dvbc;
|
||||
_active_ibuffer = NULL;
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
dvbc->set_active(true);
|
||||
}
|
||||
|
||||
if (dvbc -> _direct_3d_vertex_declaration) {
|
||||
|
|
@ -603,7 +588,7 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *DXGraphicsStateGuardian9::
|
||||
prepare_index_buffer(GeomPrimitive *data) {
|
||||
DXIndexBufferContext9 *dibc = new DXIndexBufferContext9(data);
|
||||
DXIndexBufferContext9 *dibc = new DXIndexBufferContext9(_prepared_objects, data);
|
||||
return dibc;
|
||||
}
|
||||
|
||||
|
|
@ -627,12 +612,11 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
if (dibc->_ibuffer != NULL) {
|
||||
dibc->upload_data();
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
|
||||
_d3d_device->SetIndices(dibc->_ibuffer);
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
dibc->set_active(true);
|
||||
|
||||
} else {
|
||||
_d3d_device->SetIndices(NULL);
|
||||
|
|
@ -649,7 +633,6 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
|
||||
dibc->upload_data();
|
||||
|
||||
add_to_total_buffer_record(dibc);
|
||||
dibc->mark_loaded();
|
||||
_active_ibuffer = NULL;
|
||||
}
|
||||
|
|
@ -657,7 +640,7 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
if (_active_ibuffer != dibc) {
|
||||
_d3d_device->SetIndices(dibc->_ibuffer);
|
||||
_active_ibuffer = dibc;
|
||||
add_to_index_buffer_record(dibc);
|
||||
dibc->set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1902,7 +1885,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||
if (!dtc->create_texture(*_screen)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
return;
|
||||
}
|
||||
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
|
||||
|
|
@ -1921,7 +1904,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||
// If it's still the wrong size, it's because driver can't create size
|
||||
// that we want. In that case, there's no helping it, we have to give up.
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to copy to texture, texture is wrong size: " << *dtc->_texture << endl;
|
||||
<< "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
|
||||
SAFE_RELEASE(tex_level_0);
|
||||
return;
|
||||
}
|
||||
|
|
@ -4460,7 +4443,7 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
|
|||
release_all_index_buffers();
|
||||
|
||||
// must be called before reset
|
||||
_prepared_objects->update(this);
|
||||
_prepared_objects->begin_frame(this);
|
||||
|
||||
hr = _d3d_device->Reset(&_presentation_reset);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -4518,7 +4501,7 @@ check_cooperative_level() {
|
|||
_dx_is_ready = false;
|
||||
|
||||
// call this just in case
|
||||
_prepared_objects->update (this);
|
||||
_prepared_objects->begin_frame(this);
|
||||
|
||||
hr = reset_d3d_device(&_screen->_presentation_params);
|
||||
if (FAILED(hr)) {
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ TypeHandle DXIndexBufferContext9::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXIndexBufferContext9::
|
||||
DXIndexBufferContext9(GeomPrimitive *data) :
|
||||
IndexBufferContext(data),
|
||||
DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
||||
IndexBufferContext(pgo, data),
|
||||
_ibuffer(NULL)
|
||||
{
|
||||
_managed = -1;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXIndexBufferContext9 : public IndexBufferContext {
|
||||
public:
|
||||
DXIndexBufferContext9(GeomPrimitive *data);
|
||||
DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data);
|
||||
virtual ~DXIndexBufferContext9();
|
||||
|
||||
void free_ibuffer(void);
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ static const DWORD g_LowByteMask = 0x000000FF;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXTextureContext9::
|
||||
DXTextureContext9(Texture *tex) :
|
||||
TextureContext(tex) {
|
||||
DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex) :
|
||||
TextureContext(pgo, tex) {
|
||||
|
||||
if (dxgsg9_cat.is_spam()) {
|
||||
dxgsg9_cat.spam()
|
||||
|
|
@ -63,7 +63,7 @@ DXTextureContext9::
|
|||
~DXTextureContext9() {
|
||||
if (dxgsg9_cat.is_spam()) {
|
||||
dxgsg9_cat.spam()
|
||||
<< "Deleting texture context for " << _texture->get_name() << "\n";
|
||||
<< "Deleting texture context for " << get_texture()->get_name() << "\n";
|
||||
}
|
||||
|
||||
if (_lru_page)
|
||||
|
|
@ -94,32 +94,31 @@ create_texture(DXScreenData &scrn) {
|
|||
D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
|
||||
bool needs_luminance = false;
|
||||
|
||||
nassertr(IS_VALID_PTR(_texture), false);
|
||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
||||
|
||||
delete_texture();
|
||||
|
||||
clear_dirty_flags(Texture::DF_image | Texture::DF_mipmap);
|
||||
mark_loaded();
|
||||
|
||||
// bpp indicates requested fmt, not texture fmt
|
||||
DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &num_alpha_bits);
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
|
||||
//PRINT_REFCNT(dxgsg9, scrn._d3d9);
|
||||
|
||||
DWORD orig_width = (DWORD)_texture->get_x_size();
|
||||
DWORD orig_height = (DWORD)_texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD)_texture->get_z_size();
|
||||
DWORD orig_width = (DWORD)get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD)get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD)get_texture()->get_z_size();
|
||||
|
||||
if ((_texture->get_format() == Texture::F_luminance_alpha)||
|
||||
(_texture->get_format() == Texture::F_luminance_alphamask) ||
|
||||
(_texture->get_format() == Texture::F_luminance)) {
|
||||
if ((get_texture()->get_format() == Texture::F_luminance_alpha)||
|
||||
(get_texture()->get_format() == Texture::F_luminance_alphamask) ||
|
||||
(get_texture()->get_format() == Texture::F_luminance)) {
|
||||
needs_luminance = true;
|
||||
}
|
||||
|
||||
if (num_alpha_bits > 0) {
|
||||
if (num_color_channels == 3) {
|
||||
dxgsg9_cat.error()
|
||||
<< "texture " << _texture->get_name()
|
||||
<< "texture " << get_texture()->get_name()
|
||||
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -157,7 +156,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
DWORD filter_caps;
|
||||
|
||||
switch (_texture->get_texture_type()) {
|
||||
switch (get_texture()->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
||||
|
|
@ -251,15 +250,15 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (orig_width != target_width || orig_height != target_height ||
|
||||
orig_depth != target_depth) {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
||||
dxgsg9_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< "Reducing size of " << get_texture()->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
||||
<< " to " << target_width << "x" << target_height
|
||||
<< "x" << target_depth << "\n";
|
||||
} else {
|
||||
dxgsg9_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< "Reducing size of " << get_texture()->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height
|
||||
<< " to " << target_width << "x" << target_height << "\n";
|
||||
}
|
||||
|
|
@ -469,7 +468,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
// if we've gotten here, haven't found a match
|
||||
dxgsg9_cat.error()
|
||||
<< error_message << ": " << _texture->get_name() << endl
|
||||
<< error_message << ": " << get_texture()->get_name() << endl
|
||||
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
||||
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
||||
<< "; _supported_tex_formats_mask: 0x"
|
||||
|
|
@ -482,7 +481,7 @@ create_texture(DXScreenData &scrn) {
|
|||
found_matching_format:
|
||||
// We found a suitable format that matches the texture's format.
|
||||
|
||||
if (_texture->get_match_framebuffer_format()) {
|
||||
if (get_texture()->get_match_framebuffer_format()) {
|
||||
// Instead of creating a texture with the found format, we will
|
||||
// need to make one that exactly matches the framebuffer's
|
||||
// format. Look up what that format is.
|
||||
|
|
@ -520,7 +519,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
Texture::FilterType ft;
|
||||
|
||||
ft = _texture->get_magfilter();
|
||||
ft = get_texture()->get_magfilter();
|
||||
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
||||
// mipmap settings make no sense for magfilter
|
||||
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
||||
|
|
@ -534,10 +533,10 @@ create_texture(DXScreenData &scrn) {
|
|||
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
||||
ft = Texture::FT_nearest;
|
||||
}
|
||||
_texture->set_magfilter(ft);
|
||||
get_texture()->set_magfilter(ft);
|
||||
|
||||
// figure out if we are mipmapping this texture
|
||||
ft = _texture->get_minfilter();
|
||||
ft = get_texture()->get_minfilter();
|
||||
_has_mipmaps = false;
|
||||
|
||||
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
||||
|
|
@ -555,11 +554,11 @@ create_texture(DXScreenData &scrn) {
|
|||
if (ft != Texture::FT_linear_mipmap_linear) {
|
||||
dxgsg9_cat.spam()
|
||||
<< "Forcing trilinear mipmapping on DX texture ["
|
||||
<< _texture->get_name() << "]\n";
|
||||
<< get_texture()->get_name() << "]\n";
|
||||
}
|
||||
}
|
||||
ft = Texture::FT_linear_mipmap_linear;
|
||||
_texture->set_minfilter(ft);
|
||||
get_texture()->set_minfilter(ft);
|
||||
}
|
||||
|
||||
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
||||
|
|
@ -611,23 +610,23 @@ create_texture(DXScreenData &scrn) {
|
|||
break;
|
||||
}
|
||||
|
||||
_texture->set_minfilter(ft);
|
||||
get_texture()->set_minfilter(ft);
|
||||
|
||||
uint aniso_degree;
|
||||
|
||||
aniso_degree = 1;
|
||||
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
||||
aniso_degree = _texture->get_anisotropic_degree();
|
||||
aniso_degree = get_texture()->get_anisotropic_degree();
|
||||
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
||||
dx_force_anisotropic_filtering) {
|
||||
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
||||
}
|
||||
}
|
||||
_texture->set_anisotropic_degree(aniso_degree);
|
||||
get_texture()->set_anisotropic_degree(aniso_degree);
|
||||
|
||||
#ifdef _DEBUG
|
||||
dxgsg9_cat.spam()
|
||||
<< "create_texture: setting aniso degree for " << _texture->get_name()
|
||||
<< "create_texture: setting aniso degree for " << get_texture()->get_name()
|
||||
<< " to: " << aniso_degree << endl;
|
||||
#endif
|
||||
|
||||
|
|
@ -639,7 +638,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug()
|
||||
<< "create_texture: generating mipmaps for " << _texture->get_name()
|
||||
<< "create_texture: generating mipmaps for " << get_texture()->get_name()
|
||||
<< endl;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -649,7 +648,7 @@ create_texture(DXScreenData &scrn) {
|
|||
DWORD usage;
|
||||
D3DPOOL pool;
|
||||
|
||||
if (_texture->get_render_to_texture ( )) {
|
||||
if (get_texture()->get_render_to_texture ( )) {
|
||||
// REQUIRED PARAMETERS
|
||||
_managed = false;
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
|
|
@ -752,7 +751,7 @@ create_texture(DXScreenData &scrn) {
|
|||
{
|
||||
data_size = (int) ((float) data_size * 1.3f);
|
||||
}
|
||||
if (_texture->get_texture_type() == Texture::TT_cube_map)
|
||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map)
|
||||
{
|
||||
data_size *= 6;
|
||||
}
|
||||
|
|
@ -762,7 +761,7 @@ create_texture(DXScreenData &scrn) {
|
|||
attempts = 0;
|
||||
do
|
||||
{
|
||||
switch (_texture->get_texture_type()) {
|
||||
switch (get_texture()->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
hr = scrn._d3d_device->CreateTexture
|
||||
|
|
@ -800,7 +799,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug()
|
||||
<< "create_texture: " << _texture->get_name()
|
||||
<< "create_texture: " << get_texture()->get_name()
|
||||
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
||||
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
||||
}
|
||||
|
|
@ -814,7 +813,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
|
||||
// must not put render to texture into LRU
|
||||
if (_lru_page == 0 && _managed == false && _texture->get_render_to_texture ( ) == false)
|
||||
if (_lru_page == 0 && _managed == false && get_texture()->get_render_to_texture ( ) == false)
|
||||
{
|
||||
Lru *lru;
|
||||
|
||||
|
|
@ -1130,14 +1129,14 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
HRESULT DXTextureContext9::
|
||||
fill_d3d_texture_pixels() {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
||||
return fill_d3d_volume_texture_pixels();
|
||||
}
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
CPTA_uchar image = get_texture()->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
|
|
@ -1149,13 +1148,13 @@ fill_d3d_texture_pixels() {
|
|||
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD orig_width = (DWORD) get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD) get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
int component_width = get_texture()->get_component_width();
|
||||
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
|
|
@ -1164,10 +1163,10 @@ fill_d3d_texture_pixels() {
|
|||
BYTE *pixels = NULL;
|
||||
|
||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||
pixels = image_pixels + di * _texture->get_expected_ram_page_size();
|
||||
pixels = image_pixels + di * get_texture()->get_expected_ram_page_size();
|
||||
mip_level_0 = NULL;
|
||||
|
||||
if (_texture->get_texture_type() == Texture::TT_cube_map) {
|
||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
||||
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
||||
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)di, 0, &mip_level_0);
|
||||
} else {
|
||||
|
|
@ -1177,7 +1176,7 @@ fill_d3d_texture_pixels() {
|
|||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
@ -1231,7 +1230,7 @@ fill_d3d_texture_pixels() {
|
|||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_components = get_texture()->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
|
|
@ -1259,7 +1258,7 @@ fill_d3d_texture_pixels() {
|
|||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1277,7 +1276,7 @@ fill_d3d_texture_pixels() {
|
|||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1308,9 +1307,9 @@ fill_d3d_texture_pixels() {
|
|||
HRESULT DXTextureContext9::
|
||||
fill_d3d_volume_texture_pixels() {
|
||||
HRESULT hr = E_FAIL;
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
CPTA_uchar image = get_texture()->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
|
|
@ -1321,15 +1320,15 @@ fill_d3d_volume_texture_pixels() {
|
|||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
nassertr(_texture->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
|
||||
nassertr(get_texture()->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
DWORD orig_width = (DWORD) get_texture()->get_x_size();
|
||||
DWORD orig_height = (DWORD) get_texture()->get_y_size();
|
||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||
DWORD num_color_channels = get_texture()->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
int component_width = get_texture()->get_component_width();
|
||||
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
|
|
@ -1342,7 +1341,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
@ -1401,7 +1400,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_components = get_texture()->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * orig_depth * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
|
|
@ -1430,7 +1429,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
@ -1448,7 +1447,7 @@ fill_d3d_volume_texture_pixels() {
|
|||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXTextureContext9 : public TextureContext {
|
||||
public:
|
||||
DXTextureContext9(Texture *tex);
|
||||
DXTextureContext9(PreparedGraphicsObjects *pgo, Texture *tex);
|
||||
virtual ~DXTextureContext9();
|
||||
|
||||
bool create_texture(DXScreenData &scrn);
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ TypeHandle DXVertexBufferContext9::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXVertexBufferContext9::
|
||||
DXVertexBufferContext9(GeomVertexArrayData *data, DXScreenData &scrn) :
|
||||
VertexBufferContext(data),
|
||||
DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn) :
|
||||
VertexBufferContext(pgo, data),
|
||||
_vbuffer(NULL)
|
||||
{
|
||||
// Now fill in the FVF code.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext {
|
||||
public:
|
||||
DXVertexBufferContext9(GeomVertexArrayData *data, DXScreenData &scrn);
|
||||
DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn);
|
||||
virtual ~DXVertexBufferContext9();
|
||||
|
||||
void free_vbuffer(void);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#ifdef THREADED_PIPELINE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerLinks::Constructor
|
||||
// Access: Public
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PipelineCyclerLinks::
|
||||
|
|
@ -35,7 +35,7 @@ PipelineCyclerLinks() {
|
|||
#ifdef THREADED_PIPELINE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerLinks::Destructor
|
||||
// Access: Public
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PipelineCyclerLinks::
|
||||
|
|
@ -47,7 +47,7 @@ INLINE PipelineCyclerLinks::
|
|||
#ifdef THREADED_PIPELINE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerLinks::remove_from_list
|
||||
// Access: Private
|
||||
// Access: Protected
|
||||
// Description: Removes a PipelineCyclerLinks record from the
|
||||
// doubly-linked list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -66,7 +66,7 @@ remove_from_list() {
|
|||
#ifdef THREADED_PIPELINE
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerLinks::insert_before
|
||||
// Access: Private
|
||||
// Access: Protected
|
||||
// Description: Adds a PipelineCyclerLinks record before the indicated
|
||||
// node in the doubly-linked list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1236,8 +1236,20 @@ end_frame() {
|
|||
GLP(Flush)();
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
// Check for textures, etc., that are no longer resident.
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
|
||||
|
||||
// OpenGL provides no methods for querying whether a buffer object
|
||||
// (vertex buffer) is resident. In fact, the API appears geared
|
||||
// towards the assumption that such buffers are always resident.
|
||||
// OK.
|
||||
#endif
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::begin_draw_primitives
|
||||
|
|
@ -2117,7 +2129,7 @@ prepare_texture(Texture *tex) {
|
|||
break;
|
||||
}
|
||||
|
||||
CLP(TextureContext) *gtc = new CLP(TextureContext)(tex);
|
||||
CLP(TextureContext) *gtc = new CLP(TextureContext)(_prepared_objects, tex);
|
||||
GLP(GenTextures)(1, >c->_index);
|
||||
report_my_gl_errors();
|
||||
|
||||
|
|
@ -2529,7 +2541,7 @@ record_deleted_display_list(GLuint index) {
|
|||
VertexBufferContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_vertex_buffer(GeomVertexArrayData *data) {
|
||||
if (_supports_buffers) {
|
||||
CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(data);
|
||||
CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(_prepared_objects, data);
|
||||
_glGenBuffers(1, &gvbc->_index);
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
|
|
@ -2566,7 +2578,7 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
}
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
|
||||
_current_vbuffer_index = gvbc->_index;
|
||||
add_to_vertex_buffer_record(gvbc);
|
||||
gvbc->set_active(true);
|
||||
}
|
||||
|
||||
if (gvbc->was_modified()) {
|
||||
|
|
@ -2589,7 +2601,7 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
|
|||
}
|
||||
_data_transferred_pcollector.add_level(num_bytes);
|
||||
}
|
||||
add_to_total_buffer_record(gvbc);
|
||||
|
||||
gvbc->mark_loaded();
|
||||
}
|
||||
|
||||
|
|
@ -2696,7 +2708,7 @@ setup_array_data(const GeomVertexArrayData *data) {
|
|||
IndexBufferContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_index_buffer(GeomPrimitive *data) {
|
||||
if (_supports_buffers) {
|
||||
CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(data);
|
||||
CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(_prepared_objects, data);
|
||||
_glGenBuffers(1, &gibc->_index);
|
||||
|
||||
if (GLCAT.is_debug()) {
|
||||
|
|
@ -2734,7 +2746,7 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
}
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
|
||||
_current_ibuffer_index = gibc->_index;
|
||||
add_to_index_buffer_record(gibc);
|
||||
gibc->set_active(true);
|
||||
}
|
||||
|
||||
if (gibc->was_modified()) {
|
||||
|
|
@ -2757,7 +2769,6 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||
}
|
||||
_data_transferred_pcollector.add_level(num_bytes);
|
||||
}
|
||||
add_to_total_buffer_record(gibc);
|
||||
gibc->mark_loaded();
|
||||
}
|
||||
|
||||
|
|
@ -6239,25 +6250,19 @@ void CLP(GraphicsStateGuardian)::
|
|||
apply_texture(TextureContext *tc) {
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
|
||||
add_to_texture_record(gtc);
|
||||
GLenum target = get_texture_target(gtc->_texture->get_texture_type());
|
||||
gtc->set_active(true);
|
||||
GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
|
||||
if (target == GL_NONE) {
|
||||
return;
|
||||
}
|
||||
GLP(BindTexture)(target, gtc->_index);
|
||||
|
||||
int dirty = gtc->get_dirty_flags();
|
||||
if ((dirty & (Texture::DF_wrap | Texture::DF_filter | Texture::DF_border)) != 0) {
|
||||
// We need to re-specify the texture properties.
|
||||
specify_texture(gtc->_texture);
|
||||
}
|
||||
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
|
||||
// We need to re-upload the image.
|
||||
if (gtc->was_modified()) {
|
||||
specify_texture(gtc->get_texture());
|
||||
upload_texture(gtc);
|
||||
gtc->mark_loaded();
|
||||
}
|
||||
|
||||
gtc->clear_dirty_flags();
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
|
@ -6272,7 +6277,7 @@ apply_texture(TextureContext *tc) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
upload_texture(CLP(TextureContext) *gtc) {
|
||||
Texture *tex = gtc->_texture;
|
||||
Texture *tex = gtc->get_texture();
|
||||
CPTA_uchar image = tex->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
return false;
|
||||
|
|
@ -6451,7 +6456,7 @@ upload_texture(CLP(TextureContext) *gtc) {
|
|||
gtc->_depth = depth;
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
gtc->_texture_memory_size = get_texture_memory_size(tex);
|
||||
gtc->update_data_size_bytes(get_texture_memory_size(tex));
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -6502,7 +6507,7 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
#endif
|
||||
#ifndef NDEBUG
|
||||
if (CLP(show_mipmaps) && target == GL_TEXTURE_2D) {
|
||||
build_phony_mipmaps(gtc->_texture);
|
||||
build_phony_mipmaps(gtc->get_texture());
|
||||
report_my_gl_errors();
|
||||
return true;
|
||||
|
||||
|
|
@ -6552,10 +6557,10 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
if (GLCAT.is_debug()) {
|
||||
if (image_compression != Texture::CM_off) {
|
||||
GLCAT.debug()
|
||||
<< "loading pre-compressed texture " << gtc->_texture->get_name() << "\n";
|
||||
<< "loading pre-compressed texture " << gtc->get_texture()->get_name() << "\n";
|
||||
} else if (is_compressed_format(internal_format)) {
|
||||
GLCAT.debug()
|
||||
<< "compressing texture " << gtc->_texture->get_name() << "\n";
|
||||
<< "compressing texture " << gtc->get_texture()->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6640,7 +6645,7 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
if (error_code != GL_NO_ERROR) {
|
||||
const GLubyte *error_string = GLUP(ErrorString)(error_code);
|
||||
GLCAT.error()
|
||||
<< "GL texture creation failed for " << gtc->_texture->get_name();
|
||||
<< "GL texture creation failed for " << gtc->get_texture()->get_name();
|
||||
if (error_string != (const GLubyte *)NULL) {
|
||||
GLCAT.error(false)
|
||||
<< " : " << error_string;
|
||||
|
|
@ -6737,6 +6742,42 @@ get_texture_memory_size(Texture *tex) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::check_nonresident_texture
|
||||
// Access: Private
|
||||
// Description: Checks the list of resident texture objects to see if
|
||||
// any have recently been evicted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
check_nonresident_texture(BufferContextChain &chain) {
|
||||
size_t num_textures = chain.get_count();
|
||||
CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
|
||||
GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
|
||||
size_t ti = 0;
|
||||
BufferContext *node = chain.get_first();
|
||||
while (node != (BufferContext *)NULL) {
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
|
||||
gtc_list[ti] = gtc;
|
||||
texture_list[ti] = gtc->_index;
|
||||
node = node->get_next();
|
||||
++ti;
|
||||
}
|
||||
nassertv(ti == num_textures);
|
||||
GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
|
||||
bool all_resident = (glAreTexturesResident(num_textures, texture_list, results) != 0);
|
||||
|
||||
report_my_gl_errors();
|
||||
|
||||
if (!all_resident) {
|
||||
// Some are now nonresident.
|
||||
for (ti = 0; ti < num_textures; ++ti) {
|
||||
if (!results[ti]) {
|
||||
gtc_list[ti]->set_resident(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::do_point_size
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ protected:
|
|||
Texture::CompressionMode image_compression);
|
||||
|
||||
size_t get_texture_memory_size(Texture *tex) const;
|
||||
void check_nonresident_texture(BufferContextChain &chain);
|
||||
|
||||
void do_point_size();
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(IndexBufferContext)::
|
||||
CLP(IndexBufferContext)(GeomPrimitive *data) :
|
||||
IndexBufferContext(data)
|
||||
CLP(IndexBufferContext)(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
||||
IndexBufferContext(pgo, data)
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(IndexBufferContext) : public IndexBufferContext {
|
||||
public:
|
||||
INLINE CLP(IndexBufferContext)(GeomPrimitive *data);
|
||||
INLINE CLP(IndexBufferContext)(PreparedGraphicsObjects *pgo,
|
||||
GeomPrimitive *data);
|
||||
|
||||
// This is the GL "name" of the data object.
|
||||
GLuint _index;
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(TextureContext)::
|
||||
CLP(TextureContext)(Texture *tex) :
|
||||
TextureContext(tex)
|
||||
CLP(TextureContext)(PreparedGraphicsObjects *pgo, Texture *tex) :
|
||||
TextureContext(pgo, tex)
|
||||
{
|
||||
_index = 0;
|
||||
_already_applied = false;
|
||||
_texture_memory_size = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,20 +19,3 @@
|
|||
#include "notify.h"
|
||||
|
||||
TypeHandle CLP(TextureContext)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLTextureContext::estimate_texture_memory
|
||||
// Access: Public, Virtual
|
||||
// Description: Estimates the amount of texture memory that will be
|
||||
// consumed by loading this texture. This is mainly
|
||||
// useful for debugging and reporting purposes.
|
||||
//
|
||||
// Returns a value in bytes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
size_t CLP(TextureContext)::
|
||||
estimate_texture_memory() {
|
||||
if (_texture_memory_size == 0) {
|
||||
return TextureContext::estimate_texture_memory();
|
||||
}
|
||||
return _texture_memory_size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(TextureContext) : public TextureContext {
|
||||
public:
|
||||
INLINE CLP(TextureContext)(Texture *tex);
|
||||
|
||||
virtual size_t estimate_texture_memory();
|
||||
INLINE CLP(TextureContext)(PreparedGraphicsObjects *pgo, Texture *tex);
|
||||
|
||||
// This is the GL "name" of the texture object.
|
||||
GLuint _index;
|
||||
|
|
@ -41,8 +39,6 @@ public:
|
|||
GLsizei _height;
|
||||
GLsizei _depth;
|
||||
|
||||
size_t _texture_memory_size;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(VertexBufferContext)::
|
||||
CLP(VertexBufferContext)(GeomVertexArrayData *data) :
|
||||
VertexBufferContext(data)
|
||||
CLP(VertexBufferContext)(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
|
||||
VertexBufferContext(pgo, data)
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(VertexBufferContext) : public VertexBufferContext {
|
||||
public:
|
||||
INLINE CLP(VertexBufferContext)(GeomVertexArrayData *data);
|
||||
INLINE CLP(VertexBufferContext)(PreparedGraphicsObjects *pgo,
|
||||
GeomVertexArrayData *data);
|
||||
|
||||
// This is the GL "name" of the data object.
|
||||
GLuint _index;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
bufferContext.I bufferContext.h \
|
||||
bufferContextChain.I bufferContextChain.h \
|
||||
bufferResidencyTracker.I bufferResidencyTracker.h \
|
||||
config_gobj.h \
|
||||
geom.h geom.I \
|
||||
geomContext.I geomContext.h \
|
||||
|
|
@ -61,6 +64,9 @@
|
|||
videoTexture.I videoTexture.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
bufferContext.cxx \
|
||||
bufferContextChain.cxx \
|
||||
bufferResidencyTracker.cxx \
|
||||
config_gobj.cxx \
|
||||
geomContext.cxx \
|
||||
geom.cxx \
|
||||
|
|
@ -108,6 +114,9 @@
|
|||
videoTexture.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
bufferContext.I bufferContext.h \
|
||||
bufferContextChain.I bufferContextChain.h \
|
||||
bufferResidencyTracker.I bufferResidencyTracker.h \
|
||||
config_gobj.h \
|
||||
geom.I geom.h \
|
||||
textureContext.I textureContext.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
// Filename: bufferContext.I
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: BufferContext::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContext::
|
||||
BufferContext(BufferResidencyTracker *residency) :
|
||||
_residency(residency),
|
||||
_residency_state(0),
|
||||
_data_size_bytes(0),
|
||||
_owning_chain(&residency->_chains[0])
|
||||
{
|
||||
#ifdef DO_PSTATS
|
||||
++(_owning_chain->_count);
|
||||
insert_before(_owning_chain);
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::get_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Returns the number of bytes previously reported for
|
||||
// the data object. This is used to track changes in
|
||||
// the data object's allocated size; if it changes from
|
||||
// this, we need to create a new buffer. This is also
|
||||
// used to track memory utilization in PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t BufferContext::
|
||||
get_data_size_bytes() const {
|
||||
return _data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::get_modified
|
||||
// Access: Public
|
||||
// Description: Returns the UpdateSeq that was recorded the last time
|
||||
// mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq BufferContext::
|
||||
get_modified() const {
|
||||
return _modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::set_active
|
||||
// Access: Public
|
||||
// Description: Changes the active flag associated with this object.
|
||||
// An object is considered "active" if it was rendered
|
||||
// in the current frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContext::
|
||||
set_active(bool flag) {
|
||||
#ifdef DO_PSTATS
|
||||
if (flag) {
|
||||
_residency_state |= BufferResidencyTracker::S_active;
|
||||
// Assume that rendering the object automatically makes it
|
||||
// resident.
|
||||
_residency_state |= BufferResidencyTracker::S_resident;
|
||||
} else {
|
||||
_residency_state &= ~BufferResidencyTracker::S_active;
|
||||
}
|
||||
set_owning_chain(&_residency->_chains[_residency_state]);
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::set_resident
|
||||
// Access: Public
|
||||
// Description: Changes the resident flag associated with this
|
||||
// object. An object is considered "resident" if it
|
||||
// appears to be resident in texture memory.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContext::
|
||||
set_resident(bool flag) {
|
||||
#ifdef DO_PSTATS
|
||||
if (flag) {
|
||||
_residency_state |= BufferResidencyTracker::S_resident;
|
||||
} else {
|
||||
_residency_state &= ~BufferResidencyTracker::S_resident;
|
||||
}
|
||||
set_owning_chain(&_residency->_chains[_residency_state]);
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::get_next
|
||||
// Access: Public
|
||||
// Description: This can be used along with
|
||||
// BufferContextChain::get_first() to walk through the
|
||||
// list of objects stored on a tracker.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContext *BufferContext::
|
||||
get_next() const {
|
||||
if ((BufferContextChain *)_next == _owning_chain) {
|
||||
return NULL;
|
||||
}
|
||||
return (BufferContext *)_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::update_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Should be called (usually by a derived class) when
|
||||
// the on-card size of this object has changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContext::
|
||||
update_data_size_bytes(size_t new_data_size_bytes) {
|
||||
_owning_chain->adjust_bytes((int)new_data_size_bytes - (int)_data_size_bytes);
|
||||
_data_size_bytes = new_data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::update_modified
|
||||
// Access: Public
|
||||
// Description: Should be called (usually by a derived class) when
|
||||
// the modified counter for this object has changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContext::
|
||||
update_modified(UpdateSeq new_modified) {
|
||||
_modified = new_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::set_owning_chain
|
||||
// Access: Private
|
||||
// Description: Moves this object to a different BufferContextChain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContext::
|
||||
set_owning_chain(BufferContextChain *chain) {
|
||||
if (chain != _owning_chain) {
|
||||
--(_owning_chain->_count);
|
||||
_owning_chain->adjust_bytes(-(int)_data_size_bytes);
|
||||
remove_from_list();
|
||||
_owning_chain = chain;
|
||||
++(_owning_chain->_count);
|
||||
_owning_chain->adjust_bytes((int)_data_size_bytes);
|
||||
insert_before(_owning_chain);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Filename: bufferContext.cxx
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "bufferContext.h"
|
||||
|
||||
TypeHandle BufferContext::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContext::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BufferContext::
|
||||
~BufferContext() {
|
||||
#ifdef DO_PSTATS
|
||||
--(_owning_chain->_count);
|
||||
_owning_chain->adjust_bytes(-(int)_data_size_bytes);
|
||||
remove_from_list();
|
||||
#endif // DO_PSTATS
|
||||
_owning_chain = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// Filename: bufferContext.h
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 BUFFERCONTEXT_H
|
||||
#define BUFFERCONTEXT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
#include "linkedListNode.h"
|
||||
#include "bufferContextChain.h"
|
||||
#include "bufferResidencyTracker.h"
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BufferContext
|
||||
// Description : This is a base class for those kinds of SavedContexts
|
||||
// that occupy an easily-measured (and substantial)
|
||||
// number of bytes in the video card's frame buffer
|
||||
// memory or AGP memory. At the present, this includes
|
||||
// most of the SavedContext types: VertexBufferContext
|
||||
// and IndexBufferContext, as well as TextureContext.
|
||||
//
|
||||
// This class provides methods for tracking the video
|
||||
// memory utilization, as well as residency of each
|
||||
// object, via PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA BufferContext : public SavedContext, private LinkedListNode {
|
||||
public:
|
||||
INLINE BufferContext(BufferResidencyTracker *residency);
|
||||
virtual ~BufferContext();
|
||||
|
||||
INLINE size_t get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
INLINE void set_active(bool flag);
|
||||
INLINE void set_resident(bool flag);
|
||||
|
||||
INLINE BufferContext *get_next() const;
|
||||
|
||||
INLINE void update_data_size_bytes(size_t new_data_size_bytes);
|
||||
INLINE void update_modified(UpdateSeq new_modified);
|
||||
|
||||
private:
|
||||
INLINE void set_owning_chain(BufferContextChain *chain);
|
||||
|
||||
private:
|
||||
BufferResidencyTracker *_residency;
|
||||
int _residency_state;
|
||||
|
||||
size_t _data_size_bytes;
|
||||
UpdateSeq _modified;
|
||||
BufferContextChain *_owning_chain;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
register_type(_type_handle, "BufferContext",
|
||||
SavedContext::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;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
friend class BufferResidencyTracker;
|
||||
friend class BufferContextChain;
|
||||
};
|
||||
|
||||
#include "bufferContext.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// Filename: bufferContextChain.I
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: BufferContextChain::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain::
|
||||
BufferContextChain() :
|
||||
LinkedListNode(true), // This object is the root of a list of BufferContexts.
|
||||
_total_size(0),
|
||||
_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain::
|
||||
~BufferContextChain() {
|
||||
nassertv(_total_size == 0 && _count == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::get_total_size
|
||||
// Access: Public
|
||||
// Description: Returns the total number of bytes represented by the
|
||||
// BufferContexts currently assigned to this tracker.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t BufferContextChain::
|
||||
get_total_size() const {
|
||||
return _total_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::get_count
|
||||
// Access: Public
|
||||
// Description: Returns the total number of BufferContexts currently
|
||||
// assigned to this tracker.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int BufferContextChain::
|
||||
get_count() const {
|
||||
return _count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::adjust_bytes
|
||||
// Access: Private
|
||||
// Description: Adds or removes some from the total byte count.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BufferContextChain::
|
||||
adjust_bytes(int delta) {
|
||||
_total_size += delta;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Filename: bufferContextChain.cxx
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "bufferContextChain.h"
|
||||
#include "bufferContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::get_first
|
||||
// Access: Public
|
||||
// Description: Returns the first BufferContext object stored in the
|
||||
// tracker. You can walk through the entire list of
|
||||
// objects stored on the tracker by calling get_next()
|
||||
// on each returned object, until the return value is
|
||||
// NULL.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BufferContext *BufferContextChain::
|
||||
get_first() {
|
||||
// This method is declared non-inline so we can include
|
||||
// bufferContext.h, which is necessary for proper downcasting of the
|
||||
// _next pointer.
|
||||
if (_next == this) {
|
||||
return NULL;
|
||||
}
|
||||
return (BufferContext *)_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferContextChain::take_from
|
||||
// Access: Public
|
||||
// Description: Moves all of the BufferContexts from the other
|
||||
// tracker onto this one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BufferContextChain::
|
||||
take_from(BufferContextChain &other) {
|
||||
_total_size += other._total_size;
|
||||
_count += other._count;
|
||||
other._total_size = 0;
|
||||
other._count = 0;
|
||||
|
||||
LinkedListNode *llnode = other._next;
|
||||
while (llnode != &other) {
|
||||
((BufferContext *)llnode)->_owning_chain = this;
|
||||
llnode = ((BufferContext *)llnode)->_next;
|
||||
}
|
||||
|
||||
take_list_from(&other);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Filename: bufferContextChain.h
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 BUFFERCONTEXTCHAIN_H
|
||||
#define BUFFERCONTEXTCHAIN_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "linkedListNode.h"
|
||||
|
||||
class BufferContext;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BufferContextChain
|
||||
// Description : This class maintains a linked list of BufferContexts
|
||||
// that might be allocated on the graphics card in some
|
||||
// context. There is a different BufferContextChain for
|
||||
// resident textures, active textures, evicted textures,
|
||||
// etc.
|
||||
//
|
||||
// The primary purpose of this class is to facilitate
|
||||
// PStats reporting of graphics memory usage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA BufferContextChain : private LinkedListNode {
|
||||
public:
|
||||
INLINE BufferContextChain();
|
||||
INLINE ~BufferContextChain();
|
||||
|
||||
INLINE size_t get_total_size() const;
|
||||
INLINE int get_count() const;
|
||||
|
||||
BufferContext *get_first();
|
||||
|
||||
void take_from(BufferContextChain &other);
|
||||
|
||||
private:
|
||||
INLINE void adjust_bytes(int delta);
|
||||
size_t _total_size;
|
||||
int _count;
|
||||
|
||||
friend class BufferContext;
|
||||
};
|
||||
|
||||
#include "bufferContextChain.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Filename: bufferResidencyTracker.I
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: BufferResidencyTracker::get_inactive_nonresident
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain &BufferResidencyTracker::
|
||||
get_inactive_nonresident() {
|
||||
return _chains[S_inactive_nonresident];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::get_active_nonresident
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain &BufferResidencyTracker::
|
||||
get_active_nonresident() {
|
||||
return _chains[S_active_nonresident];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::get_inactive_resident
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain &BufferResidencyTracker::
|
||||
get_inactive_resident() {
|
||||
return _chains[S_inactive_resident];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::get_active_resident
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BufferContextChain &BufferResidencyTracker::
|
||||
get_active_resident() {
|
||||
return _chains[S_active_resident];
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Filename: bufferResidencyTracker.cxx
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "bufferResidencyTracker.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
PStatCollector BufferResidencyTracker::_gmem_collector("Graphics memory");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BufferResidencyTracker::
|
||||
BufferResidencyTracker(const string &pgo_name, const string &type_name) :
|
||||
_pgo_collector(_gmem_collector, pgo_name),
|
||||
_active_resident_collector(PStatCollector(_pgo_collector, "Active"), type_name),
|
||||
_active_nonresident_collector(PStatCollector(_pgo_collector, "Thrashing"), type_name),
|
||||
_inactive_resident_collector(PStatCollector(_pgo_collector, "Inactive"), type_name),
|
||||
_inactive_nonresident_collector(PStatCollector(_pgo_collector, "Nonresident"), type_name),
|
||||
_active_frame(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::begin_frame
|
||||
// Access: Public
|
||||
// Description: To be called at the beginning of a frame, this
|
||||
// initializes the active/inactive status.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BufferResidencyTracker::
|
||||
begin_frame() {
|
||||
#ifdef DO_PSTATS
|
||||
int this_frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (_active_frame != this_frame) {
|
||||
_active_frame = this_frame;
|
||||
|
||||
// Move all of the previously "active" objects into "inactive".
|
||||
// They'll get re-added to "active" as they get rendered.
|
||||
move_inactive(_chains[S_inactive_nonresident],
|
||||
_chains[S_active_nonresident]);
|
||||
move_inactive(_chains[S_inactive_resident],
|
||||
_chains[S_active_resident]);
|
||||
}
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::end_frame
|
||||
// Access: Public
|
||||
// Description: To be called at the end of a frame, this
|
||||
// updates the PStatCollectors appropriately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BufferResidencyTracker::
|
||||
end_frame() {
|
||||
_inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size());
|
||||
_active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size());
|
||||
_inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size());
|
||||
_active_resident_collector.set_level(_chains[S_active_resident].get_total_size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BufferResidencyTracker::move_inactive
|
||||
// Access: Private
|
||||
// Description: Moves all of the "active" objects into "inactive".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BufferResidencyTracker::
|
||||
move_inactive(BufferContextChain &inactive, BufferContextChain &active) {
|
||||
BufferContext *node = active.get_first();
|
||||
while (node != (BufferContext *)NULL) {
|
||||
nassertv((node->_residency_state & S_active) != 0);
|
||||
node->_residency_state &= ~S_active;
|
||||
node = node->get_next();
|
||||
}
|
||||
|
||||
inactive.take_from(active);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Filename: bufferResidencyTracker.h
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 BUFFERRESIDENCYTRACKER_H
|
||||
#define BUFFERRESIDENCYTRACKER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "bufferContextChain.h"
|
||||
#include "pStatCollector.h"
|
||||
|
||||
class BufferContext;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BufferResidencyTracker
|
||||
// Description : This class is used to keep track of the current state
|
||||
// of all the BufferContexts for a particular graphics
|
||||
// context: whether each one is active (rendered this
|
||||
// frame) or inactive (not rendered this frame), and
|
||||
// whether it is resident or nonresident in video
|
||||
// memory.
|
||||
//
|
||||
// The primary purpose of this class is to facilitate
|
||||
// PStats reporting of video card memory usage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA BufferResidencyTracker {
|
||||
public:
|
||||
BufferResidencyTracker(const string &pgo_name, const string &type_name);
|
||||
|
||||
void begin_frame();
|
||||
void end_frame();
|
||||
|
||||
INLINE BufferContextChain &get_inactive_nonresident();
|
||||
INLINE BufferContextChain &get_active_nonresident();
|
||||
INLINE BufferContextChain &get_inactive_resident();
|
||||
INLINE BufferContextChain &get_active_resident();
|
||||
|
||||
private:
|
||||
void move_inactive(BufferContextChain &inactive, BufferContextChain &active);
|
||||
|
||||
private:
|
||||
enum State {
|
||||
// Individual bits.
|
||||
S_active = 0x01,
|
||||
S_resident = 0x02,
|
||||
|
||||
// Aggregate bits: unions of the above.
|
||||
S_inactive_nonresident = 0x00,
|
||||
S_active_nonresident = 0x01,
|
||||
S_inactive_resident = 0x02,
|
||||
S_active_resident = 0x03,
|
||||
|
||||
// The total number of different states.
|
||||
S_num_states = 4,
|
||||
};
|
||||
|
||||
// One chain for each of the possible states, ordered as above.
|
||||
BufferContextChain _chains[S_num_states];
|
||||
|
||||
// A couple of PStatCollectors just to organize names.
|
||||
static PStatCollector _gmem_collector;
|
||||
PStatCollector _pgo_collector;
|
||||
|
||||
// One PStatCollector for each state. These are ordered in reverse
|
||||
// order that we would like them to appear in the PStats graph.
|
||||
PStatCollector _active_resident_collector;
|
||||
PStatCollector _active_nonresident_collector;
|
||||
PStatCollector _inactive_resident_collector;
|
||||
PStatCollector _inactive_nonresident_collector;
|
||||
|
||||
// The frame number currently considered "active".
|
||||
int _active_frame;
|
||||
friend class BufferContext;
|
||||
};
|
||||
|
||||
#include "bufferResidencyTracker.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bufferContext.h"
|
||||
#include "config_util.h"
|
||||
#include "config_gobj.h"
|
||||
#include "geom.h"
|
||||
|
|
@ -238,6 +239,7 @@ ConfigVariableDouble default_keystone
|
|||
|
||||
|
||||
ConfigureFn(config_gobj) {
|
||||
BufferContext::init_type();
|
||||
Geom::init_type();
|
||||
GeomMunger::init_type();
|
||||
GeomPrimitive::init_type();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
#include "bufferContext.cxx"
|
||||
#include "bufferContextChain.cxx"
|
||||
#include "bufferResidencyTracker.cxx"
|
||||
#include "geom.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "geomEnums.cxx"
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE IndexBufferContext::
|
||||
IndexBufferContext(GeomPrimitive *data) :
|
||||
_data(data),
|
||||
// Initially, the number of bytes is zero, until the data has been
|
||||
// loaded (and mark_loaded() is called).
|
||||
_data_size_bytes(0)
|
||||
IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
|
||||
BufferContext(&pgo->_ibuffer_residency),
|
||||
_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -42,19 +40,6 @@ get_data() const {
|
|||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IndexBufferContext::get_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Returns the number of bytes previously reported for
|
||||
// the data object. This is used to track changes in
|
||||
// the data object's allocated size; if it changes from
|
||||
// this, we need to create a new buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int IndexBufferContext::
|
||||
get_data_size_bytes() const {
|
||||
return _data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IndexBufferContext::changed_size
|
||||
// Access: Public
|
||||
|
|
@ -63,7 +48,7 @@ get_data_size_bytes() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool IndexBufferContext::
|
||||
changed_size() const {
|
||||
return get_data_size_bytes() != _data->get_data_size_bytes();
|
||||
return get_data_size_bytes() != (size_t)_data->get_data_size_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -85,18 +70,7 @@ changed_usage_hint() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool IndexBufferContext::
|
||||
was_modified() const {
|
||||
return _modified != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IndexBufferContext::get_modified
|
||||
// Access: Public
|
||||
// Description: Returns the UpdateSeq that was recorded the last time
|
||||
// mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq IndexBufferContext::
|
||||
get_modified() const {
|
||||
return _modified;
|
||||
return get_modified() != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -108,7 +82,10 @@ get_modified() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void IndexBufferContext::
|
||||
mark_loaded() {
|
||||
_data_size_bytes = _data->get_data_size_bytes();
|
||||
update_data_size_bytes(_data->get_data_size_bytes());
|
||||
update_modified(_data->get_modified());
|
||||
_usage_hint = _data->get_usage_hint();
|
||||
_modified = _data->get_modified();
|
||||
|
||||
// Assume the buffer is now resident.
|
||||
set_resident(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
#include "bufferContext.h"
|
||||
#include "geomPrimitive.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : IndexBufferContext
|
||||
|
|
@ -36,17 +36,15 @@
|
|||
// allocate a vertex buffer for the array. OpenGL can
|
||||
// create a buffer object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA IndexBufferContext : public SavedContext {
|
||||
class EXPCL_PANDA IndexBufferContext : public BufferContext {
|
||||
public:
|
||||
INLINE IndexBufferContext(GeomPrimitive *data);
|
||||
INLINE IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data);
|
||||
|
||||
INLINE GeomPrimitive *get_data() const;
|
||||
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE bool changed_size() const;
|
||||
INLINE bool changed_usage_hint() const;
|
||||
INLINE bool was_modified() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
INLINE void mark_loaded();
|
||||
|
||||
|
|
@ -55,8 +53,6 @@ private:
|
|||
// the GSG both own their IndexBufferContexts! That would create a
|
||||
// circular reference count.
|
||||
GeomPrimitive *_data;
|
||||
UpdateSeq _modified;
|
||||
int _data_size_bytes;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
public:
|
||||
|
|
@ -64,9 +60,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
BufferContext::init_type();
|
||||
register_type(_type_handle, "IndexBufferContext",
|
||||
SavedContext::get_class_type());
|
||||
BufferContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,18 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::get_name
|
||||
// Access: Public
|
||||
// Description: Returns the name of the PreparedGraphicsObjects
|
||||
// structure. This is an arbitrary name that serves
|
||||
// mainly to uniquify the context for PStats reporting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &PreparedGraphicsObjects::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_all
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@
|
|||
#include "shaderExpansion.h"
|
||||
#include "reMutexHolder.h"
|
||||
|
||||
PStatCollector PreparedGraphicsObjects::_total_texusage_pcollector("Texture usage");
|
||||
PStatCollector PreparedGraphicsObjects::_total_buffers_pcollector("Vertex buffer size");
|
||||
int PreparedGraphicsObjects::_name_index = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::Constructor
|
||||
|
|
@ -36,7 +35,12 @@ PStatCollector PreparedGraphicsObjects::_total_buffers_pcollector("Vertex buffer
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PreparedGraphicsObjects::
|
||||
PreparedGraphicsObjects() {
|
||||
PreparedGraphicsObjects() :
|
||||
_name(init_name()),
|
||||
_texture_residency(_name, "texture"),
|
||||
_vbuffer_residency(_name, "vbuffer"),
|
||||
_ibuffer_residency(_name, "ibuffer")
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -58,8 +62,7 @@ PreparedGraphicsObjects::
|
|||
tci != _prepared_textures.end();
|
||||
++tci) {
|
||||
TextureContext *tc = (*tci);
|
||||
_total_texusage_pcollector.sub_level(tc->estimate_texture_memory());
|
||||
tc->_texture->clear_prepared(this);
|
||||
tc->get_texture()->clear_prepared(this);
|
||||
}
|
||||
|
||||
_prepared_textures.clear();
|
||||
|
|
@ -95,7 +98,6 @@ PreparedGraphicsObjects::
|
|||
vbci != _prepared_vertex_buffers.end();
|
||||
++vbci) {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
vbc->_data->clear_prepared(this);
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +110,6 @@ PreparedGraphicsObjects::
|
|||
ibci != _prepared_index_buffers.end();
|
||||
++ibci) {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
ibc->_data->clear_prepared(this);
|
||||
}
|
||||
|
||||
|
|
@ -175,8 +176,7 @@ void PreparedGraphicsObjects::
|
|||
release_texture(TextureContext *tc) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
tc->_texture->clear_prepared(this);
|
||||
_total_texusage_pcollector.sub_level(tc->estimate_texture_memory());
|
||||
tc->get_texture()->clear_prepared(this);
|
||||
|
||||
// We have to set the Texture pointer to NULL at this point, since
|
||||
// the Texture itself might destruct at any time after it has been
|
||||
|
|
@ -208,8 +208,7 @@ release_all_textures() {
|
|||
tci != _prepared_textures.end();
|
||||
++tci) {
|
||||
TextureContext *tc = (*tci);
|
||||
tc->_texture->clear_prepared(this);
|
||||
_total_texusage_pcollector.sub_level(tc->estimate_texture_memory());
|
||||
tc->get_texture()->clear_prepared(this);
|
||||
tc->_texture = (Texture *)NULL;
|
||||
|
||||
_released_textures.insert(tc);
|
||||
|
|
@ -255,8 +254,6 @@ prepare_texture_now(Texture *tex, GraphicsStateGuardianBase *gsg) {
|
|||
if (tc != (TextureContext *)NULL) {
|
||||
bool prepared = _prepared_textures.insert(tc).second;
|
||||
nassertr(prepared, tc);
|
||||
|
||||
_total_texusage_pcollector.add_level(tc->estimate_texture_memory());
|
||||
}
|
||||
|
||||
return tc;
|
||||
|
|
@ -600,7 +597,6 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
|||
ReMutexHolder holder(_lock);
|
||||
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
|
|
@ -633,7 +629,6 @@ release_all_vertex_buffers() {
|
|||
++vbci) {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
vbc->_data = (GeomVertexArrayData *)NULL;
|
||||
|
||||
_released_vertex_buffers.insert(vbc);
|
||||
|
|
@ -679,11 +674,6 @@ prepare_vertex_buffer_now(GeomVertexArrayData *data, GraphicsStateGuardianBase *
|
|||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
bool prepared = _prepared_vertex_buffers.insert(vbc).second;
|
||||
nassertr(prepared, vbc);
|
||||
|
||||
// The size has already been counted by
|
||||
// GraphicsStateGuardian::add_to_vertex_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(vbc->get_data_size_bytes());
|
||||
}
|
||||
|
||||
return vbc;
|
||||
|
|
@ -747,7 +737,6 @@ release_index_buffer(IndexBufferContext *ibc) {
|
|||
ReMutexHolder holder(_lock);
|
||||
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
|
|
@ -780,7 +769,6 @@ release_all_index_buffers() {
|
|||
++ibci) {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
ibc->_data = (GeomPrimitive *)NULL;
|
||||
|
||||
_released_index_buffers.insert(ibc);
|
||||
|
|
@ -826,22 +814,17 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
|
|||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
bool prepared = _prepared_index_buffers.insert(ibc).second;
|
||||
nassertr(prepared, ibc);
|
||||
|
||||
// The size has already been counted by
|
||||
// GraphicsStateGuardian::add_to_index_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(ibc->get_data_size_bytes());
|
||||
}
|
||||
|
||||
return ibc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::update
|
||||
// Function: PreparedGraphicsObjects::begin_frame
|
||||
// Access: Public
|
||||
// Description: This is called by the GraphicsStateGuardian to
|
||||
// indicate that it is in a state to load or release
|
||||
// textures.
|
||||
// indicate that it is about to begin processing of the
|
||||
// frame.
|
||||
//
|
||||
// Any texture contexts that were previously passed to
|
||||
// release_texture() are actually passed to the GSG to
|
||||
|
|
@ -849,7 +832,7 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
|
|||
// passed to prepare_texture are actually loaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
update(GraphicsStateGuardianBase *gsg) {
|
||||
begin_frame(GraphicsStateGuardianBase *gsg) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
// First, release all the textures, geoms, and buffers awaiting
|
||||
|
|
@ -904,6 +887,11 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_released_index_buffers.clear();
|
||||
|
||||
// Reset the residency trackers.
|
||||
_texture_residency.begin_frame();
|
||||
_vbuffer_residency.begin_frame();
|
||||
_ibuffer_residency.begin_frame();
|
||||
|
||||
// Now prepare all the textures, geoms, and buffers awaiting
|
||||
// preparation.
|
||||
EnqueuedTextures::iterator qti;
|
||||
|
|
@ -956,3 +944,33 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_enqueued_index_buffers.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::end_frame
|
||||
// Access: Public
|
||||
// Description: This is called by the GraphicsStateGuardian to
|
||||
// indicate that it has finished processing of the
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
end_frame() {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
_texture_residency.end_frame();
|
||||
_vbuffer_residency.end_frame();
|
||||
_ibuffer_residency.end_frame();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::init_name
|
||||
// Access: Private, Static
|
||||
// Description: Returns a new, unique name for a newly-constructed
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string PreparedGraphicsObjects::
|
||||
init_name() {
|
||||
++_name_index;
|
||||
ostringstream strm;
|
||||
strm << "context" << _name_index;
|
||||
return strm.str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "pStatCollector.h"
|
||||
#include "pset.h"
|
||||
#include "reMutex.h"
|
||||
#include "bufferResidencyTracker.h"
|
||||
|
||||
class TextureContext;
|
||||
class GeomContext;
|
||||
|
|
@ -62,6 +63,8 @@ public:
|
|||
PreparedGraphicsObjects();
|
||||
~PreparedGraphicsObjects();
|
||||
|
||||
INLINE const string &get_name() const;
|
||||
|
||||
INLINE void release_all();
|
||||
|
||||
void enqueue_texture(Texture *tex);
|
||||
|
|
@ -103,7 +106,11 @@ public:
|
|||
prepare_index_buffer_now(GeomPrimitive *data,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void update(GraphicsStateGuardianBase *gsg);
|
||||
void begin_frame(GraphicsStateGuardianBase *gsg);
|
||||
void end_frame();
|
||||
|
||||
private:
|
||||
static string init_name();
|
||||
|
||||
private:
|
||||
typedef phash_set<TextureContext *, pointer_hash> Textures;
|
||||
|
|
@ -118,6 +125,7 @@ private:
|
|||
typedef phash_set< PT(GeomPrimitive) > EnqueuedIndexBuffers;
|
||||
|
||||
ReMutex _lock;
|
||||
string _name;
|
||||
Textures _prepared_textures, _released_textures;
|
||||
EnqueuedTextures _enqueued_textures;
|
||||
Geoms _prepared_geoms, _released_geoms;
|
||||
|
|
@ -129,8 +137,13 @@ private:
|
|||
IndexBuffers _prepared_index_buffers, _released_index_buffers;
|
||||
EnqueuedIndexBuffers _enqueued_index_buffers;
|
||||
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
public:
|
||||
BufferResidencyTracker _texture_residency;
|
||||
BufferResidencyTracker _vbuffer_residency;
|
||||
BufferResidencyTracker _ibuffer_residency;
|
||||
|
||||
private:
|
||||
static int _name_index;
|
||||
|
||||
friend class GraphicsStateGuardian;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -542,6 +542,18 @@ set_keep_ram_image(bool keep_ram_image) {
|
|||
_keep_ram_image = keep_ram_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_modified
|
||||
// Access: Published
|
||||
// Description: Returns a sequence number which is guaranteed to
|
||||
// change at least every time the texture data or
|
||||
// properties are modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq Texture::
|
||||
get_modified() const {
|
||||
return _modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_filename
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ Texture(const string &name) :
|
|||
_wrap_w = WM_repeat;
|
||||
_anisotropic_degree = 1;
|
||||
_keep_ram_image = true;
|
||||
_all_dirty_flags = 0;
|
||||
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_compression = CM_default;
|
||||
_ram_image_compression = CM_off;
|
||||
|
|
@ -115,7 +114,6 @@ Texture(const Texture ©) :
|
|||
_border_color(copy._border_color),
|
||||
_compression(copy._compression),
|
||||
_match_framebuffer_format(copy._match_framebuffer_format),
|
||||
_all_dirty_flags(0),
|
||||
_ram_image(copy._ram_image),
|
||||
_ram_image_compression(copy._ram_image_compression),
|
||||
_ram_page_size(copy._ram_page_size)
|
||||
|
|
@ -157,10 +155,10 @@ operator = (const Texture ©) {
|
|||
_border_color = copy._border_color;
|
||||
_compression = copy._compression;
|
||||
_match_framebuffer_format = copy._match_framebuffer_format;
|
||||
_all_dirty_flags = 0;
|
||||
_ram_image = copy._ram_image;
|
||||
_ram_image_compression = copy._ram_image_compression;
|
||||
_ram_page_size = copy._ram_page_size;
|
||||
++_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -915,7 +913,7 @@ load(const PNMImage &pnmimage, int z) {
|
|||
nassertr((size_t)idx == get_expected_ram_page_size() * (z + 1), false);
|
||||
}
|
||||
|
||||
mark_dirty(DF_image);
|
||||
++_modified;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1037,7 +1035,7 @@ load_related(const PT(InternalName) &suffix) const {
|
|||
void Texture::
|
||||
set_wrap_u(Texture::WrapMode wrap) {
|
||||
if (_wrap_u != wrap) {
|
||||
mark_dirty(DF_wrap);
|
||||
++_modified;
|
||||
_wrap_u = wrap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1050,7 +1048,7 @@ set_wrap_u(Texture::WrapMode wrap) {
|
|||
void Texture::
|
||||
set_wrap_v(Texture::WrapMode wrap) {
|
||||
if (_wrap_v != wrap) {
|
||||
mark_dirty(DF_wrap);
|
||||
++_modified;
|
||||
_wrap_v = wrap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1063,7 +1061,7 @@ set_wrap_v(Texture::WrapMode wrap) {
|
|||
void Texture::
|
||||
set_wrap_w(Texture::WrapMode wrap) {
|
||||
if (_wrap_w != wrap) {
|
||||
mark_dirty(DF_wrap);
|
||||
++_modified;
|
||||
_wrap_w = wrap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1076,11 +1074,7 @@ set_wrap_w(Texture::WrapMode wrap) {
|
|||
void Texture::
|
||||
set_minfilter(Texture::FilterType filter) {
|
||||
if (_minfilter != filter) {
|
||||
if (is_mipmap(_minfilter) != is_mipmap(filter)) {
|
||||
mark_dirty(DF_filter | DF_mipmap);
|
||||
} else {
|
||||
mark_dirty(DF_filter);
|
||||
}
|
||||
++_modified;
|
||||
_minfilter = filter;
|
||||
}
|
||||
}
|
||||
|
|
@ -1093,7 +1087,7 @@ set_minfilter(Texture::FilterType filter) {
|
|||
void Texture::
|
||||
set_magfilter(Texture::FilterType filter) {
|
||||
if (_magfilter != filter) {
|
||||
mark_dirty(DF_filter);
|
||||
++_modified;
|
||||
_magfilter = filter;
|
||||
}
|
||||
}
|
||||
|
|
@ -1110,7 +1104,7 @@ set_magfilter(Texture::FilterType filter) {
|
|||
void Texture::
|
||||
set_anisotropic_degree(int anisotropic_degree) {
|
||||
if (_anisotropic_degree != anisotropic_degree) {
|
||||
mark_dirty(DF_filter);
|
||||
++_modified;
|
||||
_anisotropic_degree = anisotropic_degree;
|
||||
}
|
||||
}
|
||||
|
|
@ -1126,7 +1120,7 @@ set_anisotropic_degree(int anisotropic_degree) {
|
|||
void Texture::
|
||||
set_border_color(const Colorf &color) {
|
||||
if (_border_color != color) {
|
||||
mark_dirty(DF_border);
|
||||
++_modified;
|
||||
_border_color = color;
|
||||
}
|
||||
}
|
||||
|
|
@ -1153,7 +1147,7 @@ set_border_color(const Colorf &color) {
|
|||
void Texture::
|
||||
set_compression(Texture::CompressionMode compression) {
|
||||
if (_compression != compression) {
|
||||
mark_dirty(DF_image);
|
||||
++_modified;
|
||||
_compression = compression;
|
||||
}
|
||||
}
|
||||
|
|
@ -1254,7 +1248,7 @@ modify_ram_image() {
|
|||
make_ram_image();
|
||||
}
|
||||
|
||||
mark_dirty(DF_image);
|
||||
++_modified;
|
||||
_keep_ram_image = true;
|
||||
return _ram_image;
|
||||
}
|
||||
|
|
@ -1272,7 +1266,7 @@ PTA_uchar Texture::
|
|||
make_ram_image() {
|
||||
_ram_image = PTA_uchar::empty_array(get_expected_ram_image_size());
|
||||
_ram_image_compression = CM_off;
|
||||
mark_dirty(DF_image);
|
||||
++_modified;
|
||||
_keep_ram_image = true;
|
||||
return _ram_image;
|
||||
}
|
||||
|
|
@ -1299,7 +1293,7 @@ set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
|
|||
if (page_size == 0) {
|
||||
_ram_page_size = image.size();
|
||||
}
|
||||
mark_dirty(DF_image);
|
||||
++_modified;
|
||||
}
|
||||
_keep_ram_image = true;
|
||||
}
|
||||
|
|
@ -1685,12 +1679,6 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
_contexts[prepared_objects] = tc;
|
||||
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
// Now that we have a new TextureContext with zero dirty flags, our
|
||||
// intersection of all dirty flags must be zero. This doesn't mean
|
||||
// that some other contexts aren't still dirty, but at least one
|
||||
// context isn't.
|
||||
_all_dirty_flags = 0;
|
||||
|
||||
if (!keep_texture_ram && !_keep_ram_image) {
|
||||
// Once we have prepared the texture, we can generally safely
|
||||
// remove the pixels from main RAM. The GSG is now responsible
|
||||
|
|
@ -1706,41 +1694,6 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
return tc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::mark_dirty
|
||||
// Access: Public
|
||||
// Description: Sets the indicated dirty bits on for all texture
|
||||
// contexts that share this Texture. Does not change
|
||||
// the bits that are not on. This presumably will
|
||||
// inform the GSG that the texture properties have
|
||||
// changed. See also TextureContext::mark_dirty().
|
||||
//
|
||||
// Normally, this does not need to be called directly;
|
||||
// changing the properties on the texture will
|
||||
// automatically call this. However, if you fiddle with
|
||||
// the texture image directly, you may need to
|
||||
// explicitly call mark_dirty(Texture::DF_image).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
mark_dirty(int flags_to_set) {
|
||||
if ((_all_dirty_flags & flags_to_set) == flags_to_set) {
|
||||
// If all the texture contexts already share these bits, no need
|
||||
// to do anything else.
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, iterate through the contexts and mark them all dirty.
|
||||
Contexts::iterator ci;
|
||||
for (ci = _contexts.begin(); ci != _contexts.end(); ++ci) {
|
||||
TextureContext *tc = (*ci).second;
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
tc->mark_dirty(flags_to_set);
|
||||
}
|
||||
}
|
||||
|
||||
_all_dirty_flags |= flags_to_set;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::has_cull_callback
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "namable.h"
|
||||
#include "internalName.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
#include "updateSeq.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class PNMImage;
|
||||
|
|
@ -267,6 +268,8 @@ PUBLISHED:
|
|||
INLINE void set_keep_ram_image(bool keep_ram_image);
|
||||
virtual bool get_keep_ram_image() const;
|
||||
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
|
@ -307,19 +310,6 @@ public:
|
|||
TextureContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
// These bits are used as parameters to Texture::mark_dirty() and
|
||||
// also TextureContext::mark_dirty() (and related functions in
|
||||
// TextureContext).
|
||||
enum DirtyFlags {
|
||||
DF_image = 0x001, // The image pixels have changed.
|
||||
DF_wrap = 0x002, // The wrap properties have changed.
|
||||
DF_filter = 0x004, // The minfilter or magfilter have changed.
|
||||
DF_mipmap = 0x008, // The use of mipmaps or not has changed.
|
||||
DF_border = 0x010, // The border has changed.
|
||||
};
|
||||
|
||||
void mark_dirty(int flags_to_set);
|
||||
|
||||
virtual bool has_cull_callback() const;
|
||||
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||
|
||||
|
|
@ -415,15 +405,11 @@ protected:
|
|||
typedef pmap<PT(InternalName), PT(Texture)> RelatedTextures;
|
||||
RelatedTextures _related_textures;
|
||||
|
||||
// This value represents the intersection of all the dirty flags of
|
||||
// the various TextureContexts that might be associated with this
|
||||
// texture.
|
||||
int _all_dirty_flags;
|
||||
|
||||
PTA_uchar _ram_image;
|
||||
CompressionMode _ram_image_compression;
|
||||
size_t _ram_page_size;
|
||||
|
||||
UpdateSeq _modified;
|
||||
|
||||
// Datagram stuff
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -23,70 +23,49 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TextureContext::
|
||||
TextureContext(Texture *tex) :
|
||||
TextureContext(PreparedGraphicsObjects *pgo, Texture *tex) :
|
||||
BufferContext(&pgo->_texture_residency),
|
||||
_texture(tex)
|
||||
{
|
||||
_dirty_flags = ~0;
|
||||
#ifdef DO_PSTATS
|
||||
update_data_size_bytes(estimate_texture_memory());
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureContext::mark_dirty
|
||||
// Function: TextureContext::get_texture
|
||||
// Access: Public
|
||||
// Description: Marks the context "dirty", i.e. its properties are
|
||||
// different from the last time the GSG has seen them.
|
||||
// Presumably, the GSG will respond by updating the
|
||||
// properties and clearing the dirty bits the next time
|
||||
// it renders the texture.
|
||||
//
|
||||
// The value is the union of all the bits that are to be
|
||||
// set dirty; bits that are not set in this parameter
|
||||
// are left unchanged. See Texture::DirtyFlags for a
|
||||
// list of available bits.
|
||||
//
|
||||
// Usually this function is not called directly, but
|
||||
// rather is called by Texture::mark_dirty() as a result
|
||||
// of changing properties directly on the texture.
|
||||
// Description: Returns the pointer to the associated Texture
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture *TextureContext::
|
||||
get_texture() const {
|
||||
return _texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureContext::was_modified
|
||||
// Access: Public
|
||||
// Description: Returns true if the texture has been modified since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TextureContext::
|
||||
was_modified() const {
|
||||
return get_modified() != _texture->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureContext::mark_loaded
|
||||
// Access: Public
|
||||
// Description: Should be called after the TextureContext has been
|
||||
// loaded into graphics memory, this updates the
|
||||
// internal flags for changed_size() and modified().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextureContext::
|
||||
mark_dirty(int flags_to_set) {
|
||||
_dirty_flags |= flags_to_set;
|
||||
}
|
||||
mark_loaded() {
|
||||
// _data_size_bytes = _data->get_texture_size_bytes();
|
||||
update_modified(_texture->get_modified());
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureContext::clear_dirty_flags
|
||||
// Access: Public
|
||||
// Description: Removes the indicated flags from the "dirty" bits.
|
||||
// See mark_dirty().
|
||||
//
|
||||
// The value is the union of all the bits that are to be
|
||||
// cleared; if a bit is set in the parameter, it will be
|
||||
// removed from the dirty set. Bits that are not set in
|
||||
// this parameter are left unchanged.
|
||||
//
|
||||
// This function is intended to be called by the GSG
|
||||
// after it has updated the texture parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextureContext::
|
||||
clear_dirty_flags(int flags_to_clear) {
|
||||
_dirty_flags &= ~flags_to_clear;
|
||||
_texture->_all_dirty_flags &= ~flags_to_clear;
|
||||
// Assume the texture is now resident.
|
||||
set_resident(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureContext::get_dirty_flags
|
||||
// Access: Public
|
||||
// Description: Returns the current state of the dirty flags. If
|
||||
// this is non-zero, it represents the union of all
|
||||
// properties that have been changed since the last call
|
||||
// to clear_dirty_flags().
|
||||
//
|
||||
// This function is intended to be called by the GSG to
|
||||
// determine what properties need to be updated. See
|
||||
// Texture::DirtyFlags for a list of possible bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TextureContext::
|
||||
get_dirty_flags() const {
|
||||
_texture->reconsider_dirty();
|
||||
return _dirty_flags;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "bufferContext.h"
|
||||
#include "texture.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TextureContext
|
||||
|
|
@ -37,33 +38,31 @@
|
|||
// texture and store it here. The texture stores all of
|
||||
// these handles internally.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA TextureContext : public SavedContext {
|
||||
class EXPCL_PANDA TextureContext : public BufferContext {
|
||||
public:
|
||||
INLINE TextureContext(Texture *tex);
|
||||
INLINE TextureContext(PreparedGraphicsObjects *pgo, Texture *tex);
|
||||
|
||||
INLINE Texture *get_texture() const;
|
||||
|
||||
INLINE bool was_modified() const;
|
||||
INLINE void mark_loaded();
|
||||
|
||||
virtual size_t estimate_texture_memory();
|
||||
|
||||
private:
|
||||
// This cannot be a PT(Texture), because the texture and the GSG
|
||||
// both own their TextureContexts! That would create a circular
|
||||
// reference count.
|
||||
Texture *_texture;
|
||||
|
||||
INLINE void mark_dirty(int flags_to_set);
|
||||
INLINE void clear_dirty_flags(int flags_to_clear = ~0);
|
||||
INLINE int get_dirty_flags() const;
|
||||
|
||||
private:
|
||||
int _dirty_flags;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
BufferContext::init_type();
|
||||
register_type(_type_handle, "TextureContext",
|
||||
SavedContext::get_class_type());
|
||||
BufferContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
@ -72,6 +71,8 @@ public:
|
|||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "textureContext.I"
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE VertexBufferContext::
|
||||
VertexBufferContext(GeomVertexArrayData *data) :
|
||||
_data(data),
|
||||
// Initially, the number of bytes is zero, until the data has been
|
||||
// loaded (and mark_loaded() is called).
|
||||
_data_size_bytes(0)
|
||||
VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
|
||||
BufferContext(&pgo->_vbuffer_residency),
|
||||
_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -42,19 +40,6 @@ get_data() const {
|
|||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::get_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Returns the number of bytes previously reported for
|
||||
// the data object. This is used to track changes in
|
||||
// the data object's allocated size; if it changes from
|
||||
// this, we need to create a new buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int VertexBufferContext::
|
||||
get_data_size_bytes() const {
|
||||
return _data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::changed_size
|
||||
// Access: Public
|
||||
|
|
@ -63,7 +48,7 @@ get_data_size_bytes() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_size() const {
|
||||
return get_data_size_bytes() != _data->get_data_size_bytes();
|
||||
return get_data_size_bytes() != (size_t)_data->get_data_size_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -85,18 +70,7 @@ changed_usage_hint() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
was_modified() const {
|
||||
return _modified != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::get_modified
|
||||
// Access: Public
|
||||
// Description: Returns the UpdateSeq that was recorded the last time
|
||||
// mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq VertexBufferContext::
|
||||
get_modified() const {
|
||||
return _modified;
|
||||
return get_modified() != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -108,7 +82,10 @@ get_modified() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VertexBufferContext::
|
||||
mark_loaded() {
|
||||
_data_size_bytes = _data->get_data_size_bytes();
|
||||
update_data_size_bytes(_data->get_data_size_bytes());
|
||||
update_modified(_data->get_modified());
|
||||
_usage_hint = _data->get_usage_hint();
|
||||
_modified = _data->get_modified();
|
||||
|
||||
// Assume the buffer is now resident.
|
||||
set_resident(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
#include "bufferContext.h"
|
||||
#include "geomVertexArrayData.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : VertexBufferContext
|
||||
|
|
@ -36,17 +36,16 @@
|
|||
// allocate a vertex buffer for the array. OpenGL can
|
||||
// create a buffer object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA VertexBufferContext : public SavedContext {
|
||||
class EXPCL_PANDA VertexBufferContext : public BufferContext {
|
||||
public:
|
||||
INLINE VertexBufferContext(GeomVertexArrayData *data);
|
||||
INLINE VertexBufferContext(PreparedGraphicsObjects *pgo,
|
||||
GeomVertexArrayData *data);
|
||||
|
||||
INLINE GeomVertexArrayData *get_data() const;
|
||||
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE bool changed_size() const;
|
||||
INLINE bool changed_usage_hint() const;
|
||||
INLINE bool was_modified() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
INLINE void mark_loaded();
|
||||
|
||||
|
|
@ -55,8 +54,6 @@ private:
|
|||
// the GSG both own their VertexBufferContexts! That would create a
|
||||
// circular reference count.
|
||||
GeomVertexArrayData *_data;
|
||||
UpdateSeq _modified;
|
||||
int _data_size_bytes;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
public:
|
||||
|
|
@ -64,9 +61,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
BufferContext::init_type();
|
||||
register_type(_type_handle, "VertexBufferContext",
|
||||
SavedContext::get_class_type());
|
||||
BufferContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -154,21 +154,7 @@ static TimeCollectorProperties time_properties[] = {
|
|||
};
|
||||
|
||||
static LevelCollectorProperties level_properties[] = {
|
||||
{ 1, "Texture usage", { 1.0, 0.0, 0.5 }, "MB", 12, 1048576 },
|
||||
{ 1, "Texture usage:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Texture memory", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Texture memory:In use", { 0.0, 1.0, 1.0 } },
|
||||
{ 1, "Texture manager", { 1.0, 0.0, 0.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Texture manager:Resident", { 1.0, 1.0, 0.0 } },
|
||||
{ 1, "Prepared Textures", { 0.6, 0.8, 0.0 }, "", 500 },
|
||||
{ 1, "Prepared Textures:Active", { 0.0, 0.6, 0.8 } },
|
||||
{ 1, "Prepared Geoms", { 1.0, 0.0, 0.5 }, "", 500 },
|
||||
{ 1, "Prepared Geoms:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Prepared GeomNodes", { 1.0, 0.0, 0.5 }, "", 500 },
|
||||
{ 1, "Prepared GeomNodes:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Vertex buffer size", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Vertex buffer size:Active vertex", { 1.0, 0.0, 0.5 } },
|
||||
{ 1, "Vertex buffer size:Active index" , { 0.5, 0.6, 1.0 } },
|
||||
{ 1, "Graphics memory", { 0.0, 0.0, 1.0 }, "MB", 64, 1048576 },
|
||||
{ 1, "Vertex buffer switch", { 0.0, 0.6, 0.8 }, "", 500 },
|
||||
{ 1, "Vertex buffer switch:Vertex", { 0.8, 0.0, 0.6 } },
|
||||
{ 1, "Vertex buffer switch:Index", { 0.8, 0.6, 0.3 } },
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
ioPtaDatagramFloat.h ioPtaDatagramInt.h \
|
||||
ioPtaDatagramShort.h keyboardButton.h lineStream.I \
|
||||
lineStream.h lineStreamBuf.I lineStreamBuf.h \
|
||||
linkedListNode.I linkedListNode.h \
|
||||
load_prc_file.h \
|
||||
modifierButtons.I modifierButtons.h mouseButton.h \
|
||||
mouseData.I mouseData.h nameUniquifier.I nameUniquifier.h \
|
||||
|
|
@ -75,6 +76,7 @@
|
|||
ioPtaDatagramFloat.cxx \
|
||||
ioPtaDatagramInt.cxx ioPtaDatagramShort.cxx \
|
||||
keyboardButton.cxx lineStream.cxx lineStreamBuf.cxx \
|
||||
linkedListNode.cxx \
|
||||
load_prc_file.cxx \
|
||||
modifierButtons.cxx mouseButton.cxx mouseData.cxx \
|
||||
nameUniquifier.cxx \
|
||||
|
|
@ -119,6 +121,7 @@
|
|||
ioPtaDatagramFloat.h ioPtaDatagramInt.h \
|
||||
ioPtaDatagramShort.h iterator_types.h keyboardButton.h lineStream.I \
|
||||
lineStream.h lineStreamBuf.I lineStreamBuf.h \
|
||||
linkedListNode.I linkedListNode.h \
|
||||
load_prc_file.h \
|
||||
modifierButtons.I \
|
||||
modifierButtons.h mouseButton.h mouseData.I mouseData.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
// Filename: linkedListNode.I
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: LinkedListNode::Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LinkedListNode::
|
||||
LinkedListNode() {
|
||||
#ifndef NDEBUG
|
||||
_next = NULL;
|
||||
_prev = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinkedListNode::Constructor 2
|
||||
// Access: Protected
|
||||
// Description: This constructor should be invoked for any
|
||||
// LinkedListNodes that will be used to serve as the
|
||||
// root of a list. It sets up the pointers as an empty
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LinkedListNode::
|
||||
LinkedListNode(bool) {
|
||||
_next = this;
|
||||
_prev = this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinkedListNode::Destructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LinkedListNode::
|
||||
~LinkedListNode() {
|
||||
nassertv((_next == NULL && _prev == NULL) || (_next == this && _prev == this));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinkedListNode::remove_from_list
|
||||
// Access: Protected
|
||||
// Description: Removes a LinkedListNode record from the
|
||||
// doubly-linked list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LinkedListNode::
|
||||
remove_from_list() {
|
||||
nassertv(_prev->_next == this && _next->_prev == this);
|
||||
_prev->_next = _next;
|
||||
_next->_prev = _prev;
|
||||
#ifndef NDEBUG
|
||||
_next = NULL;
|
||||
_prev = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinkedListNode::insert_before
|
||||
// Access: Protected
|
||||
// Description: Adds a LinkedListNode record before the indicated
|
||||
// node in the doubly-linked list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LinkedListNode::
|
||||
insert_before(LinkedListNode *node) {
|
||||
nassertv(node->_prev != NULL && node->_prev->_next == node && node->_next->_prev == node);
|
||||
nassertv(_prev == (LinkedListNode *)NULL &&
|
||||
_next == (LinkedListNode *)NULL);
|
||||
_prev = node->_prev;
|
||||
_next = node;
|
||||
_prev->_next = this;
|
||||
node->_prev = this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LinkedListNode::take_list_from
|
||||
// Access: Protected
|
||||
// Description: Given that this LinkedListNode represents the root of
|
||||
// a list, and the other pointer represents the root of
|
||||
// a different list, move all of the nodes (except the
|
||||
// root itself) from other_root onto this list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LinkedListNode::
|
||||
take_list_from(LinkedListNode *other_root) {
|
||||
other_root->_next->_prev = _prev;
|
||||
_prev->_next = other_root->_next;
|
||||
other_root->_prev->_next = this;
|
||||
_prev = other_root->_prev;
|
||||
|
||||
other_root->_next = other_root;
|
||||
other_root->_prev = other_root;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Filename: linkedListNode.cxx
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "linkedListNode.h"
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// Filename: linkedListNode.h
|
||||
// Created by: drose (16Mar06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 LINKEDLISTNODE_H
|
||||
#define LINKEDLISTNODE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LinkedListNode
|
||||
// Description : This just stores the pointers to implement a
|
||||
// doubly-linked list of some kind of object. There are
|
||||
// occasions when a hand-rolled linked list is more
|
||||
// appropriate than an STL container.
|
||||
//
|
||||
// Typically, each node of the linked list, as well as
|
||||
// the root of the list, will inherit from this class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA LinkedListNode {
|
||||
protected:
|
||||
INLINE LinkedListNode();
|
||||
INLINE LinkedListNode(bool);
|
||||
INLINE ~LinkedListNode();
|
||||
|
||||
INLINE void remove_from_list();
|
||||
INLINE void insert_before(LinkedListNode *node);
|
||||
|
||||
INLINE void take_list_from(LinkedListNode *other_root);
|
||||
|
||||
LinkedListNode *_prev, *_next;
|
||||
};
|
||||
|
||||
#include "linkedListNode.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -23,4 +23,5 @@
|
|||
#include "keyboardButton.cxx"
|
||||
#include "lineStream.cxx"
|
||||
#include "lineStreamBuf.cxx"
|
||||
#include "linkedListNode.cxx"
|
||||
#include "load_prc_file.cxx"
|
||||
|
|
|
|||
Loading…
Reference in New Issue