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;
CPTA_uchar get_ram_image()
Returns the system-RAM image data associated with the texture.
set_z_size
Changes the z size indicated for the texture.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise.
get_y_size
Returns the height of the texture image in texels.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
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.
set_data
Stores a new data object on the record.
get_magfilter
Returns the filter mode of the texture for magnification.
get_fullpath
Returns the fullpath that has been set.
get_z_size
Returns the depth of the texture image in texels.
get_simple_ram_image
Returns the image data associated with the "simple" texture image.
get_component_type
Returns the numeric interpretation of each component of the texture.
get_compression
Returns the compression mode requested for this particular texture, or CM_off if the texture is not t...
int get_view() const
Returns the specific view of a multiview texture this context represents.
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...
set_magfilter
Sets the filtering method that should be used when viewing the texture up close.
This class maintains a cache of Bam and/or Txo objects generated from model files and texture images ...
constexpr bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
CPTA_uchar get_uncompressed_ram_image()
Returns the system-RAM image associated with the texture, in an uncompressed form if at all possible.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_texture_type
Returns the overall interpretation of the texture.
This is a special class object that holds all the information returned by a particular GSG to indicat...
get_anisotropic_degree
Returns the degree of anisotropic filtering that should be applied to the texture.
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
A table of objects that are saved within the graphics context for reference by handle later.
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
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.
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 texture_uploaded(Texture *tex)
This method is called by the GraphicsStateGuardian after a texture has been successfully uploaded to ...
void dequeue_lru()
Removes the page from its AdaptiveLru.
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_minfilter
Returns the filter mode of the texture for minification.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
CPTA_uchar get_ram_mipmap_image(int n) const
Returns the system-RAM image data associated with the nth mipmap level, if present.
bool store(BamCacheRecord *record)
Flushes a cache entry to disk.
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
get_expected_ram_page_size
Returns the number of bytes that should be used per each Z page of the 3-d 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.
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...
get_supports_compressed_texture
Returns true if this GSG can compress textures as it loads them into texture memory,...
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
set_format
Changes the format value for the texture components.
set_minfilter
Sets the filtering method that should be used when viewing the texture from a distance.
get_num_components
Returns the number of color components for each texel of the texture image.
set_anisotropic_degree
Specifies the level of anisotropic filtering to apply to the texture.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_y_size
Changes the y size indicated for the texture.
set_post_load_store_cache
Sets the post_load_store_cache flag.
set_x_size
Changes the x size indicated for the texture.
get_component_width
Returns the number of bytes stored for each color component of a texel.
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_simple_x_size
Returns the width of the "simple" image in texels.
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,...
void clear_ram_image()
Discards the current system-RAM image.
get_clear_color
Returns the color that was previously set using set_clear_color.
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.
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.
set_component_type
Changes the data value for the texture components.
void generate_ram_mipmap_images()
Automatically fills in the n mipmap levels of the Texture, based on the texture's source image.
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.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
virtual void evict_lru()
Evicts the page from the LRU.
get_num_ram_mipmap_images
Returns the maximum number of mipmap level images available in system memory.
get_simple_y_size
Returns the height of the "simple" image in texels.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
PTA_uchar modify_ram_image()
Returns a modifiable pointer to the system-RAM image.
void mark_simple_loaded()
Should be called after the texture's "simple" image has been loaded into graphics memory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
vector_uchar get_clear_data() const
Returns the raw image data for a single pixel if it were set to the clear color.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void delete_texture()
Release the surface used to store the texture.
get_x_size
Returns the width of the texture image in texels.
static BamCache * get_global_ptr()
Returns a pointer to the global BamCache object, which is used automatically by the ModelPool and Tex...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_post_load_store_cache
Returns the setting of the post_load_store_cache flag.
get_ram_image_compression
Returns the compression mode in which the ram image is already stored pre- compressed.
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
get_render_to_texture
Returns a flag on the texture that indicates whether the texture is intended to be used as a direct-r...