void* DiD3D9TextureDrv::LockLevel(uint32 level, uint32 &pitch, uint32 surface) { void *buffer = nullptr; if (mTexture) { if (mParent->GetTextureType() == TEXTURE_2D) { DI_ASSERT(surface == 0); IDirect3DTexture9* tex2D = static_cast<IDirect3DTexture9*>(mTexture); D3DLOCKED_RECT lockedRect; HRESULT result = tex2D->LockRect((DWORD)level, &lockedRect, 0, D3DLOCK_NOSYSLOCK); DX9_CHKERR(result); if (result == D3D_OK) { buffer = lockedRect.pBits; pitch = (uint32)lockedRect.Pitch; } } else if (mParent->GetTextureType() == TEXTURE_CUBE) { DI_ASSERT(surface >= 0 && surface <= 5); IDirect3DCubeTexture9* texCUBE = static_cast<IDirect3DCubeTexture9*>(mTexture); D3DLOCKED_RECT lockedRect; HRESULT result = texCUBE->LockRect((D3DCUBEMAP_FACES)surface, (DWORD)level, &lockedRect, 0, D3DLOCK_NOSYSLOCK); DX9_CHKERR(result); if (result == D3D_OK) { buffer = lockedRect.pBits; pitch = (uint32)lockedRect.Pitch; } } } return buffer; }
MF_API bool MFTexture_Map(MFTexture *pTexture, int element, int mipLevel, MFLockedTexture *pLock) { int numFaces = pTexture->type == MFTexType_Cubemap ? 6 : 1; MFDebug_Assert(element < numFaces, "Array textures not supported in D3D9!"); int s = mipLevel*pTexture->numElements + (element ? element : 0); MFTextureSurface &surface = pTexture->pSurfaces[s]; DWORD lockFlags = (pTexture->createFlags & MFTCF_TypeMask) == MFTCF_Scratch ? D3DLOCK_DISCARD : 0; switch(pTexture->type) { case MFTexType_1D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } case MFTexType_2D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } case MFTexType_3D: { IDirect3DVolumeTexture9 *pTex = (IDirect3DVolumeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DVOLUME_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height && (int)desc.Depth == surface.depth, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_BOX box; pTex->LockBox(mipLevel, &box, NULL, lockFlags); pLock->pData = box.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = box.RowPitch; pLock->sliceInBytes = box.SlicePitch; break; } case MFTexType_Cubemap: { IDirect3DCubeTexture9 *pTex = (IDirect3DCubeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(gD3DCubeFaces[element], mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } } return true; }
MF_API bool MFTexture_Update(MFTexture *pTexture, int element, int mipLevel, const void *pData, size_t lineStride, size_t sliceStride) { int numFaces = pTexture->type == MFTexType_Cubemap ? 6 : 1; MFDebug_Assert(element < numFaces, "Array textures not supported in D3D9!"); int s = mipLevel*pTexture->numElements + (element > -1 ? element : 0); MFTextureSurface &surface = pTexture->pSurfaces[s]; DWORD lockFlags = (pTexture->createFlags & MFTCF_TypeMask) == MFTCF_Scratch ? D3DLOCK_DISCARD : 0; size_t lineBytes = (surface.bitsPerPixel * surface.width) / 8; if(lineStride == 0) lineStride = lineBytes; if(sliceStride == 0) sliceStride = lineStride * surface.width; switch(pTexture->type) { case MFTexType_1D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); MFCopyMemory(rect.pBits, pData, lineBytes); pTex->UnlockRect(mipLevel); break; } case MFTexType_2D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); const char *pSrc = (const char*)pData; char *pDest = (char*)rect.pBits; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDest, pSrc, lineBytes); pDest += rect.Pitch; pSrc += lineStride; } pTex->UnlockRect(mipLevel); break; } case MFTexType_3D: { IDirect3DVolumeTexture9 *pTex = (IDirect3DVolumeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DVOLUME_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height && (int)desc.Depth == surface.depth, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_BOX box; pTex->LockBox(mipLevel, &box, NULL, lockFlags); MFCopyMemory(box.pBits, pData, surface.bufferLength); const char *pSrcSlice = (const char*)pData; char *pDestSlice = (char*)box.pBits; for(int d=0; d<surface.depth; ++d) { const char *pSrcLine = pSrcSlice; char *pDestLine = pDestSlice; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDestLine, pSrcLine, lineBytes); pDestLine += box.RowPitch; pSrcLine += lineStride; } pSrcSlice += sliceStride; pDestSlice += box.SlicePitch; } pTex->UnlockBox(mipLevel); break; } case MFTexType_Cubemap: { MFDebug_Assert(element != -1, "TODO: must handle setting all surfaces at once..."); IDirect3DCubeTexture9 *pTex = (IDirect3DCubeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(gD3DCubeFaces[element], mipLevel, &rect, NULL, lockFlags); const char *pSrc = (const char*)pData; char *pDest = (char*)rect.pBits; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDest, pSrc, lineBytes); pDest += rect.Pitch; pSrc += lineStride; } pTex->UnlockRect(gD3DCubeFaces[element], mipLevel); break; } } return true; }