diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index b4e2834a00..12630ca030 100644 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -5249,7 +5249,7 @@ FrameBufferProperties DXGraphicsStateGuardian9:: calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype, DWORD multisamplequality) { FrameBufferProperties props; - int index=0; + int index=0, isfloat=0; int r=0, g=0, b=0, a=0; switch (cformat) { case D3DFMT_R8G8B8: r=8; g=8; b=8; a=0; break; @@ -5263,10 +5263,19 @@ calc_fb_properties(DWORD cformat, DWORD dformat, case D3DFMT_A8R3G3B2: r=3; g=3; b=2; a=8; break; case D3DFMT_X4R4G4B4: r=4; g=4; b=4; a=0; break; case D3DFMT_A2B10G10R10: r=10;g=10;b=10;a=2; break; + case D3DFMT_R16F: r=16; isfloat=1; break; + case D3DFMT_G16R16F: r=16; isfloat=1; break; + case D3DFMT_A16B16G16R16F:r=16; g=16; b=16; a=16; isfloat=1; break; + case D3DFMT_R32F: r=32; isfloat=1; break; + case D3DFMT_G32R32F: r=32; isfloat=1; break; + case D3DFMT_A32B32G32R32F:r=32; g=32; b=32; a=32; isfloat=1; break; case D3DFMT_A8P8: index=8; a=8; break; case D3DFMT_P8: index=8; a=0; break; default: break; } + if (isfloat > 0) { + props.set_float_color(true); + } if (index > 0) { props.set_rgb_color(0); props.set_indexed_color(1); diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index 3ad37466f4..5aa07920b1 100644 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -234,6 +234,8 @@ create_texture(DXScreenData &scrn) { case 1: if (num_alpha_bits > 0) { _d3d_format = D3DFMT_A8; + } else if (tex->get_component_type() == Texture::T_float) { + _d3d_format = D3DFMT_R32F; } else { _d3d_format = D3DFMT_L8; } @@ -245,7 +247,11 @@ create_texture(DXScreenData &scrn) { _d3d_format = D3DFMT_R8G8B8; break; case 4: - _d3d_format = D3DFMT_A8R8G8B8; + if (tex->get_component_type() == Texture::T_float) { + _d3d_format = D3DFMT_A32B32G32R32F; + } else { + _d3d_format = D3DFMT_A8R8G8B8; + } break; } @@ -502,6 +508,13 @@ create_texture(DXScreenData &scrn) { break; } + if (num_color_channels == 1) { + CHECK_FOR_FMT(R32F); + CHECK_FOR_FMT(X8R8G8B8); + CHECK_FOR_FMT(R8G8B8); + break; + } + if (!((num_color_channels == 3) || (num_color_channels == 4))) break; //bail @@ -667,22 +680,7 @@ create_texture(DXScreenData &scrn) { } } case 8: - if (needs_luminance) { - // don't bother handling those other 8bit lum fmts like 4-4, since 16 - // 8-8 is usually supported too - nassertr(num_color_channels == 1, false); - - // look for native lum fmt first - CHECK_FOR_FMT(L8); - CHECK_FOR_FMT(L8); - - CHECK_FOR_FMT(R8G8B8); - CHECK_FOR_FMT(X8R8G8B8); - - CHECK_FOR_FMT(R5G6B5); - CHECK_FOR_FMT(X1R5G5B5); - - } else if (num_alpha_bits == 8) { + if (num_alpha_bits == 8) { // look for 16bpp A8L8, else 32-bit ARGB, else 16-4444. // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo @@ -693,6 +691,21 @@ create_texture(DXScreenData &scrn) { CHECK_FOR_FMT(A8L8); CHECK_FOR_FMT(A8R8G8B8); CHECK_FOR_FMT(A4R4G4B4); + } else { + if (needs_luminance) { + // don't bother handling those other 8bit lum fmts like 4-4, since 16 + // 8-8 is usually supported too + nassertr(num_color_channels == 1, false); + + // look for native lum fmt first + CHECK_FOR_FMT(L8); + } + + CHECK_FOR_FMT(R8G8B8); + CHECK_FOR_FMT(X8R8G8B8); + + CHECK_FOR_FMT(R5G6B5); + CHECK_FOR_FMT(X1R5G5B5); } break; @@ -1831,7 +1844,28 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep source_row_byte_length = width * sizeof(USHORT); pixels = (BYTE*)temp_buffer; } - else if (component_width != 1) { + else if (_d3d_format == D3DFMT_A32B32G32R32F && source_format == D3DFMT_A32B32G32R32F) { + size_t total_components = (size_t)width * (size_t)height * 4; + float *temp_buffer = new float[total_components]; + if (!IS_VALID_PTR(temp_buffer)) { + dxgsg9_cat.error() + << "FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n"; + goto exit_FillMipmapSurf; + } + using_temp_buffer = true; + + // Swap red and blue components. + float *out_pixels = (float *)temp_buffer; + const float *source_pixels = (const float *)pixels; + for (size_t i = 0; i < total_components; i += 4) { + out_pixels[i] = source_pixels[i + 2]; + out_pixels[i + 1] = source_pixels[i + 1]; + out_pixels[i + 2] = source_pixels[i + 0]; + out_pixels[i + 3] = source_pixels[i + 3]; + } + pixels = (BYTE*)temp_buffer; + } + else if (component_width != 1 && _d3d_format != D3DFMT_R32F) { // Convert from 16-bit per channel (or larger) format down to 8-bit per // channel. This throws away precision in the original image, but dx8 // doesn't support high-precision images anyway. @@ -2203,8 +2237,29 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) { source_row_byte_length = orig_width * sizeof(USHORT); source_page_byte_length = orig_height * source_row_byte_length; pixels = (BYTE*)temp_buffer; + } + else if (_d3d_format == D3DFMT_A32B32G32R32F && source_format == D3DFMT_A32B32G32R32F) { + size_t total_components = (size_t)orig_width * (size_t)orig_height * (size_t)orig_depth * 4; + float *temp_buffer = new float[total_components]; + if (!IS_VALID_PTR(temp_buffer)) { + dxgsg9_cat.error() + << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n"; + goto exit_FillDDSurf; + } + using_temp_buffer = true; - } else if (component_width != 1) { + // Swap red and blue components. + float *out_pixels = (float *)temp_buffer; + const float *source_pixels = (const float *)pixels; + for (size_t i = 0; i < total_components; i += 4) { + out_pixels[i] = source_pixels[i + 2]; + out_pixels[i + 1] = source_pixels[i + 1]; + out_pixels[i + 2] = source_pixels[i + 0]; + out_pixels[i + 3] = source_pixels[i + 3]; + } + pixels = (BYTE*)temp_buffer; + } + else if (component_width != 1 && _d3d_format != D3DFMT_R32F) { // Convert from 16-bit per channel (or larger) format down to 8-bit per // channel. This throws away precision in the original image, but dx8 // doesn't support high-precision images anyway. @@ -2350,6 +2405,9 @@ get_bits_per_pixel(Texture::Format format, int *alphbits) { *alphbits = 32; return 128; + case Texture::F_r32: + return 32; + case Texture::F_srgb: return 24; case Texture::F_srgb_alpha: diff --git a/panda/src/dxgsg9/dxgsg9base.h b/panda/src/dxgsg9/dxgsg9base.h index 430876dff5..3b77b8b386 100644 --- a/panda/src/dxgsg9/dxgsg9base.h +++ b/panda/src/dxgsg9/dxgsg9base.h @@ -169,7 +169,7 @@ typedef enum { D24S8_FLAG = FLG(20), D32_FLAG = FLG(21), INTZ_FLAG = FLG(22), - W11V11U10_FLAG = FLG(23), + R32F_FLAG = FLG(23), A2W10V10U10_FLAG = FLG(24), ATI1_FLAG = FLG(25), ATI2_FLAG = FLG(26), diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 8cb8b9782f..834250f0ee 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -862,7 +862,7 @@ void Init_D3DFORMAT_map() { INSERT_ELEM(D24S8); INSERT_ELEM(D32); INSERT_ELEM(INTZ); -// NOT IN DX9 INSERT_ELEM(W11V11U10); + INSERT_ELEM(R32F); INSERT_ELEM(A2W10V10U10); INSERT_ELEM(ATI1); INSERT_ELEM(ATI2); @@ -923,7 +923,11 @@ const char *D3DFormatStr(D3DFORMAT fmt) { CASESTR(D3DFMT_VERTEXDATA); CASESTR(D3DFMT_INDEX16); CASESTR(D3DFMT_INDEX32); + CASESTR(D3DFMT_R16F); + CASESTR(D3DFMT_G16R16F); CASESTR(D3DFMT_A16B16G16R16F); + CASESTR(D3DFMT_R32F); + CASESTR(D3DFMT_G32R32F); CASESTR(D3DFMT_A32B32G32R32F); }