//----------------------------------------------------------------------------- void D3D11HardwarePixelBuffer::unlockImpl(void) { if(mUsage == HBU_STATIC) _unmapstagingbuffer(); else if(mUsage & HBU_DYNAMIC) { if(mCurrentLockOptions == HBL_READ_ONLY || mCurrentLockOptions == HBL_NORMAL || mCurrentLockOptions == HBL_WRITE_ONLY) { size_t sizeinbytes = D3D11Mappings::_getSizeInBytes(mParentTexture->getFormat(), mParentTexture->getWidth(), mParentTexture->getHeight()); PixelBox box; _map(mParentTexture->getTextureResource(), D3D11_MAP_WRITE_DISCARD, box); void *data = box.data; memcpy(data, mCurrentLock.data, sizeinbytes); // unmap the texture and the staging buffer _unmap(mParentTexture->getTextureResource()); _unmapstagingbuffer(false); } else _unmap(mParentTexture->getTextureResource()); } else _unmapstaticbuffer(); _genMipmaps(); }
//----------------------------------------------------------------------------- void D3D10HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) { bool isDds = false; switch(mFormat) { case PF_DXT1: case PF_DXT2: case PF_DXT3: case PF_DXT4: case PF_DXT5: isDds = true; break; default: break; } if (isDds && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 )) { return; } // for scoped deletion of conversion buffer MemoryDataStreamPtr buf; PixelBox converted = src; D3D10_BOX dstBoxDx10 = OgreImageBoxToDx10Box(dstBox); // convert to pixelbuffer's native format if necessary if (src.format != mFormat) { buf.bind(new MemoryDataStream( PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), mFormat))); converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); PixelUtil::bulkPixelConversion(src, converted); } // In d3d10 the Row Pitch is defined as: "The size of one row of the source data" and not // the same as the OGRE row pitch - meaning that we need to multiple the OGRE row pitch // with the size in bytes of the element to get the d3d10 row pitch. UINT d3dRowPitch = static_cast<UINT>(converted.rowPitch) * static_cast<UINT>(PixelUtil::getNumElemBytes(mFormat)); switch(mParentTexture->getTextureType()) { case TEX_TYPE_1D: { mDevice->UpdateSubresource( mParentTexture->GetTex1D(), 0, &dstBoxDx10, converted.data, 0, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot update 1d subresource\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_CUBE_MAP: case TEX_TYPE_2D: { mDevice->UpdateSubresource( mParentTexture->GetTex2D(), static_cast<UINT>(mSubresourceIndex), &dstBoxDx10, converted.data, d3dRowPitch, mFace ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot update 2d subresource\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_3D: { mDevice->UpdateSubresource( mParentTexture->GetTex2D(), static_cast<UINT>(mSubresourceIndex), &dstBoxDx10, converted.data, d3dRowPitch, static_cast<UINT>(converted.slicePitch) ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot update 3d subresource\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blitFromMemory"); } } break; } if (!isDds) { _genMipmaps(); } }
void D3D10HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &rsrc, const Image::Box &srcBox, const Image::Box &dstBox) { if ( (srcBox.getWidth() != dstBox.getWidth()) || (srcBox.getHeight() != dstBox.getHeight()) || (srcBox.getDepth() != dstBox.getDepth()) ) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot copy a subresource - source and dest size are not the same and they have to be the same in DX10.", "D3D10HardwarePixelBuffer::blit"); } D3D10_BOX srcBoxDx10 = OgreImageBoxToDx10Box(srcBox); D3D10HardwarePixelBuffer * rsrcDx10 = static_cast<D3D10HardwarePixelBuffer *>(rsrc.get()); switch(mParentTexture->getTextureType()) { case TEX_TYPE_1D: { mDevice->CopySubresourceRegion( mParentTexture->GetTex1D(), static_cast<UINT>(mSubresourceIndex), static_cast<UINT>(dstBox.left), 0, 0, rsrcDx10->mParentTexture->GetTex1D(), static_cast<UINT>(rsrcDx10->mSubresourceIndex), &srcBoxDx10); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot copy 1d subresource Region\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blit"); } } break; case TEX_TYPE_CUBE_MAP: case TEX_TYPE_2D: { mDevice->CopySubresourceRegion( mParentTexture->GetTex2D(), static_cast<UINT>(mSubresourceIndex), static_cast<UINT>(dstBox.left), static_cast<UINT>(dstBox.top), mFace, rsrcDx10->mParentTexture->GetTex2D(), static_cast<UINT>(rsrcDx10->mSubresourceIndex), &srcBoxDx10); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot copy 2d subresource Region\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blit"); } } break; case TEX_TYPE_3D: { mDevice->CopySubresourceRegion( mParentTexture->GetTex2D(), static_cast<UINT>(mSubresourceIndex), static_cast<UINT>(dstBox.left), static_cast<UINT>(dstBox.top), static_cast<UINT>(dstBox.front), rsrcDx10->mParentTexture->GetTex2D(), static_cast<UINT>(rsrcDx10->mSubresourceIndex), &srcBoxDx10); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D10 device cannot copy 3d subresource Region\nError Description:" + errorDescription, "D3D10HardwarePixelBuffer::blit"); } } break; } _genMipmaps(); }
//----------------------------------------------------------------------------- void D3D11HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) { bool isDds = false; switch(mFormat) { case PF_DXT1: case PF_DXT2: case PF_DXT3: case PF_DXT4: case PF_DXT5: isDds = true; break; default: break; } if (isDds && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 )) { return; } // for scoped deletion of conversion buffer MemoryDataStreamPtr buf; PixelBox converted = src; D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(dstBox); dstBoxDx11.front = 0; dstBoxDx11.back = converted.getDepth(); // convert to pixelbuffer's native format if necessary if (src.format != mFormat) { buf.bind(new MemoryDataStream( PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), mFormat))); converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); PixelUtil::bulkPixelConversion(src, converted); } if (mUsage & HBU_DYNAMIC) { size_t sizeinbytes; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one row of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 8; } else { // 128 bits (16 bytes) per 4x4 block sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 16; } } else { sizeinbytes = converted.getHeight() * converted.getWidth() * PixelUtil::getNumElemBytes(converted.format); } const Ogre::PixelBox &locked = lock(dstBox, HBL_DISCARD); memcpy(locked.data, converted.data, sizeinbytes); unlock(); } else { size_t rowWidth; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one row of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block rowWidth = (converted.rowPitch / 4) * 8; } else { // 128 bits (16 bytes) per 4x4 block rowWidth = (converted.rowPitch / 4) * 16; } } else { rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); } switch(mParentTexture->getTextureType()) { case TEX_TYPE_1D: { D3D11RenderSystem* rsys = reinterpret_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex1D(), 0, &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 1d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. } } case TEX_TYPE_CUBE_MAP: case TEX_TYPE_2D: { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex2D(), D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 2d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_2D_ARRAY: { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex2D(), D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), src.front, mParentTexture->getNumMipmaps()+1), &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 2d array subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_3D: { // copied from dx9 size_t sliceWidth; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one slice of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block sliceWidth = (converted.slicePitch / 16) * 8; } else { // 128 bits (16 bytes) per 4x4 block sliceWidth = (converted.slicePitch / 16) * 16; } } else { sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); } mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex3D(), static_cast<UINT>(mSubresourceIndex), &dstBoxDx11, converted.data, rowWidth, sliceWidth ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 3d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; } if (!isDds) { _genMipmaps(); } } }