diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c index e87152ba..4cc9106d 100644 --- a/engine/client/ref_common.c +++ b/engine/client/ref_common.c @@ -1,9 +1,25 @@ +/* +ref_common.c - RefAPI implementation +Copyright (C) 2025 Xash3D FWGS contributors + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. +*/ + #include "common.h" #include "client.h" #include "library.h" #include "cl_tent.h" #include "platform/platform.h" #include "vid_common.h" +#include "imagelib.h" struct ref_state_s ref; @@ -434,6 +450,7 @@ static const ref_api_t gEngfuncs = FS_FreeImage, Image_SetMDLPointer, pfnImage_GetPFDesc, + Image_ComputeSize, pfnDrawNormalTriangles, pfnDrawTransparentTriangles, diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index 72dd3b44..d5f13f7d 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -1464,16 +1464,25 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, floa return result; } -// This codebase has too many copies of this function: -// - ref_gl has one -// - ref_vk has one -// - ref_soft has one -// - many more places probably have one too -// TODO figure out how to make it available for ref_* +/* +============ +Image_ComputeSize +============ +*/ size_t Image_ComputeSize( int type, int width, int height, int depth ) { + depth = Q_max( 1, depth ); + switch( type ) { + case PF_LUMINANCE: + return ( width * height * depth ); + case PF_BGR_24: + case PF_RGB_24: + return ( width * height * depth * 3 ); + case PF_BGRA_32: + case PF_RGBA_32: + return ( width * height * depth * 4 ); case PF_DXT1: case PF_BC4_SIGNED: case PF_BC4_UNSIGNED: @@ -1486,12 +1495,8 @@ size_t Image_ComputeSize( int type, int width, int height, int depth ) case PF_BC6H_SIGNED: case PF_BC6H_UNSIGNED: case PF_BC7_UNORM: - case PF_BC7_SRGB: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 16 ); - case PF_LUMINANCE: return ( width * height * depth ); - case PF_BGR_24: - case PF_RGB_24: return ( width * height * depth * 3 ); - case PF_BGRA_32: - case PF_RGBA_32: return ( width * height * depth * 4 ); + case PF_BC7_SRGB: + return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 16 ); } return 0; diff --git a/engine/ref_api.h b/engine/ref_api.h index a14d0291..361ca55b 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -59,6 +59,7 @@ GNU General Public License for more details. // Removed FillRGBABlend. Now FillRGBA accepts rendermode parameter. // 10. Added R_GetWindowHandle to retrieve platform-specific window object. // 11. Added size argument to Mod_ProcessRenderData +// 12. Added Image_CalcImageSize #define REF_API_VERSION 11 #define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST) @@ -483,6 +484,7 @@ typedef struct ref_api_s void (*FS_FreeImage)( rgbdata_t *pack ); void (*Image_SetMDLPointer)( byte *p ); const struct bpc_desc_s *(*Image_GetPFDesc)( int idx ); + size_t (*Image_CalcImageSize)( int type, int width, int height, int depth ); // client exports void (*pfnDrawNormalTriangles)( void ); diff --git a/ref/gl/gl_image.c b/ref/gl/gl_image.c index 9c9ee168..b2cd01d2 100644 --- a/ref/gl/gl_image.c +++ b/ref/gl/gl_image.c @@ -302,48 +302,6 @@ static int GL_CalcTextureSamples( int flags ) return FBitSet( flags, IMAGE_HAS_ALPHA ) ? 2 : 1; } -/* -================== -GL_CalcImageSize -================== -*/ -static size_t GL_CalcImageSize( pixformat_t format, int width, int height, int depth ) -{ - size_t size = 0; - - // check the depth error - depth = Q_max( 1, depth ); - - switch( format ) - { - case PF_LUMINANCE: - size = width * height * depth; - break; - case PF_RGB_24: - case PF_BGR_24: - size = width * height * depth * 3; - break; - case PF_BGRA_32: - case PF_RGBA_32: - size = width * height * depth * 4; - break; - case PF_DXT1: - size = (((width + 3) >> 2) * ((height + 3) >> 2) * 8) * depth; - break; - case PF_DXT3: - case PF_DXT5: - case PF_BC6H_SIGNED: - case PF_BC6H_UNSIGNED: - case PF_BC7_UNORM: - case PF_BC7_SRGB: - case PF_ATI2: - size = (((width + 3) >> 2) * ((height + 3) >> 2) * 16) * depth; - break; - } - - return size; -} - /* ================== GL_CalcTextureSize @@ -1173,7 +1131,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) buf = pic->buffer; bufend = pic->buffer + pic->size; // total image size include all the layers, cube sides, mipmaps - offset = GL_CalcImageSize( pic->type, pic->width, pic->height, pic->depth ); + offset = gEngfuncs.Image_CalcImageSize( pic->type, pic->width, pic->height, pic->depth ); texsize = GL_CalcTextureSize( tex->format, tex->width, tex->height, tex->depth ); normalMap = FBitSet( tex->flags, TF_NORMALMAP ) ? true : false; numSides = FBitSet( pic->flags, IMAGE_CUBEMAP ) ? 6 : 1; @@ -1198,7 +1156,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) height = Q_max( 1, ( tex->height >> j )); depth = texture3d ? Q_max( 1, ( tex->depth >> j )) : tex->depth; texsize = GL_CalcTextureSize( tex->format, width, height, depth ); - size = GL_CalcImageSize( pic->type, width, height, depth ); + size = gEngfuncs.Image_CalcImageSize( pic->type, width, height, depth ); GL_TextureImageCompressed( tex, i, j, width, height, depth, size, buf ); tex->size += texsize; buf += size; // move pointer @@ -1215,7 +1173,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) height = Q_max( 1, ( tex->height >> j )); depth = texture3d ? Q_max( 1, ( tex->depth >> j )) : tex->depth; texsize = GL_CalcTextureSize( tex->format, width, height, depth ); - size = GL_CalcImageSize( pic->type, width, height, depth ); + size = gEngfuncs.Image_CalcImageSize( pic->type, width, height, depth ); GL_TextureImageRAW( tex, i, j, width, height, depth, pic->type, buf ); tex->size += texsize; buf += size; // move pointer @@ -1243,7 +1201,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) width = Q_max( 1, ( tex->width >> j )); height = Q_max( 1, ( tex->height >> j )); texsize = GL_CalcTextureSize( tex->format, width, height, tex->depth ); - size = GL_CalcImageSize( pic->type, width, height, tex->depth ); + size = gEngfuncs.Image_CalcImageSize( pic->type, width, height, tex->depth ); GL_TextureImageRAW( tex, i, j, width, height, tex->depth, pic->type, data ); if( mipCount > 1 ) GL_BuildMipMap( data, width, height, tex->depth, tex->flags ); @@ -1255,7 +1213,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) // move to next side if( numSides > 1 && ( buf != NULL )) - buf += GL_CalcImageSize( pic->type, pic->width, pic->height, 1 ); + buf += gEngfuncs.Image_CalcImageSize( pic->type, pic->width, pic->height, 1 ); } } @@ -1683,7 +1641,7 @@ int GL_LoadTextureArray( const char **names, int flags ) { int width = Q_max( 1, ( pic->width >> j )); int height = Q_max( 1, ( pic->height >> j )); - mipsize = GL_CalcImageSize( pic->type, width, height, 1 ); + mipsize = gEngfuncs.Image_CalcImageSize( pic->type, width, height, 1 ); memcpy( pic->buffer + dstsize + mipsize * i, src->buffer + srcsize, mipsize ); dstsize += mipsize * numLayers; srcsize += mipsize; diff --git a/ref/soft/r_image.c b/ref/soft/r_image.c index 00619936..c628c6e6 100644 --- a/ref/soft/r_image.c +++ b/ref/soft/r_image.c @@ -119,42 +119,6 @@ void R_SetTextureParameters( void ) GL_UpdateTextureParams( i ); } - -/* -================== -GL_CalcImageSize -================== -*/ -static size_t GL_CalcImageSize( pixformat_t format, int width, int height, int depth ) -{ - size_t size = 0; - - // check the depth error - depth = Q_max( 1, depth ); - - switch( format ) - { - case PF_RGB_24: - case PF_BGR_24: - size = width * height * depth * 3; - break; - case PF_BGRA_32: - case PF_RGBA_32: - size = width * height * depth * 4; - break; - case PF_DXT1: - size = ((( width + 3 ) >> 2 ) * (( height + 3 ) >> 2 ) * 8 ) * depth; - break; - case PF_DXT3: - case PF_DXT5: - case PF_ATI2: - size = ((( width + 3 ) >> 2 ) * (( height + 3 ) >> 2 ) * 16 ) * depth; - break; - } - - return size; -} - /* ================== GL_CalcTextureSize @@ -563,7 +527,7 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic ) width = Q_max( 1, ( tex->width >> j )); height = Q_max( 1, ( tex->height >> j )); texsize = GL_CalcTextureSize( width, height, tex->depth ); - size = GL_CalcImageSize( pic->type, width, height, tex->depth ); + size = gEngfuncs.Image_CalcImageSize( pic->type, width, height, tex->depth ); // GL_TextureImageRAW( tex, i, j, width, height, tex->depth, pic->type, data ); // increase size to workaround triangle renderer bugs // it seems to assume memory readable. maybe it was pointed to WAD?