Example #1
0
static UINT8 *CreateSurfaceHelper(PDev *pdev, UINT32 surface_id,
                                  UINT32 cx, UINT32 cy, ULONG format,
                                  UINT8 allocation_type,
                                  INT32 *stride, UINT32 *surface_format,
                                  QXLPHYSICAL *phys_mem)
{
    UINT32 depth;
    SurfaceInfo *surface_info = GetSurfaceInfo(pdev, surface_id);
    UINT8 *base_mem;
    int size;

    BitmapFormatToDepthAndSurfaceFormat(format, &depth, surface_format);
    ASSERT(pdev, depth != 0);
    ASSERT(pdev, stride);
    QXLGetSurface(pdev, phys_mem, cx, cy, depth, stride, &base_mem, allocation_type);
    DEBUG_PRINT((pdev, 3,
        "%s: %d, pm %0lX, fmt %d, d %d, s (%d, %d) st %d\n",
        __FUNCTION__, surface_id, (uint64_t)*phys_mem, *surface_format,
        depth, cx, cy, *stride));
    size = abs(*stride) * cy;
    if (!base_mem) {
        DEBUG_PRINT((pdev, 0, "%s: %p: %d: QXLGetSurface failed (%d bytes alloc)\n",
            __FUNCTION__, pdev, surface_id, size));
        return NULL;
    }
    if (!CreateDrawArea(pdev, base_mem, surface_info->bitmap_format, cx, cy, *stride, surface_id)) {
        DEBUG_PRINT((pdev, 0, "%s: %p: CreateDrawArea failed (%d)\n",
            __FUNCTION__, pdev, surface_id, size));
        // TODO: Why did it fail? nothing in the MSDN
        QXLDelSurface(pdev, base_mem, allocation_type);
        return NULL;
    }
    return base_mem;
}
Example #2
0
static BOOL CreateDrawArea(PDev *pdev, UINT8 *base_mem, ULONG format, UINT32 cx, UINT32 cy,
                           UINT32 stride, UINT32 surface_id)
{
    SIZEL  size;
    DrawArea *drawarea;

    size.cx = cx;
    size.cy = cy;

    drawarea = &GetSurfaceInfo(pdev, surface_id)->draw_area;

    if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, stride, format, 0, base_mem))) {
        DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__));
        return FALSE;
    }

    if (!EngAssociateSurface(drawarea->bitmap, pdev->eng, 0)) {
        DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__));
        goto error;
    }

    if (!(drawarea->surf_obj = EngLockSurface(drawarea->bitmap))) {
        DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__));
        goto error;
    }

    drawarea->base_mem = base_mem;

    return TRUE;
error:
    EngDeleteSurface(drawarea->bitmap);
    return FALSE;
}
Example #3
0
/* to_surface_id is exclusive */
static void SendSurfaceRangeCreateCommand(PDev *pdev, UINT32 from_surface_id, UINT32 to_surface_id)
{
    UINT32 surface_id;

    ASSERT(pdev, from_surface_id < to_surface_id);
    ASSERT(pdev, to_surface_id <= pdev->n_surfaces);

    for (surface_id = from_surface_id; surface_id < to_surface_id; surface_id++) {
        SurfaceInfo *surface_info;
        SURFOBJ *surf_obj;
        QXLPHYSICAL phys_mem;
        UINT32 surface_format;
        UINT32 depth;

        surface_info = GetSurfaceInfo(pdev, surface_id);
        if (!surface_info->draw_area.base_mem) {
            continue;
        }

        surf_obj = surface_info->draw_area.surf_obj;

        if (!surf_obj) {
            continue;
        }

        phys_mem = SurfaceToPhysical(pdev, surface_info->draw_area.base_mem);
        BitmapFormatToDepthAndSurfaceFormat(surface_info->bitmap_format, &depth, &surface_format);

        SendSurfaceCreateCommand(pdev, surface_id, surf_obj->sizlBitmap,
                                 surface_format, -surface_info->stride, phys_mem,
                                 /* the surface is still there, tell server not to erase */
                                 1);
    }
}
Example #4
0
VOID DeleteDeviceBitmap(PDev *pdev, UINT32 surface_id, UINT8 allocation_type)
{
    DrawArea *drawarea;

    drawarea = &GetSurfaceInfo(pdev,surface_id)->draw_area;

    FreeDrawArea(drawarea);

    if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0 &&
        pdev->surfaces_info[surface_id].draw_area.base_mem != NULL) {

        if (allocation_type == DEVICE_BITMAP_ALLOCATION_TYPE_RAM) {
            /* server side this surface is already destroyed, just free it here */
            ASSERT(pdev, pdev->surfaces_info[surface_id].draw_area.base_mem ==
                         pdev->surfaces_info[surface_id].copy);
            QXLDelSurface(pdev,
                          pdev->surfaces_info[surface_id].draw_area.base_mem,
                          allocation_type);
            FreeSurfaceInfo(pdev, surface_id);
        } else {
            QXLSurfaceCmd *surface_cmd;
            surface_cmd = SurfaceCmd(pdev, QXL_SURFACE_CMD_DESTROY, surface_id);
            QXLGetDelSurface(pdev, surface_cmd, surface_id, allocation_type);
            PushSurfaceCmd(pdev, surface_cmd);
        }
    }
}
Example #5
0
INT CmSurfaceManager::CreateSurface2D(CmOsResource * pCmOsResource,
				      BOOL bIsCmCreated,
				      CmSurface2D * &pSurface2D)
{
	UINT handle = 0;
	UINT index = m_pCmDevice->ValidSurfaceIndexStart();
	INT result = 0;
	UINT width = 0;
	UINT height = 0;
	UINT pitch = 0;
	CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_UNKNOWN;

	if (pCmOsResource == NULL) {
		return CM_INVALID_GENOS_RESOURCE_HANDLE;
	}

	pSurface2D = NULL;

	result = GetSurfaceInfo(pCmOsResource, width, height, pitch, format);
	if (result != CM_SUCCESS) {
		CM_ASSERT(0);
		return result;
	}
	result = Surface2DSanityCheck(width, height, format);
	if (result != CM_SUCCESS) {
		CM_ASSERT(0);
		return result;
	}
	if (GetFreeSurfaceIndex(index) != CM_SUCCESS) {
		CM_ASSERT(0);
		return CM_EXCEED_SURFACE_AMOUNT;
	}

	if (m_2DSurfaceCount >= m_max2DSurfaceCount) {
		CM_ASSERT(0);
		return CM_EXCEED_SURFACE_AMOUNT;
	}
	result =
	    AllocateSurface2D(width, height, format, pCmOsResource, handle);
	if (result != CM_SUCCESS) {
		CM_ASSERT(0);
		return result;
	}

	result =
	    CmSurface2D::Create(index, handle, width, height, pitch, format,
				bIsCmCreated, this, pSurface2D);
	if (result != CM_SUCCESS) {
		FreeSurface2D(handle);
		CM_ASSERT(0);
		return result;
	}

	m_SurfaceArray[index] = pSurface2D;
	UPDATE_PROFILE_FOR_2D_SURFACE(index, width, height, format, FALSE);

	return CM_SUCCESS;
}
Example #6
0
static void CleanupSurfaceInfo(PDev *pdev, UINT32 surface_id, UINT8 allocation_type)
{
    SurfaceInfo *surface_info = GetSurfaceInfo(pdev, surface_id);

    FreeDrawArea(&surface_info->draw_area);
    if (surface_info->draw_area.base_mem != NULL) {
        QXLDelSurface(pdev, surface_info->draw_area.base_mem, allocation_type);
    }
}
Example #7
0
BOOL MoveAllSurfacesToRam(PDev *pdev)
{
    UINT32 surface_id;
    SurfaceInfo *surface_info;
    SURFOBJ *surf_obj;
    UINT8 *copy;
    UINT8 *line0;
    int size;
    QXLPHYSICAL phys_mem;

    for (surface_id = 1 ; surface_id < pdev->n_surfaces ; ++surface_id) {
        surface_info = GetSurfaceInfo(pdev, surface_id);
        if (!surface_info->draw_area.base_mem) {
            continue;
        }
        surf_obj = surface_info->draw_area.surf_obj;
        if (!surf_obj) {
            DEBUG_PRINT((pdev, 3, "%s: %d: no surfobj, not copying\n", __FUNCTION__, surface_id));
            continue;
        }
        size = surf_obj->sizlBitmap.cy * abs(surf_obj->lDelta);
        copy = EngAllocMem(0, size, ALLOC_TAG);
        DEBUG_PRINT((pdev, 3, "%s: %d: copying #%d to %p (%d)\n", __FUNCTION__, surface_id, size,
            copy, surf_obj->lDelta));
        RtlCopyMemory(copy, surface_info->draw_area.base_mem, size);
        surface_info->copy = copy;
        line0 = surf_obj->lDelta > 0 ? copy : copy + abs(surf_obj->lDelta) *
                (surf_obj->sizlBitmap.cy - 1);
        if (!EngModifySurface((HSURF)surface_info->hbitmap,
                      pdev->eng,
                      0, /* from the example: used to monitor memory HOOK_COPYBITS | HOOK_BITBLT, */
                      0,                    /* It's system-memory */
                      (DHSURF)surface_info,
                      line0,
                      surf_obj->lDelta,
                      NULL)) {
            /* Send a create messsage for this surface - we previously did a destroy all. */
            EngFreeMem(surface_info->copy);
            surface_info->copy = NULL;
            DEBUG_PRINT((pdev, 0, "%s: %d: EngModifySurface failed, sending create for %d-%d\n",
                         __FUNCTION__, surface_id, surface_id, pdev->n_surfaces - 1));
            SendSurfaceRangeCreateCommand(pdev, surface_id, pdev->n_surfaces);
            return FALSE;
        }
        QXLDelSurface(pdev, surface_info->draw_area.base_mem, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);
        surface_info->draw_area.base_mem = copy;
        FreeDrawArea(&surface_info->draw_area);
    }
    return TRUE;
}
Example #8
0
HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *phys_mem,
                           UINT8 **base_mem, UINT32 surface_id, UINT8 allocation_type)
{
    UINT32 surface_format, depth;
    HBITMAP hbitmap;
    INT32 stride;
    SurfaceInfo *surface_info;

    DEBUG_PRINT((pdev, 9, "%s: %p: %d, (%dx%d), %d\n", __FUNCTION__, pdev, surface_id,
                size.cx, size.cy, format));
    surface_info = GetSurfaceInfo(pdev, surface_id);

    if (!(hbitmap = EngCreateDeviceBitmap((DHSURF)surface_info, size, format))) {
        DEBUG_PRINT((pdev, 0, "%s: EngCreateDeviceBitmap failed, pdev 0x%lx, surface_id=%d\n",
                    __FUNCTION__, pdev, surface_id));
        goto out_error1;
    }

    if (!EngAssociateSurface((HSURF)hbitmap, pdev->eng, QXL_SURFACE_HOOKS)) {
        DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__));
        goto out_error2;
    }
    surface_info->u.pdev = pdev;
    surface_info->hbitmap = hbitmap;
    surface_info->copy = NULL;
    surface_info->size = size;
    surface_info->bitmap_format = format;
    if ((*base_mem = CreateSurfaceHelper(pdev, surface_id, size.cx, size.cy, format,
                                         allocation_type, &stride, &surface_format,
                                         phys_mem)) == NULL) {
        DEBUG_PRINT((pdev, 0, "%s: failed, pdev 0x%lx, surface_id=%d\n",
                    __FUNCTION__, pdev, surface_id));
        goto out_error2;
    }
    surface_info->stride = stride;
    if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0) {
        SendSurfaceCreateCommand(pdev, surface_id, size, surface_format, -stride, *phys_mem, 0);
    }

    return hbitmap;
out_error2:
    EngDeleteSurface((HSURF)hbitmap);
out_error1:
    return 0;
}
Example #9
0
BOOL MoveSurfaceToVideoRam(PDev *pdev, UINT32 surface_id)
{
    QXLSurfaceCmd *surface;
    UINT32 surface_format;
    UINT32 depth;
    int count_used = 0;
    int size;
    INT32 stride = 0;
    QXLPHYSICAL phys_mem;
    SurfaceInfo *surface_info = GetSurfaceInfo(pdev, surface_id);
    UINT32 cx = surface_info->size.cx;
    UINT32 cy = surface_info->size.cy;
    UINT8 *base_mem;

    DEBUG_PRINT((pdev, 3, "%s: %d\n", __FUNCTION__, surface_id));
    if ((base_mem = CreateSurfaceHelper(pdev, surface_id, cx, cy, surface_info->bitmap_format,
                                        DEVICE_BITMAP_ALLOCATION_TYPE_VRAM,
                                        &stride, &surface_format, &phys_mem)) == NULL) {
        DEBUG_PRINT((pdev, 0, "%s: %p: %d: failed\n", __FUNCTION__, pdev, surface_id));
        return FALSE;
    }
    size = abs(stride) * cy;
    if (!EngModifySurface((HSURF)surface_info->hbitmap, pdev->eng, QXL_SURFACE_HOOKS,
        MS_NOTSYSTEMMEMORY, (DHSURF)surface_info, NULL, 0, NULL)) {
        DEBUG_PRINT((pdev, 0, "%s: %p: %d: EngModifySurface failed\n",
            __FUNCTION__, pdev, surface_id));
        CleanupSurfaceInfo(pdev, surface_id, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);
        return FALSE;
    }
    DEBUG_PRINT((pdev, 3, "%s: stride = %d, phys_mem = %0lX, base_mem = %p\n",
        __FUNCTION__, -stride, (uint64_t)phys_mem, base_mem));
    DEBUG_PRINT((pdev, 3, "%s: copy %d bytes to %d\n", __FUNCTION__, size, surface_id));
    // Everything allocated, nothing can fail (API wise) from this point
    RtlCopyMemory(base_mem, surface_info->copy, size);
    EngFreeMem(surface_info->copy);
    surface_info->copy = NULL;
    SendSurfaceCreateCommand(pdev, surface_id, surface_info->size, surface_format,
                             -stride, phys_mem, 1);
    return TRUE;
}
Example #10
0
/* when we return from S3 we need to resend all the surface creation commands.
 * Actually moving the memory vram<->guest is not strictly neccessary since vram
 * is not reset during the suspend, so contents are not lost */
int MoveAllSurfacesToVideoRam(PDev *pdev)
{
    UINT32 surface_id;
    SurfaceInfo *surface_info;

    /* brute force implementation - alternative is to keep an updated used_surfaces list */
    DEBUG_PRINT((pdev, 3, "%s %p\n", __FUNCTION__, pdev));

    for (surface_id = 1 ; surface_id < pdev->n_surfaces ; ++surface_id) {
        surface_info = GetSurfaceInfo(pdev, surface_id);
        if (!surface_info->draw_area.base_mem) {
            continue;
        }
        if (surface_info->u.pdev != pdev) {
            DEBUG_PRINT((pdev, 3, "%s: %p: not our pdev (%p)\n", __FUNCTION__, pdev,
                         surface_info->u.pdev));
            continue;
        }
        if (surface_info->draw_area.surf_obj) {
            DEBUG_PRINT((pdev, 3, "%s: surface_id = %d, surf_obj not empty\n", __FUNCTION__,
                         surface_id));
            continue;
        }
        if (surface_info->copy == NULL) {
            DEBUG_PRINT((pdev, 3, "%s: %p: %d: no copy buffer, ignored\n", __FUNCTION__,
                         pdev, surface_id));
            continue;
        }
        if (!MoveSurfaceToVideoRam(pdev, surface_id)) {
            /* Some of the surfaces have not been moved to video ram.
             * they will remain managed by GDI. */
            DEBUG_PRINT((pdev, 0, "%s: %p: %d: failed moving to vram\n", __FUNCTION__,
                         pdev, surface_id));
        }
    }
    return TRUE;
}
Example #11
0
	virtual void Complete_MT()
	{
// 		loader.LoadPVR_Bind( m_hw_texptr, 0 );
// 		gEnv->pFileSystem->closeResFile( pTextureFile );
		glActiveTexture(GL_TEXTURE0);
		glGenTextures(1, m_hw_texptr);
		glBindTexture(GL_TEXTURE_2D, *m_hw_texptr);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, iMipCount);

		uint32 RowBytes, NumRows;
		for( int i = 0; i < iMipCount; i++ )
		{
			GetSurfaceInfo( iWidth, iHeight, fmt, NULL, &RowBytes, &NumRows );

			
			{
				//BYTE* pDestBits = ( BYTE* )LockedRect.pBits;
				if (IsCompressedTex(fmt))
				{
					glCompressedTexImage2D(
						GL_TEXTURE_2D,
						i,
						fmt,
						iWidth, 
						iHeight, 
						0, 
						RowBytes * NumRows, 
						pSrcBits);

					GLenum error = glGetError();
					if (error)
					{
						gkLogWarning(_T("bind compress texture error."));
					}		
				}
				else
				{

					//uint8* white = new uint8[iWidth * iHeight * 4];
					//memset(white, 0xff, iWidth * iHeight * 4);

					glTexImage2D(
						GL_TEXTURE_2D,
						i,
						fmt,
						iWidth,
						iHeight,
						0,
						GL_BGRA,
						GL_UNSIGNED_BYTE,
						pSrcBits
						);

					//delete white;

					GLenum error = glGetError();
					if (error)
					{
						gkLogWarning(_T("bind texture error."));
					}		
				}

				//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);


				pSrcBits += (RowBytes * NumRows);

			}

			GLenum error = glGetError();
			if (error)
			{
				gkLogWarning(_T("bind texture error."));
			}			

			iWidth = iWidth >> 1;
			iHeight = iHeight >> 1;
			if( iWidth == 0 )
				iWidth = 1;
			if( iHeight == 0 )
				iHeight = 1;
		}

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);



		gEnv->pFileSystem->closeResFile( pFile );
	}
//--------------------------------------------------------------------------------------
static HRESULT CreateTextureFromDDS( ID3D10Device* pDev, DDS_HEADER* pHeader, BYTE* pBitData,
                                     UINT BitSize, ID3D10ShaderResourceView** ppSRV, bool bSRGB )
{
    HRESULT hr = S_OK;

    UINT iWidth = pHeader->dwWidth;
    UINT iHeight = pHeader->dwHeight;
    UINT iMipCount = pHeader->dwMipMapCount;
    if( 0 == iMipCount )
        iMipCount = 1;

    D3D10_TEXTURE2D_DESC desc;
    if ((  pHeader->ddspf.dwFlags & DDS_FOURCC )
        && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC ) )
    {
        DDS_HEADER_DXT10* d3d10ext = (DDS_HEADER_DXT10*)( (char*)pHeader + sizeof(DDS_HEADER) );
        desc.ArraySize = d3d10ext->arraySize;
        desc.Format = d3d10ext->dxgiFormat;

        // For now, we only support 2D textures
        if ( d3d10ext->resourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE2D )
            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }
    else
    {
        desc.ArraySize = 1;
        desc.Format = GetDXGIFormat( pHeader->ddspf );

        if (pHeader->dwCubemapFlags != 0
            || (pHeader->dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) )
        {
            // For now only support 2D textures, not cubemaps or volumes
            return E_FAIL;
        }

        if( desc.Format == DXGI_FORMAT_UNKNOWN )
        {
            D3DFORMAT fmt = GetD3D9Format( pHeader->ddspf );

            // Swizzle some RGB to BGR common formats to be DXGI (1.0) supported
            switch( fmt )
            {
            case D3DFMT_X8R8G8B8:
            case D3DFMT_A8R8G8B8:
                {
                    desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    
                    for( UINT i = 0; i < BitSize; i += 4 )
                    {
                        BYTE a = pBitData[i];
                        pBitData[i] = pBitData[i + 2];
                        pBitData[i + 2] = a;
                    }
                }
                break;

            // Need more room to try to swizzle 24bpp or 4bpp formats

            default:
                return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
            }
        }
    }
    
    if ( bSRGB )
        desc.Format = MAKE_SRGB( desc.Format );

    // Create the texture
    desc.Width = iWidth;
    desc.Height = iHeight;
    desc.MipLevels = iMipCount;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Usage = D3D10_USAGE_DEFAULT;
    desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;

    ID3D10Texture2D* pTex2D;
    D3D10_SUBRESOURCE_DATA* pInitData = new D3D10_SUBRESOURCE_DATA[iMipCount];
    if( !pInitData )
        return E_OUTOFMEMORY;

    UINT NumBytes = 0;
    UINT RowBytes = 0;
    UINT NumRows = 0;
    BYTE* pSrcBits = pBitData;
    for( UINT j = 0; j < desc.ArraySize; j++ )
    {
        for( UINT i = 0; i < iMipCount; i++ )
        {
            GetSurfaceInfo( iWidth, iHeight, desc.Format, &NumBytes, &RowBytes, &NumRows );
            pInitData[i].pSysMem = ( void* )pSrcBits;
            pInitData[i].SysMemPitch = RowBytes;
    
            pSrcBits += NumBytes;
            iWidth = iWidth >> 1;
            iHeight = iHeight >> 1;
            if( iWidth == 0 )
                iWidth = 1;
            if( iHeight == 0 )
                iHeight = 1;
        }
    }

    hr = pDev->CreateTexture2D( &desc, pInitData, &pTex2D );
    if( SUCCEEDED( hr ) && pTex2D )
    {
        D3D10_SHADER_RESOURCE_VIEW_DESC SRVDesc;
        ZeroMemory( &SRVDesc, sizeof( SRVDesc ) );
        SRVDesc.Format = desc.Format;
        SRVDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
        SRVDesc.Texture2D.MipLevels = desc.MipLevels;
        hr = pDev->CreateShaderResourceView( pTex2D, &SRVDesc, ppSRV );
        SAFE_RELEASE( pTex2D );
    }

    SAFE_DELETE( pInitData );

    return hr;
}
//--------------------------------------------------------------------------------------
HRESULT CreateTextureFromDDS( LPDIRECT3DDEVICE9 pDev, DDS_HEADER* pHeader, BYTE* pBitData, UINT BitSize,
                              LPDIRECT3DTEXTURE9* ppTex )
{
    HRESULT hr = S_OK;
    D3DLOCKED_RECT LockedRect;

    UINT iWidth = pHeader->dwWidth;
    UINT iHeight = pHeader->dwHeight;
    UINT iMipCount = pHeader->dwMipMapCount;
    if( 0 == iMipCount )
        iMipCount = 1;

    if (pHeader->dwCubemapFlags != 0
        || (pHeader->dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) )
    {
        // For now only support 2D textures, not cubemaps or volumes
        return E_FAIL;
    }

    D3DFORMAT fmt = GetD3D9Format( pHeader->ddspf );

    // Create the texture
    LPDIRECT3DTEXTURE9 pTexture;
    LPDIRECT3DTEXTURE9 pStagingTexture;
    hr = pDev->CreateTexture( iWidth,
                              iHeight,
                              iMipCount,
                              0, // usage
                              fmt,
                              D3DPOOL_DEFAULT,
                              &pTexture,
                              NULL );
    if( FAILED( hr ) )
        return hr;

    hr = pDev->CreateTexture( iWidth,
                              iHeight,
                              iMipCount,
                              0, // usage
                              fmt,
                              D3DPOOL_SYSTEMMEM,
                              &pStagingTexture,
                              NULL );
    if( FAILED( hr ) )
    {
        SAFE_RELEASE( pTexture );
        return hr;
    }

    // Lock, fill, unlock
    UINT RowBytes, NumRows;
    BYTE* pSrcBits = pBitData;

    for( UINT i = 0; i < iMipCount; i++ )
    {
        GetSurfaceInfo( iWidth, iHeight, fmt, NULL, &RowBytes, &NumRows );

        if( SUCCEEDED( pStagingTexture->LockRect( i, &LockedRect, NULL, 0 ) ) )
        {
            BYTE* pDestBits = ( BYTE* )LockedRect.pBits;

            // Copy stride line by line
            for( UINT h = 0; h < NumRows; h++ )
            {
                CopyMemory( pDestBits, pSrcBits, RowBytes );
                pDestBits += LockedRect.Pitch;
                pSrcBits += RowBytes;
            }

            pStagingTexture->UnlockRect( i );
        }

        iWidth = iWidth >> 1;
        iHeight = iHeight >> 1;
        if( iWidth == 0 )
            iWidth = 1;
        if( iHeight == 0 )
            iHeight = 1;
    }

    hr = pDev->UpdateTexture( pStagingTexture, pTexture );
    SAFE_RELEASE( pStagingTexture );
    if( FAILED( hr ) )
        return hr;

    // Set the result
    *ppTex = pTexture;
    return hr;
}
Example #14
0
static LPDIRECT3DTEXTURE9 LoadBC45TextureFromFileInMemory(LPDIRECT3DDEVICE9 pDevice, const void *data, int size, bool NONPOW2) {
  if ((((DDS_HEADER *)data)->ddspf.dwFourCC != FOURCC_ATI1N) &&
      (((DDS_HEADER *)data)->ddspf.dwFourCC != FOURCC_ATI2N))
    return NULL;

#if 0
  // Check if ATI1N is supported
  hr = lastOBGEDirect3D9->CheckDeviceFormat(AdapterOrdinal, DeviceType, AdapterFormat,
    0, D3DRTYPE_TEXTURE, FOURCC_ATI1N);
  BOOL bATI1NSupported = (hr == D3D_OK);
  • To check support for ATI2N:
  // Check if ATI2N is supported
  HRESULT hr;
  hr = lastOBGEDirect3D9->CheckDeviceFormat(AdapterOrdinal, DeviceType, AdapterFormat,
    0, D3DRTYPE_TEXTURE, FOURCC_ATI2N);
  BOOL bATI2NSupported = (hr == D3D_OK);
#endif

  LPDIRECT3DTEXTURE9 GPUTexture = NULL;
  HRESULT res;

  if (FAILED(res = pDevice->CreateTexture(
	((DDS_HEADER *)data)->dwWidth,
	((DDS_HEADER *)data)->dwHeight,
	((DDS_HEADER *)data)->dwMipMapCount,
	0, (D3DFORMAT)
	((DDS_HEADER *)data)->ddspf.dwFourCC,
	D3DPOOL_MANAGED,
	&GPUTexture,
	NULL)))
    return NULL;

  // Lock, fill, unlock
  D3DLOCKED_RECT LockedRect;
  UINT RowBytes, NumRows;
  BYTE *pSrcBits = (BYTE *)data + sizeof(DDS_HEADER);

  UINT iWidth = ((DDS_HEADER *)data)->dwWidth;
  UINT iHeight = ((DDS_HEADER *)data)->dwHeight;
  UINT iMipCount = ((DDS_HEADER *)data)->dwMipMapCount;
  DWORD iFourCC = ((DDS_HEADER *)data)->ddspf.dwFourCC;
  if (0 == iMipCount)
    iMipCount = 1;

  for (UINT i = 0; i < iMipCount; i++) {
    GetSurfaceInfo(iWidth, iHeight, iFourCC, NULL, &RowBytes, &NumRows);

    if (SUCCEEDED(GPUTexture->LockRect(i, &LockedRect, NULL, 0))) {
      BYTE *pDestBits = (BYTE *)LockedRect.pBits;

#if 1
      int size = (iWidth * iHeight * (iFourCC == FOURCC_ATI2N ? 2 : 1)) >> 1;
      CopyMemory(pDestBits, pSrcBits, size);
      pDestBits += size;
      pSrcBits += size;
#else
      // Copy stride line by line
      for (UINT h = 0; h < NumRows; h++) {
	CopyMemory(pDestBits, pSrcBits, RowBytes);

	pDestBits += LockedRect.Pitch;
	pSrcBits += RowBytes;
      }
#endif

      GPUTexture->UnlockRect(i);
    }

    iWidth  = iWidth  >> 1;
    iHeight = iHeight >> 1;

    if (iWidth == 0)
      iWidth = 1;
    if (iHeight == 0)
      iHeight = 1;
  }