24 #define DEBUG_SURFACES false
25 #define DEBUG_TEXTURES true
33 static const DWORD g_LowByteMask = 0x000000FF;
42 if (dxgsg9_cat.is_spam()) {
47 _d3d_texture =
nullptr;
48 _d3d_2d_texture =
nullptr;
49 _d3d_volume_texture =
nullptr;
50 _d3d_cube_texture =
nullptr;
52 _is_render_target =
false;
60 ~DXTextureContext9() {
81 if (dxgsg9_cat.is_debug()) {
104 if (_d3d_2d_texture || _d3d_cube_texture || _d3d_volume_texture) {
111 D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
112 bool needs_luminance =
false;
113 bool needs_depth =
false;
114 bool needs_stencil =
false;
115 bool compress_texture =
false;
118 nassertr(IS_VALID_PTR(tex),
false);
128 bool texture_wants_compressed =
false;
130 bool texture_stored_compressed = compression_mode != Texture::CM_off;
132 if (texture_stored_compressed) {
133 texture_wants_compressed =
true;
140 if (compressed_textures) {
141 texture_wants_compressed =
true;
144 texture_wants_compressed =
true;
150 case Texture::TT_1d_texture:
151 case Texture::TT_2d_texture:
152 case Texture::TT_cube_map:
155 orig_width >= 4 && orig_height >= 4) {
156 if (texture_wants_compressed){
157 compress_texture =
true;
161 case Texture::TT_3d_texture:
166 if (texture_stored_compressed && !compress_texture) {
181 DWORD target_bpp = get_bits_per_pixel(tex->
get_format(), &num_alpha_bits);
187 case Texture::F_depth_stencil:
188 _d3d_format = D3DFMT_D24S8;
190 needs_stencil =
true;
193 case Texture::F_depth_component:
194 case Texture::F_depth_component16:
195 _d3d_format = D3DFMT_D16;
199 case Texture::F_depth_component24:
200 _d3d_format = D3DFMT_D24X8;
204 case Texture::F_depth_component32:
205 _d3d_format = D3DFMT_D32;
209 case Texture::F_luminance:
210 case Texture::F_sluminance:
211 _d3d_format = D3DFMT_L8;
212 needs_luminance =
true;
215 case Texture::F_luminance_alpha:
216 case Texture::F_luminance_alphamask:
217 case Texture::F_sluminance_alpha:
218 _d3d_format = D3DFMT_A8L8;
219 needs_luminance =
true;
223 if (num_alpha_bits > 0) {
224 if (num_color_channels == 3) {
226 <<
"texture " << tex->get_name()
227 <<
" has no inherent alpha channel, but alpha format is requested!\n";
231 _d3d_format = D3DFMT_UNKNOWN;
233 switch (num_color_channels) {
235 if (num_alpha_bits > 0) {
236 _d3d_format = D3DFMT_A8;
238 _d3d_format = D3DFMT_L8;
242 _d3d_format = D3DFMT_A8L8;
245 _d3d_format = D3DFMT_R8G8B8;
248 _d3d_format = D3DFMT_A8R8G8B8;
253 nassertr(_d3d_format != D3DFMT_UNKNOWN,
false);
256 DWORD target_width = orig_width;
257 DWORD target_height = orig_height;
258 DWORD target_depth = orig_depth;
263 case Texture::TT_1d_texture:
264 case Texture::TT_2d_texture:
265 filter_caps = scrn._d3dcaps.TextureFilterCaps;
267 if (target_width > scrn._d3dcaps.MaxTextureWidth) {
268 target_width = scrn._d3dcaps.MaxTextureWidth;
270 if (target_height > scrn._d3dcaps.MaxTextureHeight) {
271 target_height = scrn._d3dcaps.MaxTextureHeight;
274 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
275 if (!ISPOW2(target_width)) {
276 target_width = down_to_power_2(target_width);
278 if (!ISPOW2(target_height)) {
279 target_height = down_to_power_2(target_height);
284 case Texture::TT_3d_texture:
285 if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) {
287 <<
"3-d textures are not supported by this graphics driver.\n";
291 filter_caps = scrn._d3dcaps.VolumeTextureFilterCaps;
293 if (target_width > scrn._d3dcaps.MaxVolumeExtent) {
294 target_width = scrn._d3dcaps.MaxVolumeExtent;
296 if (target_height > scrn._d3dcaps.MaxVolumeExtent) {
297 target_height = scrn._d3dcaps.MaxVolumeExtent;
299 if (target_depth > scrn._d3dcaps.MaxVolumeExtent) {
300 target_depth = scrn._d3dcaps.MaxVolumeExtent;
303 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) {
304 if (!ISPOW2(target_width)) {
305 target_width = down_to_power_2(target_width);
307 if (!ISPOW2(target_height)) {
308 target_height = down_to_power_2(target_height);
310 if (!ISPOW2(target_depth)) {
311 target_depth = down_to_power_2(target_depth);
316 case Texture::TT_cube_map:
317 if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) {
319 <<
"Cube map textures are not supported by this graphics driver.\n";
323 filter_caps = scrn._d3dcaps.CubeTextureFilterCaps;
325 if (target_width > scrn._d3dcaps.MaxTextureWidth) {
326 target_width = scrn._d3dcaps.MaxTextureWidth;
329 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) {
330 if (!ISPOW2(target_width)) {
331 target_width = down_to_power_2(target_width);
335 target_height = target_width;
340 if ((target_width != target_height) &&
341 (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0) {
344 int i, width_exp, height_exp;
345 for (i = target_width, width_exp = 0; i > 1; width_exp++, i >>= 1) {
347 for (i = target_height, height_exp = 0; i > 1; height_exp++, i >>= 1) {
349 target_height = target_width = 1<<((width_exp+height_exp)>>1);
352 bool shrink_original =
false;
354 if (orig_width != target_width || orig_height != target_height ||
355 orig_depth != target_depth) {
358 <<
"Reducing size of " << tex->get_name()
359 <<
" from " << orig_width <<
"x" << orig_height <<
"x" << orig_depth
360 <<
" to " << target_width <<
"x" << target_height
361 <<
"x" << target_depth <<
"\n";
364 <<
"Reducing size of " << tex->get_name()
365 <<
" from " << orig_width <<
"x" << orig_height
366 <<
" to " << target_width <<
"x" << target_height <<
"\n";
369 shrink_original =
true;
372 if (target_width == 0 || target_height == 0) {
378 const char *error_message;
380 error_message =
"create_texture failed: couldn't find compatible device Texture Pixel Format for input texture";
382 if (dxgsg9_cat.is_spam()) {
384 <<
"create_texture handling target bitdepth: " << target_bpp
385 <<
" alphabits: " << num_alpha_bits << endl;
392 #define CHECK_FOR_FMT(FMT) \
393 if (scrn._supported_tex_formats_mask & FMT##_FLAG) { \
394 target_pixel_format = D3DFMT_##FMT; \
395 goto found_matching_format; }
397 if (texture_stored_compressed && compress_texture) {
401 switch (compression_mode){
402 case Texture::CM_dxt1:
405 case Texture::CM_dxt2:
408 case Texture::CM_dxt3:
411 case Texture::CM_dxt4:
414 case Texture::CM_dxt5:
417 case Texture::CM_rgtc:
418 if (num_color_channels == 1) {
429 if (compress_texture) {
430 if (num_color_channels == 1) {
432 }
else if (num_alpha_bits == 0 && num_color_channels == 2) {
435 if (num_alpha_bits <= 1) {
437 }
else if (num_alpha_bits <= 4) {
446 if (texture_stored_compressed) {
449 texture_stored_compressed = compression_mode != Texture::CM_off;
450 compress_texture =
false;
455 switch (target_bpp) {
462 if (scrn._supports_rgba32_texture_format) {
463 target_pixel_format = D3DFMT_A32B32G32R32F;
466 target_pixel_format = scrn._render_to_texture_d3d_format;
468 goto found_matching_format;
472 if (scrn._supports_rgba16f_texture_format) {
473 target_pixel_format = D3DFMT_A16B16G16R16F;
476 target_pixel_format = scrn._render_to_texture_d3d_format;
478 goto found_matching_format;
482 nassertr(num_alpha_bits == 0,
false);
483 nassertr(num_color_channels == 1,
false);
489 if (!((num_color_channels == 3) || (num_color_channels == 4)))
492 CHECK_FOR_FMT(A8R8G8B8);
494 if (num_alpha_bits>0) {
495 nassertr(num_color_channels == 4,
false);
511 if (num_alpha_bits == 1) {
512 CHECK_FOR_FMT(A1R5G5B5);
516 CHECK_FOR_FMT(A4R4G4B4);
517 CHECK_FOR_FMT(A1R5G5B5);
521 error_message =
"create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
525 if (num_color_channels == 3) {
526 CHECK_FOR_FMT(R5G6B5);
527 CHECK_FOR_FMT(X1R5G5B5);
529 CHECK_FOR_FMT(R5G6B5);
530 CHECK_FOR_FMT(X1R5G5B5);
537 nassertr(num_alpha_bits == 0,
false);
538 nassertr(num_color_channels == 1,
false);
545 CHECK_FOR_FMT(D24S8);
547 CHECK_FOR_FMT(D24X8);
551 if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
552 target_pixel_format = D3DFMT_INTZ;
553 goto found_matching_format;
559 CHECK_FOR_FMT(D24X8);
562 nassertr(num_color_channels == 3,
false);
564 CHECK_FOR_FMT(R8G8B8);
569 CHECK_FOR_FMT(X8R8G8B8);
570 CHECK_FOR_FMT(A8R8G8B8);
573 CHECK_FOR_FMT(R5G6B5);
574 CHECK_FOR_FMT(X1R5G5B5);
575 CHECK_FOR_FMT(A1R5G5B5);
581 nassertr(num_alpha_bits == 0,
false);
582 nassertr(num_color_channels == 1,
false);
589 CHECK_FOR_FMT(D24S8);
592 CHECK_FOR_FMT(D24X8);
595 if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
596 target_pixel_format = D3DFMT_INTZ;
597 goto found_matching_format;
603 CHECK_FOR_FMT(D24X8);
606 }
else if (needs_luminance) {
607 nassertr(num_alpha_bits > 0,
false);
608 nassertr(num_color_channels == 2,
false);
611 CHECK_FOR_FMT(A8R8G8B8);
613 if (num_alpha_bits == 1) {
614 CHECK_FOR_FMT(A1R5G5B5);
618 CHECK_FOR_FMT(A4R4G4B4);
619 CHECK_FOR_FMT(A1R5G5B5);
621 nassertr((num_color_channels == 3)||(num_color_channels == 4),
false);
624 switch(num_alpha_bits) {
626 if (num_color_channels == 3) {
627 CHECK_FOR_FMT(R5G6B5);
628 CHECK_FOR_FMT(X1R5G5B5);
630 nassertr(num_color_channels == 4,
false);
632 CHECK_FOR_FMT(R5G6B5);
633 CHECK_FOR_FMT(X1R5G5B5);
640 nassertr(num_color_channels == 4,
false);
641 CHECK_FOR_FMT(X1R5G5B5);
646 nassertr(num_color_channels == 4,
false);
647 CHECK_FOR_FMT(A4R4G4B4);
650 nassertr(
false,
false);
654 if (needs_luminance) {
657 nassertr(num_color_channels == 1,
false);
663 CHECK_FOR_FMT(R8G8B8);
664 CHECK_FOR_FMT(X8R8G8B8);
666 CHECK_FOR_FMT(R5G6B5);
667 CHECK_FOR_FMT(X1R5G5B5);
669 }
else if (num_alpha_bits == 8) {
678 CHECK_FOR_FMT(A8R8G8B8);
679 CHECK_FOR_FMT(A4R4G4B4);
684 error_message =
"create_texture failed: unhandled pixel bitdepth in DX loader";
689 << error_message <<
": " << tex->get_name() << endl
690 <<
"NumColorChannels: " << num_color_channels <<
"; NumAlphaBits: "
691 << num_alpha_bits <<
"; targetbpp: " <<target_bpp
692 <<
"; _supported_tex_formats_mask: 0x"
693 << std::hex << scrn._supported_tex_formats_mask << std::dec
694 <<
"; NeedLuminance: " << needs_luminance << endl;
698 found_matching_format:
705 IDirect3DSurface9 *render_target;
708 hr = scrn._d3d_device->GetDepthStencilSurface(&render_target);
710 hr = scrn._d3d_device->GetRenderTarget(0, &render_target);
714 <<
"GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
716 D3DSURFACE_DESC surface_desc;
717 hr = render_target->GetDesc(&surface_desc);
720 <<
"GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
722 if (target_pixel_format != surface_desc.Format &&
723 target_pixel_format != D3DFMT_INTZ) {
724 if (dxgsg9_cat.is_debug()) {
726 <<
"Chose format " << D3DFormatStr(surface_desc.Format)
727 <<
" instead of " << D3DFormatStr(target_pixel_format)
728 <<
" for texture to match framebuffer.\n";
730 target_pixel_format = surface_desc.Format;
733 SAFE_RELEASE(render_target);
739 SamplerState::FilterType ft;
742 if ((ft != SamplerState::FT_linear) && ft != SamplerState::FT_nearest) {
744 if (ft == SamplerState::FT_nearest_mipmap_nearest) {
745 ft = SamplerState::FT_nearest;
747 ft = SamplerState::FT_linear;
751 if (ft == SamplerState::FT_linear &&
752 (filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
753 ft = SamplerState::FT_nearest;
759 _has_mipmaps =
false;
761 if (!dx_ignore_mipmaps) {
763 case SamplerState::FT_nearest_mipmap_nearest:
764 case SamplerState::FT_linear_mipmap_nearest:
765 case SamplerState::FT_nearest_mipmap_linear:
766 case SamplerState::FT_linear_mipmap_linear:
770 if (dx_mipmap_everything) {
772 if (dxgsg9_cat.is_spam()) {
773 if (ft != SamplerState::FT_linear_mipmap_linear) {
775 <<
"Forcing trilinear mipmapping on DX texture ["
776 << tex->get_name() <<
"]\n";
779 ft = SamplerState::FT_linear_mipmap_linear;
783 }
else if ((ft == SamplerState::FT_nearest_mipmap_nearest) ||
784 (ft == SamplerState::FT_nearest_mipmap_linear)) {
785 ft = SamplerState::FT_nearest;
787 }
else if ((ft == SamplerState::FT_linear_mipmap_nearest) ||
788 (ft == SamplerState::FT_linear_mipmap_linear)) {
789 ft = SamplerState::FT_linear;
792 nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0,
false);
794 #define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR)
798 case SamplerState::FT_linear_mipmap_linear:
799 if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
800 if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
801 ft = SamplerState::FT_linear_mipmap_nearest;
805 ft = SamplerState::FT_nearest_mipmap_nearest;
810 case SamplerState::FT_nearest_mipmap_linear:
812 if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
813 (filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
814 ft = SamplerState::FT_nearest_mipmap_nearest;
818 case SamplerState::FT_linear_mipmap_nearest:
820 if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
821 ft = SamplerState::FT_nearest_mipmap_nearest;
825 case SamplerState::FT_linear:
826 if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
827 ft = SamplerState::FT_nearest;
837 if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
839 if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
840 dx_force_anisotropic_filtering) {
841 aniso_degree = scrn._d3dcaps.MaxAnisotropy;
848 <<
"create_texture: setting aniso degree for " << tex->get_name()
849 <<
" to: " << aniso_degree << endl;
852 UINT mip_level_count;
857 if (mip_level_count < 2) {
861 if (dxgsg9_cat.is_debug()) {
863 <<
"create_texture: generating mipmaps for " << tex->get_name()
870 if (target_pixel_format == D3DFMT_ATI1 ||
871 target_pixel_format == D3DFMT_ATI2) {
873 UINT dimension = min(target_height, target_width);
875 while (dimension >= 4) {
896 _is_render_target =
true;
898 pool = D3DPOOL_DEFAULT;
900 usage = D3DUSAGE_DEPTHSTENCIL;
902 usage = D3DUSAGE_RENDERTARGET;
908 <<
"*** RENDER TO TEXTURE ***: format "
909 << D3DFormatStr(target_pixel_format)
911 << target_pixel_format
915 _managed = scrn._managed_textures;
917 pool = D3DPOOL_MANAGED;
921 if (scrn._supports_automatic_mipmap_generation) {
922 pool = D3DPOOL_DEFAULT;
923 usage = D3DUSAGE_AUTOGENMIPMAP;
926 if (dx_use_dynamic_textures) {
927 if (scrn._supports_dynamic_textures) {
928 pool = D3DPOOL_DEFAULT;
929 usage = D3DUSAGE_DYNAMIC;
935 pool = D3DPOOL_MANAGED;
940 pool = D3DPOOL_DEFAULT;
947 PN_stdfloat bytes_per_texel;
949 bytes_per_texel =
this -> d3d_format_to_bytes_per_pixel (target_pixel_format);
950 if (bytes_per_texel == 0.0f) {
952 <<
"D3D create_texture ( ) unknown texture format\n";
957 data_size = target_width * target_height * target_depth;
959 data_size = (int) ((PN_stdfloat) data_size * 1.3333333);
961 data_size = (int) ((PN_stdfloat) data_size * bytes_per_texel);
969 if (dxgsg9_cat.is_debug()) {
971 <<
"Creating " << *tex <<
", " << data_size <<
" bytes, "
972 << scrn._d3d_device->GetAvailableTextureMem()
973 <<
" reported available.\n";
975 <<
" size is " << target_width <<
" w * " << target_height <<
" h * "
976 << target_depth <<
" d";
978 dxgsg9_cat.debug(
false)
979 <<
" * 1.3333333 mipmaps";
981 dxgsg9_cat.debug(
false)
982 <<
" * " << bytes_per_texel <<
" bpt";
984 dxgsg9_cat.debug(
false)
987 dxgsg9_cat.debug(
false)
995 case Texture::TT_1d_texture:
996 case Texture::TT_2d_texture:
997 hr = scrn._d3d_device->CreateTexture
998 (target_width, target_height, mip_level_count, usage,
999 target_pixel_format, pool, &_d3d_2d_texture,
nullptr);
1000 _d3d_texture = _d3d_2d_texture;
1003 case Texture::TT_3d_texture:
1004 hr = scrn._d3d_device->CreateVolumeTexture
1005 (target_width, target_height, target_depth, mip_level_count, usage,
1006 target_pixel_format, pool, &_d3d_volume_texture,
nullptr);
1007 _d3d_texture = _d3d_volume_texture;
1010 case Texture::TT_cube_map:
1011 hr = scrn._d3d_device->CreateCubeTexture
1012 (target_width, mip_level_count, usage,
1013 target_pixel_format, pool, &_d3d_cube_texture,
nullptr);
1014 _d3d_texture = _d3d_cube_texture;
1016 target_height = target_width;
1021 }
while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
1025 <<
"D3D create_texture failed!" << D3DERRORSTRING(hr);
1027 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
1032 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
1034 <<
"create_texture: " << tex->get_name()
1035 <<
" converting panda equivalent of " << D3DFormatStr(_d3d_format)
1036 <<
" => " << D3DFormatStr(target_pixel_format) << endl;
1039 hr = fill_d3d_texture_pixels(scrn, compress_texture);
1043 <<
"*** fill_d3d_texture_pixels failed ***: format "
1044 << target_pixel_format
1057 if (record !=
nullptr) {
1059 cache->
store(record);
1075 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1076 _d3d_2d_texture =
nullptr;
1077 _d3d_volume_texture =
nullptr;
1078 _d3d_cube_texture =
nullptr;
1085 bool DXTextureContext9::
1093 _d3d_format = D3DFMT_A8R8G8B8;
1094 D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
1095 DWORD target_bpp = 32;
1096 DWORD num_color_channels = 4;
1100 DWORD mip_level_count = 1;
1102 D3DPOOL pool = D3DPOOL_MANAGED;
1104 int data_size = target_width * target_height * 4;
1106 hr = scrn._d3d_device->CreateTexture
1107 (target_width, target_height, mip_level_count, usage,
1108 target_pixel_format, pool, &_d3d_2d_texture,
nullptr);
1109 _d3d_texture = _d3d_2d_texture;
1112 <<
"D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
1114 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
1119 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
1121 <<
"create_simple_texture: " <<
get_texture()->get_name()
1131 IDirect3DSurface9 *surface =
nullptr;
1132 _d3d_2d_texture->GetSurfaceLevel(0, &surface);
1135 source_size.left = source_size.top = 0;
1136 source_size.right = target_width;
1137 source_size.bottom = target_height;
1139 DWORD mip_filter = D3DX_FILTER_LINEAR;
1141 hr = D3DXLoadSurfaceFromMemory
1142 (surface,
nullptr,
nullptr, (LPCVOID)image.
p(),
1143 target_pixel_format, target_width * 4,
nullptr,
1144 &source_size, mip_filter, (D3DCOLOR)0x0);
1146 RELEASE(surface, dxgsg9,
"create_simple_texture Surface", RELEASE_ONCE);
1151 <<
"*** fill_d3d_texture_pixels failed ***: format "
1152 << target_pixel_format
1162 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1163 _d3d_2d_texture =
nullptr;
1164 _d3d_volume_texture =
nullptr;
1165 _d3d_cube_texture =
nullptr;
1175 if (_d3d_texture ==
nullptr) {
1180 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1181 _d3d_2d_texture =
nullptr;
1182 _d3d_volume_texture =
nullptr;
1183 _d3d_cube_texture =
nullptr;
1204 nassertr(IS_VALID_PTR(_d3d_2d_texture),
false);
1206 D3DSURFACE_DESC desc;
1207 hr = _d3d_2d_texture->GetLevelDesc(0, &desc);
1210 <<
"Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr);
1215 Texture::Format format = Texture::F_rgba;
1216 Texture::CompressionMode compression = Texture::CM_off;
1218 switch (desc.Format) {
1220 format = Texture::F_rgb;
1223 case D3DFMT_A8R8G8B8:
1224 case D3DFMT_X8R8G8B8:
1228 format = Texture::F_luminance;
1232 format = Texture::F_luminance_alpha;
1236 format = Texture::F_depth_stencil;
1240 format = Texture::F_depth_component16;
1244 format = Texture::F_depth_component24;
1248 format = Texture::F_depth_component32;
1252 compression = Texture::CM_dxt1;
1256 compression = Texture::CM_dxt2;
1260 compression = Texture::CM_dxt3;
1264 compression = Texture::CM_dxt4;
1268 compression = Texture::CM_dxt5;
1273 compression = Texture::CM_rgtc;
1279 <<
"Cannot extract texture data: unhandled surface format "
1280 << desc.Format <<
"\n";
1284 int num_levels = _d3d_2d_texture->GetLevelCount();
1293 if (_is_render_target) {
1294 IDirect3DSurface9* source_surface;
1295 IDirect3DSurface9* destination_surface;
1298 destination_surface = 0;
1300 hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface);
1304 D3DSURFACE_DESC surface_description;
1306 pool = D3DPOOL_SYSTEMMEM;
1307 source_surface -> GetDesc (&surface_description);
1309 hr = screen._d3d_device->CreateOffscreenPlainSurface (
1310 surface_description.Width,
1311 surface_description.Height,
1312 surface_description.Format,
1314 &destination_surface,
1317 if (source_surface && destination_surface) {
1318 hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
1321 D3DLOCKED_RECT rect;
1323 hr = destination_surface -> LockRect (&rect,
nullptr, D3DLOCK_READONLY);
1330 int surface_bytes_per_line;
1331 unsigned char *surface_pointer;
1333 bytes_per_line = surface_description.Width *
this -> d3d_format_to_bytes_per_pixel (surface_description.Format);
1334 size = bytes_per_line * surface_description.Height;
1336 surface_bytes_per_line = rect.Pitch;
1337 surface_pointer = (
unsigned char *) rect.pBits;
1339 PTA_uchar image = PTA_uchar::empty_array(size);
1344 for (y = 0; y < surface_description.Height; y++)
1346 memcpy (&image [offset], surface_pointer, bytes_per_line);
1348 offset += bytes_per_line;
1349 surface_pointer += surface_bytes_per_line;
1356 destination_surface -> UnlockRect();
1361 destination_surface -> Release ( );
1365 <<
"CreateImageSurface failed in extract_texture_data()"
1366 << D3DERRORSTRING(hr);
1368 source_surface -> Release ( );
1372 for (
int n = 0; n < num_levels; ++n) {
1373 D3DLOCKED_RECT rect;
1374 hr = _d3d_2d_texture->LockRect(n, &rect,
nullptr, D3DLOCK_READONLY);
1377 <<
"Texture::LockRect() failed! level = " << n <<
" " << D3DERRORSTRING(hr);
1385 if (compression == Texture::CM_off) {
1388 pitch = min(pitch, (
int)rect.Pitch);
1389 int size = pitch * y_size;
1390 image = PTA_uchar::empty_array(size);
1391 if (pitch == rect.Pitch) {
1393 memcpy(image.p(), rect.pBits, size);
1397 unsigned char *dest = image.p();
1398 unsigned char *source = (
unsigned char *)rect.pBits;
1399 for (
int yi = 0; yi < y_size; ++yi) {
1400 memcpy(dest, source, pitch);
1402 source += rect.Pitch;
1408 int size = rect.Pitch * (y_size / div);
1409 image = PTA_uchar::empty_array(size);
1410 memcpy(image.p(), rect.pBits, size);
1413 _d3d_2d_texture->UnlockRect(n);
1432 bool inverted,
Texture *result,
int view,
int z) {
1442 nassertr((num_components == 3) || (num_components == 4), E_FAIL);
1443 nassertr(IS_VALID_PTR(d3d_surface), E_FAIL);
1447 nassertr(z < result->get_z_size(), E_FAIL);
1454 if (IsBadWritePtr(d3d_surface,
sizeof(DWORD))) {
1456 <<
"d3d_surface_to_texture failed: bad pD3DSurf ptr value ("
1457 << ((
void*)d3d_surface) <<
")\n";
1461 DWORD x_window_offset, y_window_offset;
1462 DWORD copy_width, copy_height;
1464 D3DLOCKED_RECT locked_rect;
1465 D3DSURFACE_DESC surface_desc;
1467 hr = d3d_surface->GetDesc(&surface_desc);
1469 x_window_offset = source_rect.left, y_window_offset = source_rect.top;
1470 copy_width = RECT_XSIZE(source_rect);
1471 copy_height = RECT_YSIZE(source_rect);
1478 <<
"d3d_surface_to_texture, Texture size (" << result->
get_x_size()
1480 <<
") too small to hold display surface ("
1481 << copy_width <<
", " << copy_height <<
")\n";
1482 nassertr(
false, E_FAIL);
1486 hr = d3d_surface->LockRect(&locked_rect,
nullptr, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE));
1489 <<
"d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
1494 nassertr((surface_desc.Format == D3DFMT_A8R8G8B8) ||
1495 (surface_desc.Format == D3DFMT_X8R8G8B8) ||
1496 (surface_desc.Format == D3DFMT_R8G8B8) ||
1497 (surface_desc.Format == D3DFMT_R5G6B5) ||
1498 (surface_desc.Format == D3DFMT_X1R5G5B5) ||
1499 (surface_desc.Format == D3DFMT_A1R5G5B5) ||
1500 (surface_desc.Format == D3DFMT_A4R4G4B4), E_FAIL);
1504 int byte_pitch = locked_rect.Pitch;
1505 BYTE *surface_bytes = (BYTE *)locked_rect.pBits;
1508 surface_bytes += byte_pitch * (y_window_offset + copy_height - 1);
1509 byte_pitch = -byte_pitch;
1511 surface_bytes += byte_pitch * y_window_offset;
1517 if (DEBUG_SURFACES && dxgsg9_cat.is_debug()) {
1519 <<
"d3d_surface_to_texture converting "
1520 << D3DFormatStr(surface_desc.Format)
1521 <<
" DDSurf to " << num_components <<
"-channel panda Texture\n";
1524 DWORD *dest_word = (DWORD *)buf;
1525 BYTE *dest_byte = (BYTE *)buf;
1527 switch(surface_desc.Format) {
1528 case D3DFMT_A8R8G8B8:
1529 case D3DFMT_X8R8G8B8: {
1530 if (num_components == 4) {
1532 BYTE *dest_line = (BYTE*)dest_word;
1534 for (DWORD y = 0; y < copy_height; y++) {
1535 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1536 memcpy(dest_line, source_word, byte_pitch);
1537 dest_line += byte_pitch;
1538 surface_bytes += byte_pitch;
1543 for (DWORD y = 0; y < copy_height; y++) {
1544 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1546 for (DWORD x = 0; x < copy_width; x++) {
1548 DWORD
pixel = *source_word;
1550 r = (BYTE)((
pixel>>16) & g_LowByteMask);
1551 g = (BYTE)((
pixel>> 8) & g_LowByteMask);
1552 b = (BYTE)((
pixel ) & g_LowByteMask);
1559 surface_bytes += byte_pitch;
1565 case D3DFMT_R8G8B8: {
1568 if (num_components == 4) {
1569 for (DWORD y = 0; y < copy_height; y++) {
1570 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1571 for (DWORD x = 0; x < copy_width; x++) {
1578 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1581 surface_bytes += byte_pitch;
1585 for (DWORD y = 0; y < copy_height; y++) {
1586 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1587 memcpy(dest_byte, source_byte, byte_pitch);
1588 dest_byte += byte_pitch;
1589 surface_bytes += byte_pitch;
1596 case D3DFMT_X1R5G5B5:
1597 case D3DFMT_A1R5G5B5:
1598 case D3DFMT_A4R4G4B4: {
1602 BYTE redshift, greenshift, blueshift;
1603 DWORD redmask, greenmask, bluemask;
1605 if (surface_desc.Format == D3DFMT_R5G6B5) {
1612 }
else if (surface_desc.Format == D3DFMT_A4R4G4B4) {
1628 if (num_components == 4) {
1635 for (DWORD y = 0; y < copy_height; y++) {
1636 source_word = ((WORD*)surface_bytes) + x_window_offset;
1637 for (DWORD x = 0; x < copy_width; x++) {
1638 WORD
pixel = *source_word;
1641 b = (
pixel & bluemask) << blueshift;
1642 g = (
pixel & greenmask) >> greenshift;
1643 r = (
pixel & redmask) >> redshift;
1647 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1651 surface_bytes += byte_pitch;
1655 for (DWORD y = 0; y < copy_height; y++) {
1656 source_word = ((WORD*)surface_bytes) + x_window_offset;
1657 for (DWORD x = 0; x < copy_width; x++) {
1658 WORD
pixel = *source_word;
1661 b = (
pixel & bluemask) << blueshift;
1662 g = (
pixel & greenmask) >> greenshift;
1663 r = (
pixel & redmask) >> redshift;
1671 surface_bytes += byte_pitch;
1679 <<
"d3d_surface_to_texture: unsupported D3DFORMAT!\n";
1682 d3d_surface->UnlockRect();
1691 static UINT calculate_row_byte_length (
int width,
int num_color_channels, D3DFORMAT tex_format)
1693 UINT source_row_byte_length = 0;
1697 switch (tex_format) {
1703 source_row_byte_length = max(1,width / 4)*8;
1711 source_row_byte_length = max(1,width / 4)*16;
1715 source_row_byte_length = width*num_color_channels;
1718 return source_row_byte_length;
1726 HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(
int mip_level,
int depth_index, D3DFORMAT source_format)
1730 IDirect3DSurface9 *mip_surface =
nullptr;
1731 bool using_temp_buffer =
false;
1732 HRESULT hr = E_FAIL;
1734 BYTE *pixels = (BYTE*) image.
p();
1741 vector_uchar clear_data;
1742 if (page_size > 0) {
1746 nassertr(!image.
is_null(), E_FAIL);
1747 pixels = (BYTE *)image.
p();
1749 view_size = image.size();
1751 pixels += page_size * depth_index;
1757 pixels = clear_data.data();
1758 view_size = clear_data.size();
1761 if (
get_texture()->get_texture_type() == Texture::TT_cube_map) {
1762 nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
1763 hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface);
1765 nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
1766 hr = _d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface);
1771 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1772 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
1777 source_size.left = source_size.top = 0;
1778 source_size.right = width;
1779 source_size.bottom = height;
1781 UINT source_row_byte_length = calculate_row_byte_length(width,
get_texture()->get_num_components(), source_format);
1786 mip_filter = D3DX_FILTER_LINEAR ;
1789 mip_filter |= D3DX_FILTER_SRGB;
1794 if (_d3d_format == D3DFMT_A8) {
1796 USHORT *temp_buffer =
new USHORT[width * height];
1797 if (!IS_VALID_PTR(temp_buffer)) {
1799 <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1800 goto exit_FillMipmapSurf;
1802 using_temp_buffer =
true;
1804 USHORT *out_pixels = temp_buffer;
1805 BYTE *source_pixels = pixels + component_width - 1;
1806 for (UINT y = 0; y < height; y++) {
1807 for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) {
1810 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
1814 source_format = D3DFMT_A8L8;
1815 source_row_byte_length = width *
sizeof(USHORT);
1816 pixels = (BYTE*)temp_buffer;
1818 else if (component_width != 1) {
1824 int num_pixels = width * height * num_components;
1825 BYTE *temp_buffer =
new BYTE[num_pixels];
1826 if (!IS_VALID_PTR(temp_buffer)) {
1827 dxgsg9_cat.error() <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1828 goto exit_FillMipmapSurf;
1830 using_temp_buffer =
true;
1832 BYTE *source_pixels = pixels + component_width - 1;
1833 for (
int i = 0; i < num_pixels; i++) {
1834 temp_buffer[i] = *source_pixels;
1835 source_pixels += component_width;
1837 pixels = (BYTE*)temp_buffer;
1842 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height);
1844 if (source_format == D3DFMT_ATI1 || source_format == D3DFMT_ATI2) {
1846 D3DLOCKED_RECT rect;
1847 _d3d_2d_texture->LockRect(mip_level, &rect, 0, D3DLOCK_DISCARD);
1849 unsigned char *dest = (
unsigned char *)rect.pBits;
1850 memcpy(dest, pixels, view_size);
1852 _d3d_2d_texture->UnlockRect(mip_level);
1855 hr = D3DXLoadSurfaceFromMemory
1856 (mip_surface,
nullptr,
nullptr, (LPCVOID)pixels,
1857 source_format, source_row_byte_length,
nullptr,
1858 &source_size, mip_filter, (D3DCOLOR)0x0);
1861 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1862 <<
", mip_level " << mip_level
1863 <<
", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
1867 exit_FillMipmapSurf:
1868 if (using_temp_buffer) {
1869 SAFE_DELETE_ARRAY(pixels);
1872 RELEASE(mip_surface, dxgsg9,
"FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE);
1879 HRESULT DXTextureContext9::
1880 fill_d3d_texture_pixels(
DXScreenData &scrn,
bool compress_texture) {
1881 IDirect3DDevice9 *device = scrn._d3d_device;
1883 nassertr(IS_VALID_PTR(tex), E_FAIL);
1885 return fill_d3d_volume_texture_pixels(scrn);
1888 HRESULT hr = E_FAIL;
1891 Texture::CompressionMode image_compression = Texture::CM_off;
1892 if (compress_texture) {
1912 if (_d3d_2d_texture) {
1914 IDirect3DSurface9 *surface;
1916 result = _d3d_2d_texture -> GetSurfaceLevel (0, &surface);
1917 if (result == D3D_OK) {
1918 D3DSURFACE_DESC surface_description;
1920 if (surface -> GetDesc (&surface_description) == D3D_OK) {
1921 IDirect3DSurface9 *current_render_target;
1923 if (device -> GetRenderTarget (0, ¤t_render_target) == D3D_OK) {
1924 IDirect3DSurface9 *depth_stencil_surface;
1927 depth_stencil_surface = 0;
1928 if (device -> GetDepthStencilSurface (&depth_stencil_surface) == D3D_OK) {
1929 if (device -> SetDepthStencilSurface (
nullptr) == D3D_OK) {
1934 if (device -> SetRenderTarget (0, surface) == D3D_OK) {
1938 LColor scaled = tex->
get_clear_color().fmin(LColor(1)).fmax(LColor::zero());
1940 color = D3DCOLOR_RGBA((
int)scaled[0], (
int)scaled[1], (
int)scaled[2], (
int)scaled[3]);
1941 flags = D3DCLEAR_TARGET;
1942 if (device -> Clear (0,
nullptr, flags, color, 0.0f, 0) == D3D_OK) {
1947 if (depth_stencil_surface) {
1948 device -> SetDepthStencilSurface (depth_stencil_surface);
1949 depth_stencil_surface -> Release();
1953 device -> SetRenderTarget (0, current_render_target);
1954 current_render_target -> Release();
1958 surface -> Release();
1966 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
1968 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
1970 DWORD orig_depth = (DWORD) tex->
get_z_size();
1971 D3DFORMAT source_format = _d3d_format;
1974 switch (image_compression) {
1975 case Texture::CM_dxt1:
1976 source_format = D3DFMT_DXT1;
1978 case Texture::CM_dxt2:
1979 source_format = D3DFMT_DXT2;
1981 case Texture::CM_dxt3:
1982 source_format = D3DFMT_DXT3;
1984 case Texture::CM_dxt4:
1985 source_format = D3DFMT_DXT4;
1987 case Texture::CM_dxt5:
1988 source_format = D3DFMT_DXT5;
1990 case Texture::CM_rgtc:
1992 source_format = D3DFMT_ATI1;
1994 source_format = D3DFMT_ATI2;
2002 for (
unsigned int di = 0; di < orig_depth; di++) {
2005 hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
2013 int miplevel_count = _d3d_texture->GetLevelCount();
2014 if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) {
2016 <<
"Using pre-calculated mipmap levels for texture " << tex->get_name() <<
"\n";
2018 for (
int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
2019 hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
2028 if (_managed ==
false && scrn._supports_automatic_mipmap_generation) {
2035 hr = _d3d_texture -> SetAutoGenFilterType (D3DTEXF_LINEAR);
2037 dxgsg9_cat.error() <<
"SetAutoGenFilterType failed " << D3DERRORSTRING(hr);
2040 _d3d_texture -> GenerateMipSubLevels ( );
2044 DWORD mip_filter_flags;
2045 if (!dx_use_triangle_mipgen_filter) {
2046 mip_filter_flags = D3DX_FILTER_BOX;
2048 mip_filter_flags = D3DX_FILTER_TRIANGLE;
2052 mip_filter_flags |= D3DX_FILTER_SRGB;
2056 hr = D3DXFilterTexture(_d3d_texture,
nullptr, 0,
2061 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2062 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
2076 HRESULT DXTextureContext9::
2079 HRESULT hr = E_FAIL;
2080 nassertr(IS_VALID_PTR(tex), E_FAIL);
2089 Texture::CompressionMode image_compression;
2091 image_compression = Texture::CM_off;
2098 image_compression = Texture::CM_off;
2107 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
2109 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
2112 DWORD orig_width = (DWORD) tex->
get_x_size();
2113 DWORD orig_height = (DWORD) tex->
get_y_size();
2114 DWORD orig_depth = (DWORD) tex->
get_z_size();
2116 D3DFORMAT source_format = _d3d_format;
2117 BYTE *image_pixels = (BYTE*)image.
p();
2120 nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
2123 image_pixels += view_size *
get_view();
2125 IDirect3DVolume9 *mip_level_0 =
nullptr;
2126 bool using_temp_buffer =
false;
2127 BYTE *pixels = image_pixels;
2129 nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL);
2130 hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0);
2134 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2135 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
2140 source_size.Left = source_size.Top = source_size.Front = 0;
2141 source_size.Right = orig_width;
2142 source_size.Bottom = orig_height;
2143 source_size.Back = orig_depth;
2145 UINT source_row_byte_length = orig_width * num_color_channels;
2146 UINT source_page_byte_length = orig_height * source_row_byte_length;
2148 DWORD level_0_filter, mip_filter_flags;
2149 using_temp_buffer =
false;
2153 level_0_filter = D3DX_FILTER_LINEAR ;
2156 level_0_filter |= D3DX_FILTER_SRGB;
2161 if (_d3d_format == D3DFMT_A8) {
2163 USHORT *temp_buffer =
new USHORT[orig_width * orig_height * orig_depth];
2164 if (!IS_VALID_PTR(temp_buffer)) {
2166 <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2167 goto exit_FillDDSurf;
2169 using_temp_buffer =
true;
2171 USHORT *out_pixels = temp_buffer;
2172 BYTE *source_pixels = pixels + component_width - 1;
2173 for (UINT z = 0; z < orig_depth; z++) {
2174 for (UINT y = 0; y < orig_height; y++) {
2177 x++, source_pixels += component_width, out_pixels++) {
2181 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
2186 source_format = D3DFMT_A8L8;
2187 source_row_byte_length = orig_width *
sizeof(USHORT);
2188 source_page_byte_length = orig_height * source_row_byte_length;
2189 pixels = (BYTE*)temp_buffer;
2191 }
else if (component_width != 1) {
2197 int num_pixels = orig_width * orig_height * orig_depth * num_components;
2198 BYTE *temp_buffer =
new BYTE[num_pixels];
2199 if (!IS_VALID_PTR(temp_buffer)) {
2200 dxgsg9_cat.error() <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2201 goto exit_FillDDSurf;
2203 using_temp_buffer =
true;
2205 BYTE *source_pixels = pixels + component_width - 1;
2206 for (
int i = 0; i < num_pixels; i++) {
2207 temp_buffer[i] = *source_pixels;
2208 source_pixels += component_width;
2210 pixels = (BYTE*)temp_buffer;
2216 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth);
2218 hr = D3DXLoadVolumeFromMemory
2219 (mip_level_0,
nullptr,
nullptr, (LPCVOID)pixels,
2220 source_format, source_row_byte_length, source_page_byte_length,
2222 &source_size, level_0_filter, (D3DCOLOR)0x0);
2225 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2226 <<
", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
2227 goto exit_FillDDSurf;
2231 if (!dx_use_triangle_mipgen_filter) {
2232 mip_filter_flags = D3DX_FILTER_BOX;
2234 mip_filter_flags = D3DX_FILTER_TRIANGLE;
2238 mip_filter_flags |= D3DX_FILTER_SRGB;
2243 hr = D3DXFilterTexture(_d3d_texture,
nullptr, 0,
2247 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2248 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
2249 goto exit_FillDDSurf;
2254 if (using_temp_buffer) {
2255 SAFE_DELETE_ARRAY(pixels);
2257 RELEASE(mip_level_0, dxgsg9,
"FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
2265 int DXTextureContext9::
2266 down_to_power_2(
int value) {
2268 while ((x << 1) <= value) {
2279 unsigned int DXTextureContext9::
2280 get_bits_per_pixel(Texture::Format format,
int *alphbits) {
2283 case Texture::F_alpha:
2285 case Texture::F_color_index:
2286 case Texture::F_red:
2287 case Texture::F_green:
2288 case Texture::F_blue:
2289 case Texture::F_rgb332:
2291 case Texture::F_luminance_alphamask:
2294 case Texture::F_luminance_alpha:
2297 case Texture::F_luminance:
2299 case Texture::F_rgba4:
2302 case Texture::F_rgba5:
2305 case Texture::F_depth_component:
2306 case Texture::F_depth_component16:
2308 case Texture::F_depth_stencil:
2309 case Texture::F_depth_component24:
2311 case Texture::F_depth_component32:
2313 case Texture::F_rgb5:
2315 case Texture::F_rgb8:
2316 case Texture::F_rgb:
2318 case Texture::F_rgba8:
2319 case Texture::F_rgba:
2322 case Texture::F_rgbm:
2325 case Texture::F_rgb12:
2327 case Texture::F_rgba12:
2330 case Texture::F_rgba16:
2333 case Texture::F_rgba32:
2337 case Texture::F_srgb:
2339 case Texture::F_srgb_alpha:
2342 case Texture::F_sluminance:
2344 case Texture::F_sluminance_alpha:
2354 PN_stdfloat DXTextureContext9::
2355 d3d_format_to_bytes_per_pixel (D3DFORMAT format)
2357 PN_stdfloat bytes_per_pixel;
2359 bytes_per_pixel = 0.0f;
2368 bytes_per_pixel = 1.0f;
2375 case D3DFMT_X1R5G5B5:
2376 case D3DFMT_A1R5G5B5:
2377 case D3DFMT_A4R4G4B4:
2380 case D3DFMT_A8R3G3B2:
2381 case D3DFMT_X4R4G4B4:
2383 case (D3DFORMAT)MAKEFOURCC(
'D',
'F',
'1',
'6'):
2384 bytes_per_pixel = 2.0f;
2388 bytes_per_pixel = 3.0f;
2391 case D3DFMT_G16R16F:
2392 case D3DFMT_Q8W8V8U8:
2395 case D3DFMT_A8R8G8B8:
2396 case D3DFMT_X8R8G8B8:
2397 case D3DFMT_A2B10G10R10:
2398 case D3DFMT_A8B8G8R8:
2399 case D3DFMT_X8B8G8R8:
2401 case D3DFMT_A2R10G10B10:
2405 case (D3DFORMAT)MAKEFOURCC(
'D',
'F',
'2',
'4'):
2407 bytes_per_pixel = 4.0f;
2410 case D3DFMT_G32R32F:
2411 case D3DFMT_A16B16G16R16F:
2412 case D3DFMT_Q16W16V16U16:
2413 case D3DFMT_A16B16G16R16:
2414 bytes_per_pixel = 8.0f;
2417 case D3DFMT_A32B32G32R32F:
2418 bytes_per_pixel = 16.0f;
2423 bytes_per_pixel = 0.5f;
2430 bytes_per_pixel = 1.0f;
2434 return bytes_per_pixel;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void mark_used_lru() const
To be called when the page is used; this will move it to the tail of the AdaptiveLru queue it is alre...
void dequeue_lru()
Removes the page from its AdaptiveLru.
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
set_data
Stores a new data object on the record.
This class maintains a cache of Bam and/or Txo objects generated from model files and texture images ...
bool store(BamCacheRecord *record)
Flushes a cache entry to disk.
static BamCache * get_global_ptr()
Returns a pointer to the global BamCache object, which is used automatically by the ModelPool and Tex...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
virtual void evict_lru()
Evicts the page from the LRU.
bool extract_texture_data(DXScreenData &scrn)
This method will be called in the draw thread to download the texture memory's image into its ram_ima...
void delete_texture()
Release the surface used to store the texture.
static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, bool inverted, Texture *result, int view, int z)
copies source_rect in pD3DSurf to upper left of texture
void texture_uploaded(Texture *tex)
This method is called by the GraphicsStateGuardian after a texture has been successfully uploaded to ...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
virtual bool get_supports_compressed_texture_format(int compression_mode) const
Returns true if this GSG can accept textures pre-compressed in the indicated format.
get_supports_compressed_texture
Returns true if this GSG can compress textures as it loads them into texture memory,...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
constexpr bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
A table of objects that are saved within the graphics context for reference by handle later.
This is a special class object that holds all the information returned by a particular GSG to indicat...
void update_data_size_bytes(size_t new_data_size_bytes)
Should be called (usually by a derived class) when the on-card size of this object has changed.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
void mark_simple_loaded()
Should be called after the texture's "simple" image has been loaded into graphics memory.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
int get_view() const
Returns the specific view of a multiview texture this context represents.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_post_load_store_cache
Returns the setting of the post_load_store_cache flag.
CPTA_uchar get_uncompressed_ram_image()
Returns the system-RAM image associated with the texture, in an uncompressed form if at all possible.
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
get_minfilter
Returns the filter mode of the texture for minification.
void generate_ram_mipmap_images()
Automatically fills in the n mipmap levels of the Texture, based on the texture's source image.
PTA_uchar modify_ram_image()
Returns a modifiable pointer to the system-RAM image.
set_z_size
Changes the z size indicated for the texture.
get_render_to_texture
Returns a flag on the texture that indicates whether the texture is intended to be used as a direct-r...
get_compression
Returns the compression mode requested for this particular texture, or CM_off if the texture is not t...
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
get_texture_type
Returns the overall interpretation of the texture.
CPTA_uchar get_ram_image()
Returns the system-RAM image data associated with the texture.
get_simple_ram_image
Returns the image data associated with the "simple" texture image.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise.
get_ram_image_compression
Returns the compression mode in which the ram image is already stored pre- compressed.
set_format
Changes the format value for the texture components.
get_component_width
Returns the number of bytes stored for each color component of a texel.
vector_uchar get_clear_data() const
Returns the raw image data for a single pixel if it were set to the clear color.
set_anisotropic_degree
Specifies the level of anisotropic filtering to apply to the texture.
get_anisotropic_degree
Returns the degree of anisotropic filtering that should be applied to the texture.
get_match_framebuffer_format
Returns true if the special flag was set that indicates to the GSG that the Texture's format should b...
get_y_size
Returns the height of the texture image in texels.
size_t get_ram_mipmap_view_size(int n) const
Returns the number of bytes used by the in-memory image per view for mipmap level n,...
get_magfilter
Returns the filter mode of the texture for magnification.
get_z_size
Returns the depth of the texture image in texels.
set_x_size
Changes the x size indicated for the texture.
void set_ram_mipmap_image(int n, CPTA_uchar image, size_t page_size=0)
Replaces the current system-RAM image for the indicated mipmap level with the new data.
size_t get_expected_ram_mipmap_page_size(int n) const
Returns the number of bytes that should be used per each Z page of the 3-d texture,...
set_minfilter
Sets the filtering method that should be used when viewing the texture from a distance.
set_magfilter
Sets the filtering method that should be used when viewing the texture up close.
PTA_uchar make_ram_mipmap_image(int n)
Discards the current system-RAM image for the nth mipmap level, if any, and allocates a new buffer of...
int get_expected_mipmap_x_size(int n) const
Returns the x_size that the nth mipmap level should have, based on the texture's size.
get_num_components
Returns the number of color components for each texel of the texture image.
void clear_ram_image()
Discards the current system-RAM image.
get_fullpath
Returns the fullpath that has been set.
get_x_size
Returns the width of the texture image in texels.
get_simple_y_size
Returns the height of the "simple" image in texels.
get_expected_ram_page_size
Returns the number of bytes that should be used per each Z page of the 3-d texture.
int get_expected_mipmap_y_size(int n) const
Returns the y_size that the nth mipmap level should have, based on the texture's size.
set_y_size
Changes the y size indicated for the texture.
set_post_load_store_cache
Sets the post_load_store_cache flag.
get_component_type
Returns the numeric interpretation of each component of the texture.
void set_ram_image(CPTA_uchar image, CompressionMode compression=CM_off, size_t page_size=0)
Replaces the current system-RAM image with the new data.
get_simple_x_size
Returns the width of the "simple" image in texels.
get_num_loadable_ram_mipmap_images
Returns the number of contiguous mipmap levels that exist in RAM, up until the first gap in the seque...
CPTA_uchar get_ram_mipmap_image(int n) const
Returns the system-RAM image data associated with the nth mipmap level, if present.
get_clear_color
Returns the color that was previously set using set_clear_color.
set_component_type
Changes the data value for the texture components.
get_num_ram_mipmap_images
Returns the maximum number of mipmap level images available in system memory.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.