Exemplo n.º 1
0
Bitmap::Bitmap(const Graphics& g, const Bitmap& bitmap)
{
    if (this == &bitmap)
        return;

    m_platformBitmap = ThePlatformFactory->CreatePlatformBitmap(
        g.GetPlatformGraphics(), bitmap.Width(), bitmap.Height(),
        bitmap.BitsPerPixel());

    uchar* bits = new uchar[Height() * BytesPerLine()];
    bitmap.GetBits(g, bits, 0, Height(), BitsPerPixel());
    SetBits(g, bits, 0, Height(), BitsPerPixel());
    delete[] bits;
}
Exemplo n.º 2
0
static void
XAAGetImage (
    DrawablePtr pDraw,
    int	sx, int sy, int w, int h,
    unsigned int    format,
    unsigned long   planemask,
    char	    *pdstLine 
)
{
    ScreenPtr pScreen = pDraw->pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    ScrnInfoPtr pScrn = infoRec->pScrn;

    if(pScrn->vtSema && 
	((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) 
    {
	if(infoRec->ReadPixmap && (format == ZPixmap) && 
	   ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == 
                           infoRec->FullPlanemasks[pDraw->depth - 1]) &&
	   (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
	{
	    (*infoRec->ReadPixmap)(pScrn, 
		   sx + pDraw->x, sy + pDraw->y, w, h,
		   (unsigned char *)pdstLine,
		   PixmapBytePad(w, pDraw->depth), 
		   pDraw->bitsPerPixel, pDraw->depth);
	    return;
	}
	SYNC_CHECK(pDraw);
    }

    XAA_SCREEN_PROLOGUE (pScreen, GetImage);
    (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
    XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
}
Exemplo n.º 3
0
void RenderWindow2D::Blit(unsigned int destX, unsigned int destY, const PalettedSurface& buffer)
{
   if (BitsPerPixel() == 32)
      Blit32(destX, destY, buffer);
   else
      Blit16(destX, destY, buffer);
}
Exemplo n.º 4
0
/*
 * RootlessUpdateScreenPixmap
 *  miCreateScreenResources does not like a null framebuffer pointer,
 *  it leaves the screen pixmap with an uninitialized data pointer.
 *  Thus, rootless implementations typically set the framebuffer width
 *  to zero so that miCreateScreenResources does not allocate a screen
 *  pixmap for us. We allocate our own screen pixmap here since we need
 *  the screen pixmap to be valid (e.g. CopyArea from the root window).
 */
void
RootlessUpdateScreenPixmap(ScreenPtr pScreen)
{
    RootlessScreenRec *s = SCREENREC(pScreen);
    PixmapPtr pPix;
    unsigned int rowbytes;

    pPix = (*pScreen->GetScreenPixmap)(pScreen);
    if (pPix == NULL) {
        pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
        (*pScreen->SetScreenPixmap)(pPix);
    }

    rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);

    if (s->pixmap_data_size < rowbytes) {
        free(s->pixmap_data);

        s->pixmap_data_size = rowbytes;
        s->pixmap_data = malloc(s->pixmap_data_size);
        if (s->pixmap_data == NULL)
            return;

        memset(s->pixmap_data, 0xFF, s->pixmap_data_size);

        pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
                                    pScreen->rootDepth,
                                    BitsPerPixel(pScreen->rootDepth),
                                    0, s->pixmap_data);
        /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
           by hand. */
        pPix->devKind = 0;
    }
}
Exemplo n.º 5
0
static PixmapPtr 
kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
    PixmapPtr		pPixmap;
    KaaPixmapPrivPtr	pKaaPixmap;
    int			bpp;
    
    bpp = BitsPerPixel (depth);
    if (bpp == 32 && depth == 24)
    {
	int fb;
	KdScreenPriv (pScreen);
	
	for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++)
	    if (pScreenPriv->screen->fb[fb].depth == 24)
	    {
		bpp = pScreenPriv->screen->fb[fb].bitsPerPixel;
		break;
	    }
    }

    pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp);
    if (!pPixmap)
	return NULL;
    pKaaPixmap = KaaGetPixmapPriv(pPixmap);
    if (!w || !h)
	pKaaPixmap->score = KAA_PIXMAP_SCORE_PINNED;
    else
	pKaaPixmap->score = KAA_PIXMAP_SCORE_INIT;
    
    pKaaPixmap->area = NULL;
    pKaaPixmap->dirty = FALSE;

    return pPixmap;
}
Exemplo n.º 6
0
static PixmapPtr
xwl_dri3_pixmap_from_fd(ScreenPtr screen, int fd,
                        CARD16 width, CARD16 height, CARD16 stride,
                        CARD8 depth, CARD8 bpp)
{
    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
    struct gbm_import_fd_data data;
    struct gbm_bo *bo;
    PixmapPtr pixmap;

    if (width == 0 || height == 0 ||
        depth < 15 || bpp != BitsPerPixel(depth) || stride < width * bpp / 8)
        return NULL;

    data.fd = fd;
    data.width = width;
    data.height = height;
    data.stride = stride;
    data.format = gbm_format_for_depth(depth);
    bo = gbm_bo_import(xwl_screen->gbm, GBM_BO_IMPORT_FD, &data,
                       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
    if (bo == NULL)
        return NULL;

    pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
    if (pixmap == NULL) {
        gbm_bo_destroy(bo);
        return NULL;
    }

    return pixmap;
}
Exemplo n.º 7
0
/* this plugs into pScreen->ModifyPixmapHeader */
Bool
miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
                     int bitsPerPixel, int devKind, void *pPixData)
{
    if (!pPixmap)
        return FALSE;

    /*
     * If all arguments are specified, reinitialize everything (including
     * validated state).
     */
    if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
        (devKind > 0) && pPixData) {
        pPixmap->drawable.depth = depth;
        pPixmap->drawable.bitsPerPixel = bitsPerPixel;
        pPixmap->drawable.id = 0;
        pPixmap->drawable.x = 0;
        pPixmap->drawable.y = 0;
        pPixmap->drawable.width = width;
        pPixmap->drawable.height = height;
        pPixmap->devKind = devKind;
        pPixmap->refcnt = 1;
        pPixmap->devPrivate.ptr = pPixData;
    }
    else {
        /*
         * Only modify specified fields, keeping all others intact.
         */

        if (width > 0)
            pPixmap->drawable.width = width;

        if (height > 0)
            pPixmap->drawable.height = height;

        if (depth > 0)
            pPixmap->drawable.depth = depth;

        if (bitsPerPixel > 0)
            pPixmap->drawable.bitsPerPixel = bitsPerPixel;
        else if ((bitsPerPixel < 0) && (depth > 0))
            pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);

        /*
         * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
         *          other purposes.
         */
        if (devKind > 0)
            pPixmap->devKind = devKind;
        else if ((devKind < 0) && ((width > 0) || (depth > 0)))
            pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
                                             pPixmap->drawable.depth);

        if (pPixData)
            pPixmap->devPrivate.ptr = pPixData;
    }
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    return TRUE;
}
Exemplo n.º 8
0
Bool
fbCreateGC(GCPtr pGC)
{
    pGC->ops = (GCOps *) & fbGCOps;
    pGC->funcs = (GCFuncs *) & fbGCFuncs;

    /* fb wants to translate before scan conversion */
    pGC->miTranslate = 1;
    pGC->fExpose = 1;

    fbGetGCPrivate(pGC)->bpp = BitsPerPixel(pGC->depth);
    return TRUE;
}
		bool TextureOpenGL::Load()
		{
			OpenGLContextStackLock lock;

#if defined ION_RENDER_SUPPORTS_SDL2IMAGE
			//Load image onto a new SDL surface
			SDL_Surface* sdlSurface = IMG_Load(m_imageFilename.c_str());

			if(!sdlSurface)
			{
				debug::log << "TextureOpenGL::Load() - Error loading " << m_imageFilename.c_str() << ", IMG_Load() failed with: " << IMG_GetError() << debug::end;
			}

			if(sdlSurface)
			{
				//Get dimensions
				m_width = sdlSurface->w;
				m_height = sdlSurface->h;

				//Convert to RGBA
                SDL_PixelFormat format;
                format.palette = 0;
                format.BitsPerPixel = 32;
                format.BytesPerPixel = 4;
                
#if defined ION_ENDIAN_LITTLE
                format.Rmask = 0xFF000000; format.Rshift =  0; format.Rloss = 0;
                format.Gmask = 0x00FF0000; format.Gshift =  8; format.Gloss = 0;
                format.Bmask = 0x0000FF00; format.Bshift = 16; format.Bloss = 0;
                format.Amask = 0x000000FF; format.Ashift = 24; format.Aloss = 0;
#else
                format.Rmask = 0x000000FF; format.Rshift = 24; format.Rloss = 0;
                format.Gmask = 0x0000FF00; format.Gshift = 16; format.Gloss = 0;
                format.Bmask = 0x00FF0000; format.Bshift =  8; format.Bloss = 0;
                format.Amask = 0xFF000000; format.Ashift =  0; format.Aloss = 0;
#endif
				
                SDL_Surface* surfaceRGBA = SDL_ConvertSurface(sdlSurface, &format, SDL_SWSURFACE);
                
				//Load image to OpenGL texture
				Load(m_width, m_height, Format::RGBA, Format::RGBA, BitsPerPixel(surfaceRGBA->format->BytesPerPixel * 8), true, false, (const u8*)surfaceRGBA->pixels);

				//Free SDL surface
				SDL_FreeSurface(sdlSurface);
			}
#endif

			return m_glTextureId != 0;
		}
Exemplo n.º 10
0
Arquivo: shm.c Projeto: Agnarr/xserver
static PixmapPtr
fbShmCreatePixmap (ScreenPtr pScreen,
		   int width, int height, int depth, char *addr)
{
    PixmapPtr pPixmap;

    pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
    if (!pPixmap)
	return NullPixmap;

    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
	(*pScreen->DestroyPixmap)(pPixmap);
	return NullPixmap;
    }
    return pPixmap;
}
Exemplo n.º 11
0
/*
 * If the given request doesn't exactly match PutImage's constraints,
 * wrap the image in a scratch pixmap header and let CopyArea sort it out.
 */
static void
doShmPutImage(DrawablePtr dst, GCPtr pGC,
              int depth, unsigned int format,
              int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
              char *data)
{
    PixmapPtr pPixmap;

    if (format == ZPixmap || (format == XYPixmap && depth == 1)) {
        pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
                                         BitsPerPixel(depth),
                                         PixmapBytePad(w, depth), data);
        if (!pPixmap)
            return;
        pGC->ops->CopyArea((DrawablePtr) pPixmap, dst, pGC, sx, sy, sw, sh, dx,
                           dy);
        FreeScratchPixmapHeader(pPixmap);
    }
    else {
        GCPtr putGC = GetScratchGC(depth, dst->pScreen);

        if (!putGC)
            return;

        pPixmap = (*dst->pScreen->CreatePixmap) (dst->pScreen, sw, sh, depth,
                                                 CREATE_PIXMAP_USAGE_SCRATCH);
        if (!pPixmap) {
            FreeScratchGC(putGC);
            return;
        }
        ValidateGC(&pPixmap->drawable, putGC);
        (*putGC->ops->PutImage) (&pPixmap->drawable, putGC, depth, -sx, -sy, w,
                                 h, 0,
                                 (format == XYPixmap) ? XYPixmap : ZPixmap,
                                 data);
        FreeScratchGC(putGC);
        if (format == XYBitmap)
            (void) (*pGC->ops->CopyPlane) (&pPixmap->drawable, dst, pGC, 0, 0,
                                           sw, sh, dx, dy, 1L);
        else
            (void) (*pGC->ops->CopyArea) (&pPixmap->drawable, dst, pGC, 0, 0,
                                          sw, sh, dx, dy);
        (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
    }
}
//--------------------------------------------------------------------------------------
// Get surface information for a particular format
//--------------------------------------------------------------------------------------
static void GetSurfaceInfo( UINT width, UINT height, D3DFORMAT fmt, UINT* pNumBytes, UINT* pRowBytes, UINT* pNumRows )
{
    UINT numBytes = 0;
    UINT rowBytes = 0;
    UINT numRows = 0;

    // From the DXSDK docs:
    //
    //     When computing DXTn compressed sizes for non-square textures, the 
    //     following formula should be used at each mipmap level:
    //
    //         max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
    //
    //     The pitch for DXTn formats is different from what was returned in 
    //     Microsoft DirectX 7.0. It now refers the pitch of a row of blocks. 
    //     For example, if you have a width of 16, then you will have a pitch 
    //     of four blocks (4*8 for DXT1, 4*16 for DXT2-5.)"

    if( fmt == D3DFMT_DXT1 || fmt == D3DFMT_DXT2 || fmt == D3DFMT_DXT3 || fmt == D3DFMT_DXT4 || fmt == D3DFMT_DXT5 )
    {
        int numBlocksWide = 0;
        if( width > 0 )
            numBlocksWide = max( 1, width / 4 );
        int numBlocksHigh = 0;
        if( height > 0 )
            numBlocksHigh = max( 1, height / 4 );
        int numBytesPerBlock = ( fmt == D3DFMT_DXT1 ? 8 : 16 );
        rowBytes = numBlocksWide * numBytesPerBlock;
        numRows = numBlocksHigh;
    }
    else
    {
        UINT bpp = BitsPerPixel( fmt );
        rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
        numRows = height;
    }
    numBytes = rowBytes * numRows;
    if( pNumBytes != NULL )
        *pNumBytes = numBytes;
    if( pRowBytes != NULL )
        *pRowBytes = rowBytes;
    if( pNumRows != NULL )
        *pNumRows = numRows;
}
Exemplo n.º 13
0
static void GetSurfaceInfo(UINT width, UINT height, DWORD FourCC, UINT *pNumBytes, UINT *pRowBytes, UINT *pNumRows) {
  UINT numBytes = 0;
  UINT rowBytes = 0;
  UINT numRows = 0;

  bool bc = true;
  int bcnumBytesPerBlock = 16;
  switch (FourCC) {
    case FOURCC_ATI1N:
      bcnumBytesPerBlock = 8;
      break;
    case FOURCC_ATI2N:
      bcnumBytesPerBlock = 16;
      break;
    default:
      bc = false;
      break;
  }

  if (bc) {
    int numBlocksWide = 0;
    if (width > 0)
      numBlocksWide = max(1, width / 4);
    int numBlocksHigh = 0;
    if (height > 0)
      numBlocksHigh = max(1, height / 4);

    rowBytes = numBlocksWide * bcnumBytesPerBlock;
    numRows = numBlocksHigh;
  }
  else {
    UINT bpp = BitsPerPixel(FourCC);
    rowBytes = (width * bpp + 7) / 8; // round up to nearest byte
    numRows = height;
  }

  numBytes = rowBytes * numRows;
  if (pNumBytes != NULL)
    *pNumBytes = numBytes;
  if (pRowBytes != NULL)
    *pRowBytes = rowBytes;
  if (pNumRows != NULL)
    *pNumRows = numRows;
}
Exemplo n.º 14
0
Bool
fbCreateGC(GCPtr pGC)
{
    pGC->clientClip = NULL;
    pGC->clientClipType = CT_NONE;

    pGC->ops = (GCOps *) &fbGCOps;
    pGC->funcs = (GCFuncs *) &fbGCFuncs;

    /* fb wants to translate before scan conversion */
    pGC->miTranslate = 1;

    fbGetRotatedPixmap(pGC) = 0;
    fbGetExpose(pGC) = 1;
    fbGetFreeCompClip(pGC) = 0;
    fbGetCompositeClip(pGC) = 0;
    fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
    return TRUE;
}
Exemplo n.º 15
0
/* With the introduction of pixmap privates, the "screen pixmap" can no
 * longer be created in miScreenInit, since all the modules that could
 * possibly ask for pixmap private space have not been initialized at
 * that time.  pScreen->CreateScreenResources is called after all
 * possible private-requesting modules have been inited; we create the
 * screen pixmap here.
 */
Bool
miCreateScreenResources(ScreenPtr pScreen)
{
    miScreenInitParmsPtr pScrInitParms;
    void *value;

    pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;

    /* if width is non-zero, pScreen->devPrivate will be a pixmap
     * else it will just take the value pbits
     */
    if (pScrInitParms->width) {
        PixmapPtr pPixmap;

        /* create a pixmap with no data, then redirect it to point to
         * the screen
         */
        pPixmap =
            (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
        if (!pPixmap)
            return FALSE;

        if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
                                             pScreen->height,
                                             pScreen->rootDepth,
                                             BitsPerPixel(pScreen->rootDepth),
                                             PixmapBytePad(pScrInitParms->width,
                                                           pScreen->rootDepth),
                                             pScrInitParms->pbits))
            return FALSE;
        value = (void *) pPixmap;
    }
    else {
        value = pScrInitParms->pbits;
    }
    free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
    pScreen->devPrivate = value;        /* pPixmap or pbits */
    return TRUE;
}
Exemplo n.º 16
0
void Texture::Create( size_t Width, size_t Height, DXGI_FORMAT Format, const void* InitData )
{
	m_UsageState = D3D12_RESOURCE_STATE_COMMON;

	D3D12_RESOURCE_DESC textDesc = {};
	textDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
	textDesc.Width = Width;
	textDesc.Height = (UINT)Height;
	textDesc.DepthOrArraySize = 1;
	textDesc.MipLevels = 1;
	textDesc.Format = Format;
	textDesc.SampleDesc.Count = 1;
	textDesc.SampleDesc.Quality = 0;
	textDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
	textDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

	D3D12_HEAP_PROPERTIES HeapProps;
	HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
	HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
	HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
	HeapProps.CreationNodeMask = 1;
	HeapProps.VisibleNodeMask = 1;

	HRESULT hr;
	V( Graphics::g_device->CreateCommittedResource( &HeapProps, D3D12_HEAP_FLAG_NONE, &textDesc,
		m_UsageState, nullptr, IID_PPV_ARGS( m_pResource.ReleaseAndGetAddressOf() ) ) );
	m_pResource->SetName( L"Texture" );

	D3D12_SUBRESOURCE_DATA texResource;
	texResource.pData = InitData;
	texResource.RowPitch = Width * BitsPerPixel( Format ) / 8;
	texResource.SlicePitch = texResource.RowPitch * Height;

	CommandContext::InitializeTexture( *this, 1, &texResource );

	if (m_hCpuDescriptorHandle.ptr == ~0ull)
		m_hCpuDescriptorHandle = Graphics::g_pCSUDescriptorHeap->Append().GetCPUHandle();
	Graphics::g_device->CreateShaderResourceView( m_pResource.Get(), nullptr, m_hCpuDescriptorHandle );
}
Exemplo n.º 17
0
Bool
winUpdateFBPointer(ScreenPtr pScreen, void *pbits)
{
    winScreenPriv(pScreen);
    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;

    /* Location of shadow framebuffer has changed */
    pScreenInfo->pfb = pbits;

    /* Update the screen pixmap */
    if (!(*pScreen->ModifyPixmapHeader) (pScreen->devPrivate,
                                         pScreen->width,
                                         pScreen->height,
                                         pScreen->rootDepth,
                                         BitsPerPixel(pScreen->rootDepth),
                                         PixmapBytePad(pScreenInfo->dwStride,
                                                       pScreenInfo->dwBPP),
                                         pScreenInfo->pfb)) {
        FatalError("winUpdateFramebufferPointer - Failed modifying "
                   "screen pixmap\n");
    }

    return TRUE;
}
Exemplo n.º 18
0
static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
                                     _In_ float alphaRef )
{
    if ( !image.pixels || !result.pixels )
        return E_POINTER;

    // Parallel version doesn't support degenerate case
    assert( ((image.width % 4) == 0) && ((image.height % 4) == 0 ) );

    assert( image.width == result.width );
    assert( image.height == result.height );

    const DXGI_FORMAT format = image.format;
    size_t sbpp = BitsPerPixel( format );
    if ( !sbpp )
        return E_FAIL;

    if ( sbpp < 8 )
    {
        // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Round to bytes
    sbpp = ( sbpp + 7 ) / 8;

    // Determine BC format encoder
    BC_ENCODE pfEncode;
    size_t blocksize;
    switch(result.format)
    {
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfEncode = nullptr;         blocksize = 8;   break;
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfEncode = D3DXEncodeBC2;   blocksize = 16;  break;
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfEncode = D3DXEncodeBC3;   blocksize = 16;  break;
    case DXGI_FORMAT_BC4_UNORM:         pfEncode = D3DXEncodeBC4U;  blocksize = 8;   break;
    case DXGI_FORMAT_BC4_SNORM:         pfEncode = D3DXEncodeBC4S;  blocksize = 8;   break;
    case DXGI_FORMAT_BC5_UNORM:         pfEncode = D3DXEncodeBC5U;  blocksize = 16;  break;
    case DXGI_FORMAT_BC5_SNORM:         pfEncode = D3DXEncodeBC5S;  blocksize = 16;  break;
    case DXGI_FORMAT_BC6H_UF16:         pfEncode = D3DXEncodeBC6HU; blocksize = 16;  break;
    case DXGI_FORMAT_BC6H_SF16:         pfEncode = D3DXEncodeBC6HS; blocksize = 16;  break;
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfEncode = D3DXEncodeBC7;   blocksize = 16;  break;
    default:
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Refactored version of loop to support parallel independance
    const size_t nBlocks = std::max<size_t>(1, image.width / 4) * std::max<size_t>(1, image.height / 4);

    bool fail = false;

#pragma omp parallel for
    for( int nb=0; nb < static_cast<int>( nBlocks ); ++nb )
    {
        const size_t nbWidth = std::max<size_t>(1, image.width / 4);

        const size_t y = nb / nbWidth;
        const size_t x = nb - (y*nbWidth);

        assert( x < image.width && y < image.height );

        size_t rowPitch = image.rowPitch;
        const uint8_t *pSrc = image.pixels + (y*4*rowPitch) + (x*4*sbpp);

        uint8_t *pDest = result.pixels + (nb*blocksize);

        XMVECTOR temp[16];
        if ( !_LoadScanline( &temp[0], 4, pSrc, rowPitch, format ) )
            fail = true;

        if ( !_LoadScanline( &temp[4], 4, pSrc + rowPitch, rowPitch, format ) )
            fail = true;

        if ( !_LoadScanline( &temp[8], 4, pSrc + rowPitch*2, rowPitch, format ) )
            fail = true;

        if ( !_LoadScanline( &temp[12], 4, pSrc + rowPitch*3, rowPitch, format ) )
            fail = true;

        _ConvertScanline( temp, 16, result.format, format, 0 );
            
        if ( pfEncode )
            pfEncode( pDest, temp, bcflags );
        else
            D3DXEncodeBC1( pDest, temp, alphaRef, bcflags );
    }

    return (fail) ? E_FAIL : S_OK;
}
Exemplo n.º 19
0
//-------------------------------------------------------------------------------------
static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result )
{
    if ( !cImage.pixels || !result.pixels )
        return E_POINTER;

    assert( cImage.width == result.width );
    assert( cImage.height == result.height );

    // Image must be a multiple of 4 (degenerate cases of 1x1, 1x2, 2x1, and 2x2 are allowed)
    size_t width = cImage.width;
    if ( (width % 4) != 0 )
    {
        if ( width != 1 && width != 2 )
            return E_INVALIDARG;
    }

    size_t height = cImage.height;
    if ( (height % 4) != 0 )
    {
        if ( height != 1 && height != 2 )
            return E_INVALIDARG;
    }

    const DXGI_FORMAT format = result.format;
    size_t dbpp = BitsPerPixel( format );
    if ( !dbpp )
        return E_FAIL;

    if ( dbpp < 8 )
    {
        // We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM)
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Round to bytes
    dbpp = ( dbpp + 7 ) / 8;

    uint8_t *pDest = result.pixels;
    if ( !pDest )
        return E_POINTER;

    // Promote "typeless" BC formats
    DXGI_FORMAT cformat;
    switch( cImage.format )
    {
    case DXGI_FORMAT_BC1_TYPELESS:  cformat = DXGI_FORMAT_BC1_UNORM; break;
    case DXGI_FORMAT_BC2_TYPELESS:  cformat = DXGI_FORMAT_BC2_UNORM; break;
    case DXGI_FORMAT_BC3_TYPELESS:  cformat = DXGI_FORMAT_BC3_UNORM; break;
    case DXGI_FORMAT_BC4_TYPELESS:  cformat = DXGI_FORMAT_BC4_UNORM; break;
    case DXGI_FORMAT_BC5_TYPELESS:  cformat = DXGI_FORMAT_BC5_UNORM; break;
    case DXGI_FORMAT_BC6H_TYPELESS: cformat = DXGI_FORMAT_BC6H_UF16; break;
    case DXGI_FORMAT_BC7_TYPELESS:  cformat = DXGI_FORMAT_BC7_UNORM; break;
    default:                        cformat = cImage.format;         break;
    }

    // Determine BC format decoder
    BC_DECODE pfDecode;
    size_t sbpp;
    switch(cformat)
    {
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfDecode = D3DXDecodeBC1;   sbpp = 8;   break;
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfDecode = D3DXDecodeBC2;   sbpp = 16;  break;
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfDecode = D3DXDecodeBC3;   sbpp = 16;  break;
    case DXGI_FORMAT_BC4_UNORM:         pfDecode = D3DXDecodeBC4U;  sbpp = 8;   break;
    case DXGI_FORMAT_BC4_SNORM:         pfDecode = D3DXDecodeBC4S;  sbpp = 8;   break;
    case DXGI_FORMAT_BC5_UNORM:         pfDecode = D3DXDecodeBC5U;  sbpp = 16;  break;
    case DXGI_FORMAT_BC5_SNORM:         pfDecode = D3DXDecodeBC5S;  sbpp = 16;  break;
    case DXGI_FORMAT_BC6H_UF16:         pfDecode = D3DXDecodeBC6HU; sbpp = 16;  break;
    case DXGI_FORMAT_BC6H_SF16:         pfDecode = D3DXDecodeBC6HS; sbpp = 16;  break;
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfDecode = D3DXDecodeBC7;   sbpp = 16;  break;
    default:
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    XMVECTOR temp[16];
    const uint8_t *pSrc = cImage.pixels;
    const size_t rowPitch = result.rowPitch;
    for( size_t h=0; h < cImage.height; h += 4 )
    {
        const uint8_t *sptr = pSrc;
        uint8_t* dptr = pDest;
        for( size_t count = 0; count < cImage.rowPitch; count += sbpp )
        {
            pfDecode( temp, sptr );
            _ConvertScanline( temp, 16, format, cformat, 0 );

            if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], 4 ) )
                return E_FAIL;

            if ( result.height > 1 )
            {
                if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], 4 ) )
                    return E_FAIL;

                if ( result.height > 2 )
                {
                    if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], 4 ) )
                        return E_FAIL;

                    if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], 4 ) )
                        return E_FAIL;
                }
            }

            sptr += sbpp;
            dptr += dbpp*4;
        }

        pSrc += cImage.rowPitch;
        pDest += rowPitch*4;
    }

    return S_OK;
}
Exemplo n.º 20
0
//-------------------------------------------------------------------------------------
static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
                            _In_ DWORD srgb, _In_ float alphaRef )
{
    if ( !image.pixels || !result.pixels )
        return E_POINTER;

    assert( image.width == result.width );
    assert( image.height == result.height );

    const DXGI_FORMAT format = image.format;
    size_t sbpp = BitsPerPixel( format );
    if ( !sbpp )
        return E_FAIL;

    if ( sbpp < 8 )
    {
        // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Round to bytes
    sbpp = ( sbpp + 7 ) / 8;

    uint8_t *pDest = result.pixels;

    // Determine BC format encoder
    BC_ENCODE pfEncode;
    size_t blocksize;
    DWORD cflags;
    if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

    XMVECTOR temp[16];
    const uint8_t *pSrc = image.pixels;
    const size_t rowPitch = image.rowPitch;
    for( size_t h=0; h < image.height; h += 4 )
    {
        const uint8_t *sptr = pSrc;
        uint8_t* dptr = pDest;
        size_t ph = std::min<size_t>( 4, image.height - h );
        size_t w = 0;
        for( size_t count = 0; count < rowPitch; count += sbpp*4, w += 4 )
        {
            size_t pw = std::min<size_t>( 4, image.width - w );
            assert( pw > 0 && ph > 0 );

            if ( !_LoadScanline( &temp[0], pw, sptr, rowPitch, format ) )
                return E_FAIL;

            if ( ph > 1 )
            {
                if ( !_LoadScanline( &temp[4], pw, sptr + rowPitch, rowPitch, format ) )
                    return E_FAIL;

                if ( ph > 2 )
                {
                    if ( !_LoadScanline( &temp[8], pw, sptr + rowPitch*2, rowPitch, format ) )
                        return E_FAIL;

                    if ( ph > 3 )
                    {
                        if ( !_LoadScanline( &temp[12], pw, sptr + rowPitch*3, rowPitch, format ) )
                            return E_FAIL;
                    }
                }
            }

            if ( pw != 4 || ph != 4 )
            {
                // Replicate pixels for partial block
                static const size_t uSrc[] = { 0, 0, 0, 1 };

                if ( pw < 4 )
                {
                    for( size_t t = 0; t < ph && t < 4; ++t )
                    {
                        for( size_t s = pw; s < 4; ++s )
                        {
#pragma prefast(suppress: 26000, "PREFAST false positive")
                            temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ]; 
                        }
                    }
                }

                if ( ph < 4 )
                {
                    for( size_t t = ph; t < 4; ++t )
                    {
                        for( size_t s = 0; s < 4; ++s )
                        {
#pragma prefast(suppress: 26000, "PREFAST false positive")
                            temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ]; 
                        }
                    }
                }
            }

            _ConvertScanline( temp, 16, result.format, format, cflags | srgb );
            
            if ( pfEncode )
                pfEncode( dptr, temp, bcflags );
            else
                D3DXEncodeBC1( dptr, temp, alphaRef, bcflags );

            sptr += sbpp*4;
            dptr += blocksize;
        }

        pSrc += rowPitch*4;
        pDest += result.rowPitch;
    }

    return S_OK;
}
Exemplo n.º 21
0
//-------------------------------------------------------------------------------------
static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result )
{
    if ( !cImage.pixels || !result.pixels )
        return E_POINTER;

    assert( cImage.width == result.width );
    assert( cImage.height == result.height );

    const DXGI_FORMAT format = result.format;
    size_t dbpp = BitsPerPixel( format );
    if ( !dbpp )
        return E_FAIL;

    if ( dbpp < 8 )
    {
        // We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM)
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Round to bytes
    dbpp = ( dbpp + 7 ) / 8;

    uint8_t *pDest = result.pixels;
    if ( !pDest )
        return E_POINTER;

    // Promote "typeless" BC formats
    DXGI_FORMAT cformat;
    switch( cImage.format )
    {
    case DXGI_FORMAT_BC1_TYPELESS:  cformat = DXGI_FORMAT_BC1_UNORM; break;
    case DXGI_FORMAT_BC2_TYPELESS:  cformat = DXGI_FORMAT_BC2_UNORM; break;
    case DXGI_FORMAT_BC3_TYPELESS:  cformat = DXGI_FORMAT_BC3_UNORM; break;
    case DXGI_FORMAT_BC4_TYPELESS:  cformat = DXGI_FORMAT_BC4_UNORM; break;
    case DXGI_FORMAT_BC5_TYPELESS:  cformat = DXGI_FORMAT_BC5_UNORM; break;
    case DXGI_FORMAT_BC6H_TYPELESS: cformat = DXGI_FORMAT_BC6H_UF16; break;
    case DXGI_FORMAT_BC7_TYPELESS:  cformat = DXGI_FORMAT_BC7_UNORM; break;
    default:                        cformat = cImage.format;         break;
    }

    // Determine BC format decoder
    BC_DECODE pfDecode;
    size_t sbpp;
    switch(cformat)
    {
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfDecode = D3DXDecodeBC1;   sbpp = 8;   break;
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfDecode = D3DXDecodeBC2;   sbpp = 16;  break;
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfDecode = D3DXDecodeBC3;   sbpp = 16;  break;
    case DXGI_FORMAT_BC4_UNORM:         pfDecode = D3DXDecodeBC4U;  sbpp = 8;   break;
    case DXGI_FORMAT_BC4_SNORM:         pfDecode = D3DXDecodeBC4S;  sbpp = 8;   break;
    case DXGI_FORMAT_BC5_UNORM:         pfDecode = D3DXDecodeBC5U;  sbpp = 16;  break;
    case DXGI_FORMAT_BC5_SNORM:         pfDecode = D3DXDecodeBC5S;  sbpp = 16;  break;
    case DXGI_FORMAT_BC6H_UF16:         pfDecode = D3DXDecodeBC6HU; sbpp = 16;  break;
    case DXGI_FORMAT_BC6H_SF16:         pfDecode = D3DXDecodeBC6HS; sbpp = 16;  break;
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfDecode = D3DXDecodeBC7;   sbpp = 16;  break;
    default:
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    XMVECTOR temp[16];
    const uint8_t *pSrc = cImage.pixels;
    const size_t rowPitch = result.rowPitch;
    for( size_t h=0; h < cImage.height; h += 4 )
    {
        const uint8_t *sptr = pSrc;
        uint8_t* dptr = pDest;
        size_t ph = std::min<size_t>( 4, cImage.height - h );
        size_t w = 0;
        for( size_t count = 0; count < cImage.rowPitch; count += sbpp, w += 4 )
        {
            pfDecode( temp, sptr );
            _ConvertScanline( temp, 16, format, cformat, 0 );

            size_t pw = std::min<size_t>( 4, cImage.width - w );
            assert( pw > 0 && ph > 0 );

            if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], pw ) )
                return E_FAIL;

            if ( ph > 1 )
            {
                if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], pw ) )
                    return E_FAIL;

                if ( ph > 2 )
                {
                    if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], pw ) )
                        return E_FAIL;

                    if ( ph > 3 )
                    {
                        if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], pw ) )
                            return E_FAIL;
                    }
                }
            }

            sptr += sbpp;
            dptr += dbpp*4;
        }

        pSrc += cImage.rowPitch;
        pDest += rowPitch*4;
    }

    return S_OK;
}
Exemplo n.º 22
0
Arquivo: shm.c Projeto: Agnarr/xserver
static int
ProcShmCreatePixmap(ClientPtr client)
{
    PixmapPtr pMap;
    DrawablePtr pDraw;
    DepthPtr pDepth;
    int i, rc;
    ShmDescPtr shmdesc;
    ShmScrPrivateRec *screen_priv;
    REQUEST(xShmCreatePixmapReq);
    unsigned int width, height, depth;
    unsigned long size;

    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
    client->errorValue = stuff->pid;
    if (!sharedPixmaps)
	return BadImplementation;
    LEGAL_NEW_RESOURCE(stuff->pid, client);
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
			   DixGetAttrAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
    
    width = stuff->width;
    height = stuff->height;
    depth = stuff->depth;
    if (!width || !height || !depth)
    {
	client->errorValue = 0;
        return BadValue;
    }
    if (width > 32767 || height > 32767)
	return BadAlloc;

    if (stuff->depth != 1)
    {
        pDepth = pDraw->pScreen->allowedDepths;
        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
	   if (pDepth->depth == stuff->depth)
               goto CreatePmap;
	client->errorValue = stuff->depth;
        return BadValue;
    }

CreatePmap:
    size = PixmapBytePad(width, depth) * height;
    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
	if (size < width * height)
	    return BadAlloc;
    }
    /* thankfully, offset is unsigned */
    if (stuff->offset + size < size)
	return BadAlloc;

    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
    screen_priv = ShmGetScreenPriv(pDraw->pScreen);
    pMap = (*screen_priv->shmFuncs->CreatePixmap)(
			    pDraw->pScreen, stuff->width,
			    stuff->height, stuff->depth,
			    shmdesc->addr + stuff->offset);
    if (pMap)
    {
	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
		      pMap, RT_NONE, NULL, DixCreateAccess);
	if (rc != Success) {
	    pDraw->pScreen->DestroyPixmap(pMap);
	    return rc;
	}
	dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
	shmdesc->refcnt++;
	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	pMap->drawable.id = stuff->pid;
	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
	{
	    return Success;
	}
	pDraw->pScreen->DestroyPixmap(pMap);
    }
    return BadAlloc;
}
Exemplo n.º 23
0
Arquivo: shm.c Projeto: Agnarr/xserver
static int
ProcPanoramiXShmCreatePixmap(ClientPtr client)
{
    ScreenPtr pScreen = NULL;
    PixmapPtr pMap = NULL;
    DrawablePtr pDraw;
    DepthPtr pDepth;
    int i, j, result, rc;
    ShmDescPtr shmdesc;
    REQUEST(xShmCreatePixmapReq);
    unsigned int width, height, depth;
    unsigned long size;
    PanoramiXRes *newPix;

    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
    client->errorValue = stuff->pid;
    if (!sharedPixmaps)
	return BadImplementation;
    LEGAL_NEW_RESOURCE(stuff->pid, client);
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
			   DixGetAttrAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);

    width = stuff->width;
    height = stuff->height;
    depth = stuff->depth;
    if (!width || !height || !depth)
    {
	client->errorValue = 0;
        return BadValue;
    }
    if (width > 32767 || height > 32767)
        return BadAlloc;

    if (stuff->depth != 1)
    {
        pDepth = pDraw->pScreen->allowedDepths;
        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
	   if (pDepth->depth == stuff->depth)
               goto CreatePmap;
	client->errorValue = stuff->depth;
        return BadValue;
    }

CreatePmap:
    size = PixmapBytePad(width, depth) * height;
    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
        if (size < width * height)
            return BadAlloc;
    }
    /* thankfully, offset is unsigned */
    if (stuff->offset + size < size)
	return BadAlloc;

    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);

    if(!(newPix = malloc(sizeof(PanoramiXRes))))
	return BadAlloc;

    newPix->type = XRT_PIXMAP;
    newPix->u.pix.shared = TRUE;
    newPix->info[0].id = stuff->pid;
    for(j = 1; j < PanoramiXNumScreens; j++)
	newPix->info[j].id = FakeClientID(client->index);

    result = Success;

    FOR_NSCREENS(j) {
	ShmScrPrivateRec *screen_priv;
	pScreen = screenInfo.screens[j];

	screen_priv = ShmGetScreenPriv(pScreen);
	pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
				stuff->width, stuff->height, stuff->depth,
				shmdesc->addr + stuff->offset);

	if (pMap) {
	    dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
            shmdesc->refcnt++;
	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	    pMap->drawable.id = newPix->info[j].id;
	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
		(*pScreen->DestroyPixmap)(pMap);
		result = BadAlloc;
		break;
	    }
	} else {
	   result = BadAlloc;
	   break;
	}
    }

    if(result == BadAlloc) {
	while(j--) {
	    (*pScreen->DestroyPixmap)(pMap);
	    FreeResource(newPix->info[j].id, RT_NONE);
	}
	free(newPix);
    } else 
	AddResource(stuff->pid, XRT_PIXMAP, newPix);

    return result;
}
Exemplo n.º 24
0
bool TestRenderer::LoadTexture(const std::wstring& filename, ID3D11ShaderResourceView** srv)
{
    FileHandle texFile(CreateFile(filename.c_str(), GENERIC_READ,
        FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
    if (!texFile.IsValid())
    {
        LogError(L"Failed to open texture.");
        return false;
    }

    DWORD bytesRead{};
    uint32_t fileSize = GetFileSize(texFile.Get(), nullptr);

    TextureHeader texHeader{};
    if (!ReadFile(texFile.Get(), &texHeader, sizeof(texHeader), &bytesRead, nullptr))
    {
        LogError(L"Failed to read texture.");
        return false;
    }

    if (texHeader.Signature != TextureHeader::ExpectedSignature)
    {
        LogError(L"Invalid texture file.");
        return false;
    }

    uint32_t pixelDataSize = fileSize - sizeof(TextureHeader);
    std::unique_ptr<uint8_t[]> pixelData(new uint8_t[pixelDataSize]);
    if (!ReadFile(texFile.Get(), pixelData.get(), pixelDataSize, &bytesRead, nullptr))
    {
        LogError(L"Failed to read texture data.");
        return false;
    }

    D3D11_TEXTURE2D_DESC td{};
    td.ArraySize = texHeader.ArrayCount;
    td.Format = texHeader.Format;
#if USE_SRGB
    if (td.Format == DXGI_FORMAT_R8G8B8A8_UNORM)
    {
        td.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
    }
    else if (td.Format == DXGI_FORMAT_B8G8R8A8_UNORM)
    {
        td.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
    }
#endif
    td.Width = texHeader.Width;
    td.Height = texHeader.Height;
    td.MipLevels = texHeader.MipLevels;
    td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    td.SampleDesc.Count = 1;
    td.Usage = D3D11_USAGE_DEFAULT;

    D3D11_SUBRESOURCE_DATA init[20] {};
    uint32_t bpp = (uint32_t)BitsPerPixel(td.Format) / 8;

    ComPtr<ID3D11Texture2D> texture;
    HRESULT hr = S_OK;

    // Only try to use mips if width & height are the same size
    if (td.Width == td.Height && td.MipLevels > 1)
    {
        uint32_t width = td.Width;
        uint32_t height = td.Height;
        uint8_t* pPixels = pixelData.get();

        for (int m = 0; m < (int)td.MipLevels; ++m)
        {
            init[m].pSysMem = pPixels;
            init[m].SysMemPitch = width * bpp;
            init[m].SysMemSlicePitch = width * height * bpp;

            width = max(width >> 1, 1);
            height = max(height >> 1, 1);
            pPixels += init[m].SysMemSlicePitch;
        }

        hr = Device->CreateTexture2D(&td, init, &texture);
    }
Exemplo n.º 25
0
		size_t numBlocksHigh = 0;
		if (height > 0)
		{
			numBlocksHigh = std::max<size_t>(1, (height + 3) / 4);
		}
		rowBytes = numBlocksWide * bcnumBytesPerBlock;
		numRows = numBlocksHigh;
	}
	else if (packed)
	{
		rowBytes = ((width + 1) >> 1) * 4;
		numRows = height;
	}
	else
	{
		size_t bpp = BitsPerPixel(fmt);
		rowBytes = (width * bpp + 7) / 8; // round up to nearest byte
		numRows = height;
	}

	numBytes = rowBytes * numRows;
	if (outNumBytes)
	{
		*outNumBytes = numBytes;
	}
	if (outRowBytes)
	{
		*outRowBytes = rowBytes;
	}
	if (outNumRows)
	{
Exemplo n.º 26
0
//-------------------------------------------------------------------------------------
static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
                            _In_ float alphaRef, _In_ bool degenerate )
{
    if ( !image.pixels || !result.pixels )
        return E_POINTER;

    assert( image.width == result.width );
    assert( image.height == result.height );

    const DXGI_FORMAT format = image.format;
    size_t sbpp = BitsPerPixel( format );
    if ( !sbpp )
        return E_FAIL;

    if ( sbpp < 8 )
    {
        // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Round to bytes
    sbpp = ( sbpp + 7 ) / 8;

    uint8_t *pDest = result.pixels;

    // Determine BC format encoder
    BC_ENCODE pfEncode;
    size_t blocksize;
    switch(result.format)
    {
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfEncode = nullptr;         blocksize = 8;   break;
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfEncode = D3DXEncodeBC2;   blocksize = 16;  break;
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfEncode = D3DXEncodeBC3;   blocksize = 16;  break;
    case DXGI_FORMAT_BC4_UNORM:         pfEncode = D3DXEncodeBC4U;  blocksize = 8;   break;
    case DXGI_FORMAT_BC4_SNORM:         pfEncode = D3DXEncodeBC4S;  blocksize = 8;   break;
    case DXGI_FORMAT_BC5_UNORM:         pfEncode = D3DXEncodeBC5U;  blocksize = 16;  break;
    case DXGI_FORMAT_BC5_SNORM:         pfEncode = D3DXEncodeBC5S;  blocksize = 16;  break;
    case DXGI_FORMAT_BC6H_UF16:         pfEncode = D3DXEncodeBC6HU; blocksize = 16;  break;
    case DXGI_FORMAT_BC6H_SF16:         pfEncode = D3DXEncodeBC6HS; blocksize = 16;  break;
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfEncode = D3DXEncodeBC7;   blocksize = 16;  break;
    default:
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    XMVECTOR temp[16];
    const uint8_t *pSrc = image.pixels;
    const size_t rowPitch = image.rowPitch;
    for( size_t h=0; h < image.height; h += 4 )
    {
        const uint8_t *sptr = pSrc;
        uint8_t* dptr = pDest;
        for( size_t count = 0; count < rowPitch; count += sbpp*4 )
        {
            if ( !_LoadScanline( &temp[0], 4, sptr, rowPitch, format ) )
                return E_FAIL;

            if ( image.height > 1 )
            {
                if ( !_LoadScanline( &temp[4], 4, sptr + rowPitch, rowPitch, format ) )
                    return E_FAIL;

                if ( image.height > 2 )
                {
                    if ( !_LoadScanline( &temp[8], 4, sptr + rowPitch*2, rowPitch, format ) )
                        return E_FAIL;

                    if ( !_LoadScanline( &temp[12], 4, sptr + rowPitch*3, rowPitch, format ) )
                        return E_FAIL;
                }
            }

            if ( degenerate )
            {
                assert( image.width < 4 || image.height < 4 );
                const size_t uSrc[] = { 0, 0, 0, 1 };

                if ( image.width < 4 )
                {
                    for( size_t t=0; t < image.height && t < 4; ++t )
                    {
                        for( size_t s = image.width; s < 4; ++s )
                        {
                            temp[ t*4 + s ] = temp[ t*4 + uSrc[s] ]; 
                        }
                    }
                }

                if ( image.height < 4 )
                {
                    for( size_t t=image.height; t < 4; ++t )
                    {
                        for( size_t s =0; s < 4; ++s )
                        {
                            temp[ t*4 + s ] = temp[ uSrc[t]*4 + s ]; 
                        }
                    }
                }
            }

            _ConvertScanline( temp, 16, result.format, format, 0 );
            
            if ( pfEncode )
                pfEncode( dptr, temp, bcflags );
            else
                D3DXEncodeBC1( dptr, temp, alphaRef, bcflags );

            sptr += sbpp*4;
            dptr += blocksize;
        }

        pSrc += rowPitch*4;
        pDest += result.rowPitch;
    }

    return S_OK;
}
Exemplo n.º 27
0
/**
 * glamor_trapezoids will generate trapezoid mask accumulating in
 * system memory.
 */
void
glamor_trapezoids(CARD8 op,
                  PicturePtr src, PicturePtr dst,
                  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
                  int ntrap, xTrapezoid *traps)
{
    ScreenPtr screen = dst->pDrawable->pScreen;
    BoxRec bounds;
    PicturePtr picture;
    INT16 x_dst, y_dst;
    INT16 x_rel, y_rel;
    int width, height, stride;
    PixmapPtr pixmap;
    pixman_image_t *image = NULL;

    /* If a mask format wasn't provided, we get to choose, but behavior should
     * be as if there was no temporary mask the traps were accumulated into.
     */
    if (!mask_format) {
        if (dst->polyEdge == PolyEdgeSharp)
            mask_format = PictureMatchFormat(screen, 1, PICT_a1);
        else
            mask_format = PictureMatchFormat(screen, 8, PICT_a8);
        for (; ntrap; ntrap--, traps++)
            glamor_trapezoids(op, src, dst, mask_format, x_src,
                              y_src, 1, traps);
        return;
    }

    miTrapezoidBounds(ntrap, traps, &bounds);

    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
        return;

    x_dst = traps[0].left.p1.x >> 16;
    y_dst = traps[0].left.p1.y >> 16;

    width = bounds.x2 - bounds.x1;
    height = bounds.y2 - bounds.y1;
    stride = PixmapBytePad(width, mask_format->depth);

    picture = glamor_create_mask_picture(screen, dst, mask_format,
                                         width, height);
    if (!picture)
        return;

    image = pixman_image_create_bits(picture->format,
                                     width, height, NULL, stride);
    if (!image) {
        FreePicture(picture, 0);
        return;
    }

    for (; ntrap; ntrap--, traps++)
        pixman_rasterize_trapezoid(image,
                                   (pixman_trapezoid_t *) traps,
                                   -bounds.x1, -bounds.y1);

    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);

    screen->ModifyPixmapHeader(pixmap, width, height,
                               mask_format->depth,
                               BitsPerPixel(mask_format->depth),
                               PixmapBytePad(width,
                                             mask_format->depth),
                               pixman_image_get_data(image));

    x_rel = bounds.x1 + x_src - x_dst;
    y_rel = bounds.y1 + y_src - y_dst;

    CompositePicture(op, src, picture, dst,
                     x_rel, y_rel,
                     0, 0,
                     bounds.x1, bounds.y1,
                     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);

    if (image)
        pixman_image_unref(image);

    FreePicture(picture, 0);
}
Exemplo n.º 28
0
void
fbPutImage (DrawablePtr	pDrawable,
	    GCPtr	pGC,
	    int		depth,
	    int		x,
	    int		y,
	    int		w,
	    int		h,
	    int		leftPad,
	    int		format,
	    char	*pImage)
{
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    unsigned long   i;
    FbStride	    srcStride;
    FbStip	    *src = (FbStip *) pImage;
    
    x += pDrawable->x;
    y += pDrawable->y;
    
    switch (format)
    {
    case XYBitmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	fbPutXYImage (pDrawable,
		      fbGetCompositeClip(pGC),
		      pPriv->fg,
		      pPriv->bg,
		      pPriv->pm,
		      pGC->alu,
		      TRUE,
		      x, y, w, h,
		      src,
		      srcStride,
		      leftPad);
	break;
    case XYPixmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	for (i = 1 << (pDrawable->depth - 1); i; i >>= 1)
	{
	    if (i & pGC->planemask)
	    {
		fbPutXYImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      FB_ALLONES,
			      0,
			      fbReplicatePixel (i, pDrawable->bitsPerPixel),
			      pGC->alu,
			      TRUE,
			      x, y, w, h,
			      src,
			      srcStride,
			      leftPad);
		src += srcStride * h;
	    }
	}
	break;
    case ZPixmap:
#ifdef FB_24_32BIT
	if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth);
	    fb24_32PutZImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      pGC->alu,
			      (FbBits) pGC->planemask,
			      x, y, w, h,
			      (CARD8 *) pImage,
			      srcStride);
	}
	else
#endif
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip);
	    fbPutZImage (pDrawable,
			 fbGetCompositeClip(pGC),
			 pGC->alu,
			 pPriv->pm,
			 x, y, w, h, 
			 src, srcStride);
	}
    }
}
Exemplo n.º 29
0
static void
winShadowUpdateDD (ScreenPtr pScreen, 
		   shadowBufPtr pBuf)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RegionPtr		damage = shadowDamage(pBuf);
  HRESULT		ddrval = DD_OK;
  RECT			rcDest, rcSrc;
  POINT			ptOrigin;
  DWORD			dwBox = REGION_NUM_RECTS (damage);
  BoxPtr		pBox = REGION_RECTS (damage);
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
      || pScreenPriv->fBadDepth) return;

  /* Get the origin of the window in the screen coords */
  ptOrigin.x = pScreenInfo->dwXOffset;
  ptOrigin.y = pScreenInfo->dwYOffset;
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);

  /* Unlock the shadow surface, so we can blit */
  ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Unlock failed\n");
      return;
    }

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (pScreenInfo->dwClipUpdatesNBoxes == 0
      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /* Assign damage box to source rectangle */
	  rcSrc.left = pBox->x1;
	  rcSrc.top = pBox->y1;
	  rcSrc.right = pBox->x2;
	  rcSrc.bottom = pBox->y2;
	  
	  /* Calculate destination rectange */
	  rcDest.left = ptOrigin.x + rcSrc.left;
	  rcDest.top = ptOrigin.y + rcSrc.top;
	  rcDest.right = ptOrigin.x + rcSrc.right;
	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
	  
	  /* Blit the damaged areas */
	  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					    &rcDest,
					    pScreenPriv->pddsShadow,
					    &rcSrc,
					    DDBLT_WAIT,
					    NULL);
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else
    {
      BoxPtr		pBoxExtents = REGION_EXTENTS (pScreen, damage);

      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}  

      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      DeleteObject (hrgnCombined);
      hrgnCombined = NULL;

      /* Calculating a bounding box for the source is easy */
      rcSrc.left = pBoxExtents->x1;
      rcSrc.top = pBoxExtents->y1;
      rcSrc.right = pBoxExtents->x2;
      rcSrc.bottom = pBoxExtents->y2;

      /* Calculating a bounding box for the destination is trickier */
      rcDest.left = ptOrigin.x + rcSrc.left;
      rcDest.top = ptOrigin.y + rcSrc.top;
      rcDest.right = ptOrigin.x + rcSrc.right;
      rcDest.bottom = ptOrigin.y + rcSrc.bottom;
      
      /* Our Blt should be clipped to the invalidated region */
      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					&rcDest,
					pScreenPriv->pddsShadow,
					&rcSrc,
					DDBLT_WAIT,
					NULL);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }

  /* Relock the shadow surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
				     NULL,
				     pScreenPriv->pddsdShadow,
				     DDLOCK_WAIT,
				     NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Lock failed\n");
      return;
    }

  /* Has our memory pointer changed? */
  if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
    {
      ErrorF ("winShadowUpdateDD - Memory location of the shadow "
	      "surface has changed, trying to update the root window "
	      "pixmap header to point to the new address.  If you get "
	      "this message and "PROJECT_NAME" freezes or crashes "
	      "after this message then send a problem report and your "
	      "%s file to " BUILDERADDR, g_pszLogFile);

      /* Location of shadow framebuffer has changed */
      pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface;
      
      /* Update the screen pixmap */
      if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate,
					  pScreen->width,
					  pScreen->height,
					  pScreen->rootDepth,
					  BitsPerPixel (pScreen->rootDepth),
					  PixmapBytePad (pScreenInfo->dwStride,
							 pScreenInfo->dwBPP),
					  pScreenInfo->pfb))
	{
	  ErrorF ("winShadowUpdateDD - Bits changed, could not "
		  "notify fb.\n");
	  return;
	}
    }
}
Exemplo n.º 30
0
void
fbGetImage (DrawablePtr	    pDrawable,
	    int		    x,
	    int		    y,
	    int		    w,
	    int		    h,
	    unsigned int    format,
	    unsigned long   planeMask,
	    char	    *d)
{
    FbBits	    *src;
    FbStride	    srcStride;
    int		    srcBpp;
    int		    srcXoff, srcYoff;
    FbStip	    *dst;
    FbStride	    dstStride;
    
    /*
     * XFree86 DDX empties the root borderClip when the VT is
     * switched away; this checks for that case
     */
    if (!fbDrawableEnabled(pDrawable))
	return;
    
#ifdef FB_24_32BIT
    if (format == ZPixmap &&
	pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth))
    {
	fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d);
	return;
    }
#endif
    
    fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
    
    x += pDrawable->x;
    y += pDrawable->y;
    
    dst = (FbStip *) d;
    if (format == ZPixmap || srcBpp == 1)
    {
	FbBits	pm;

	pm = fbReplicatePixel (planeMask, srcBpp);
	dstStride = PixmapBytePad(w, pDrawable->depth);
	if (pm != FB_ALLONES)
	    memset (d, 0, dstStride * h);
	dstStride /= sizeof (FbStip);
	fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride), 
		   FbBitsStrideToStipStride(srcStride),
		   (x + srcXoff) * srcBpp,
		   
		   dst,
		   dstStride,
		   0,
		   
		   w * srcBpp, h,

		   GXcopy,
		   pm,
		   srcBpp);
    }
    else
    {
	dstStride = BitmapBytePad(w) / sizeof (FbStip);
	fbBltPlane (src + (y + srcYoff) * srcStride,
		    srcStride, 
		    (x + srcXoff) * srcBpp,
		    srcBpp,

		    dst,
		    dstStride,
		    0,
		    
		    w * srcBpp, h,

		    fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
		    fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
		    fbAndStip(GXcopy,0,FB_STIP_ALLONES),
		    fbXorStip(GXcopy,0,FB_STIP_ALLONES),
		    planeMask);
    }
}