mirror of
https://github.com/panda3d/panda3d.git
synced 2026-05-12 17:48:49 -05:00
dxgsg9: Fix some format handling, support for r32f and rgba32f textures
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user