2021-04-12 20:49:04 +00:00
/*
Copyright 2021 flyinghead
This file is part of Flycast .
Flycast is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
Flycast is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Flycast . If not , see < https : //www.gnu.org/licenses/>.
*/
# include "d3d_texture.h"
void D3DTexture : : UploadToGPU ( int width , int height , u8 * temp_tex_buffer , bool mipmapped , bool mipmapsIncluded )
{
D3DFORMAT d3dFormat ;
u32 bpp = 2 ;
switch ( tex_type )
{
case TextureType : : _5551 :
d3dFormat = D3DFMT_A1R5G5B5 ;
break ;
case TextureType : : _4444 :
d3dFormat = D3DFMT_A4R4G4B4 ;
break ;
case TextureType : : _565 :
d3dFormat = D3DFMT_R5G6B5 ;
break ;
case TextureType : : _8888 :
bpp = 4 ;
d3dFormat = D3DFMT_A8R8G8B8 ;
break ;
case TextureType : : _8 :
bpp = 1 ;
d3dFormat = D3DFMT_A8 ;
break ;
default :
return ;
}
2021-04-16 16:30:47 +00:00
int mipmapLevels = 1 ;
2021-04-12 20:49:04 +00:00
if ( mipmapsIncluded )
{
2021-04-16 16:30:47 +00:00
mipmapLevels = 0 ;
2021-04-12 20:49:04 +00:00
int dim = width ;
while ( dim ! = 0 )
{
mipmapLevels + + ;
dim > > = 1 ;
}
}
2021-04-16 16:30:47 +00:00
2021-04-15 13:17:32 +00:00
D3DLOCKED_RECT rect ;
while ( true )
2021-04-12 20:49:04 +00:00
{
2021-04-15 13:17:32 +00:00
if ( texture = = nullptr )
{
2021-04-16 16:30:47 +00:00
u32 levels = mipmapLevels ;
u32 usage = 0 ;
if ( mipmapped & & ! mipmapsIncluded )
{
levels = 0 ;
usage = D3DUSAGE_AUTOGENMIPMAP ;
}
theDXContext . getDevice ( ) - > CreateTexture ( width , height , levels , usage , d3dFormat , D3DPOOL_MANAGED , & texture . get ( ) , 0 ) ; // TODO the managed pool persists between device resets
2021-04-15 13:17:32 +00:00
verify ( texture ! = nullptr ) ;
}
2021-04-16 16:30:47 +00:00
if ( SUCCEEDED ( texture - > LockRect ( mipmapLevels - 1 , & rect , nullptr , 0 ) ) )
2021-04-15 13:17:32 +00:00
break ;
D3DSURFACE_DESC desc ;
texture - > GetLevelDesc ( 0 , & desc ) ;
if ( desc . Pool ! = D3DPOOL_DEFAULT )
// it should be lockable so error out
return ;
2021-04-16 16:30:47 +00:00
// RTT targets are created in the default pool and aren't lockable, so delete it and recreate it in the managed pool
2021-04-15 13:17:32 +00:00
texture . reset ( ) ;
2021-04-12 20:49:04 +00:00
}
2021-04-16 16:30:47 +00:00
for ( int i = 0 ; i < mipmapLevels ; i + + )
2021-04-12 20:49:04 +00:00
{
2021-04-16 16:30:47 +00:00
u32 w = mipmapLevels = = 1 ? width : 1 < < i ;
u32 h = mipmapLevels = = 1 ? height : 1 < < i ;
if ( w * bpp = = ( u32 ) rect . Pitch )
memcpy ( rect . pBits , temp_tex_buffer , w * bpp * h ) ;
else
2021-04-12 20:49:04 +00:00
{
2021-04-16 16:30:47 +00:00
u8 * dst = ( u8 * ) rect . pBits ;
u8 * src = temp_tex_buffer ;
for ( u32 l = 0 ; l < h ; l + + )
{
memcpy ( dst , src , w * bpp ) ;
dst + = rect . Pitch ;
src + = w * bpp ;
}
2021-04-12 20:49:04 +00:00
}
2021-04-16 16:30:47 +00:00
texture - > UnlockRect ( mipmapLevels - i - 1 ) ;
temp_tex_buffer + = ( 1 < < ( 2 * i ) ) * bpp ;
if ( i < mipmapLevels - 1 )
if ( FAILED ( texture - > LockRect ( mipmapLevels - i - 2 , & rect , nullptr , 0 ) ) )
break ;
2021-04-12 20:49:04 +00:00
}
}
bool D3DTexture : : Delete ( )
{
if ( ! BaseTextureCacheData : : Delete ( ) )
return false ;
texture . reset ( ) ;
return true ;
}
2021-04-16 16:30:47 +00:00
void D3DTexture : : loadCustomTexture ( )
{
u32 size = custom_width * custom_height ;
u8 * p = custom_image_data ;
while ( size - - )
{
// RGBA -> BGRA
std : : swap ( p [ 0 ] , p [ 2 ] ) ;
p + = 4 ;
}
CheckCustomTexture ( ) ;
}