Преглед изворни кода

Add textures to LRU memory management.
Keep LRU disabled for now in GSG, so DX managment is still used.
LRU code needs more testing, ...

aignacio_sf пре 20 година
родитељ
комит
56c453f547

+ 54 - 2
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -66,7 +66,7 @@
 
 
 #define DEBUG_LRU false
-#define DEFAULT_ENABLE_LRU false
+#define DEFAULT_ENABLE_LRU !true
 
 
 TypeHandle DXGraphicsStateGuardian9::_type_handle;
@@ -196,6 +196,11 @@ apply_texture(int i, TextureContext *tc) {
 
   DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
 
+  if (_lru)
+  {
+    _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
@@ -811,12 +816,25 @@ end_frame() {
     _lru -> partial_lru_update (maximum_updates);
 //    _lru -> update_entire_lru ( );
 
+
+    if (false && dxgsg9_cat.is_debug())
+    {
+        dxgsg9_cat.debug() << "*  start_priority_index " << _lru -> _m.start_priority_index << "\n";
+        dxgsg9_cat.debug() << "*  start_update_lru_page " << _lru -> _m.start_update_lru_page << "\n";
+    }
+
     frames = 256;
     if ((_lru -> _m.current_frame_identifier % frames) == 0)
     {
       if (dxgsg9_cat.is_debug())
       {
+        UINT available_texture_memory;
+
+        available_texture_memory = _d3d_device->GetAvailableTextureMem ( );
+
         dxgsg9_cat.debug() << "* LRU: total_pages " << _lru -> _m.total_pages << "\n";
+        dxgsg9_cat.debug() << "*  DX available_texture_memory = " << available_texture_memory << "\n";
+        dxgsg9_cat.debug() << "*  DX delta_memory " << available_texture_memory - _lru -> _m.available_memory << "\n";
         dxgsg9_cat.debug() << "*  available_memory " << _lru -> _m.available_memory << "\n";
         dxgsg9_cat.debug() << "*  total lifetime pages created " << _lru -> _m.identifier << "\n";
         dxgsg9_cat.debug() << "*  total_lifetime_page_ins " << _lru -> _m.total_lifetime_page_ins << "\n";
@@ -1817,6 +1835,39 @@ bool index_buffer_page_out_function (LruPage *lru_page)
   return true;
 }
 
+bool texture_page_in_function (LruPage *lru_page)
+{
+  DXGraphicsStateGuardian9 *gsg;
+  DXTextureContext9 *texture;
+
+  gsg = (DXGraphicsStateGuardian9 *) (lru_page -> _m.lru -> _m.context);
+  texture = (DXTextureContext9 *) lru_page -> _m.lru_page_type.pointer;
+
+  texture -> create_texture (*(gsg->_screen));
+
+  if (DEBUG_LRU && dxgsg9_cat.is_debug())
+  {
+    dxgsg9_cat.debug() << "  *** page IN TEX " << lru_page -> _m.identifier << " size " << lru_page -> _m.size << "\n";
+  }
+
+  return true;
+}
+
+bool texture_page_out_function (LruPage *lru_page)
+{
+  DXTextureContext9 *texture;
+
+  texture = (DXTextureContext9 *) lru_page -> _m.lru_page_type.pointer;
+  texture -> delete_texture ( );
+
+  if (DEBUG_LRU && dxgsg9_cat.is_debug())
+  {
+    dxgsg9_cat.debug() << "  *** page OUT TEX " << lru_page -> _m.identifier << " size " << lru_page -> _m.size << "\n";
+  }
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::reset
 //       Access: Public, Virtual
@@ -1924,7 +1975,7 @@ reset() {
 maximum_memory = available_texture_memory;
 
 // TEST LRU *****
-maximum_memory = 20000000;
+maximum_memory = 55000000;
 maximum_pages = 20000;
 
     lru = new Lru (maximum_memory, maximum_pages);
@@ -1934,6 +1985,7 @@ maximum_pages = 20000;
 
       lru -> register_lru_page_type (GPT_VertexBuffer, vertex_buffer_page_in_function, vertex_buffer_page_out_function);
       lru -> register_lru_page_type (GPT_IndexBuffer, index_buffer_page_in_function, index_buffer_page_out_function);
+      lru -> register_lru_page_type (GPT_Texture, texture_page_in_function, texture_page_out_function);
 
       lru -> _m.context = (void *) this;
     }

+ 107 - 2
panda/src/dxgsg9/dxTextureContext9.cxx

@@ -16,10 +16,10 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#include "dxTextureContext9.h"
 #include "config_dxgsg9.h"
 #include "dxGraphicsStateGuardian9.h"
 #include "pStatTimer.h"
+#include "dxTextureContext9.h"
 #include <d3dx9tex.h>
 #include <assert.h>
 #include <time.h>
@@ -48,6 +48,7 @@ DXTextureContext9(Texture *tex) :
   _d3d_cube_texture = NULL;
   _has_mipmaps = false;
   _managed = -1;
+  _lru_page = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -61,6 +62,14 @@ DXTextureContext9::
     dxgsg9_cat.spam()
       << "Deleting texture context for " << _texture->get_name() << "\n";
   }
+
+  if (_lru_page)
+  {
+    _lru_page -> _m.lru -> remove_page (_lru_page);
+    _lru_page -> _m.lru -> free_page (_lru_page);
+    _lru_page = 0;
+  }
+
   delete_texture();
   TextureContext::~TextureContext();
 }
@@ -637,7 +646,7 @@ create_texture(DXScreenData &scrn) {
   DWORD usage;
   D3DPOOL pool;
 
-  if (_texture->get_render_to_texture ()) {
+  if (_texture->get_render_to_texture ( )) {
     // REQUIRED PARAMETERS
     _managed = false;
     pool = D3DPOOL_DEFAULT;
@@ -690,6 +699,8 @@ create_texture(DXScreenData &scrn) {
       (target_width, mip_level_count, usage,
        target_pixel_format, pool, &_d3d_cube_texture, NULL);
     _d3d_texture = _d3d_cube_texture;
+
+    target_height = target_width;
     break;
   }
 
@@ -713,6 +724,99 @@ create_texture(DXScreenData &scrn) {
 
   // PRINT_REFCNT(dxgsg9, scrn._d3d9);
 
+  float bytes_per_texel;
+
+  bytes_per_texel = 1.0f;
+  switch (target_pixel_format)
+  {
+    case D3DFMT_R3G3B2:
+    case D3DFMT_A8:
+    case D3DFMT_A8P8:
+    case D3DFMT_P8:
+    case D3DFMT_L8:
+    case D3DFMT_A4L4:
+      bytes_per_texel = 1.0f;
+      break;
+
+    case D3DFMT_R16F:
+    case D3DFMT_CxV8U8:
+    case D3DFMT_V8U8:
+    case D3DFMT_R5G6B5:
+    case D3DFMT_X1R5G5B5:
+    case D3DFMT_A1R5G5B5:
+    case D3DFMT_A4R4G4B4:
+    case D3DFMT_L16:
+    case D3DFMT_A8L8:
+    case D3DFMT_A8R3G3B2:
+    case D3DFMT_X4R4G4B4:
+      bytes_per_texel = 2.0f;
+      break;
+
+    case D3DFMT_R8G8B8:
+      bytes_per_texel = 3.0f;
+      break;
+
+    case D3DFMT_G16R16F:
+    case D3DFMT_Q8W8V8U8:
+    case D3DFMT_V16U16:
+    case D3DFMT_R32F:
+    case D3DFMT_A8R8G8B8:
+    case D3DFMT_X8R8G8B8:
+    case D3DFMT_A2B10G10R10:
+    case D3DFMT_A8B8G8R8:
+    case D3DFMT_X8B8G8R8:
+    case D3DFMT_G16R16:
+    case D3DFMT_A2R10G10B10:
+      bytes_per_texel = 4.0f;
+      break;
+
+    case D3DFMT_G32R32F:
+    case D3DFMT_A16B16G16R16F:
+    case D3DFMT_Q16W16V16U16:
+    case D3DFMT_A16B16G16R16:
+      bytes_per_texel = 8.0f;
+      break;
+
+    case D3DFMT_A32B32G32R32F:
+      bytes_per_texel = 16.0f;
+      break;
+
+    default:
+      dxgsg9_cat.error()
+        << "D3D create_texture ( ) unknown texture format\n";
+      break;
+  }
+
+  // must not put render to texture into LRU
+  if (_lru_page == 0 && _managed == false && _texture->get_render_to_texture ( ) == false)
+  {
+    int data_size;
+    Lru *lru;
+
+    data_size = target_width * target_height * target_depth;
+    data_size = (int) ((float) data_size * bytes_per_texel);
+    if (_has_mipmaps)
+    {
+      data_size = (int) ((float) data_size * 1.3f);
+    }
+
+    lru = scrn._dxgsg9 -> _lru;
+    if (lru)
+    {
+      LruPage *lru_page;
+
+      lru_page = lru -> allocate_page (data_size);
+      if (lru_page)
+      {
+        lru_page -> _m.type = GPT_Texture;
+        lru_page -> _m.lru_page_type.pointer = this;
+
+        lru -> add_cached_page (LPP_New, lru_page);
+        _lru_page = lru_page;
+      }
+    }
+  }
+
   return true;
 
  error_exit:
@@ -731,6 +835,7 @@ create_texture(DXScreenData &scrn) {
 ////////////////////////////////////////////////////////////////////
 void DXTextureContext9::
 delete_texture() {
+
   if (_d3d_texture == NULL) {
     // dont bother printing the msg below, since we already released it.
     return;

+ 7 - 0
panda/src/dxgsg9/dxTextureContext9.h

@@ -23,6 +23,8 @@
 #include "texture.h"
 #include "textureContext.h"
 
+#include "lru.h"
+
 ////////////////////////////////////////////////////////////////////
 //       Class : DXTextureContext9
 // Description :
@@ -60,6 +62,11 @@ private:
   IDirect3DCubeTexture9 *_d3d_cube_texture;
 
   int _managed;
+
+public:
+  LruPage *_lru_page;
+
+private:
   bool _has_mipmaps;
 
 public: