void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, const void *input) { ASSERT(xoffset % 4 == 0); ASSERT(yoffset % 4 == 0); D3D11_MAPPED_SUBRESOURCE mappedImage; ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAP mapType = D3D11_MAP_WRITE; if (dxContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) { mapType = D3D11_MAP_WRITE_DISCARD; } HRESULT result = map(mapType, &mappedImage); if (FAILED(result)) { ERR("Could not map image for loading."); return; } // Size computation assumes a 4x4 block compressed texture format size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8; void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize)); GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); int rows = inputSize / inputPitch; for (int i = 0; i < rows; ++i) { memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); } unmap(); }
void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { gl::Renderbuffer *colorbuffer = source->getReadColorbuffer(); if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat) { // No conversion needed-- use copyback fastpath ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) { D3D11_TEXTURE2D_DESC textureDesc; colorBufferTexture->GetDesc(&textureDesc); ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11Texture2D* srcTex = NULL; if (textureDesc.SampleDesc.Count > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = textureDesc.Width; resolveDesc.Height = textureDesc.Height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureDesc.Format; resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); if (FAILED(result)) { ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); return; } deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); subresourceIndex = 0; } else { srcTex = colorBufferTexture; srcTex->AddRef(); } D3D11_BOX srcBox; srcBox.left = x; srcBox.right = x + width; srcBox.top = y; srcBox.bottom = y + height; srcBox.front = 0; srcBox.back = 1; deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox); srcTex->Release(); colorBufferTexture->Release(); } } else { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAP mapType = D3D11_MAP_WRITE; if (dxContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) { mapType = D3D11_MAP_WRITE_DISCARD; } HRESULT result = map(mapType, &mappedImage); // determine the offset coordinate into the destination buffer GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset; void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset; mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset); unmap(); } }
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint unpackAlignment, const void *input) { D3D11_MAPPED_SUBRESOURCE mappedImage; ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAP mapType = D3D11_MAP_WRITE; if (dxContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) { mapType = D3D11_MAP_WRITE_DISCARD; } HRESULT result = map(mapType, &mappedImage); if (FAILED(result)) { ERR("Could not map image for loading."); return; } GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8; void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize)); switch (mInternalFormat) { case GL_ALPHA8_EXT: if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3 && 0 ) loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); else loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE8_EXT: loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); break; case GL_ALPHA32F_EXT: loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE32F_EXT: loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_ALPHA16F_EXT: loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE16F_EXT: loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE8_ALPHA8_EXT: loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); break; case GL_LUMINANCE_ALPHA32F_EXT: loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_LUMINANCE_ALPHA16F_EXT: loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB8_OES: loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB565: loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGBA8_OES: loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGBA4: loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB5_A1: loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_BGRA8_EXT: loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB32F_EXT: loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGB16F_EXT: loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGBA32F_EXT: loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; case GL_RGBA16F_EXT: loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); break; default: UNREACHABLE(); } unmap(); }