Implemented D3D11 offscreen texture share handle support.

Chrome uses this to for composited rendering. Currently Chrome uses a BGRA texture format for surface sharing, so we must create our offscreen textures this way. See EGL_ANGLE_query_surface_pointer, EGL_ANGLE_surface_d3d_texture_2d_share_handle, EGL_ANGLE_d3d_share_handle_client_buffer. TRAC #22410 Signed-off-by: Geoff Lang Signed-off-by: Daniel Koch Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1772 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent bec04bf4
...@@ -59,6 +59,14 @@ Config::Config(rx::ConfigDesc desc, EGLint minInterval, EGLint maxInterval, EGLi ...@@ -59,6 +59,14 @@ Config::Config(rx::ConfigDesc desc, EGLint minInterval, EGLint maxInterval, EGLi
mAlphaSize = 0; mAlphaSize = 0;
mBindToTextureRGB = true; mBindToTextureRGB = true;
break; break;
case GL_BGRA8_EXT:
mBufferSize = 32;
mRedSize = 8;
mGreenSize = 8;
mBlueSize = 8;
mAlphaSize = 8;
mBindToTextureRGBA = true;
break;
default: default:
UNREACHABLE(); // Other formats should not be valid UNREACHABLE(); // Other formats should not be valid
} }
......
...@@ -41,6 +41,7 @@ namespace rx ...@@ -41,6 +41,7 @@ namespace rx
{ {
static const DXGI_FORMAT RenderTargetFormats[] = static const DXGI_FORMAT RenderTargetFormats[] =
{ {
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM DXGI_FORMAT_R8G8B8A8_UNORM
}; };
...@@ -1892,11 +1893,10 @@ bool Renderer11::getInstancingSupport() const ...@@ -1892,11 +1893,10 @@ bool Renderer11::getInstancingSupport() const
bool Renderer11::getShareHandleSupport() const bool Renderer11::getShareHandleSupport() const
{ {
// TODO // We only currently support share handles with BGRA surfaces, because
// UNIMPLEMENTED(); // chrome needs BGRA. Once chrome fixes this, we should always support them.
// PIX doesn't seem to support using share handles, so disable them. // PIX doesn't seem to support using share handles, so disable them.
return false && !gl::perfActive(); return getBGRATextureSupport() && !gl::perfActive();
} }
bool Renderer11::getDerivativeInstructionSupport() const bool Renderer11::getDerivativeInstructionSupport() const
......
...@@ -40,6 +40,7 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, ...@@ -40,6 +40,7 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
mPassThroughPS = NULL; mPassThroughPS = NULL;
mWidth = -1; mWidth = -1;
mHeight = -1; mHeight = -1;
mAppCreatedShareHandle = mShareHandle != NULL;
} }
SwapChain11::~SwapChain11() SwapChain11::~SwapChain11()
...@@ -127,8 +128,10 @@ void SwapChain11::release() ...@@ -127,8 +128,10 @@ void SwapChain11::release()
mPassThroughPS = NULL; mPassThroughPS = NULL;
} }
if (mWindow) if (!mAppCreatedShareHandle)
{
mShareHandle = NULL; mShareHandle = NULL;
}
} }
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
...@@ -190,44 +193,107 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap ...@@ -190,44 +193,107 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
mDepthStencilDSView = NULL; mDepthStencilDSView = NULL;
} }
HANDLE *pShareHandle = NULL; // If the app passed in a share handle, open the resource
if (!mWindow && mRenderer->getShareHandleSupport()) // See EGL_ANGLE_d3d_share_handle_client_buffer
if (mAppCreatedShareHandle)
{ {
pShareHandle = &mShareHandle; ID3D11Resource *tempResource11;
} HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; if (FAILED(result))
offscreenTextureDesc.Width = backbufferWidth; {
offscreenTextureDesc.Height = backbufferHeight; ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); release();
offscreenTextureDesc.MipLevels = 1; return EGL_BAD_PARAMETER;
offscreenTextureDesc.ArraySize = 1; }
offscreenTextureDesc.SampleDesc.Count = 1;
offscreenTextureDesc.SampleDesc.Quality = 0;
offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
offscreenTextureDesc.CPUAccessFlags = 0;
offscreenTextureDesc.MiscFlags = 0; // D3D11_RESOURCE_MISC_SHARED
HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture"); tempResource11->Release();
if (FAILED(result)) if (FAILED(result))
{
ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
release();
return EGL_BAD_PARAMETER;
}
// Validate offscreen texture parameters
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
if (offscreenTextureDesc.Width != (UINT)backbufferWidth
|| offscreenTextureDesc.Height != (UINT)backbufferHeight
|| offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
|| offscreenTextureDesc.MipLevels != 1
|| offscreenTextureDesc.ArraySize != 1)
{
ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
release();
return EGL_BAD_PARAMETER;
}
}
else
{ {
ERR("Could not create offscreen texture: %08lX", result); const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
release();
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
offscreenTextureDesc.Width = backbufferWidth;
offscreenTextureDesc.Height = backbufferHeight;
offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1;
offscreenTextureDesc.SampleDesc.Count = 1;
offscreenTextureDesc.SampleDesc.Quality = 0;
offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
offscreenTextureDesc.CPUAccessFlags = 0;
offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
if (isDeviceLostError(result)) if (FAILED(result))
{ {
return EGL_CONTEXT_LOST; ERR("Could not create offscreen texture: %08lX", result);
release();
if (isDeviceLostError(result))
{
return EGL_CONTEXT_LOST;
}
else
{
return EGL_BAD_ALLOC;
}
} }
else
d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
// EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
if (useSharedResource)
{ {
return EGL_BAD_ALLOC; IDXGIResource *offscreenTextureResource = NULL;
result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
// Fall back to no share handle on failure
if (FAILED(result))
{
ERR("Could not query offscreen texture resource: %08lX", result);
}
else
{
result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
if (FAILED(result))
{
mShareHandle = NULL;
ERR("Could not get offscreen texture shared handle: %08lX", result);
}
}
} }
} }
result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView); HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target"); d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
......
...@@ -47,6 +47,7 @@ class SwapChain11 : public SwapChain ...@@ -47,6 +47,7 @@ class SwapChain11 : public SwapChain
Renderer11 *mRenderer; Renderer11 *mRenderer;
EGLint mHeight; EGLint mHeight;
EGLint mWidth; EGLint mWidth;
bool mAppCreatedShareHandle;
IDXGISwapChain *mSwapChain; IDXGISwapChain *mSwapChain;
......
...@@ -217,6 +217,7 @@ GLenum ConvertBackBufferFormat(DXGI_FORMAT format) ...@@ -217,6 +217,7 @@ GLenum ConvertBackBufferFormat(DXGI_FORMAT format)
switch (format) switch (format)
{ {
case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES; case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES;
case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -240,6 +241,8 @@ GLenum ConvertRenderbufferFormat(DXGI_FORMAT format) ...@@ -240,6 +241,8 @@ GLenum ConvertRenderbufferFormat(DXGI_FORMAT format)
{ {
switch (format) switch (format)
{ {
case DXGI_FORMAT_B8G8R8A8_UNORM:
return GL_BGRA8_EXT;
case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM:
return GL_RGBA8_OES; return GL_RGBA8_OES;
case DXGI_FORMAT_D24_UNORM_S8_UINT: case DXGI_FORMAT_D24_UNORM_S8_UINT:
...@@ -307,6 +310,8 @@ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format) ...@@ -307,6 +310,8 @@ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
case GL_RGB565: case GL_RGB565:
case GL_RGB8_OES: case GL_RGB8_OES:
return DXGI_FORMAT_R8G8B8A8_UNORM; return DXGI_FORMAT_R8G8B8A8_UNORM;
case GL_BGRA8_EXT:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT16:
case GL_STENCIL_INDEX8: case GL_STENCIL_INDEX8:
case GL_DEPTH24_STENCIL8_OES: case GL_DEPTH24_STENCIL8_OES:
......
...@@ -533,6 +533,8 @@ bool IsColorRenderable(GLenum internalformat) ...@@ -533,6 +533,8 @@ bool IsColorRenderable(GLenum internalformat)
case GL_STENCIL_INDEX8: case GL_STENCIL_INDEX8:
case GL_DEPTH24_STENCIL8_OES: case GL_DEPTH24_STENCIL8_OES:
return false; return false;
case GL_BGRA8_EXT:
return true;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
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