|
@@ -119,6 +119,8 @@ create_texture(DXScreenData &scrn) {
|
|
|
int num_alpha_bits; // number of alpha bits in texture pixfmt
|
|
int num_alpha_bits; // number of alpha bits in texture pixfmt
|
|
|
D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
|
|
D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
|
|
|
bool needs_luminance = false;
|
|
bool needs_luminance = false;
|
|
|
|
|
+ bool needs_depth = false;
|
|
|
|
|
+ bool needs_stencil = false;
|
|
|
bool compress_texture = false;
|
|
bool compress_texture = false;
|
|
|
|
|
|
|
|
Texture *tex = get_texture();
|
|
Texture *tex = get_texture();
|
|
@@ -190,53 +192,75 @@ create_texture(DXScreenData &scrn) {
|
|
|
DWORD target_bpp = get_bits_per_pixel(tex->get_format(), &num_alpha_bits);
|
|
DWORD target_bpp = get_bits_per_pixel(tex->get_format(), &num_alpha_bits);
|
|
|
DWORD num_color_channels = tex->get_num_components();
|
|
DWORD num_color_channels = tex->get_num_components();
|
|
|
|
|
|
|
|
-// printf ("format = %d \n", tex->get_format());
|
|
|
|
|
-// printf ("target_bpp %d, num_color_channels %d num_alpha_bits %d \n", target_bpp, num_color_channels, num_alpha_bits);
|
|
|
|
|
|
|
+ // figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
|
|
|
|
|
+ switch (tex->get_format()) {
|
|
|
|
|
+ case Texture::F_depth_stencil:
|
|
|
|
|
+ _d3d_format = D3DFMT_D24S8;
|
|
|
|
|
+ needs_depth = true;
|
|
|
|
|
+ needs_stencil = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- //PRINT_REFCNT(dxgsg9, scrn._d3d9);
|
|
|
|
|
|
|
+ case Texture::F_depth_component:
|
|
|
|
|
+ case Texture::F_depth_component16:
|
|
|
|
|
+ _d3d_format = D3DFMT_D16;
|
|
|
|
|
+ needs_depth = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- if ((tex->get_format() == Texture::F_luminance_alpha)||
|
|
|
|
|
- (tex->get_format() == Texture::F_luminance_alphamask) ||
|
|
|
|
|
- (tex->get_format() == Texture::F_luminance) ||
|
|
|
|
|
- (tex->get_format() == Texture::F_sluminance_alpha) ||
|
|
|
|
|
- (tex->get_format() == Texture::F_sluminance)) {
|
|
|
|
|
- needs_luminance = true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case Texture::F_depth_component24:
|
|
|
|
|
+ _d3d_format = D3DFMT_D24X8;
|
|
|
|
|
+ needs_depth = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- if (num_alpha_bits > 0) {
|
|
|
|
|
- if (num_color_channels == 3) {
|
|
|
|
|
- dxgsg9_cat.error()
|
|
|
|
|
- << "texture " << tex->get_name()
|
|
|
|
|
- << " has no inherent alpha channel, but alpha format is requested!\n";
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case Texture::F_depth_component32:
|
|
|
|
|
+ _d3d_format = D3DFMT_D32;
|
|
|
|
|
+ needs_depth = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- _d3d_format = D3DFMT_UNKNOWN;
|
|
|
|
|
|
|
+ case Texture::F_luminance:
|
|
|
|
|
+ case Texture::F_sluminance:
|
|
|
|
|
+ _d3d_format = D3DFMT_L8;
|
|
|
|
|
+ needs_luminance = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- // figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
|
|
|
|
|
|
|
+ case Texture::F_luminance_alpha:
|
|
|
|
|
+ case Texture::F_luminance_alphamask:
|
|
|
|
|
+ case Texture::F_sluminance_alpha:
|
|
|
|
|
+ _d3d_format = D3DFMT_A8L8;
|
|
|
|
|
+ needs_luminance = true;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
- switch (num_color_channels) {
|
|
|
|
|
- case 1:
|
|
|
|
|
|
|
+ default:
|
|
|
if (num_alpha_bits > 0) {
|
|
if (num_alpha_bits > 0) {
|
|
|
- _d3d_format = D3DFMT_A8;
|
|
|
|
|
- } else if (needs_luminance) {
|
|
|
|
|
- _d3d_format = D3DFMT_L8;
|
|
|
|
|
|
|
+ if (num_color_channels == 3) {
|
|
|
|
|
+ dxgsg9_cat.error()
|
|
|
|
|
+ << "texture " << tex->get_name()
|
|
|
|
|
+ << " has no inherent alpha channel, but alpha format is requested!\n";
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- break;
|
|
|
|
|
- case 2:
|
|
|
|
|
- nassertr(needs_luminance && (num_alpha_bits > 0), false);
|
|
|
|
|
- _d3d_format = D3DFMT_A8L8;
|
|
|
|
|
- break;
|
|
|
|
|
- case 3:
|
|
|
|
|
- _d3d_format = D3DFMT_R8G8B8;
|
|
|
|
|
- break;
|
|
|
|
|
- case 4:
|
|
|
|
|
- _d3d_format = D3DFMT_A8R8G8B8;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // make sure we handled all the possible cases
|
|
|
|
|
- nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
|
|
|
|
|
|
|
+ _d3d_format = D3DFMT_UNKNOWN;
|
|
|
|
|
+
|
|
|
|
|
+ switch (num_color_channels) {
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ if (num_alpha_bits > 0) {
|
|
|
|
|
+ _d3d_format = D3DFMT_A8;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ nassertr(false && (num_alpha_bits > 0), false);
|
|
|
|
|
+ _d3d_format = D3DFMT_A8L8;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ _d3d_format = D3DFMT_R8G8B8;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ _d3d_format = D3DFMT_A8R8G8B8;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // make sure we handled all the possible cases
|
|
|
|
|
+ nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
DWORD target_width = orig_width;
|
|
DWORD target_width = orig_width;
|
|
|
DWORD target_height = orig_height;
|
|
DWORD target_height = orig_height;
|
|
@@ -447,6 +471,14 @@ create_texture(DXScreenData &scrn) {
|
|
|
goto found_matching_format;
|
|
goto found_matching_format;
|
|
|
|
|
|
|
|
case 32:
|
|
case 32:
|
|
|
|
|
+ if (needs_depth) {
|
|
|
|
|
+ nassertr(num_alpha_bits == 0, false);
|
|
|
|
|
+ nassertr(num_color_channels == 1, false);
|
|
|
|
|
+
|
|
|
|
|
+ CHECK_FOR_FMT(D32);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!((num_color_channels == 3) || (num_color_channels == 4)))
|
|
if (!((num_color_channels == 3) || (num_color_channels == 4)))
|
|
|
break; //bail
|
|
break; //bail
|
|
|
|
|
|
|
@@ -494,25 +526,78 @@ create_texture(DXScreenData &scrn) {
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case 24:
|
|
case 24:
|
|
|
- nassertr(num_color_channels == 3, false);
|
|
|
|
|
|
|
+ if (needs_depth) {
|
|
|
|
|
+ nassertr(num_alpha_bits == 0, false);
|
|
|
|
|
+ nassertr(num_color_channels == 1, false);
|
|
|
|
|
|
|
|
- CHECK_FOR_FMT(R8G8B8);
|
|
|
|
|
|
|
+ // In DirectX 9, all built-in depth formats use shadow map filtering.
|
|
|
|
|
+ // Some drivers (GeForce 8000+, Radeon HD 4000+, Intel G45+) expose a
|
|
|
|
|
+ // FourCC format called "INTZ" that allows access to the actual depth.
|
|
|
|
|
+ if (tex->get_minfilter() == Texture::FT_shadow) {
|
|
|
|
|
+ if (needs_stencil) {
|
|
|
|
|
+ CHECK_FOR_FMT(D24S8);
|
|
|
|
|
+ }
|
|
|
|
|
+ CHECK_FOR_FMT(D24X8);
|
|
|
|
|
+ CHECK_FOR_FMT(D32);
|
|
|
|
|
+ CHECK_FOR_FMT(D16);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
|
|
|
|
|
+ target_pixel_format = (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z');
|
|
|
|
|
+ goto found_matching_format;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // no 24-bit fmt. look for 32 bit fmt (note: this is
|
|
|
|
|
- // memory-hogging choice instead I could look for
|
|
|
|
|
- // memory-conserving 16-bit fmt).
|
|
|
|
|
|
|
+ // We fall back to a depth format. Chances are that it is going to
|
|
|
|
|
+ // be used for shadow mapping, in which case the depth comparison
|
|
|
|
|
+ // will probably still result in a useful value.
|
|
|
|
|
+ CHECK_FOR_FMT(D24X8);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ nassertr(num_color_channels == 3, false);
|
|
|
|
|
|
|
|
- CHECK_FOR_FMT(X8R8G8B8);
|
|
|
|
|
- CHECK_FOR_FMT(A8R8G8B8);
|
|
|
|
|
|
|
+ CHECK_FOR_FMT(R8G8B8);
|
|
|
|
|
+
|
|
|
|
|
+ // no 24-bit fmt. look for 32 bit fmt (note: this is
|
|
|
|
|
+ // memory-hogging choice instead I could look for
|
|
|
|
|
+ // memory-conserving 16-bit fmt).
|
|
|
|
|
+
|
|
|
|
|
+ CHECK_FOR_FMT(X8R8G8B8);
|
|
|
|
|
+ CHECK_FOR_FMT(A8R8G8B8);
|
|
|
|
|
|
|
|
- // no 24-bit or 32 fmt. look for 16 bit fmt (higher res 565 1st)
|
|
|
|
|
- CHECK_FOR_FMT(R5G6B5);
|
|
|
|
|
- CHECK_FOR_FMT(X1R5G5B5);
|
|
|
|
|
- CHECK_FOR_FMT(A1R5G5B5);
|
|
|
|
|
|
|
+ // no 24-bit or 32 fmt. look for 16 bit fmt (higher res 565 1st)
|
|
|
|
|
+ CHECK_FOR_FMT(R5G6B5);
|
|
|
|
|
+ CHECK_FOR_FMT(X1R5G5B5);
|
|
|
|
|
+ CHECK_FOR_FMT(A1R5G5B5);
|
|
|
|
|
+ }
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case 16:
|
|
case 16:
|
|
|
- if (needs_luminance) {
|
|
|
|
|
|
|
+ if (needs_depth) {
|
|
|
|
|
+ nassertr(num_alpha_bits == 0, false);
|
|
|
|
|
+ nassertr(num_color_channels == 1, false);
|
|
|
|
|
+
|
|
|
|
|
+ // In DirectX 9, all built-in depth formats use shadow map filtering.
|
|
|
|
|
+ // Some drivers (GeForce 8000+, Radeon HD 4000+, Intel G45+) expose a
|
|
|
|
|
+ // FourCC format called "INTZ" that allows access to the actual depth.
|
|
|
|
|
+ if (tex->get_minfilter() == Texture::FT_shadow) {
|
|
|
|
|
+ if (needs_stencil) {
|
|
|
|
|
+ CHECK_FOR_FMT(D24S8);
|
|
|
|
|
+ }
|
|
|
|
|
+ CHECK_FOR_FMT(D16);
|
|
|
|
|
+ CHECK_FOR_FMT(D24X8);
|
|
|
|
|
+ CHECK_FOR_FMT(D32);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
|
|
|
|
|
+ target_pixel_format = (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z');
|
|
|
|
|
+ goto found_matching_format;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // We fall back to a depth format. Chances are that it is going to
|
|
|
|
|
+ // be used for shadow mapping, in which case the depth comparison
|
|
|
|
|
+ // will probably still result in a useful value.
|
|
|
|
|
+ CHECK_FOR_FMT(D24X8);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else if (needs_luminance) {
|
|
|
nassertr(num_alpha_bits > 0, false);
|
|
nassertr(num_alpha_bits > 0, false);
|
|
|
nassertr(num_color_channels == 2, false);
|
|
nassertr(num_color_channels == 2, false);
|
|
|
|
|
|
|
@@ -613,11 +698,13 @@ create_texture(DXScreenData &scrn) {
|
|
|
// Instead of creating a texture with the found format, we will
|
|
// Instead of creating a texture with the found format, we will
|
|
|
// need to make one that exactly matches the framebuffer's
|
|
// need to make one that exactly matches the framebuffer's
|
|
|
// format. Look up what that format is.
|
|
// format. Look up what that format is.
|
|
|
- DWORD render_target_index;
|
|
|
|
|
IDirect3DSurface9 *render_target;
|
|
IDirect3DSurface9 *render_target;
|
|
|
|
|
|
|
|
- render_target_index = 0;
|
|
|
|
|
- hr = scrn._d3d_device->GetRenderTarget(render_target_index, &render_target);
|
|
|
|
|
|
|
+ if (needs_depth) {
|
|
|
|
|
+ hr = scrn._d3d_device->GetDepthStencilSurface(&render_target);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ hr = scrn._d3d_device->GetRenderTarget(0, &render_target);
|
|
|
|
|
+ }
|
|
|
if (FAILED(hr)) {
|
|
if (FAILED(hr)) {
|
|
|
dxgsg9_cat.error()
|
|
dxgsg9_cat.error()
|
|
|
<< "GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
|
|
<< "GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
|
|
@@ -628,7 +715,8 @@ create_texture(DXScreenData &scrn) {
|
|
|
dxgsg9_cat.error()
|
|
dxgsg9_cat.error()
|
|
|
<< "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
|
|
<< "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
|
|
|
} else {
|
|
} else {
|
|
|
- if (target_pixel_format != surface_desc.Format) {
|
|
|
|
|
|
|
+ if (target_pixel_format != surface_desc.Format &&
|
|
|
|
|
+ target_pixel_format != MAKEFOURCC('I', 'N', 'T', 'Z')) {
|
|
|
if (dxgsg9_cat.is_debug()) {
|
|
if (dxgsg9_cat.is_debug()) {
|
|
|
dxgsg9_cat.debug()
|
|
dxgsg9_cat.debug()
|
|
|
<< "Chose format " << D3DFormatStr(surface_desc.Format)
|
|
<< "Chose format " << D3DFormatStr(surface_desc.Format)
|
|
@@ -786,10 +874,14 @@ create_texture(DXScreenData &scrn) {
|
|
|
_is_render_target = true;
|
|
_is_render_target = true;
|
|
|
|
|
|
|
|
pool = D3DPOOL_DEFAULT;
|
|
pool = D3DPOOL_DEFAULT;
|
|
|
- usage = D3DUSAGE_RENDERTARGET;
|
|
|
|
|
- if (target_bpp <= 32 ) {
|
|
|
|
|
- target_pixel_format = scrn._render_to_texture_d3d_format;
|
|
|
|
|
|
|
+ if (needs_depth) {
|
|
|
|
|
+ usage = D3DUSAGE_DEPTHSTENCIL;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ usage = D3DUSAGE_RENDERTARGET;
|
|
|
}
|
|
}
|
|
|
|
|
+ //if (target_bpp <= 32) {
|
|
|
|
|
+ // target_pixel_format = scrn._render_to_texture_d3d_format;
|
|
|
|
|
+ //}
|
|
|
|
|
|
|
|
dxgsg9_cat.debug ()
|
|
dxgsg9_cat.debug ()
|
|
|
<< "*** RENDER TO TEXTURE ***: format "
|
|
<< "*** RENDER TO TEXTURE ***: format "
|
|
@@ -1126,6 +1218,22 @@ extract_texture_data(DXScreenData &screen) {
|
|
|
format = Texture::F_luminance_alpha;
|
|
format = Texture::F_luminance_alpha;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case D3DFMT_D24S8:
|
|
|
|
|
+ format = Texture::F_depth_stencil;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case D3DFMT_D16:
|
|
|
|
|
+ format = Texture::F_depth_component16;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case D3DFMT_D24X8:
|
|
|
|
|
+ format = Texture::F_depth_component24;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case D3DFMT_D32:
|
|
|
|
|
+ format = Texture::F_depth_component32;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
case D3DFMT_DXT1:
|
|
case D3DFMT_DXT1:
|
|
|
compression = Texture::CM_dxt1;
|
|
compression = Texture::CM_dxt1;
|
|
|
div = 4;
|
|
div = 4;
|
|
@@ -2159,8 +2267,12 @@ get_bits_per_pixel(Texture::Format format, int *alphbits) {
|
|
|
*alphbits = 1;
|
|
*alphbits = 1;
|
|
|
return 16;
|
|
return 16;
|
|
|
case Texture::F_depth_component:
|
|
case Texture::F_depth_component:
|
|
|
|
|
+ case Texture::F_depth_component16:
|
|
|
return 16;
|
|
return 16;
|
|
|
case Texture::F_depth_stencil:
|
|
case Texture::F_depth_stencil:
|
|
|
|
|
+ case Texture::F_depth_component24:
|
|
|
|
|
+ return 24;
|
|
|
|
|
+ case Texture::F_depth_component32:
|
|
|
return 32;
|
|
return 32;
|
|
|
case Texture::F_rgb5:
|
|
case Texture::F_rgb5:
|
|
|
return 16;
|
|
return 16;
|
|
@@ -2233,6 +2345,8 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
|
|
|
case D3DFMT_A8L8:
|
|
case D3DFMT_A8L8:
|
|
|
case D3DFMT_A8R3G3B2:
|
|
case D3DFMT_A8R3G3B2:
|
|
|
case D3DFMT_X4R4G4B4:
|
|
case D3DFMT_X4R4G4B4:
|
|
|
|
|
+ case D3DFMT_D16:
|
|
|
|
|
+ case (D3DFORMAT)MAKEFOURCC('D', 'F', '1', '6'):
|
|
|
bytes_per_pixel = 2.0f;
|
|
bytes_per_pixel = 2.0f;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
@@ -2251,6 +2365,11 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
|
|
|
case D3DFMT_X8B8G8R8:
|
|
case D3DFMT_X8B8G8R8:
|
|
|
case D3DFMT_G16R16:
|
|
case D3DFMT_G16R16:
|
|
|
case D3DFMT_A2R10G10B10:
|
|
case D3DFMT_A2R10G10B10:
|
|
|
|
|
+ case D3DFMT_D24X8:
|
|
|
|
|
+ case D3DFMT_D24S8:
|
|
|
|
|
+ case D3DFMT_D32:
|
|
|
|
|
+ case (D3DFORMAT)MAKEFOURCC('D', 'F', '2', '4'):
|
|
|
|
|
+ case (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'):
|
|
|
bytes_per_pixel = 4.0f;
|
|
bytes_per_pixel = 4.0f;
|
|
|
break;
|
|
break;
|
|
|
|
|
|