Commit 955f5c05 by Jamie Madill

Add TextureStorage::setData.

Usually we copy data from the Image classes into the Storage. This method, which will only apply to D3D11, is useful for our SubData performance workaround. BUG=angle:729 Change-Id: I50ca8158ee9e0638f59f617b9e6170b508eaeb44 Reviewed-on: https://chromium-review.googlesource.com/219837Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent e6b6da03
...@@ -13,10 +13,13 @@ ...@@ -13,10 +13,13 @@
#include "libGLESv2/Error.h" #include "libGLESv2/Error.h"
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <cstdint>
namespace gl namespace gl
{ {
struct ImageIndex; struct ImageIndex;
struct Box;
struct PixelUnpackState;
} }
namespace rx namespace rx
...@@ -40,6 +43,8 @@ class TextureStorage ...@@ -40,6 +43,8 @@ class TextureStorage
virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0; virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0; virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
virtual gl::Error setData(const gl::ImageIndex &index, const gl::Box &sourceBox, GLenum internalFormat, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0;
unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const; unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const;
unsigned int getTextureSerial() const; unsigned int getTextureSerial() const;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
#include "libGLESv2/ImageIndex.h" #include "libGLESv2/ImageIndex.h"
...@@ -414,6 +415,61 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) ...@@ -414,6 +415,61 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error TextureStorage11::setData(const gl::ImageIndex &index, const gl::Box &destBox, GLenum internalFormat, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
{
ID3D11Resource *resource = getResource();
ASSERT(resource);
UINT destSubresource = getSubresourceIndex(index.mipIndex, index.hasLayer() ? index.layerIndex : 0);
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
// TODO(jmadill): Handle compressed formats
// Compressed formats have different load syntax, so we'll have to handle them with slightly
// different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
// with compressed formats in the calling logic.
ASSERT(!internalFormatInfo.compressed);
UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, destBox.width, unpack.alignment);
UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, destBox.width, destBox.height, unpack.alignment);
D3D11_BOX destD3DBox;
destD3DBox.left = destBox.x;
destD3DBox.right = destBox.x + destBox.width;
destD3DBox.top = destBox.y;
destD3DBox.bottom = destBox.y + destBox.height;
destD3DBox.front = 0;
destD3DBox.back = 1;
const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(internalFormat);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
UINT bufferRowPitch = outputPixelSize * destBox.width;
UINT bufferDepthPitch = bufferRowPitch * destBox.height;
MemoryBuffer conversionBuffer;
if (!conversionBuffer.resize(bufferDepthPitch * destBox.depth))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
}
// TODO: fast path
LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
loadFunction(destBox.width, destBox.height, destBox.depth,
pixelData, srcRowPitch, srcDepthPitch,
conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
immediateContext->UpdateSubresource(resource, destSubresource,
&destD3DBox, conversionBuffer.data(),
bufferRowPitch, bufferDepthPitch);
return gl::Error(GL_NO_ERROR);
}
TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
: TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
mTexture(swapchain->getOffscreenTexture()), mTexture(swapchain->getOffscreenTexture()),
......
...@@ -71,6 +71,8 @@ class TextureStorage11 : public TextureStorage ...@@ -71,6 +71,8 @@ class TextureStorage11 : public TextureStorage
virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0; virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0;
virtual gl::Error copyToStorage(TextureStorage *destStorage); virtual gl::Error copyToStorage(TextureStorage *destStorage);
virtual gl::Error setData(const gl::ImageIndex &index, const gl::Box &sourceBox, GLenum internalFormat, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected: protected:
TextureStorage11(Renderer *renderer, UINT bindFlags); TextureStorage11(Renderer *renderer, UINT bindFlags);
......
...@@ -87,6 +87,13 @@ int TextureStorage9::getLevelCount() const ...@@ -87,6 +87,13 @@ int TextureStorage9::getLevelCount() const
return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0; return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0;
} }
gl::Error TextureStorage9::setData(const gl::ImageIndex &index, const gl::Box &sourceBox, GLenum internalFormat, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain)
: TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
{ {
......
...@@ -42,6 +42,9 @@ class TextureStorage9 : public TextureStorage ...@@ -42,6 +42,9 @@ class TextureStorage9 : public TextureStorage
virtual bool isManaged() const; virtual bool isManaged() const;
virtual int getLevelCount() const; virtual int getLevelCount() const;
virtual gl::Error setData(const gl::ImageIndex &index, const gl::Box &sourceBox, GLenum internalFormat, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected: protected:
int mTopLevel; int mTopLevel;
Renderer9 *mRenderer; Renderer9 *mRenderer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment