24#define DEBUG_SURFACES false
25#define DEBUG_TEXTURES true
33static 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;
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) {
434 if (num_alpha_bits == 0 && !needs_luminance) {
435 if (num_color_channels == 1) {
436 if (scrn._supported_tex_formats_mask & ATI1_FLAG) {
438 target_pixel_format = D3DFMT_ATI1;
439 goto found_matching_format;
442 }
else if (num_color_channels == 2) {
443 if (scrn._supported_tex_formats_mask & ATI2_FLAG) {
445 target_pixel_format = D3DFMT_ATI2;
446 goto found_matching_format;
451 if (num_alpha_bits <= 1) {
453 }
else if (num_alpha_bits <= 4) {
462 if (texture_stored_compressed) {
465 texture_stored_compressed = compression_mode != Texture::CM_off;
466 compress_texture =
false;
471 switch (target_bpp) {
478 if (scrn._supports_rgba32_texture_format) {
479 target_pixel_format = D3DFMT_A32B32G32R32F;
482 target_pixel_format = scrn._render_to_texture_d3d_format;
484 goto found_matching_format;
488 if (scrn._supports_rgba16f_texture_format) {
489 target_pixel_format = D3DFMT_A16B16G16R16F;
492 target_pixel_format = scrn._render_to_texture_d3d_format;
494 goto found_matching_format;
498 nassertr(num_alpha_bits == 0,
false);
499 nassertr(num_color_channels == 1,
false);
505 if (!((num_color_channels == 3) || (num_color_channels == 4)))
508 CHECK_FOR_FMT(A8R8G8B8);
510 if (num_alpha_bits>0) {
511 nassertr(num_color_channels == 4,
false);
527 if (num_alpha_bits == 1) {
528 CHECK_FOR_FMT(A1R5G5B5);
532 CHECK_FOR_FMT(A4R4G4B4);
533 CHECK_FOR_FMT(A1R5G5B5);
537 error_message =
"create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
541 if (num_color_channels == 3) {
542 CHECK_FOR_FMT(R5G6B5);
543 CHECK_FOR_FMT(X1R5G5B5);
545 CHECK_FOR_FMT(R5G6B5);
546 CHECK_FOR_FMT(X1R5G5B5);
553 nassertr(num_alpha_bits == 0,
false);
554 nassertr(num_color_channels == 1,
false);
561 CHECK_FOR_FMT(D24S8);
563 CHECK_FOR_FMT(D24X8);
567 if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
568 target_pixel_format = D3DFMT_INTZ;
569 goto found_matching_format;
575 CHECK_FOR_FMT(D24X8);
578 nassertr(num_color_channels == 3,
false);
580 CHECK_FOR_FMT(R8G8B8);
585 CHECK_FOR_FMT(X8R8G8B8);
586 CHECK_FOR_FMT(A8R8G8B8);
589 CHECK_FOR_FMT(R5G6B5);
590 CHECK_FOR_FMT(X1R5G5B5);
591 CHECK_FOR_FMT(A1R5G5B5);
597 nassertr(num_alpha_bits == 0,
false);
598 nassertr(num_color_channels == 1,
false);
605 CHECK_FOR_FMT(D24S8);
608 CHECK_FOR_FMT(D24X8);
611 if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
612 target_pixel_format = D3DFMT_INTZ;
613 goto found_matching_format;
619 CHECK_FOR_FMT(D24X8);
622 }
else if (needs_luminance) {
623 nassertr(num_alpha_bits > 0,
false);
624 nassertr(num_color_channels == 2,
false);
627 CHECK_FOR_FMT(A8R8G8B8);
629 if (num_alpha_bits == 1) {
630 CHECK_FOR_FMT(A1R5G5B5);
634 CHECK_FOR_FMT(A4R4G4B4);
635 CHECK_FOR_FMT(A1R5G5B5);
637 nassertr((num_color_channels == 3)||(num_color_channels == 4),
false);
640 switch(num_alpha_bits) {
642 if (num_color_channels == 3) {
643 CHECK_FOR_FMT(R5G6B5);
644 CHECK_FOR_FMT(X1R5G5B5);
646 nassertr(num_color_channels == 4,
false);
648 CHECK_FOR_FMT(R5G6B5);
649 CHECK_FOR_FMT(X1R5G5B5);
656 nassertr(num_color_channels == 4,
false);
657 CHECK_FOR_FMT(X1R5G5B5);
662 nassertr(num_color_channels == 4,
false);
663 CHECK_FOR_FMT(A4R4G4B4);
666 nassertr(
false,
false);
670 if (needs_luminance) {
673 nassertr(num_color_channels == 1,
false);
679 CHECK_FOR_FMT(R8G8B8);
680 CHECK_FOR_FMT(X8R8G8B8);
682 CHECK_FOR_FMT(R5G6B5);
683 CHECK_FOR_FMT(X1R5G5B5);
685 }
else if (num_alpha_bits == 8) {
694 CHECK_FOR_FMT(A8R8G8B8);
695 CHECK_FOR_FMT(A4R4G4B4);
700 error_message =
"create_texture failed: unhandled pixel bitdepth in DX loader";
705 << error_message <<
": " << tex->get_name() << endl
706 <<
"NumColorChannels: " << num_color_channels <<
"; NumAlphaBits: "
707 << num_alpha_bits <<
"; targetbpp: " <<target_bpp
708 <<
"; _supported_tex_formats_mask: 0x"
709 << std::hex << scrn._supported_tex_formats_mask << std::dec
710 <<
"; NeedLuminance: " << needs_luminance << endl;
714 found_matching_format:
721 IDirect3DSurface9 *render_target;
724 hr = scrn._d3d_device->GetDepthStencilSurface(&render_target);
726 hr = scrn._d3d_device->GetRenderTarget(0, &render_target);
730 <<
"GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
732 D3DSURFACE_DESC surface_desc;
733 hr = render_target->GetDesc(&surface_desc);
736 <<
"GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
738 if (target_pixel_format != surface_desc.Format &&
739 target_pixel_format != D3DFMT_INTZ) {
740 if (dxgsg9_cat.is_debug()) {
742 <<
"Chose format " << D3DFormatStr(surface_desc.Format)
743 <<
" instead of " << D3DFormatStr(target_pixel_format)
744 <<
" for texture to match framebuffer.\n";
746 target_pixel_format = surface_desc.Format;
749 SAFE_RELEASE(render_target);
755 SamplerState::FilterType ft;
758 if ((ft != SamplerState::FT_linear) && ft != SamplerState::FT_nearest) {
760 if (ft == SamplerState::FT_nearest_mipmap_nearest) {
761 ft = SamplerState::FT_nearest;
763 ft = SamplerState::FT_linear;
767 if (ft == SamplerState::FT_linear &&
768 (filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
769 ft = SamplerState::FT_nearest;
775 _has_mipmaps =
false;
777 if (!dx_ignore_mipmaps) {
779 case SamplerState::FT_nearest_mipmap_nearest:
780 case SamplerState::FT_linear_mipmap_nearest:
781 case SamplerState::FT_nearest_mipmap_linear:
782 case SamplerState::FT_linear_mipmap_linear:
786 if (dx_mipmap_everything) {
788 if (dxgsg9_cat.is_spam()) {
789 if (ft != SamplerState::FT_linear_mipmap_linear) {
791 <<
"Forcing trilinear mipmapping on DX texture ["
792 << tex->get_name() <<
"]\n";
795 ft = SamplerState::FT_linear_mipmap_linear;
799 }
else if ((ft == SamplerState::FT_nearest_mipmap_nearest) ||
800 (ft == SamplerState::FT_nearest_mipmap_linear)) {
801 ft = SamplerState::FT_nearest;
803 }
else if ((ft == SamplerState::FT_linear_mipmap_nearest) ||
804 (ft == SamplerState::FT_linear_mipmap_linear)) {
805 ft = SamplerState::FT_linear;
808 nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0,
false);
810#define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR)
814 case SamplerState::FT_linear_mipmap_linear:
815 if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
816 if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
817 ft = SamplerState::FT_linear_mipmap_nearest;
821 ft = SamplerState::FT_nearest_mipmap_nearest;
826 case SamplerState::FT_nearest_mipmap_linear:
828 if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
829 (filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
830 ft = SamplerState::FT_nearest_mipmap_nearest;
834 case SamplerState::FT_linear_mipmap_nearest:
836 if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
837 ft = SamplerState::FT_nearest_mipmap_nearest;
841 case SamplerState::FT_linear:
842 if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
843 ft = SamplerState::FT_nearest;
853 if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
855 if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
856 dx_force_anisotropic_filtering) {
857 aniso_degree = scrn._d3dcaps.MaxAnisotropy;
864 <<
"create_texture: setting aniso degree for " << tex->get_name()
865 <<
" to: " << aniso_degree << endl;
868 UINT mip_level_count;
873 if (mip_level_count < 2) {
877 if (dxgsg9_cat.is_debug()) {
879 <<
"create_texture: generating mipmaps for " << tex->get_name()
886 if (target_pixel_format == D3DFMT_ATI1 ||
887 target_pixel_format == D3DFMT_ATI2) {
889 UINT dimension = min(target_height, target_width);
891 while (dimension >= 4) {
912 _is_render_target =
true;
914 pool = D3DPOOL_DEFAULT;
916 usage = D3DUSAGE_DEPTHSTENCIL;
918 usage = D3DUSAGE_RENDERTARGET;
924 <<
"*** RENDER TO TEXTURE ***: format "
925 << D3DFormatStr(target_pixel_format)
927 << target_pixel_format
931 _managed = scrn._managed_textures;
933 pool = D3DPOOL_MANAGED;
937 if (scrn._supports_automatic_mipmap_generation) {
938 pool = D3DPOOL_DEFAULT;
939 usage = D3DUSAGE_AUTOGENMIPMAP;
942 if (dx_use_dynamic_textures) {
943 if (scrn._supports_dynamic_textures) {
944 pool = D3DPOOL_DEFAULT;
945 usage = D3DUSAGE_DYNAMIC;
951 pool = D3DPOOL_MANAGED;
956 pool = D3DPOOL_DEFAULT;
963 PN_stdfloat bytes_per_texel;
965 bytes_per_texel =
this -> d3d_format_to_bytes_per_pixel (target_pixel_format);
966 if (bytes_per_texel == 0.0f) {
968 <<
"D3D create_texture ( ) unknown texture format\n";
973 data_size = target_width * target_height * target_depth;
975 data_size = (int) ((PN_stdfloat) data_size * 1.3333333);
977 data_size = (int) ((PN_stdfloat) data_size * bytes_per_texel);
985 if (dxgsg9_cat.is_debug()) {
987 <<
"Creating " << *tex <<
", " << data_size <<
" bytes, "
988 << scrn._d3d_device->GetAvailableTextureMem()
989 <<
" reported available.\n";
991 <<
" size is " << target_width <<
" w * " << target_height <<
" h * "
992 << target_depth <<
" d";
994 dxgsg9_cat.debug(
false)
995 <<
" * 1.3333333 mipmaps";
997 dxgsg9_cat.debug(
false)
998 <<
" * " << bytes_per_texel <<
" bpt";
1000 dxgsg9_cat.debug(
false)
1003 dxgsg9_cat.debug(
false)
1011 case Texture::TT_1d_texture:
1012 case Texture::TT_2d_texture:
1013 hr = scrn._d3d_device->CreateTexture
1014 (target_width, target_height, mip_level_count, usage,
1015 target_pixel_format, pool, &_d3d_2d_texture,
nullptr);
1016 _d3d_texture = _d3d_2d_texture;
1019 case Texture::TT_3d_texture:
1020 hr = scrn._d3d_device->CreateVolumeTexture
1021 (target_width, target_height, target_depth, mip_level_count, usage,
1022 target_pixel_format, pool, &_d3d_volume_texture,
nullptr);
1023 _d3d_texture = _d3d_volume_texture;
1026 case Texture::TT_cube_map:
1027 hr = scrn._d3d_device->CreateCubeTexture
1028 (target_width, mip_level_count, usage,
1029 target_pixel_format, pool, &_d3d_cube_texture,
nullptr);
1030 _d3d_texture = _d3d_cube_texture;
1032 target_height = target_width;
1037 }
while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
1041 <<
"D3D create_texture failed!" << D3DERRORSTRING(hr);
1043 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
1048 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
1050 <<
"create_texture: " << tex->get_name()
1051 <<
" converting panda equivalent of " << D3DFormatStr(_d3d_format)
1052 <<
" => " << D3DFormatStr(target_pixel_format) << endl;
1055 hr = fill_d3d_texture_pixels(scrn, compress_texture);
1059 <<
"*** fill_d3d_texture_pixels failed ***: format "
1060 << target_pixel_format
1073 if (record !=
nullptr) {
1075 cache->
store(record);
1091 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1092 _d3d_2d_texture =
nullptr;
1093 _d3d_volume_texture =
nullptr;
1094 _d3d_cube_texture =
nullptr;
1101bool DXTextureContext9::
1109 _d3d_format = D3DFMT_A8R8G8B8;
1110 D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
1111 DWORD target_bpp = 32;
1112 DWORD num_color_channels = 4;
1116 DWORD mip_level_count = 1;
1118 D3DPOOL pool = D3DPOOL_MANAGED;
1120 int data_size = target_width * target_height * 4;
1122 hr = scrn._d3d_device->CreateTexture
1123 (target_width, target_height, mip_level_count, usage,
1124 target_pixel_format, pool, &_d3d_2d_texture,
nullptr);
1125 _d3d_texture = _d3d_2d_texture;
1128 <<
"D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
1130 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
1135 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
1137 <<
"create_simple_texture: " <<
get_texture()->get_name()
1147 IDirect3DSurface9 *surface =
nullptr;
1148 _d3d_2d_texture->GetSurfaceLevel(0, &surface);
1151 source_size.left = source_size.top = 0;
1152 source_size.right = target_width;
1153 source_size.bottom = target_height;
1155 DWORD mip_filter = D3DX_FILTER_LINEAR;
1157 hr = D3DXLoadSurfaceFromMemory
1158 (surface,
nullptr,
nullptr, (LPCVOID)image.
p(),
1159 target_pixel_format, target_width * 4,
nullptr,
1160 &source_size, mip_filter, (D3DCOLOR)0x0);
1162 RELEASE(surface, dxgsg9,
"create_simple_texture Surface", RELEASE_ONCE);
1167 <<
"*** fill_d3d_texture_pixels failed ***: format "
1168 << target_pixel_format
1178 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1179 _d3d_2d_texture =
nullptr;
1180 _d3d_volume_texture =
nullptr;
1181 _d3d_cube_texture =
nullptr;
1191 if (_d3d_texture ==
nullptr) {
1196 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1197 _d3d_2d_texture =
nullptr;
1198 _d3d_volume_texture =
nullptr;
1199 _d3d_cube_texture =
nullptr;
1220 nassertr(IS_VALID_PTR(_d3d_2d_texture),
false);
1222 D3DSURFACE_DESC desc;
1223 hr = _d3d_2d_texture->GetLevelDesc(0, &desc);
1226 <<
"Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr);
1231 Texture::Format format = Texture::F_rgba;
1232 Texture::CompressionMode compression = Texture::CM_off;
1234 switch (desc.Format) {
1236 format = Texture::F_rgb;
1239 case D3DFMT_A8R8G8B8:
1240 case D3DFMT_X8R8G8B8:
1244 format = Texture::F_luminance;
1248 format = Texture::F_luminance_alpha;
1252 format = Texture::F_depth_stencil;
1256 format = Texture::F_depth_component16;
1260 format = Texture::F_depth_component24;
1264 format = Texture::F_depth_component32;
1268 compression = Texture::CM_dxt1;
1272 compression = Texture::CM_dxt2;
1276 compression = Texture::CM_dxt3;
1280 compression = Texture::CM_dxt4;
1284 compression = Texture::CM_dxt5;
1289 compression = Texture::CM_rgtc;
1295 <<
"Cannot extract texture data: unhandled surface format "
1296 << desc.Format <<
"\n";
1300 int num_levels = _d3d_2d_texture->GetLevelCount();
1309 if (_is_render_target) {
1310 IDirect3DSurface9* source_surface;
1311 IDirect3DSurface9* destination_surface;
1314 destination_surface = 0;
1316 hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface);
1320 D3DSURFACE_DESC surface_description;
1322 pool = D3DPOOL_SYSTEMMEM;
1323 source_surface -> GetDesc (&surface_description);
1325 hr = screen._d3d_device->CreateOffscreenPlainSurface (
1326 surface_description.Width,
1327 surface_description.Height,
1328 surface_description.Format,
1330 &destination_surface,
1333 if (source_surface && destination_surface) {
1334 hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
1337 D3DLOCKED_RECT rect;
1339 hr = destination_surface -> LockRect (&rect,
nullptr, D3DLOCK_READONLY);
1346 int surface_bytes_per_line;
1347 unsigned char *surface_pointer;
1349 bytes_per_line = surface_description.Width *
this -> d3d_format_to_bytes_per_pixel (surface_description.Format);
1350 size = bytes_per_line * surface_description.Height;
1352 surface_bytes_per_line = rect.Pitch;
1353 surface_pointer = (
unsigned char *) rect.pBits;
1355 PTA_uchar image = PTA_uchar::empty_array(size);
1360 for (y = 0; y < surface_description.Height; y++)
1362 memcpy (&image [offset], surface_pointer, bytes_per_line);
1364 offset += bytes_per_line;
1365 surface_pointer += surface_bytes_per_line;
1372 destination_surface -> UnlockRect();
1377 destination_surface -> Release ( );
1381 <<
"CreateImageSurface failed in extract_texture_data()"
1382 << D3DERRORSTRING(hr);
1384 source_surface -> Release ( );
1388 for (
int n = 0; n < num_levels; ++n) {
1389 D3DLOCKED_RECT rect;
1390 hr = _d3d_2d_texture->LockRect(n, &rect,
nullptr, D3DLOCK_READONLY);
1393 <<
"Texture::LockRect() failed! level = " << n <<
" " << D3DERRORSTRING(hr);
1401 if (compression == Texture::CM_off) {
1404 pitch = min(pitch, (
int)rect.Pitch);
1405 int size = pitch * y_size;
1406 image = PTA_uchar::empty_array(size);
1407 if (pitch == rect.Pitch) {
1409 memcpy(image.p(), rect.pBits, size);
1413 unsigned char *dest = image.p();
1414 unsigned char *source = (
unsigned char *)rect.pBits;
1415 for (
int yi = 0; yi < y_size; ++yi) {
1416 memcpy(dest, source, pitch);
1418 source += rect.Pitch;
1424 int size = rect.Pitch * (y_size / div);
1425 image = PTA_uchar::empty_array(size);
1426 memcpy(image.p(), rect.pBits, size);
1429 _d3d_2d_texture->UnlockRect(n);
1448 bool inverted,
Texture *result,
int view,
int z) {
1458 nassertr((num_components == 3) || (num_components == 4), E_FAIL);
1459 nassertr(IS_VALID_PTR(d3d_surface), E_FAIL);
1463 nassertr(z < result->get_z_size(), E_FAIL);
1470 if (IsBadWritePtr(d3d_surface,
sizeof(DWORD))) {
1472 <<
"d3d_surface_to_texture failed: bad pD3DSurf ptr value ("
1473 << ((
void*)d3d_surface) <<
")\n";
1477 DWORD x_window_offset, y_window_offset;
1478 DWORD copy_width, copy_height;
1480 D3DLOCKED_RECT locked_rect;
1481 D3DSURFACE_DESC surface_desc;
1483 hr = d3d_surface->GetDesc(&surface_desc);
1485 x_window_offset = source_rect.left, y_window_offset = source_rect.top;
1486 copy_width = RECT_XSIZE(source_rect);
1487 copy_height = RECT_YSIZE(source_rect);
1494 <<
"d3d_surface_to_texture, Texture size (" << result->
get_x_size()
1496 <<
") too small to hold display surface ("
1497 << copy_width <<
", " << copy_height <<
")\n";
1498 nassertr(
false, E_FAIL);
1502 hr = d3d_surface->LockRect(&locked_rect,
nullptr, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE));
1505 <<
"d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
1510 nassertr((surface_desc.Format == D3DFMT_A8R8G8B8) ||
1511 (surface_desc.Format == D3DFMT_X8R8G8B8) ||
1512 (surface_desc.Format == D3DFMT_R8G8B8) ||
1513 (surface_desc.Format == D3DFMT_R5G6B5) ||
1514 (surface_desc.Format == D3DFMT_X1R5G5B5) ||
1515 (surface_desc.Format == D3DFMT_A1R5G5B5) ||
1516 (surface_desc.Format == D3DFMT_A4R4G4B4), E_FAIL);
1520 int byte_pitch = locked_rect.Pitch;
1521 BYTE *surface_bytes = (BYTE *)locked_rect.pBits;
1524 surface_bytes += byte_pitch * (y_window_offset + copy_height - 1);
1525 byte_pitch = -byte_pitch;
1527 surface_bytes += byte_pitch * y_window_offset;
1533 if (DEBUG_SURFACES && dxgsg9_cat.is_debug()) {
1535 <<
"d3d_surface_to_texture converting "
1536 << D3DFormatStr(surface_desc.Format)
1537 <<
" DDSurf to " << num_components <<
"-channel panda Texture\n";
1540 DWORD *dest_word = (DWORD *)buf;
1541 BYTE *dest_byte = (BYTE *)buf;
1543 switch(surface_desc.Format) {
1544 case D3DFMT_A8R8G8B8:
1545 case D3DFMT_X8R8G8B8: {
1546 if (num_components == 4) {
1548 BYTE *dest_line = (BYTE*)dest_word;
1550 for (DWORD y = 0; y < copy_height; y++) {
1551 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1552 memcpy(dest_line, source_word, byte_pitch);
1553 dest_line += byte_pitch;
1554 surface_bytes += byte_pitch;
1559 for (DWORD y = 0; y < copy_height; y++) {
1560 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1562 for (DWORD x = 0; x < copy_width; x++) {
1564 DWORD
pixel = *source_word;
1566 r = (BYTE)((
pixel>>16) & g_LowByteMask);
1567 g = (BYTE)((
pixel>> 8) & g_LowByteMask);
1568 b = (BYTE)((
pixel ) & g_LowByteMask);
1575 surface_bytes += byte_pitch;
1581 case D3DFMT_R8G8B8: {
1584 if (num_components == 4) {
1585 for (DWORD y = 0; y < copy_height; y++) {
1586 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1587 for (DWORD x = 0; x < copy_width; x++) {
1594 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1597 surface_bytes += byte_pitch;
1601 for (DWORD y = 0; y < copy_height; y++) {
1602 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1603 memcpy(dest_byte, source_byte, byte_pitch);
1604 dest_byte += byte_pitch;
1605 surface_bytes += byte_pitch;
1612 case D3DFMT_X1R5G5B5:
1613 case D3DFMT_A1R5G5B5:
1614 case D3DFMT_A4R4G4B4: {
1618 BYTE redshift, greenshift, blueshift;
1619 DWORD redmask, greenmask, bluemask;
1621 if (surface_desc.Format == D3DFMT_R5G6B5) {
1628 }
else if (surface_desc.Format == D3DFMT_A4R4G4B4) {
1644 if (num_components == 4) {
1651 for (DWORD y = 0; y < copy_height; y++) {
1652 source_word = ((WORD*)surface_bytes) + x_window_offset;
1653 for (DWORD x = 0; x < copy_width; x++) {
1654 WORD
pixel = *source_word;
1657 b = (
pixel & bluemask) << blueshift;
1658 g = (
pixel & greenmask) >> greenshift;
1659 r = (
pixel & redmask) >> redshift;
1663 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1667 surface_bytes += byte_pitch;
1671 for (DWORD y = 0; y < copy_height; y++) {
1672 source_word = ((WORD*)surface_bytes) + x_window_offset;
1673 for (DWORD x = 0; x < copy_width; x++) {
1674 WORD
pixel = *source_word;
1677 b = (
pixel & bluemask) << blueshift;
1678 g = (
pixel & greenmask) >> greenshift;
1679 r = (
pixel & redmask) >> redshift;
1687 surface_bytes += byte_pitch;
1695 <<
"d3d_surface_to_texture: unsupported D3DFORMAT!\n";
1698 d3d_surface->UnlockRect();
1707static UINT calculate_row_byte_length (
int width,
int num_color_channels, D3DFORMAT tex_format)
1709 UINT source_row_byte_length = 0;
1713 switch (tex_format) {
1719 source_row_byte_length = max(1,width / 4)*8;
1727 source_row_byte_length = max(1,width / 4)*16;
1731 source_row_byte_length = width*num_color_channels;
1734 return source_row_byte_length;
1742HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(
int mip_level,
int depth_index, D3DFORMAT source_format)
1746 IDirect3DSurface9 *mip_surface =
nullptr;
1747 bool using_temp_buffer =
false;
1748 HRESULT hr = E_FAIL;
1750 BYTE *pixels = (BYTE*) image.
p();
1757 vector_uchar clear_data;
1758 if (page_size > 0) {
1762 nassertr(!image.
is_null(), E_FAIL);
1763 pixels = (BYTE *)image.
p();
1765 view_size = image.size();
1767 pixels += page_size * depth_index;
1773 pixels = clear_data.data();
1774 view_size = clear_data.size();
1777 if (
get_texture()->get_texture_type() == Texture::TT_cube_map) {
1778 nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
1779 hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface);
1781 nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
1782 hr = _d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface);
1787 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1788 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
1793 source_size.left = source_size.top = 0;
1794 source_size.right = width;
1795 source_size.bottom = height;
1797 UINT source_row_byte_length = calculate_row_byte_length(width,
get_texture()->get_num_components(), source_format);
1802 mip_filter = D3DX_FILTER_LINEAR ;
1805 mip_filter |= D3DX_FILTER_SRGB;
1810 if (_d3d_format == D3DFMT_A8) {
1812 USHORT *temp_buffer =
new USHORT[width * height];
1813 if (!IS_VALID_PTR(temp_buffer)) {
1815 <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1816 goto exit_FillMipmapSurf;
1818 using_temp_buffer =
true;
1820 USHORT *out_pixels = temp_buffer;
1821 BYTE *source_pixels = pixels + component_width - 1;
1822 for (UINT y = 0; y < height; y++) {
1823 for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) {
1826 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
1830 source_format = D3DFMT_A8L8;
1831 source_row_byte_length = width *
sizeof(USHORT);
1832 pixels = (BYTE*)temp_buffer;
1834 else if (component_width != 1) {
1840 int num_pixels = width * height * num_components;
1841 BYTE *temp_buffer =
new BYTE[num_pixels];
1842 if (!IS_VALID_PTR(temp_buffer)) {
1843 dxgsg9_cat.error() <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1844 goto exit_FillMipmapSurf;
1846 using_temp_buffer =
true;
1848 BYTE *source_pixels = pixels + component_width - 1;
1849 for (
int i = 0; i < num_pixels; i++) {
1850 temp_buffer[i] = *source_pixels;
1851 source_pixels += component_width;
1853 pixels = (BYTE*)temp_buffer;
1858 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height);
1860 if (source_format == D3DFMT_ATI1 || source_format == D3DFMT_ATI2) {
1862 D3DLOCKED_RECT rect;
1863 _d3d_2d_texture->LockRect(mip_level, &rect, 0, D3DLOCK_DISCARD);
1865 unsigned char *dest = (
unsigned char *)rect.pBits;
1866 memcpy(dest, pixels, view_size);
1868 _d3d_2d_texture->UnlockRect(mip_level);
1871 hr = D3DXLoadSurfaceFromMemory
1872 (mip_surface,
nullptr,
nullptr, (LPCVOID)pixels,
1873 source_format, source_row_byte_length,
nullptr,
1874 &source_size, mip_filter, (D3DCOLOR)0x0);
1877 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1878 <<
", mip_level " << mip_level
1879 <<
", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
1884 if (using_temp_buffer) {
1885 SAFE_DELETE_ARRAY(pixels);
1888 RELEASE(mip_surface, dxgsg9,
"FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE);
1895HRESULT DXTextureContext9::
1896fill_d3d_texture_pixels(
DXScreenData &scrn,
bool compress_texture) {
1897 IDirect3DDevice9 *device = scrn._d3d_device;
1899 nassertr(IS_VALID_PTR(tex), E_FAIL);
1901 return fill_d3d_volume_texture_pixels(scrn);
1904 HRESULT hr = E_FAIL;
1907 Texture::CompressionMode image_compression = Texture::CM_off;
1908 if (compress_texture) {
1928 if (_d3d_2d_texture) {
1930 IDirect3DSurface9 *surface;
1932 result = _d3d_2d_texture -> GetSurfaceLevel (0, &surface);
1933 if (result == D3D_OK) {
1934 D3DSURFACE_DESC surface_description;
1936 if (surface -> GetDesc (&surface_description) == D3D_OK) {
1937 IDirect3DSurface9 *current_render_target;
1939 if (device -> GetRenderTarget (0, ¤t_render_target) == D3D_OK) {
1940 IDirect3DSurface9 *depth_stencil_surface;
1943 depth_stencil_surface = 0;
1944 if (device -> GetDepthStencilSurface (&depth_stencil_surface) == D3D_OK) {
1945 if (device -> SetDepthStencilSurface (
nullptr) == D3D_OK) {
1950 if (device -> SetRenderTarget (0, surface) == D3D_OK) {
1954 LColor scaled = tex->
get_clear_color().fmin(LColor(1)).fmax(LColor::zero());
1956 color = D3DCOLOR_RGBA((
int)scaled[0], (
int)scaled[1], (
int)scaled[2], (
int)scaled[3]);
1957 flags = D3DCLEAR_TARGET;
1958 if (device -> Clear (0,
nullptr, flags, color, 0.0f, 0) == D3D_OK) {
1963 if (depth_stencil_surface) {
1964 device -> SetDepthStencilSurface (depth_stencil_surface);
1965 depth_stencil_surface -> Release();
1969 device -> SetRenderTarget (0, current_render_target);
1970 current_render_target -> Release();
1974 surface -> Release();
1982 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
1984 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
1986 DWORD orig_depth = (DWORD) tex->
get_z_size();
1987 D3DFORMAT source_format = _d3d_format;
1990 switch (image_compression) {
1991 case Texture::CM_dxt1:
1992 source_format = D3DFMT_DXT1;
1994 case Texture::CM_dxt2:
1995 source_format = D3DFMT_DXT2;
1997 case Texture::CM_dxt3:
1998 source_format = D3DFMT_DXT3;
2000 case Texture::CM_dxt4:
2001 source_format = D3DFMT_DXT4;
2003 case Texture::CM_dxt5:
2004 source_format = D3DFMT_DXT5;
2006 case Texture::CM_rgtc:
2008 source_format = D3DFMT_ATI1;
2010 source_format = D3DFMT_ATI2;
2018 for (
unsigned int di = 0; di < orig_depth; di++) {
2021 hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
2029 int miplevel_count = _d3d_texture->GetLevelCount();
2030 if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) {
2032 <<
"Using pre-calculated mipmap levels for texture " << tex->get_name() <<
"\n";
2034 for (
int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
2035 hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
2044 if (_managed ==
false && scrn._supports_automatic_mipmap_generation) {
2051 hr = _d3d_texture -> SetAutoGenFilterType (D3DTEXF_LINEAR);
2053 dxgsg9_cat.error() <<
"SetAutoGenFilterType failed " << D3DERRORSTRING(hr);
2056 _d3d_texture -> GenerateMipSubLevels ( );
2060 DWORD mip_filter_flags;
2061 if (!dx_use_triangle_mipgen_filter) {
2062 mip_filter_flags = D3DX_FILTER_BOX;
2064 mip_filter_flags = D3DX_FILTER_TRIANGLE;
2068 mip_filter_flags |= D3DX_FILTER_SRGB;
2072 hr = D3DXFilterTexture(_d3d_texture,
nullptr, 0,
2077 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2078 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
2092HRESULT DXTextureContext9::
2095 HRESULT hr = E_FAIL;
2096 nassertr(IS_VALID_PTR(tex), E_FAIL);
2105 Texture::CompressionMode image_compression;
2107 image_compression = Texture::CM_off;
2114 image_compression = Texture::CM_off;
2123 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
2125 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
2128 DWORD orig_width = (DWORD) tex->
get_x_size();
2129 DWORD orig_height = (DWORD) tex->
get_y_size();
2130 DWORD orig_depth = (DWORD) tex->
get_z_size();
2132 D3DFORMAT source_format = _d3d_format;
2133 BYTE *image_pixels = (BYTE*)image.
p();
2136 nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
2139 image_pixels += view_size *
get_view();
2141 IDirect3DVolume9 *mip_level_0 =
nullptr;
2142 bool using_temp_buffer =
false;
2143 BYTE *pixels = image_pixels;
2145 nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL);
2146 hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0);
2150 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2151 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
2156 source_size.Left = source_size.Top = source_size.Front = 0;
2157 source_size.Right = orig_width;
2158 source_size.Bottom = orig_height;
2159 source_size.Back = orig_depth;
2161 UINT source_row_byte_length = orig_width * num_color_channels;
2162 UINT source_page_byte_length = orig_height * source_row_byte_length;
2164 DWORD level_0_filter, mip_filter_flags;
2165 using_temp_buffer =
false;
2169 level_0_filter = D3DX_FILTER_LINEAR ;
2172 level_0_filter |= D3DX_FILTER_SRGB;
2177 if (_d3d_format == D3DFMT_A8) {
2179 USHORT *temp_buffer =
new USHORT[orig_width * orig_height * orig_depth];
2180 if (!IS_VALID_PTR(temp_buffer)) {
2182 <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2183 goto exit_FillDDSurf;
2185 using_temp_buffer =
true;
2187 USHORT *out_pixels = temp_buffer;
2188 BYTE *source_pixels = pixels + component_width - 1;
2189 for (UINT z = 0; z < orig_depth; z++) {
2190 for (UINT y = 0; y < orig_height; y++) {
2193 x++, source_pixels += component_width, out_pixels++) {
2197 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
2202 source_format = D3DFMT_A8L8;
2203 source_row_byte_length = orig_width *
sizeof(USHORT);
2204 source_page_byte_length = orig_height * source_row_byte_length;
2205 pixels = (BYTE*)temp_buffer;
2207 }
else if (component_width != 1) {
2213 int num_pixels = orig_width * orig_height * orig_depth * num_components;
2214 BYTE *temp_buffer =
new BYTE[num_pixels];
2215 if (!IS_VALID_PTR(temp_buffer)) {
2216 dxgsg9_cat.error() <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2217 goto exit_FillDDSurf;
2219 using_temp_buffer =
true;
2221 BYTE *source_pixels = pixels + component_width - 1;
2222 for (
int i = 0; i < num_pixels; i++) {
2223 temp_buffer[i] = *source_pixels;
2224 source_pixels += component_width;
2226 pixels = (BYTE*)temp_buffer;
2232 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth);
2234 hr = D3DXLoadVolumeFromMemory
2235 (mip_level_0,
nullptr,
nullptr, (LPCVOID)pixels,
2236 source_format, source_row_byte_length, source_page_byte_length,
2238 &source_size, level_0_filter, (D3DCOLOR)0x0);
2241 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2242 <<
", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
2243 goto exit_FillDDSurf;
2247 if (!dx_use_triangle_mipgen_filter) {
2248 mip_filter_flags = D3DX_FILTER_BOX;
2250 mip_filter_flags = D3DX_FILTER_TRIANGLE;
2254 mip_filter_flags |= D3DX_FILTER_SRGB;
2259 hr = D3DXFilterTexture(_d3d_texture,
nullptr, 0,
2263 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2264 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
2265 goto exit_FillDDSurf;
2270 if (using_temp_buffer) {
2271 SAFE_DELETE_ARRAY(pixels);
2273 RELEASE(mip_level_0, dxgsg9,
"FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
2281int DXTextureContext9::
2282down_to_power_2(
int value) {
2284 while ((x << 1) <= value) {
2295unsigned int DXTextureContext9::
2296get_bits_per_pixel(Texture::Format format,
int *alphbits) {
2299 case Texture::F_alpha:
2301 case Texture::F_color_index:
2302 case Texture::F_red:
2303 case Texture::F_green:
2304 case Texture::F_blue:
2305 case Texture::F_rgb332:
2307 case Texture::F_luminance_alphamask:
2310 case Texture::F_luminance_alpha:
2313 case Texture::F_luminance:
2315 case Texture::F_rgba4:
2318 case Texture::F_rgba5:
2321 case Texture::F_depth_component:
2322 case Texture::F_depth_component16:
2324 case Texture::F_depth_stencil:
2325 case Texture::F_depth_component24:
2327 case Texture::F_depth_component32:
2329 case Texture::F_rgb5:
2331 case Texture::F_rgb8:
2332 case Texture::F_rgb:
2334 case Texture::F_rgba8:
2335 case Texture::F_rgba:
2338 case Texture::F_rgbm:
2341 case Texture::F_rgb12:
2343 case Texture::F_rgba12:
2346 case Texture::F_rgba16:
2349 case Texture::F_rgba32:
2353 case Texture::F_srgb:
2355 case Texture::F_srgb_alpha:
2358 case Texture::F_sluminance:
2360 case Texture::F_sluminance_alpha:
2370PN_stdfloat DXTextureContext9::
2371d3d_format_to_bytes_per_pixel (D3DFORMAT format)
2373 PN_stdfloat bytes_per_pixel;
2375 bytes_per_pixel = 0.0f;
2384 bytes_per_pixel = 1.0f;
2391 case D3DFMT_X1R5G5B5:
2392 case D3DFMT_A1R5G5B5:
2393 case D3DFMT_A4R4G4B4:
2396 case D3DFMT_A8R3G3B2:
2397 case D3DFMT_X4R4G4B4:
2399 case (D3DFORMAT)MAKEFOURCC(
'D',
'F',
'1',
'6'):
2400 bytes_per_pixel = 2.0f;
2404 bytes_per_pixel = 3.0f;
2407 case D3DFMT_G16R16F:
2408 case D3DFMT_Q8W8V8U8:
2411 case D3DFMT_A8R8G8B8:
2412 case D3DFMT_X8R8G8B8:
2413 case D3DFMT_A2B10G10R10:
2414 case D3DFMT_A8B8G8R8:
2415 case D3DFMT_X8B8G8R8:
2417 case D3DFMT_A2R10G10B10:
2421 case (D3DFORMAT)MAKEFOURCC(
'D',
'F',
'2',
'4'):
2423 bytes_per_pixel = 4.0f;
2426 case D3DFMT_G32R32F:
2427 case D3DFMT_A16B16G16R16F:
2428 case D3DFMT_Q16W16V16U16:
2429 case D3DFMT_A16B16G16R16:
2430 bytes_per_pixel = 8.0f;
2433 case D3DFMT_A32B32G32R32F:
2434 bytes_per_pixel = 16.0f;
2439 bytes_per_pixel = 0.5f;
2446 bytes_per_pixel = 1.0f;
2450 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.
bool compress_ram_image(CompressionMode compression=CM_on, QualityLevel quality_level=QL_default, GraphicsStateGuardianBase *gsg=nullptr)
Attempts to compress the texture's RAM image internally, to a format supported by the indicated GSG.
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.