Browse Source

Fix regressions with Direct3D support. Add sRGB support to DX9 renderer.

rdb 11 years ago
parent
commit
7524299de9

+ 1 - 1
makepanda/makepanda.py

@@ -492,7 +492,7 @@ if (COMPILER == "MSVC"):
                 LibName(pkg, 'dxerr.lib')
             else:
                 LibName(pkg, 'dxerrVNUM.lib'.replace("VNUM", vnum))
-            LibName(pkg, 'ddraw.lib')
+            #LibName(pkg, 'ddraw.lib')
             LibName(pkg, 'dxguid.lib')
     IncDirectory("ALWAYS", GetThirdpartyDir() + "extras/include")
     LibName("WINSOCK", "wsock32.lib")

+ 1 - 1
panda/src/dxgsg8/Sources.pp

@@ -22,7 +22,7 @@
     wdxGraphicsPipe8.I wdxGraphicsPipe8.h \
     wdxGraphicsWindow8.I wdxGraphicsWindow8.h \
     dxgsg8base.h config_dxgsg8.h dxGraphicsStateGuardian8.I dxGraphicsStateGuardian8.h \
-    dxVertexBufferContext8.h dxVertexbufferContext8.I \
+    dxVertexBufferContext8.h dxVertexBufferContext8.I \
     dxIndexBufferContext8.h dxIndexBufferContext8.I \
     dxTextureContext8.h dxTextureContext8.I \
     dxGeomMunger8.h dxGeomMunger8.I \

+ 2 - 2
panda/src/dxgsg8/wdxGraphicsWindow8.cxx

@@ -413,7 +413,7 @@ handle_reshape() {
   GdiFlush();
   WinGraphicsWindow::handle_reshape();
 
-  if (_dxgsg != NULL) {
+  if (_dxgsg != NULL && _dxgsg->_d3d_device != NULL) {
     // create the new resized rendertargets
     WindowProperties props = get_properties();
     int x_size = props.get_x_size();
@@ -422,7 +422,7 @@ handle_reshape() {
     if (_wcontext._presentation_params.BackBufferWidth != x_size ||
         _wcontext._presentation_params.BackBufferHeight != y_size) {
       bool resize_succeeded = reset_device_resize_window(x_size, y_size);
-      
+
       if (wdxdisplay8_cat.is_debug()) {
         if (!resize_succeeded) {
           wdxdisplay8_cat.debug()

+ 1 - 1
panda/src/dxgsg9/Sources.pp

@@ -22,7 +22,7 @@
     wdxGraphicsPipe9.I wdxGraphicsPipe9.h \
     wdxGraphicsWindow9.I wdxGraphicsWindow9.h \
     dxgsg9base.h config_dxgsg9.h dxGraphicsStateGuardian9.I dxGraphicsStateGuardian9.h \
-    dxVertexBufferContext9.h dxVertexbufferContext9.I \
+    dxVertexBufferContext9.h dxVertexBufferContext9.I \
     dxIndexBufferContext9.h dxIndexBufferContext9.I \
     dxTextureContext9.h dxTextureContext9.I \
     dxGeomMunger9.h dxGeomMunger9.I \

+ 77 - 57
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -224,6 +224,13 @@ apply_texture(int i, TextureContext *tc) {
   DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
   Texture *tex = tc->get_texture();
 
+  //if (tex->get_color_space() == CS_srgb) {
+  if (Texture::is_srgb(tex->get_format())) {
+    set_sampler_state(i, D3DSAMP_SRGBTEXTURE, TRUE);
+  } else {
+    set_sampler_state(i, D3DSAMP_SRGBTEXTURE, FALSE);
+  }
+
   Texture::WrapMode wrap_u, wrap_v, wrap_w;
 
   DWORD address_u;
@@ -256,7 +263,7 @@ apply_texture(int i, TextureContext *tc) {
 
   int supports_anisotropic_mag_filter;
   D3DTEXTUREFILTERTYPE new_mag_filter;
-  
+
   supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
   if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
     new_mag_filter = ((ft != Texture::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
@@ -268,8 +275,8 @@ apply_texture(int i, TextureContext *tc) {
   hr = set_sampler_state(i, D3DSAMP_MAGFILTER, new_mag_filter);
   if (hr != D3D_OK) {
     dxgsg9_cat.error()
-      << "ERROR: set_sampler_state (D3DSAMP_MAGFILTER, " 
-      << new_mag_filter << ") failed for texture:" << tex -> get_name() << endl;    
+      << "ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
+      << new_mag_filter << ") failed for texture:" << tex -> get_name() << endl;
   }
 
   // map Panda composite min+mip filter types to d3d's separate min & mip filter types
@@ -353,7 +360,7 @@ upload_texture(DXTextureContext9 *dtc, bool force) {
   dtc->delete_texture();
   dtc->update_data_size_bytes(0);
   dtc->mark_unloaded();
-  
+
   if (_effective_incomplete_render && !force) {
     bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
     if (!has_image && tex->might_have_ram_image() &&
@@ -371,7 +378,7 @@ upload_texture(DXTextureContext9 *dtc, bool force) {
       }
     }
   }
-  
+
   return dtc->create_texture(*_screen);
 }
 
@@ -746,7 +753,7 @@ begin_occlusion_query() {
       << "Occlusion query failed.\n";
     return;
   }
-  
+
   PT(DXOcclusionQueryContext9) queryobj = new DXOcclusionQueryContext9(query);
 
   if (dxgsg9_cat.is_debug()) {
@@ -776,7 +783,7 @@ end_occlusion_query() {
   PT(OcclusionQueryContext) result = _current_occlusion_query;
 
   IDirect3DQuery9 *query = DCAST(DXOcclusionQueryContext9, result)->_query;
-    
+
   if (dxgsg9_cat.is_debug()) {
     dxgsg9_cat.debug()
       << "ending occlusion query " << query << "\n";
@@ -857,7 +864,7 @@ clear(DrawableRegion *clearable) {
           aux_flags |=  D3DCLEAR_ZBUFFER;
           HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value,
                                            depth_clear_value, stencil_clear_value);
-          if (FAILED(hr2)) {          
+          if (FAILED(hr2)) {
             dxgsg9_cat.error()
               << "Unable to clear depth buffer; removing.\n";
             // This is really hacky code.
@@ -1040,6 +1047,12 @@ begin_frame(Thread *current_thread) {
     return false;
   }
 
+  if (_current_properties->get_srgb_color()) {
+    set_render_state(D3DRS_SRGBWRITEENABLE, TRUE);
+  } else {
+    set_render_state(D3DRS_SRGBWRITEENABLE, FALSE);
+  }
+
   return true;
 }
 
@@ -1343,14 +1356,14 @@ update_standard_vertex_arrays(bool force) {
       dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
       return false;
     }
-  
+
     // Get the vertex buffer for this array.
     CLP(VertexBufferContext)* dvbc;
     if (!setup_array_data(dvbc, array_reader, force)) {
       dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
       return false;
     }
-  
+
     // Bind this array as the data source for the corresponding stream.
     const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
     hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
@@ -2315,7 +2328,7 @@ reset() {
   // want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
 
   nassertv(_screen->_d3d9 != NULL);
-  
+
   if (_d3d_device == NULL) {
     return;
   }
@@ -2379,27 +2392,27 @@ reset() {
     _shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_2_0;
 */
   }
-  
+
   if (dxgsg9_cat.is_debug()) {
-    
+
     CGprofile vertex_profile;
     CGprofile pixel_profile;
-    
+
     vertex_profile = cgD3D9GetLatestVertexProfile();
     pixel_profile = cgD3D9GetLatestPixelProfile();
-    
+
     const char *vertex_profile_str =
       cgGetProfileString(vertex_profile);
     const char *pixel_profile_str =
       cgGetProfileString(pixel_profile);
-    
+
     if (vertex_profile_str == NULL) {
       vertex_profile_str = "(null)";
     }
     if (pixel_profile_str == NULL) {
       pixel_profile_str = "(null)";
     }
-    
+
     dxgsg9_cat.debug()
       << "\nCg vertex profile = " << vertex_profile_str << "  id = " << vertex_profile
       << "\nCg pixel profile = " << pixel_profile_str << "  id = " << pixel_profile
@@ -2495,7 +2508,7 @@ reset() {
       << "\nDirectX SDK version " DIRECTX_SDK_VERSION
       << "\n";
   }
-  
+
   // OVERRIDE SUPPORT SINCE IT DOES NOT WORK WELL
   _screen->_supports_automatic_mipmap_generation = false;
 
@@ -2618,12 +2631,19 @@ reset() {
 
   _last_testcooplevel_result = D3D_OK;
 
+  if (dxgsg9_cat.is_debug()) {
+    dxgsg9_cat.debug() << "Supported texture formats:\n";
+  }
+
   for(int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
     // look for all possible DX9 texture fmts
     D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
     hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
                                           0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
-    if (SUCCEEDED(hr)){
+    if (SUCCEEDED(hr)) {
+      if (dxgsg9_cat.is_debug()) {
+        dxgsg9_cat.debug() << "  " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) << "\n";
+      }
       _screen->_supported_tex_formats_mask |= fmtflag;
     }
   }
@@ -2632,7 +2652,7 @@ reset() {
   #define CHECK_FOR_DXTVERSION(num) \
   if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\
     if (dxgsg9_cat.is_debug()) {\
-      dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported \n";\
+      dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported\n";\
     }\
     _supports_compressed_texture = true;\
     _compressed_texture_formats.set_bit(Texture::CM_dxt##num);\
@@ -2641,9 +2661,9 @@ reset() {
   if (_screen->_intel_compressed_texture_bug) {
     dxgsg9_cat.info()
       << "Buggy Intel driver detected; disabling compressed textures.\n";
-    _screen->_supported_tex_formats_mask &= 
+    _screen->_supported_tex_formats_mask &=
       ~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
-                                              
+
   } else {
     // Check for available compressed formats normally.
     CHECK_FOR_DXTVERSION(1);
@@ -2652,7 +2672,7 @@ reset() {
     CHECK_FOR_DXTVERSION(4);
     CHECK_FOR_DXTVERSION(5);
   }
-      
+
   #undef CHECK_FOR_DXTVERSION
 
   _screen->_supports_rgba16f_texture_format = false;
@@ -3292,7 +3312,7 @@ set_state_and_transform(const RenderState *target,
       !_state_mask.get_bit(transparency_slot) ||
       !_state_mask.get_bit(color_write_slot) ||
       !_state_mask.get_bit(color_blend_slot) ||
-      (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) != 
+      (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
        _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
     //PStatTimer timer(_draw_set_state_blending_pcollector);
     do_issue_blending();
@@ -3353,7 +3373,7 @@ set_state_and_transform(const RenderState *target,
     do_issue_stencil();
     _state_mask.set_bit(stencil_slot);
   }
-     
+
   int fog_slot = FogAttrib::get_class_slot();
   if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
       !_state_mask.get_bit(fog_slot)) {
@@ -3446,22 +3466,22 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
     const LMatrix4 &light_mat = transform->get_mat();
     LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
     LVector3f dir = LCAST(float, light_obj->get_direction() * rel_mat);
-    
+
     D3DCOLORVALUE black;
     black.r = black.g = black.b = black.a = 0.0f;
-    
+
     ZeroMemory(&fdata, sizeof(D3DLIGHT9));
-    
+
     fdata.Type =  D3DLIGHT_DIRECTIONAL;
     fdata.Ambient  =  black ;
     LColorf color = LCAST(float, light_obj->get_specular_color());
     fdata.Specular = *(D3DCOLORVALUE *)(color.get_data());
-    
+
     fdata.Direction = *(D3DVECTOR *)dir.get_data();
-    
+
     fdata.Range =  __D3DLIGHT_RANGE_MAX;
     fdata.Falloff =  1.0f;
-    
+
     fdata.Attenuation0 = 1.0f;       // constant
     fdata.Attenuation1 = 0.0f;       // linear
     fdata.Attenuation2 = 0.0f;       // quadratic
@@ -4125,7 +4145,7 @@ close_gsg() {
 
   if (dxgsg9_cat.is_debug()) {
     dxgsg9_cat.debug()
-      << "Closing GSG, prepared_objects count = " 
+      << "Closing GSG, prepared_objects count = "
       << _prepared_objects->get_ref_count() << "\n";
   }
 
@@ -4210,9 +4230,9 @@ set_read_buffer(const RenderBuffer &rb) {
   if (rb._buffer_type & RenderBuffer::T_front) {
     _cur_read_pixel_buffer = RenderBuffer::T_front;
   } else  if (rb._buffer_type & RenderBuffer::T_back) {
-    _cur_read_pixel_buffer = RenderBuffer::T_back;      
+    _cur_read_pixel_buffer = RenderBuffer::T_back;
   } else  if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
-    _cur_read_pixel_buffer = RenderBuffer::T_back;      
+    _cur_read_pixel_buffer = RenderBuffer::T_back;
   } else {
     dxgsg9_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n";
   }
@@ -4816,7 +4836,7 @@ check_cooperative_level() {
   case D3DERR_DEVICELOST:
     // sleep while the device is lost to free up the CPU
     Sleep (10);
-    
+
     if (SUCCEEDED(_last_testcooplevel_result)) {
       if (_dx_is_ready) {
         _dx_is_ready = false;
@@ -4847,7 +4867,7 @@ show_frame() {
   if (_swap_chain) {
     DWORD flags;
     flags = 0;
-    
+
     hr = _swap_chain->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL, flags);
   } else {
     hr = _d3d_device->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL);
@@ -5220,7 +5240,7 @@ check_dx_allocation (HRESULT result, int allocation_size, int attempts)
         // increase the page out size as the number of attempts increases
         {
           size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
-          size_t target_size = max(current_size - allocation_size * attempts, 0);
+          size_t target_size = max(current_size - allocation_size * attempts, (size_t) 0);
           _prepared_objects->_graphics_memory_lru.evict_to(target_size);
           dxgsg9_cat.info()
             << "Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() << " bytes of texture memory to make room for more.\n";
@@ -5435,7 +5455,7 @@ do_issue_stencil() {
 ////////////////////////////////////////////////////////////////////
 //     Function: dxGraphicsStateGuardian9::do_issue_scissor
 //       Access: Protected
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
 do_issue_scissor() {
@@ -5522,8 +5542,8 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
     // avoid divide by zero and negative exponents
     gamma = 1.0;
   }
-  gamma_correction = 1.0 / (double) gamma;    
-  
+  gamma_correction = 1.0 / (double) gamma;
+
   for (i = 0; i < 256; i++) {
     double r;
     double g;
@@ -5534,11 +5554,11 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
       g = (double) original_green_table [i] / GAMMA_1;
       b = (double) original_blue_table [i] / GAMMA_1;
     }
-    else {    
+    else {
       r = ((double) i / 255.0);
       g = r;
       b = r;
-    }    
+    }
 
     r = pow (r, gamma_correction);
     g = pow (g, gamma_correction);
@@ -5554,14 +5574,14 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
       b = 1.0;
     }
 
-    r = r * GAMMA_1;    
-    g = g * GAMMA_1;    
-    b = b * GAMMA_1;    
+    r = r * GAMMA_1;
+    g = g * GAMMA_1;
+    b = b * GAMMA_1;
 
     red_table [i] = r;
     green_table [i] = g;
     blue_table [i] = b;
-  }    
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -5571,13 +5591,13 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
 ////////////////////////////////////////////////////////////////////
 bool DXGraphicsStateGuardian9::
 get_gamma_table(void) {
-  bool get;  
+  bool get;
 
   get = false;
   if (_gamma_table_initialized == false) {
     HDC hdc = GetDC(NULL);
 
-    if (hdc) {   
+    if (hdc) {
       if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
         _gamma_table_initialized = true;
         get = true;
@@ -5586,26 +5606,26 @@ get_gamma_table(void) {
       ReleaseDC (NULL, hdc);
     }
   }
-  
+
   return get;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::static_set_gamma
 //       Access: Public, Static
-//  Description: Static function for setting gamma which is needed 
+//  Description: Static function for setting gamma which is needed
 //               for atexit.
 ////////////////////////////////////////////////////////////////////
 bool DXGraphicsStateGuardian9::
 static_set_gamma(bool restore, PN_stdfloat gamma) {
-  bool set;  
+  bool set;
   HDC hdc = GetDC(NULL);
 
   set = false;
-  if (hdc) {   
+  if (hdc) {
     unsigned short ramp [256 * 3];
 
-    if (restore && _gamma_table_initialized) {    
+    if (restore && _gamma_table_initialized) {
       _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
     }
     else {
@@ -5615,7 +5635,7 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
     if (SetDeviceGammaRamp (hdc, ramp)) {
       set = true;
     }
-    
+
     ReleaseDC (NULL, hdc);
   }
 
@@ -5634,7 +5654,7 @@ set_gamma(PN_stdfloat gamma) {
 
   set = static_set_gamma(false, gamma);
   if (set) {
-    _gamma = gamma;  
+    _gamma = gamma;
   }
 
   return set;
@@ -5664,7 +5684,7 @@ atexit_function(void) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::get_supports_cg_profile
 //       Access: Public, Virtual
-//  Description: Returns true if this particular GSG supports the 
+//  Description: Returns true if this particular GSG supports the
 //               specified Cg Shader Profile.
 ////////////////////////////////////////////////////////////////////
 bool DXGraphicsStateGuardian9::
@@ -5673,7 +5693,7 @@ get_supports_cg_profile(const string &name) const {
   return false;
 #else
   CGprofile profile = cgGetProfile(name.c_str());
-  
+
   if (profile == CG_PROFILE_UNKNOWN) {
     dxgsg9_cat.error() << name <<", unknown Cg-profile\n";
     return false;

+ 5 - 5
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -36,9 +36,7 @@
 #include "vertexElementArray.h"
 #include "dxShaderContext9.h"
 
-
-enum GsgPageType
-{
+enum GsgPageType {
   GPT_Texture,
   GPT_VertexBuffer,
   GPT_IndexBuffer,
@@ -52,6 +50,8 @@ class DXTextureContext9;
 class DXVertexBufferContext9;
 class DXIndexBufferContext9;
 
+class wdxGraphicsBuffer9;
+
 ////////////////////////////////////////////////////////////////////
 //       Class : DXGraphicsStateGuardian9
 // Description : A GraphicsStateGuardian for rendering into DirectX9
@@ -265,7 +265,7 @@ protected:
 
 public:
   DXScreenData *_screen;
-  
+
 protected:
   LPDIRECT3DDEVICE9 _d3d_device;  // same as _screen->_d3d_device, cached for spd
   IDirect3DSwapChain9 *_swap_chain;
@@ -374,7 +374,7 @@ protected:
 
   list <wdxGraphicsBuffer9 **> _graphics_buffer_list;
 
-  int _supports_gamma_calibration;  
+  int _supports_gamma_calibration;
 
   static LPDIRECT3DDEVICE9 _cg_device;
 

+ 87 - 58
panda/src/dxgsg9/dxTextureContext9.cxx

@@ -135,13 +135,13 @@ create_texture(DXScreenData &scrn) {
   bool texture_wants_compressed = false;
   Texture::CompressionMode compression_mode = tex->get_ram_image_compression();
   bool texture_stored_compressed = compression_mode != Texture::CM_off;
-  
+
   if (texture_stored_compressed) {
-    texture_wants_compressed = true;  
+    texture_wants_compressed = true;
   } else {
     if (tex->get_compression() == Texture::CM_off) {
       // no compression
-    } else {    
+    } else {
       if (tex->get_compression() == Texture::CM_default) {
         // default = use "compressed-textures" config setting
         if (compressed_textures) {
@@ -150,9 +150,9 @@ create_texture(DXScreenData &scrn) {
       } else {
         texture_wants_compressed = true;
       }
-    }  
+    }
   }
-    
+
   switch (tex->get_texture_type()) {
     case Texture::TT_1d_texture:
     case Texture::TT_2d_texture:
@@ -197,7 +197,9 @@ create_texture(DXScreenData &scrn) {
 
   if ((tex->get_format() == Texture::F_luminance_alpha)||
       (tex->get_format() == Texture::F_luminance_alphamask) ||
-      (tex->get_format() == Texture::F_luminance)) {
+      (tex->get_format() == Texture::F_luminance) ||
+      (tex->get_format() == Texture::F_sluminance_alpha) ||
+      (tex->get_format() == Texture::F_sluminance)) {
     needs_luminance = true;
   }
 
@@ -232,7 +234,7 @@ create_texture(DXScreenData &scrn) {
     _d3d_format = D3DFMT_A8R8G8B8;
     break;
   }
-  
+
   // make sure we handled all the possible cases
   nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
 
@@ -398,9 +400,9 @@ create_texture(DXScreenData &scrn) {
 
   if (compress_texture) {
     if (num_alpha_bits <= 1) {
-      CHECK_FOR_FMT(DXT1);    
+      CHECK_FOR_FMT(DXT1);
     } else if (num_alpha_bits <= 4) {
-      CHECK_FOR_FMT(DXT3);    
+      CHECK_FOR_FMT(DXT3);
     } else {
       CHECK_FOR_FMT(DXT5);
     }
@@ -425,7 +427,7 @@ create_texture(DXScreenData &scrn) {
     // array (the texture array contains num_color_channels*8bits)
 
   case 128:
-    // check if format is supported    
+    // check if format is supported
     if (scrn._supports_rgba32_texture_format) {
       target_pixel_format = D3DFMT_A32B32G32R32F;
     }
@@ -435,7 +437,7 @@ create_texture(DXScreenData &scrn) {
     goto found_matching_format;
 
   case 64:
-    // check if format is supported 
+    // check if format is supported
     if (scrn._supports_rgba16f_texture_format) {
       target_pixel_format = D3DFMT_A16B16G16R16F;
     }
@@ -443,7 +445,7 @@ create_texture(DXScreenData &scrn) {
       target_pixel_format = scrn._render_to_texture_d3d_format;
     }
     goto found_matching_format;
-    
+
   case 32:
     if (!((num_color_channels == 3) || (num_color_channels == 4)))
       break; //bail
@@ -502,7 +504,7 @@ create_texture(DXScreenData &scrn) {
 
     CHECK_FOR_FMT(X8R8G8B8);
     CHECK_FOR_FMT(A8R8G8B8);
-    
+
     // no 24-bit or 32 fmt.  look for 16 bit fmt (higher res 565 1st)
     CHECK_FOR_FMT(R5G6B5);
     CHECK_FOR_FMT(X1R5G5B5);
@@ -782,13 +784,13 @@ create_texture(DXScreenData &scrn) {
     // REQUIRED PARAMETERS
     _managed = false;
     _is_render_target = true;
-    
+
     pool = D3DPOOL_DEFAULT;
     usage = D3DUSAGE_RENDERTARGET;
     if (target_bpp <= 32 ) {
       target_pixel_format = scrn._render_to_texture_d3d_format;
     }
-    
+
     dxgsg9_cat.debug ()
       << "*** RENDER TO TEXTURE ***: format "
       << D3DFormatStr(target_pixel_format)
@@ -848,7 +850,7 @@ create_texture(DXScreenData &scrn) {
     data_size *= 6;
   }
   update_data_size_bytes(data_size);
-  
+
   int attempts;
 
   if (dxgsg9_cat.is_debug()) {
@@ -882,7 +884,7 @@ create_texture(DXScreenData &scrn) {
       hr = scrn._d3d_device->CreateTexture
         (target_width, target_height, mip_level_count, usage,
          target_pixel_format, pool, &_d3d_2d_texture, NULL);
-      _d3d_texture = _d3d_2d_texture;      
+      _d3d_texture = _d3d_2d_texture;
       break;
 
     case Texture::TT_3d_texture:
@@ -952,7 +954,7 @@ create_texture(DXScreenData &scrn) {
     scrn._dxgsg9->get_engine()->texture_uploaded(tex);
   }
   mark_loaded();
-  
+
   return true;
 
  error_exit:
@@ -967,7 +969,7 @@ create_texture(DXScreenData &scrn) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXTextureContext9::create_simple_texture
 //       Access: Public
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 bool DXTextureContext9::
 create_simple_texture(DXScreenData &scrn) {
@@ -993,7 +995,7 @@ create_simple_texture(DXScreenData &scrn) {
   hr = scrn._d3d_device->CreateTexture
     (target_width, target_height, mip_level_count, usage,
      target_pixel_format, pool, &_d3d_2d_texture, NULL);
-  _d3d_texture = _d3d_2d_texture;      
+  _d3d_texture = _d3d_2d_texture;
   if (FAILED(hr)) {
     dxgsg9_cat.error()
       << "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
@@ -1032,13 +1034,13 @@ create_simple_texture(DXScreenData &scrn) {
 
     RELEASE(surface, dxgsg9, "create_simple_texture Surface", RELEASE_ONCE);
   }
-    
+
   if (FAILED(hr)) {
     dxgsg9_cat.debug ()
       << "*** fill_d3d_texture_pixels failed ***: format "
       << target_pixel_format
       << "\n";
-    
+
     goto error_exit;
   }
 
@@ -1084,7 +1086,7 @@ bool DXTextureContext9::
 extract_texture_data(DXScreenData &screen) {
   bool state;
   HRESULT hr;
-  
+
   state = false;
   Texture *tex = get_texture();
   if (tex->get_texture_type() != Texture::TT_2d_texture) {
@@ -1147,7 +1149,7 @@ extract_texture_data(DXScreenData &screen) {
 
   default:
     dxgsg9_cat.error()
-      << "Cannot extract texture data: unhandled surface format " 
+      << "Cannot extract texture data: unhandled surface format "
       << desc.Format << "\n";
     return state;
   }
@@ -1164,13 +1166,13 @@ extract_texture_data(DXScreenData &screen) {
   if (_is_render_target) {
     IDirect3DSurface9* source_surface;
     IDirect3DSurface9* destination_surface;
-  
+
     source_surface = 0;
     destination_surface = 0;
-    
+
     hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface);
-    if (hr == D3D_OK) {    
-       
+    if (hr == D3D_OK) {
+
       D3DPOOL pool;
       D3DSURFACE_DESC surface_description;
 
@@ -1186,7 +1188,7 @@ extract_texture_data(DXScreenData &screen) {
         NULL);
       if (hr == D3D_OK) {
         if (source_surface && destination_surface) {
-          hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);          
+          hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
           if (hr == D3D_OK) {
 
             D3DLOCKED_RECT rect;
@@ -1200,13 +1202,13 @@ extract_texture_data(DXScreenData &screen) {
 
               int surface_bytes_per_line;
               unsigned char *surface_pointer;
-              
+
               bytes_per_line = surface_description.Width * this -> d3d_format_to_bytes_per_pixel (surface_description.Format);
               size = bytes_per_line * surface_description.Height;
 
               surface_bytes_per_line = rect.Pitch;
               surface_pointer = (unsigned char *) rect.pBits;
-              
+
               PTA_uchar image = PTA_uchar::empty_array(size);
 
               int offset;
@@ -1217,29 +1219,29 @@ extract_texture_data(DXScreenData &screen) {
                 memcpy (&image [offset], surface_pointer, bytes_per_line);
 
                 offset += bytes_per_line;
-                surface_pointer += surface_bytes_per_line;  
+                surface_pointer += surface_bytes_per_line;
               }
 
               tex->set_ram_image(image, Texture::CM_off);
 
               state = true;
-              
+
               destination_surface -> UnlockRect();
             }
           }
-        }    
-        
+        }
+
         destination_surface -> Release ( );
       }
       else {
         dxgsg9_cat.error()
           << "CreateImageSurface failed in extract_texture_data()"
-          << D3DERRORSTRING(hr);      
-      }      
+          << D3DERRORSTRING(hr);
+      }
       source_surface -> Release ( );
     }
   }
-  else {  
+  else {
     for (int n = 0; n < num_levels; ++n) {
       D3DLOCKED_RECT rect;
       hr = _d3d_2d_texture->LockRect(n, &rect, NULL, D3DLOCK_READONLY);
@@ -1248,11 +1250,11 @@ extract_texture_data(DXScreenData &screen) {
           << "Texture::LockRect() failed!  level = " << n << " " << D3DERRORSTRING(hr);
         return state;
       }
-    
+
       int x_size = tex->get_expected_mipmap_x_size(n);
       int y_size = tex->get_expected_mipmap_y_size(n);
       PTA_uchar image;
-      
+
       if (compression == Texture::CM_off) {
         // Uncompressed, but we have to respect the pitch.
         int pitch = x_size * tex->get_num_components() * tex->get_component_width();
@@ -1273,7 +1275,7 @@ extract_texture_data(DXScreenData &screen) {
             source += rect.Pitch;
           }
         }
-        
+
       } else {
         // Compressed; just copy the data verbatim.
         int size = rect.Pitch * (y_size / div);
@@ -1288,10 +1290,10 @@ extract_texture_data(DXScreenData &screen) {
         tex->set_ram_mipmap_image(n, image);
       }
     }
-    
+
     state = true;
   }
-  
+
   return state;
 }
 
@@ -1560,7 +1562,7 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface,
 ////////////////////////////////////////////////////////////////////
 //     Function: calculate_row_byte_length
 //       Access: Private, hidden
-//  Description: local helper function, which calculates the 
+//  Description: local helper function, which calculates the
 //               'row_byte_length' or 'pitch' needed for calling
 //               D3DXLoadSurfaceFromMemory.
 //               Takes compressed formats (DXTn) into account.
@@ -1596,12 +1598,12 @@ static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFOR
 //       Access: Private
 //  Description: Called from fill_d3d_texture_pixels, this function
 //               fills a single mipmap with texture data.
-//               Takes care of all necessery conversions and error
+//               Takes care of all necessary conversions and error
 //               handling.
 ////////////////////////////////////////////////////////////////////
 HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format)
 {
-  // This whole function was refactored out of fill_d3d_texture_pixels to make the code 
+  // This whole function was refactored out of fill_d3d_texture_pixels to make the code
   // more readable and to avoid code duplication.
   IDirect3DSurface9 *mip_surface = NULL;
   bool using_temp_buffer = false;
@@ -1617,7 +1619,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
   pixels += view_size * get_view();
   size_t page_size = get_texture()->get_expected_ram_mipmap_page_size(mip_level);
   pixels += page_size * depth_index;
-  
+
   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)depth_index, mip_level, &mip_surface);
@@ -1645,6 +1647,10 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
   // dithering)??)
   mip_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER;  //dithering looks ugly on i810 for 4444 textures
 
+  if (Texture::is_srgb(get_texture()->get_format())) {
+    mip_filter |= D3DX_FILTER_SRGB;
+  }
+
   // D3DXLoadSurfaceFromMemory will load black luminance and we want
   // full white, so convert to explicit luminance-alpha format
   if (_d3d_format == D3DFMT_A8) {
@@ -1671,7 +1677,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
     source_format = D3DFMT_A8L8;
     source_row_byte_length = width * sizeof(USHORT);
     pixels = (BYTE*)temp_buffer;
-  } 
+  }
   else if (component_width != 1) {
     // Convert from 16-bit per channel (or larger) format down to
     // 8-bit per channel.  This throws away precision in the
@@ -1756,7 +1762,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
     // The texture doesn't have an image to load.  That's ok; it
     // might be a texture we've rendered to by frame buffer
     // operations or something.
-    if (tex->get_render_to_texture()) {   
+    if (tex->get_render_to_texture()) {
       HRESULT result;
 
       if (_d3d_2d_texture) {
@@ -1777,7 +1783,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
               depth_stencil_surface = 0;
               if (device -> GetDepthStencilSurface (&depth_stencil_surface) == D3D_OK) {
                 if (device -> SetDepthStencilSurface (NULL) == D3D_OK) {
-      
+
                 }
               }
 
@@ -1791,7 +1797,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
                 }
               }
 
-              // restore depth stencil 
+              // restore depth stencil
               if (depth_stencil_surface) {
                 device -> SetDepthStencilSurface (depth_stencil_surface);
                 depth_stencil_surface -> Release();
@@ -1806,7 +1812,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
           surface -> Release();
         }
       }
-      
+
       return S_OK;
     }
     return E_FAIL;
@@ -1842,7 +1848,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
   }
 
   for (unsigned int di = 0; di < orig_depth; di++) {
-    
+
     // fill top level mipmap
     hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
     if (FAILED(hr)) {
@@ -1861,8 +1867,8 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
           if (FAILED(hr)) {
             return hr; // error message was already output in fill_d3d_texture_mipmap_pixels
           }
-        }        
-      } 
+        }
+      }
       else {
         // mipmaps need to be generated, either use autogen or d3dx functions
 
@@ -1888,6 +1894,10 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
             mip_filter_flags = D3DX_FILTER_TRIANGLE;
           }
 
+          if (Texture::is_srgb(tex->get_format())) {
+            mip_filter_flags |= D3DX_FILTER_SRGB;
+          }
+
           // mip_filter_flags |= D3DX_FILTER_DITHER;
           hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
                                 mip_filter_flags);
@@ -1934,7 +1944,7 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
   if (!scrn._dxgsg9->get_supports_compressed_texture_format(image_compression)) {
     image = tex->get_uncompressed_ram_image();
     image_compression = Texture::CM_off;
-  }    
+  }
 
   if (image.is_null()) {
     // The texture doesn't have an image to load.  That's ok; it
@@ -1991,6 +2001,10 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
   // dithering)??)
   level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER;  //dithering looks ugly on i810 for 4444 textures
 
+  if (Texture::is_srgb(tex->get_format())) {
+    level_0_filter |= D3DX_FILTER_SRGB;
+  }
+
   // D3DXLoadSurfaceFromMemory will load black luminance and we want
   // full white, so convert to explicit luminance-alpha format
   if (_d3d_format == D3DFMT_A8) {
@@ -2070,6 +2084,10 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
       mip_filter_flags = D3DX_FILTER_TRIANGLE;
     }
 
+    if (Texture::is_srgb(tex->get_format())) {
+      mip_filter_flags |= D3DX_FILTER_SRGB;
+    }
+
     //    mip_filter_flags| = D3DX_FILTER_DITHER;
 
     hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
@@ -2167,6 +2185,17 @@ get_bits_per_pixel(Texture::Format format, int *alphbits) {
   case Texture::F_rgba32:
     *alphbits = 32;
     return 128;
+
+  case Texture::F_srgb:
+    return 24;
+  case Texture::F_srgb_alpha:
+    *alphbits = 8;
+    return 32;
+  case Texture::F_sluminance:
+    return 8;
+  case Texture::F_sluminance_alpha:
+    *alphbits = 8;
+    return 16;
   }
   return 8;
 }
@@ -2180,7 +2209,7 @@ PN_stdfloat DXTextureContext9::
 d3d_format_to_bytes_per_pixel (D3DFORMAT format)
 {
   PN_stdfloat bytes_per_pixel;
-  
+
   bytes_per_pixel = 0.0f;
   switch (format)
   {
@@ -2246,6 +2275,6 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
       bytes_per_pixel = 1.0f;
       break;
   }
-  
+
   return bytes_per_pixel;
 }

+ 4 - 4
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -139,7 +139,7 @@ make_output(const string &name,
     // Early failure - if we are sure that this buffer WONT
     // meet specs, we can bail out early.
     if ((flags & BF_fb_props_optional) == 0) {
-      if ((fb_prop.get_indexed_color() > 0)||
+      if (fb_prop.get_indexed_color() ||
           (fb_prop.get_back_buffers() > 0)||
           (fb_prop.get_accum_bits() > 0)||
           (fb_prop.get_multisamples() > 0)) {
@@ -649,7 +649,7 @@ search_for_valid_displaymode(DXScreenData &scrn,
         continue;
       }
 
-      // disable refresh rate checking since SLI video cards may use 
+      // disable refresh rate checking since SLI video cards may use
       // refresh rates less than 60
       if (0) {
         if ((dispmode.RefreshRate<60) && (dispmode.RefreshRate>1)) {
@@ -663,7 +663,7 @@ search_for_valid_displaymode(DXScreenData &scrn,
           continue;
         }
       }
-      
+
       // Note no attempt is made to verify if format will work at
       // requested size, so even if this call succeeds, could still get
       // an out-of-video-mem error
@@ -956,7 +956,7 @@ const char *D3DFormatStr(D3DFORMAT fmt) {
     CASESTR(D3DFMT_D24X4S4);
     CASESTR(D3DFMT_VERTEXDATA);
     CASESTR(D3DFMT_INDEX16);
-    CASESTR(D3DFMT_INDEX32);    
+    CASESTR(D3DFMT_INDEX32);
     CASESTR(D3DFMT_A16B16G16R16F);
     CASESTR(D3DFMT_A32B32G32R32F);
   }

+ 14 - 14
panda/src/dxgsg9/wdxGraphicsWindow9.cxx

@@ -252,7 +252,7 @@ verify_window_sizes(int numsizes, int *dimen) {
 void wdxGraphicsWindow9::
 close_window() {
   if (wdxdisplay9_cat.is_debug()) {
-    wdxdisplay9_cat.debug() 
+    wdxdisplay9_cat.debug()
       << "wdxGraphicsWindow9::close_window() " << this << "\n";
   }
 
@@ -300,7 +300,7 @@ open_window() {
   // window.
   {
     WindowProperties resized_props;
-    resized_props.set_size(_wcontext._display_mode.Width, 
+    resized_props.set_size(_wcontext._display_mode.Width,
                            _wcontext._display_mode.Height);
     _properties.add_properties(resized_props);
   }
@@ -420,17 +420,17 @@ void wdxGraphicsWindow9::
 handle_reshape() {
   GdiFlush();
   WinGraphicsWindow::handle_reshape();
-  
-  if (_dxgsg != NULL) {
+
+  if (_dxgsg != NULL && _dxgsg->_d3d_device != NULL) {
     // create the new resized rendertargets
     WindowProperties props = get_properties();
     int x_size = props.get_x_size();
     int y_size = props.get_y_size();
-    
+
     if (_wcontext._presentation_params.BackBufferWidth != x_size ||
         _wcontext._presentation_params.BackBufferHeight != y_size) {
       bool resize_succeeded = reset_device_resize_window(x_size, y_size);
-      
+
       if (wdxdisplay9_cat.is_debug()) {
         if (!resize_succeeded) {
           wdxdisplay9_cat.debug()
@@ -708,7 +708,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
   if (dx_disable_driver_management_ex) {
     dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX;
   }
-  
+
   if (is_fullscreen()) {
     // CREATE FULLSCREEN BUFFERS
 
@@ -751,11 +751,11 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
     }
 
     //From d3d8caps.h
-    //D3DPRESENT_INTERVAL_DEFAULT  = 0x00000000L 
+    //D3DPRESENT_INTERVAL_DEFAULT  = 0x00000000L
     //#define D3DPRESENT_INTERVAL_ONE         0x00000001L
     //Next line is really sloppy, should either be D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_ONE
     //not a direct number! but I'm not going to touch it because it's working as is. Zhao 12/15/2011
-    presentation_params->PresentationInterval = 0;    
+    presentation_params->PresentationInterval = 0;
 
     //ATI 5450 doesn't like D3DSWAPEFFECT_FLIP
     presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
@@ -803,7 +803,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
 
   PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
 
-  if (presentation_params->EnableAutoDepthStencil) {    
+  if (presentation_params->EnableAutoDepthStencil) {
     int depth_bits;
     int stencil_bits;
 
@@ -846,7 +846,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
         wdxdisplay9_cat.error() << "unknown depth stencil format  " << presentation_params->AutoDepthStencilFormat;
         break;
     }
-      
+
     _fb_properties.set_stencil_bits(stencil_bits);
     _fb_properties.set_depth_bits(depth_bits);
   } else {
@@ -1118,16 +1118,16 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
 
   if (is_fullscreen()) {
     bool bCouldntFindValidZBuf;
-    
+
     dxpipe->search_for_valid_displaymode(_wcontext, dwRenderWidth, dwRenderHeight,
                                          bNeedZBuffer, bWantStencil,
                                          &_wcontext._supported_screen_depths_mask,
                                          &bCouldntFindValidZBuf,
                                          &pixFmt, dx_force_16bpp_zbuffer, true);
-    
+
     // note I'm not saving refresh rate, will just use adapter
     // default at given res for now
-    
+
     if (pixFmt == D3DFMT_UNKNOWN) {
       wdxdisplay9_cat.error()
         << (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes")

+ 1 - 1
panda/src/wgldisplay/wglGraphicsPipe.cxx

@@ -170,7 +170,7 @@ make_output(const string &name,
         _fbo_multisample = 16;
     }
     if ((flags & BF_fb_props_optional)==0) {
-      if ((fb_prop.get_indexed_color() > 0)||
+      if (fb_prop.get_indexed_color() ||
           (fb_prop.get_back_buffers() > 0)||
           (fb_prop.get_accum_bits() > 0)||
           (fb_prop.get_multisamples() > _fbo_multisample)) {