async texture loading support for dx8,9

This commit is contained in:
David Rose 2008-08-14 00:25:34 +00:00
parent f6b0191067
commit 93cef9c3bf
8 changed files with 265 additions and 38 deletions

View File

@ -160,7 +160,9 @@ prepare_texture(Texture *tex) {
return NULL;
}
if (!dtc->create_texture(*_screen)) {
if (!upload_texture(dtc)) {
dxgsg8_cat.error()
<< "Unable to create texture " << *tex << endl;
delete dtc;
return NULL;
}
@ -186,28 +188,21 @@ apply_texture(int i, TextureContext *tc) {
tc->set_active(true);
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
Texture *tex = tc->get_texture();
// If the texture image has changed, or if its use of mipmaps has
// changed, we need to re-create the image.
if (dtc->was_modified()) {
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
dxgsg8_cat.error()
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
return;
}
if (!dtc->create_texture(*_screen)) {
if (!upload_texture(dtc)) {
// Oops, we can't re-create the texture for some reason.
dxgsg8_cat.error()
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
<< "Unable to re-create texture " << *tex << endl;
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
return;
}
}
Texture *tex = tc->get_texture();
Texture::WrapMode wrap_u, wrap_v, wrap_w;
wrap_u = tex->get_wrap_u();
wrap_v = tex->get_wrap_v();
@ -249,16 +244,10 @@ apply_texture(int i, TextureContext *tc) {
new_mip_filter = D3DTEXF_NONE;
}
#ifndef NDEBUG
// sanity check
if ((!dtc->has_mipmaps()) && (new_mip_filter != D3DTEXF_NONE)) {
dxgsg8_cat.error()
<< "Trying to set mipmap filtering for texture with no generated mipmaps!! texname["
<< tex->get_name() << "], filter("
<< tex->get_minfilter() << ")\n";
if (!dtc->has_mipmaps()) {
new_mip_filter = D3DTEXF_NONE;
}
#endif
if (aniso_degree >= 2) {
new_min_filter = D3DTEXF_ANISOTROPIC;
@ -270,6 +259,39 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTexture(i, dtc->get_d3d_texture());
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::upload_texture
// Access: Public
// Description: Creates a texture surface on the graphics card and
// fills it with its pixel data.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
upload_texture(DXTextureContext8 *dtc) {
Texture *tex = dtc->get_texture();
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
dxgsg8_cat.error()
<< *tex << " is stored in an unsupported compressed format.\n";
return false;
}
if (_incomplete_render &&
!tex->has_ram_image() && tex->might_have_ram_image() &&
tex->has_simple_ram_image() &&
!_loader.is_null()) {
// If we don't have the texture data right now, go get it, but in
// the meantime load a temporary simple image in its place.
async_reload_texture(dtc);
if (!tex->has_ram_image()) {
if (dtc->was_simple_image_modified()) {
return dtc->create_simple_texture(*_screen);
}
return true;
}
}
return dtc->create_texture(*_screen);
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::release_texture
// Access: Public, Virtual

View File

@ -31,6 +31,7 @@
class Light;
class DXTextureContext8;
class DXVertexBufferContext8;
class DXIndexBufferContext8;
@ -49,6 +50,7 @@ public:
virtual TextureContext *prepare_texture(Texture *tex);
void apply_texture(int i, TextureContext *tc);
bool upload_texture(DXTextureContext8 *dtc);
virtual void release_texture(TextureContext *tc);
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);

View File

@ -722,6 +722,95 @@ create_texture(DXScreenData &scrn) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DXTextureContext8::create_simple_texture
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool DXTextureContext8::
create_simple_texture(DXScreenData &scrn) {
nassertr(IS_VALID_PTR(get_texture()), false);
HRESULT hr;
delete_texture();
_d3d_format = D3DFMT_A8R8G8B8;
D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
DWORD target_bpp = 32;
DWORD num_color_channels = 4;
DWORD target_width = (DWORD)get_texture()->get_simple_x_size();
DWORD target_height = (DWORD)get_texture()->get_simple_y_size();
DWORD mip_level_count = 1;
DWORD usage = 0;
D3DPOOL pool = D3DPOOL_MANAGED;
int data_size = target_width * target_height * 4;
hr = scrn._d3d_device->CreateTexture
(target_width, target_height, mip_level_count, usage,
target_pixel_format, pool, &_d3d_2d_texture);
_d3d_texture = _d3d_2d_texture;
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
dxgsg8_cat.error()
<< " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n";
goto error_exit;
}
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "create_simple_texture: " << get_texture()->get_name()
<< "\n";
}
{
CPTA_uchar image = get_texture()->get_simple_ram_image();
hr = -1;
// hr = fill_d3d_texture_pixels(scrn._supports_automatic_mipmap_generation, scrn._d3d_device);
IDirect3DSurface8 *surface = NULL;
_d3d_2d_texture->GetSurfaceLevel(0, &surface);
RECT source_size;
source_size.left = source_size.top = 0;
source_size.right = target_width;
source_size.bottom = target_height;
DWORD mip_filter = D3DX_FILTER_LINEAR;
hr = D3DXLoadSurfaceFromMemory
(surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)image.p(),
target_pixel_format, target_width * 4, (PALETTEENTRY*)NULL,
&source_size, mip_filter, (D3DCOLOR)0x0);
RELEASE(surface, dxgsg8, "create_simple_texture Surface", RELEASE_ONCE);
}
if (FAILED(hr)) {
dxgsg8_cat.debug ()
<< "*** fill_d3d_texture_pixels failed ***: format "
<< target_pixel_format
<< "\n";
goto error_exit;
}
mark_simple_loaded();
return true;
error_exit:
RELEASE(_d3d_texture, dxgsg8, "texture", RELEASE_ONCE);
_d3d_2d_texture = NULL;
_d3d_volume_texture = NULL;
_d3d_cube_texture = NULL;
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DXTextureContext8::delete_texture
// Access: Public

View File

@ -29,6 +29,7 @@ public:
virtual ~DXTextureContext8();
bool create_texture(DXScreenData &scrn);
bool create_simple_texture(DXScreenData &scrn);
void delete_texture();
INLINE bool has_mipmaps() const;

View File

@ -207,7 +207,9 @@ prepare_texture(Texture *tex) {
return NULL;
}
if (!dtc->create_texture(*_screen)) {
if (!upload_texture(dtc)) {
dxgsg9_cat.error()
<< "Unable to create texture " << *tex << endl;
delete dtc;
return NULL;
}
@ -237,28 +239,21 @@ apply_texture(int i, TextureContext *tc) {
if (_lru) {
_lru -> access_page (dtc -> _lru_page);
}
Texture *tex = tc->get_texture();
// If the texture image has changed, or if its use of mipmaps has
// changed, we need to re-create the image.
if (dtc->was_modified()) {
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
dxgsg9_cat.error()
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
return;
}
if (!dtc->create_texture(*_screen)) {
if (!upload_texture(dtc)) {
// Oops, we can't re-create the texture for some reason.
dxgsg9_cat.error()
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
<< "Unable to re-create texture " << *tex << endl;
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
return;
}
}
Texture *tex = tc->get_texture();
Texture::WrapMode wrap_u, wrap_v, wrap_w;
DWORD address_u;
@ -311,16 +306,10 @@ apply_texture(int i, TextureContext *tc) {
new_mip_filter = D3DTEXF_NONE;
}
#ifndef NDEBUG
// sanity check
if ((!dtc->has_mipmaps()) && (new_mip_filter != D3DTEXF_NONE)) {
dxgsg9_cat.error()
<< "Trying to set mipmap filtering for texture with no generated mipmaps!! texname["
<< tex->get_name() << "], filter("
<< tex->get_minfilter() << ")\n";
if (!dtc->has_mipmaps()) {
new_mip_filter = D3DTEXF_NONE;
}
#endif
if (aniso_degree >= 2) {
new_min_filter = D3DTEXF_ANISOTROPIC;
@ -332,6 +321,39 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTexture(i, dtc->get_d3d_texture());
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian9::upload_texture
// Access: Public
// Description: Creates a texture surface on the graphics card and
// fills it with its pixel data.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian9::
upload_texture(DXTextureContext9 *dtc) {
Texture *tex = dtc->get_texture();
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
dxgsg9_cat.error()
<< *tex << " is stored in an unsupported compressed format.\n";
return false;
}
if (_incomplete_render &&
!tex->has_ram_image() && tex->might_have_ram_image() &&
tex->has_simple_ram_image() &&
!_loader.is_null()) {
// If we don't have the texture data right now, go get it, but in
// the meantime load a temporary simple image in its place.
async_reload_texture(dtc);
if (!tex->has_ram_image()) {
if (dtc->was_simple_image_modified()) {
return dtc->create_simple_texture(*_screen);
}
return true;
}
}
return dtc->create_texture(*_screen);
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian9::release_texture
// Access: Public, Virtual

View File

@ -64,6 +64,7 @@ enum GsgPageType
class Light;
class DXTextureContext9;
class DXVertexBufferContext9;
class DXIndexBufferContext9;
@ -83,6 +84,7 @@ public:
virtual TextureContext *prepare_texture(Texture *tex);
void apply_texture(int i, TextureContext *tc);
bool upload_texture(DXTextureContext9 *dtc);
virtual void release_texture(TextureContext *tc);
ShaderContext *prepare_shader(Shader *se);

View File

@ -88,7 +88,6 @@ create_texture(DXScreenData &scrn) {
nassertr(IS_VALID_PTR(get_texture()), false);
delete_texture();
mark_loaded();
// bpp indicates requested fmt, not texture fmt
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
@ -968,6 +967,95 @@ create_texture(DXScreenData &scrn) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DXTextureContext9::create_simple_texture
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool DXTextureContext9::
create_simple_texture(DXScreenData &scrn) {
nassertr(IS_VALID_PTR(get_texture()), false);
HRESULT hr;
delete_texture();
_d3d_format = D3DFMT_A8R8G8B8;
D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
DWORD target_bpp = 32;
DWORD num_color_channels = 4;
DWORD target_width = (DWORD)get_texture()->get_simple_x_size();
DWORD target_height = (DWORD)get_texture()->get_simple_y_size();
DWORD mip_level_count = 1;
DWORD usage = 0;
D3DPOOL pool = D3DPOOL_MANAGED;
int data_size = target_width * target_height * 4;
hr = scrn._d3d_device->CreateTexture
(target_width, target_height, mip_level_count, usage,
target_pixel_format, pool, &_d3d_2d_texture, NULL);
_d3d_texture = _d3d_2d_texture;
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
dxgsg9_cat.error()
<< " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n";
goto error_exit;
}
if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug()
<< "create_simple_texture: " << get_texture()->get_name()
<< "\n";
}
{
CPTA_uchar image = get_texture()->get_simple_ram_image();
hr = -1;
// hr = fill_d3d_texture_pixels(scrn._supports_automatic_mipmap_generation, scrn._d3d_device);
IDirect3DSurface9 *surface = NULL;
_d3d_2d_texture->GetSurfaceLevel(0, &surface);
RECT source_size;
source_size.left = source_size.top = 0;
source_size.right = target_width;
source_size.bottom = target_height;
DWORD mip_filter = D3DX_FILTER_LINEAR;
hr = D3DXLoadSurfaceFromMemory
(surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)image.p(),
target_pixel_format, target_width * 4, (PALETTEENTRY*)NULL,
&source_size, mip_filter, (D3DCOLOR)0x0);
RELEASE(surface, dxgsg9, "create_simple_texture Surface", RELEASE_ONCE);
}
if (FAILED(hr)) {
dxgsg9_cat.debug ()
<< "*** fill_d3d_texture_pixels failed ***: format "
<< target_pixel_format
<< "\n";
goto error_exit;
}
mark_simple_loaded();
return true;
error_exit:
RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE);
_d3d_2d_texture = NULL;
_d3d_volume_texture = NULL;
_d3d_cube_texture = NULL;
return false;
}
////////////////////////////////////////////////////////////////////
// Function: DXTextureContext9::delete_texture
// Access: Public

View File

@ -31,6 +31,7 @@ public:
virtual ~DXTextureContext9();
bool create_texture(DXScreenData &scrn);
bool create_simple_texture(DXScreenData &scrn);
void delete_texture();
INLINE bool has_mipmaps() const;