The mach64 texture engine requires a power of two texture pitch. The
attached patch tries to solve the problem by allowing drivers to request
power of two pitches.
It adds three values max_power_of_two_{pixelpitch,bytepitch,height} to
CardLimitaions. If the buffer pitch is below these values the
surfacemanager will increase the pitch to the next power of two value.
The biggest problem with this solution is that it can waste a lot of
memory needlessly. One solution I can think of would involve the driver
setting some flag in CheckState() which would signal
dfb_surfacemanager_assure_video() to reallocate the buffer with a power of
two pitch. But that might increase memory fragmentation.
Any thoughts?
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
Index: gfxdrivers/mach64/mach64.c
===================================================================
RCS file: /cvs/directfb/DirectFB/gfxdrivers/mach64/mach64.c,v
retrieving revision 1.23
diff -u -r1.23 mach64.c
--- gfxdrivers/mach64/mach64.c 9 Jun 2004 00:52:59 -0000 1.23
+++ gfxdrivers/mach64/mach64.c 9 Jun 2004 01:01:59 -0000
@@ -965,6 +965,10 @@
if (!mdev->rage_pro)
snprintf( device_info->name,
DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Mach64 GT" );
+
+ /* Max texture size is 1024x1024 */
+ device_info->limits.surface_max_power_of_two_pixelpitch = 1024;
+ device_info->limits.surface_max_power_of_two_height = 1024;
break;
}
Index: src/core/gfxcard.h
===================================================================
RCS file: /cvs/directfb/DirectFB/src/core/gfxcard.h,v
retrieving revision 1.68
diff -u -r1.68 gfxcard.h
--- src/core/gfxcard.h 11 May 2004 03:51:16 -0000 1.68
+++ src/core/gfxcard.h 9 Jun 2004 01:01:59 -0000
@@ -63,6 +63,10 @@
unsigned int surface_byteoffset_alignment;
unsigned int surface_pixelpitch_alignment;
unsigned int surface_bytepitch_alignment;
+
+ unsigned int surface_max_power_of_two_pixelpitch;
+ unsigned int surface_max_power_of_two_bytepitch;
+ unsigned int surface_max_power_of_two_height;
} CardLimitations;
DECLARE_MODULE_DIRECTORY( dfb_graphics_drivers );
@@ -70,7 +74,7 @@
/*
* Increase this number when changes result in binary incompatibility!
*/
-#define DFB_GRAPHICS_DRIVER_ABI_VERSION 22
+#define DFB_GRAPHICS_DRIVER_ABI_VERSION 23
#define DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH 60
#define DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH 80
Index: src/core/surfacemanager.c
===================================================================
RCS file: /cvs/directfb/DirectFB/src/core/surfacemanager.c,v
retrieving revision 1.62
diff -u -r1.62 surfacemanager.c
--- src/core/surfacemanager.c 21 May 2004 09:33:28 -0000 1.62
+++ src/core/surfacemanager.c 9 Jun 2004 01:02:00 -0000
@@ -49,6 +49,8 @@
#include <core/surfacemanager.h>
#include <core/system.h>
+#include <misc/util.h>
+
#include <direct/mem.h>
#include <direct/memcpy.h>
#include <direct/messages.h>
@@ -96,6 +98,10 @@
unsigned int byteoffset_align;
unsigned int pixelpitch_align;
unsigned int bytepitch_align;
+
+ unsigned int max_power_of_two_pixelpitch;
+ unsigned int max_power_of_two_bytepitch;
+ unsigned int max_power_of_two_height;
};
@@ -130,6 +136,9 @@
manager->byteoffset_align = limits->surface_byteoffset_alignment;
manager->pixelpitch_align = limits->surface_pixelpitch_alignment;
manager->bytepitch_align = limits->surface_bytepitch_alignment;
+ manager->max_power_of_two_pixelpitch =
limits->surface_max_power_of_two_pixelpitch;
+ manager->max_power_of_two_bytepitch =
limits->surface_max_power_of_two_bytepitch;
+ manager->max_power_of_two_height = limits->surface_max_power_of_two_height;
fusion_skirmish_init( &manager->lock );
@@ -315,6 +324,10 @@
/* calculate the required length depending on limitations */
pitch = MAX( surface->width, surface->min_width );
+ if (pitch < manager->max_power_of_two_pixelpitch &&
+ surface->height < manager->max_power_of_two_height)
+ pitch = 1 << dfb_log2( pitch );
+
if (manager->pixelpitch_align > 1) {
pitch += manager->pixelpitch_align - 1;
pitch -= pitch % manager->pixelpitch_align;
@@ -322,6 +335,10 @@
pitch = DFB_BYTES_PER_LINE( buffer->format, pitch );
+ if (pitch < manager->max_power_of_two_bytepitch &&
+ surface->height < manager->max_power_of_two_height)
+ pitch = 1 << dfb_log2( pitch );
+
if (manager->bytepitch_align > 1) {
pitch += manager->bytepitch_align - 1;
pitch -= pitch % manager->bytepitch_align;
Index: src/misc/util.h
===================================================================
RCS file: /cvs/directfb/DirectFB/src/misc/util.h,v
retrieving revision 1.24
diff -u -r1.24 util.h
--- src/misc/util.h 21 May 2004 09:33:28 -0000 1.24
+++ src/misc/util.h 9 Jun 2004 01:02:00 -0000
@@ -93,5 +93,16 @@
/* Returns the current time after startup of DirectFB in milliseconds */
long long dfb_get_millis();
+static inline int dfb_log2( int val )
+{
+ register int ret = 0;
+
+ while (val >> ++ret);
+
+ if ((1 << --ret) < val)
+ ret++;
+
+ return ret;
+}
#endif