Add support for the "fast path" (GPU copy) pixel unpack buffers in TexImage2D.
TRAC #23844
Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
index 7397dbe..e4f7c78 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
@@ -10,6 +10,7 @@
#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
#include "libGLESv2/main.h"
#include "libGLESv2/renderer/d3d11/Renderer11.h"
+#include "libGLESv2/renderer/d3d11/formatutils11.h"
namespace rx
{
@@ -268,7 +269,38 @@
ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
{
- return NULL;
+ ID3D11Buffer *buffer = getBuffer(false);
+
+ auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
+
+ if (bufferSRVIt != mBufferResourceViews.end())
+ {
+ if (bufferSRVIt->second.first == buffer)
+ {
+ return bufferSRVIt->second.second;
+ }
+ else
+ {
+ // The underlying buffer has changed since the SRV was created: recreate the SRV.
+ SafeRelease(bufferSRVIt->second.second);
+ }
+ }
+
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11ShaderResourceView *bufferSRV = NULL;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc;
+ bufferSRVDesc.Buffer.ElementOffset = 0;
+ bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat, mRenderer->getCurrentClientVersion());
+ bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+ bufferSRVDesc.Format = srvFormat;
+
+ HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV);
+ ASSERT(SUCCEEDED(result));
+
+ mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV);
+
+ return bufferSRV;
}
DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, bool isConstantBufferUsage)
@@ -352,7 +384,7 @@
if (!mIsConstantBufferUsage)
{
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
- bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_SHADER_RESOURCE;
bufferDesc->CPUAccessFlags = 0;
}
else
diff --git a/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
index ee76c4a..689e413 100644
--- a/src/libGLESv2/renderer/d3d11/BufferStorage11.h
+++ b/src/libGLESv2/renderer/d3d11/BufferStorage11.h
@@ -42,6 +42,10 @@
unsigned int mStagingBufferSize;
std::vector<DirectBufferStorage11*> mDirectBuffers;
+
+ typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
+ std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
+
unsigned int mSize;
void *mResolvedData;
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 18ba51f..e9e13b3 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -2769,8 +2769,39 @@
bool Renderer11::supportsFastCopyBufferToTexture(GLint internalFormat) const
{
- //TODO
- return false;
+ int clientVersion = getCurrentClientVersion();
+
+ // We only support buffer to texture copies in ES3
+ if (clientVersion <= 2)
+ {
+ return false;
+ }
+
+ // sRGB formats do not work with D3D11 buffer SRVs
+ if (gl::GetColorEncoding(internalFormat, clientVersion) == GL_SRGB)
+ {
+ return false;
+ }
+
+ // We cannot support direct copies to non-color-renderable formats
+ if (!gl::IsColorRenderingSupported(internalFormat, this))
+ {
+ return false;
+ }
+
+ // We skip all 3-channel formats since sometimes format support is missing
+ if (gl::GetComponentCount(internalFormat, clientVersion) == 3)
+ {
+ return false;
+ }
+
+ // We don't support formats which we can't represent without conversion
+ if (getNativeTextureFormat(internalFormat) != internalFormat)
+ {
+ return false;
+ }
+
+ return true;
}
bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,