📄 twiddle.c
字号:
/******************************************************************************
<module>
* Name : Twiddle.h
* Title : D3DM Texture twiddling
* Author(s) : Imagination Technologies
* Created : 2 March 2004
*
* Copyright : 2004 by Imagination Technologies Limited.
* All rights reserved. No part of this software, either
* material or conceptual may be copied or distributed,
* transmitted, transcribed, stored in a retrieval system
* or translated into any human or computer language in any
* form by any means, electronic, mechanical, manual or
* other-wise, or disclosed to third parties without the
* express written permission of Imagination Technologies
* Limited, Unit 8, HomePark Industrial Estate,
* King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description : Twiddle functions
*
* Platform : Windows CE
*
</module>
Modifications :
$Log: twiddle.c $
*********************************************************************************/
#include "context.h"
/***********************************************************************************
Function Name : getTwiddledAddress
Inputs : ui32UPos, ui32VPos, ui32USize, ui32VSize
Outputs : -
Returns : Twiddled address
Description : Interleaves UV addresses to form a twiddled address
************************************************************************************/
static IMG_UINT32 getTwiddledAddress(IMG_UINT32 ui32UPos, IMG_UINT32 ui32VPos, IMG_UINT32 ui32USize, IMG_UINT32 ui32VSize)
{
IMG_UINT32 ui32Valids=0;
IMG_UINT32 ui32Mask = 1;
IMG_UINT32 ui32UValid=0,ui32VValid=0;
IMG_UINT32 ui32Addr = 0;
while(ui32VSize || ui32USize)
{
ui32UValid = ui32VValid = 0;
if(ui32VSize)
{
ui32Addr |= (ui32VPos & ui32Mask) << ui32Valids;
ui32VSize--;
ui32VValid++;
}
if(ui32USize)
{
ui32Addr |= (ui32UPos & ui32Mask) << (ui32Valids + ui32VValid);
ui32USize--;
ui32UValid++;
}
ui32Mask <<= 1;
ui32Valids += ui32UValid + ui32VValid - 1;
}
return ui32Addr;
}
/***********************************************************************************
Function Name : TwiddleAddress[8/16/32]bpp
Inputs : pvSrc, ui32Log2Width, ui32Log2Height, ui32X, ui32Y, ui32WWidth,
ui32Height, ui32SrcStride
Outputs : pvDest
Returns : -
Description : Twiddles a subtexture using seqential read, random write.
************************************************************************************/
static IMG_VOID TwiddleAddress8bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width,
IMG_UINT32 ui32Log2Height, IMG_UINT32 ui32X, IMG_UINT32 ui32Y,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32SrcStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT8 *pui8Address = (IMG_UINT8 *)pvDest;
IMG_UINT8 *pui8Pixels = (IMG_UINT8 *)pvSrc;
for(ui32YCount=0;ui32YCount < ui32Height;ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui8Address[ui32Address] = pui8Pixels[ui32YCount*ui32SrcStride + ui32XCount];
}
}
}
/************************************************************************************
************************************************************************************/
static IMG_VOID TwiddleAddress16bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width, IMG_UINT32 ui32Log2Height,
IMG_UINT32 ui32X, IMG_UINT32 ui32Y, IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32SrcStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT16 *pui16Address = (IMG_UINT16 *)pvDest;
IMG_UINT16 *pui16Pixels = (IMG_UINT16 *)pvSrc;
for(ui32YCount=0;ui32YCount < ui32Height;ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui16Address[ui32Address] = pui16Pixels[ui32YCount*ui32SrcStride + ui32XCount];
}
}
}
/************************************************************************************
************************************************************************************/
static IMG_VOID TwiddleAddress32bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width, IMG_UINT32 ui32Log2Height,
IMG_UINT32 ui32X, IMG_UINT32 ui32Y, IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32SrcStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT32 *pui32Address = (IMG_UINT32 *)pvDest;
IMG_UINT32 *pui32Pixels = (IMG_UINT32 *)pvSrc;
for(ui32YCount=0;ui32YCount < ui32Height;ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui32Address[ui32Address] = pui32Pixels[ui32YCount*ui32SrcStride + ui32XCount];
}
}
}
/***********************************************************************************
Function Name : ReadBackTwiddle[8/16/32]bpp
Inputs : pvSrc, ui32Log2Width, ui32Log2Height, ui32X, ui32Y, ui32Width,
ui32Height, ui32DstStride
Outputs : pvDest
Returns : -
Description : Reads a subregion back from a twiddled texture
using random read, sequential write.
************************************************************************************/
static IMG_VOID ReadBackTwiddle8bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width,
IMG_UINT32 ui32Log2Height, IMG_UINT32 ui32X, IMG_UINT32 ui32Y,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32DstStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT8 *pui8Address = (IMG_UINT8 *)pvDest;
IMG_UINT8 *pui8Pixels = (IMG_UINT8 *)pvSrc;
for(ui32YCount=0; ui32YCount < ui32Height; ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui8Address[ui32YCount*ui32DstStride + ui32XCount] = pui8Pixels[ui32Address];
}
}
}
/************************************************************************************
************************************************************************************/
static IMG_VOID ReadBackTwiddle16bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width,
IMG_UINT32 ui32Log2Height, IMG_UINT32 ui32X, IMG_UINT32 ui32Y,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32DstStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT16 *pui16Address = (IMG_UINT16 *)pvDest;
IMG_UINT16 *pui16Pixels = (IMG_UINT16 *)pvSrc;
for(ui32YCount=0;ui32YCount < ui32Height;ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui16Address[ui32YCount*ui32DstStride + ui32XCount] = pui16Pixels[ui32Address];
}
}
}
/************************************************************************************
************************************************************************************/
static IMG_VOID ReadBackTwiddle32bpp(IMG_VOID *pvDest, const IMG_VOID *pvSrc, IMG_UINT32 ui32Log2Width,
IMG_UINT32 ui32Log2Height, IMG_UINT32 ui32X, IMG_UINT32 ui32Y,
IMG_UINT32 ui32Width, IMG_UINT32 ui32Height, IMG_UINT32 ui32DstStride)
{
IMG_UINT32 ui32XCount, ui32YCount, ui32Address;
IMG_UINT32 *pui32Address = (IMG_UINT32 *)pvDest;
IMG_UINT32 *pui32Pixels = (IMG_UINT32 *)pvSrc;
for(ui32YCount=0;ui32YCount < ui32Height;ui32YCount++)
{
for(ui32XCount=0; ui32XCount < ui32Width; ui32XCount++)
{
ui32Address = getTwiddledAddress(ui32XCount + ui32X, ui32YCount + ui32Y, ui32Log2Width, ui32Log2Height);
pui32Address[ui32YCount*ui32DstStride + ui32XCount] = pui32Pixels[ui32Address];
}
}
}
/***********************************************************************************
Function Name : TwiddleSurface
Inputs :
Outputs :
Returns : -
Description : Twiddles a texture
************************************************************************************/
IMG_VOID TwiddleSurface(LPD3DM_SURFACE psSource,
LPD3DM_SURFACE psDest,
PRECT psSrcRect,
PRECT psDestRect)
{
IMG_UINT32 ui32Log2Width, ui32Log2Height, ui32Stride;
ui32Stride = ui32Stride = psDest->dwStrideByte / (psDest->dwBpp / 8);
ui32Log2Width = AsPowerOfTwo(psDest->sDescription.sTexture.dwScaledWidth);
ui32Log2Height = AsPowerOfTwo(psDest->sDescription.sTexture.dwScaledHeight);
switch(psDest->dwBpp)
{
case 8:
{
pfnSubTextureTwiddle = TwiddleAddress8bpp;
break;
}
case 16:
{
pfnSubTextureTwiddle = TwiddleAddress16bpp;
break;
}
case 32:
{
pfnSubTextureTwiddle = TwiddleAddress32bpp;
break;
}
}
pfnSubTextureTwiddle((IMG_VOID *) ((DWORD) (psDest->psMemInfo->pvLinAddr) + psDest->sDescription.sTexture.dwLevelOffset),
(IMG_VOID *) ((DWORD) (psSource->psMemInfo->pvLinAddr) + psSource->sDescription.sTexture.dwLevelOffset +
(psSource->dwStrideByte * psSrcRect->top) +
(psSrcRect->left * (psSource->dwBpp / 8))),
ui32Log2Width,
ui32Log2Height,
psDestRect->left,
psDestRect->top,
psDestRect->right - psDestRect->left,
psDestRect->bottom - psDestRect->top,
psSource->dwStridePixel);
}
/***********************************************************************************
Function Name : TwiddleRegionFromBuffer
Inputs :
Outputs :
Returns : -
Description : Twiddles texture region from an untwiddled buffer
************************************************************************************/
IMG_VOID TwiddleRegionFromBuffer(VOID *pvSource,
LPD3DM_SURFACE psDest,
PRECT psDestRect)
{
IMG_UINT32 ui32Log2Width, ui32Log2Height, ui32Stride;
ui32Stride = psDestRect->right - psDestRect->left;
switch(psDest->dwBpp)
{
case 8:
{
pfnSubTextureTwiddle = TwiddleAddress8bpp;
break;
}
case 16:
{
pfnSubTextureTwiddle = TwiddleAddress16bpp;
break;
}
case 32:
{
pfnSubTextureTwiddle = TwiddleAddress32bpp;
break;
}
}
ui32Log2Width = AsPowerOfTwo(psDest->sDescription.sTexture.dwScaledWidth);
ui32Log2Height = AsPowerOfTwo(psDest->sDescription.sTexture.dwScaledHeight);
/* Twiddle to dest from memory region */
pfnSubTextureTwiddle((IMG_VOID *) ((DWORD) (psDest->psMemInfo->pvLinAddr) + psDest->sDescription.sTexture.dwLevelOffset),
pvSource,
ui32Log2Width,
ui32Log2Height,
psDestRect->left,
psDestRect->top,
psDestRect->right - psDestRect->left,
psDestRect->bottom - psDestRect->top,
ui32Stride);
}
/***********************************************************************************
Function Name : TwiddleRegionFromTwiddled
Inputs :
Outputs :
Returns : -
Description : Twiddles texture region from a twiddled surface
************************************************************************************/
IMG_VOID TwiddleRegionFromTwiddled(LPD3DM_SURFACE psSource,
LPD3DM_SURFACE psDest,
PRECT psSrcRect,
PRECT psDestRect)
{
IMG_UINT32 ui32Log2Width, ui32Log2Height, ui32Stride;
IMG_VOID *pvBuffer = D3DMAllocate((psDestRect->right - psDestRect->left) *
(psDestRect->bottom - psDestRect->top) *
(psDest->dwBpp / 8));
IMG_VOID *pvDest = (IMG_VOID *) ((DWORD) (psDest->psMemInfo->pvLinAddr) +
psDest->sDescription.sTexture.dwLevelOffset +
(psDestRect->top * psDest->dwStrideByte) +
(psDestRect->left * (psDest->dwBpp / 8)));
ui32Stride = psDestRect->right - psDestRect->left;
ui32Log2Width = AsPowerOfTwo(psSource->sDescription.sTexture.dwScaledWidth);
ui32Log2Height = AsPowerOfTwo(psSource->sDescription.sTexture.dwScaledHeight);
switch(psDest->dwBpp)
{
case 8:
{
pfnReadBackData = ReadBackTwiddle8bpp;
pfnSubTextureTwiddle = TwiddleAddress8bpp;
break;
}
case 16:
{
pfnReadBackData = ReadBackTwiddle16bpp;
pfnSubTextureTwiddle = TwiddleAddress16bpp;
break;
}
case 32:
{
pfnReadBackData = ReadBackTwiddle32bpp;
pfnSubTextureTwiddle = TwiddleAddress32bpp;
break;
}
}
/* Untwiddle from source to memory region */
pfnReadBackData(pvBuffer,
(IMG_VOID *) ((DWORD) (psSource->psMemInfo->pvLinAddr) + psSource->sDescription.sTexture.dwLevelOffset),
ui32Log2Width,
ui32Log2Height,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -