зеркало из https://github.com/AvaloniaUI/angle.git
Add support for D3D11 texture backed EGLImages
Implement EGL_ANGLE_image_d3d11_texture extension. Images created with this extension might not be renderable based on bind flags and resource usage of the client provided texture in which case attaching them to a framebuffer won't succeed. The intended use case is to bind the front and back buffers of a swap chain to GL textures that can be used for rendering in the case of the back buffer and as a shader input for the front buffer. Bug: chromium:939655 Change-Id: Ic3328e831880292217b88be84740740df6031fa6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1646732 Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
eee67c6ec2
Коммит
f9686af021
|
@ -227,6 +227,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribANGLE(EGLDisplay dpy, EGLint
|
|||
#endif
|
||||
#endif /* EGL_ANGLE_feature_control */
|
||||
|
||||
#ifndef EGL_ANGLE_image_d3d11_texture
|
||||
#define EGL_D3D11_TEXTURE_ANGLE 0x3484
|
||||
#endif /* EGL_ANGLE_image_d3d11_texture */
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // INCLUDE_EGL_EGLEXT_ANGLE_
|
||||
|
|
|
@ -954,6 +954,7 @@ bool IsExternalImageTarget(EGLenum target)
|
|||
switch (target)
|
||||
{
|
||||
case EGL_NATIVE_BUFFER_ANDROID:
|
||||
case EGL_D3D11_TEXTURE_ANGLE:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1422,7 +1422,8 @@ DisplayExtensions::DisplayExtensions()
|
|||
imageNativeBuffer(false),
|
||||
getFrameTimestamps(false),
|
||||
recordable(false),
|
||||
powerPreference(false)
|
||||
powerPreference(false),
|
||||
imageD3D11Texture(false)
|
||||
{}
|
||||
|
||||
std::vector<std::string> DisplayExtensions::getStrings() const
|
||||
|
@ -1477,6 +1478,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
|
|||
InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANDROID_recordable", recordable, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings);
|
||||
InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings);
|
||||
// TODO(jmadill): Enable this when complete.
|
||||
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
|
||||
// clang-format on
|
||||
|
|
|
@ -887,6 +887,9 @@ struct DisplayExtensions
|
|||
|
||||
// EGL_ANGLE_power_preference
|
||||
bool powerPreference;
|
||||
|
||||
// EGL_ANGLE_image_d3d11_texture
|
||||
bool imageD3D11Texture;
|
||||
};
|
||||
|
||||
struct DeviceExtensions
|
||||
|
|
|
@ -215,6 +215,15 @@ StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture(
|
|||
return mRenderer->createStreamProducerD3DTexture(consumerType, attribs);
|
||||
}
|
||||
|
||||
ExternalImageSiblingImpl *DisplayD3D::createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
ASSERT(mRenderer != nullptr);
|
||||
return mRenderer->createExternalImageSibling(context, target, buffer, attribs);
|
||||
}
|
||||
|
||||
egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface,
|
||||
egl::Surface *readSurface,
|
||||
gl::Context *context)
|
||||
|
@ -290,14 +299,33 @@ egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration,
|
|||
attribs);
|
||||
|
||||
case EGL_D3D_TEXTURE_ANGLE:
|
||||
return mRenderer->getD3DTextureInfo(
|
||||
configuration, static_cast<IUnknown *>(clientBuffer), nullptr, nullptr, nullptr);
|
||||
return mRenderer->getD3DTextureInfo(configuration,
|
||||
static_cast<IUnknown *>(clientBuffer), nullptr,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
default:
|
||||
return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
|
||||
}
|
||||
}
|
||||
|
||||
egl::Error DisplayD3D::validateImageClientBuffer(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs) const
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case EGL_D3D11_TEXTURE_ANGLE:
|
||||
{
|
||||
return mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(clientBuffer),
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
default:
|
||||
return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
|
||||
{
|
||||
mRenderer->generateDisplayExtensions(outExtensions);
|
||||
|
|
|
@ -52,6 +52,11 @@ class DisplayD3D : public DisplayImpl, public d3d::Context
|
|||
StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
|
||||
const egl::AttributeMap &attribs) override;
|
||||
|
||||
ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs) override;
|
||||
|
||||
egl::Error makeCurrent(egl::Surface *drawSurface,
|
||||
egl::Surface *readSurface,
|
||||
gl::Context *context) override;
|
||||
|
@ -66,6 +71,10 @@ class DisplayD3D : public DisplayImpl, public d3d::Context
|
|||
EGLenum buftype,
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs) const override;
|
||||
egl::Error validateImageClientBuffer(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer clientBuffer,
|
||||
const egl::AttributeMap &attribs) const override;
|
||||
|
||||
DeviceImpl *createDevice() override;
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
IUnknown *d3dTexture,
|
||||
EGLint *width,
|
||||
EGLint *height,
|
||||
EGLint *samples,
|
||||
const angle::Format **angleFormat) const = 0;
|
||||
virtual egl::Error validateShareHandle(const egl::Config *config,
|
||||
HANDLE shareHandle,
|
||||
|
@ -275,6 +276,11 @@ class RendererD3D : public BufferFactoryD3D
|
|||
|
||||
// Image operations
|
||||
virtual ImageD3D *createImage() = 0;
|
||||
virtual ExternalImageSiblingImpl *createExternalImageSibling(
|
||||
const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs) = 0;
|
||||
virtual angle::Result generateMipmap(const gl::Context *context,
|
||||
ImageD3D *dest,
|
||||
ImageD3D *source) = 0;
|
||||
|
|
|
@ -106,7 +106,7 @@ egl::Error SurfaceD3D::initialize(const egl::Display *display)
|
|||
if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
|
||||
{
|
||||
ANGLE_TRY(mRenderer->getD3DTextureInfo(mState.config, mD3DTexture, &mFixedWidth,
|
||||
&mFixedHeight, &mColorFormat));
|
||||
&mFixedHeight, nullptr, &mColorFormat));
|
||||
if (mState.attributes.contains(EGL_GL_COLORSPACE))
|
||||
{
|
||||
if (mColorFormat->id != angle::FormatID::R8G8B8A8_TYPELESS &&
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
//
|
||||
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
|
||||
|
||||
#include "libANGLE/Context.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "libANGLE/angletypes.h"
|
||||
#include "libANGLE/formatutils.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer, EGLClientBuffer buffer)
|
||||
: mRenderer(renderer),
|
||||
mBuffer(buffer),
|
||||
mFormat(GL_NONE),
|
||||
mIsRenderable(false),
|
||||
mIsTexturable(false),
|
||||
mSamples(0)
|
||||
{}
|
||||
|
||||
ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {}
|
||||
|
||||
egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display)
|
||||
{
|
||||
EGLint width, height, samples = 0;
|
||||
const angle::Format *format = nullptr;
|
||||
ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(mBuffer), &width,
|
||||
&height, &samples, &format));
|
||||
mFormat = gl::Format(format->glInternalFormat);
|
||||
mSize = gl::Extents(width, height, 1);
|
||||
mSamples = static_cast<size_t>(samples);
|
||||
|
||||
ID3D11Texture2D *texture =
|
||||
d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer));
|
||||
ASSERT(texture != nullptr);
|
||||
// TextureHelper11 will release texture on destruction.
|
||||
mTexture.set(texture, d3d11::Format::Get(format->glInternalFormat,
|
||||
mRenderer->getRenderer11DeviceCaps()));
|
||||
D3D11_TEXTURE2D_DESC textureDesc = {};
|
||||
mTexture.getDesc(&textureDesc);
|
||||
|
||||
IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get());
|
||||
ASSERT(resource != nullptr);
|
||||
DXGI_USAGE resourceUsage = 0;
|
||||
resource->GetUsage(&resourceUsage);
|
||||
SafeRelease(resource);
|
||||
|
||||
mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
|
||||
(resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) &&
|
||||
!(resourceUsage & DXGI_USAGE_READ_ONLY);
|
||||
|
||||
mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) &&
|
||||
(resourceUsage & DXGI_USAGE_SHADER_INPUT);
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
gl::Format ExternalImageSiblingImpl11::getFormat() const
|
||||
{
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const
|
||||
{
|
||||
return mIsRenderable;
|
||||
}
|
||||
|
||||
bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const
|
||||
{
|
||||
return mIsTexturable;
|
||||
}
|
||||
|
||||
gl::Extents ExternalImageSiblingImpl11::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
size_t ExternalImageSiblingImpl11::getSamples() const
|
||||
{
|
||||
return mSamples;
|
||||
}
|
||||
|
||||
angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget(
|
||||
const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
FramebufferAttachmentRenderTarget **rtOut)
|
||||
{
|
||||
ANGLE_TRY(createRenderTarget(context));
|
||||
*rtOut = mRenderTarget.get();
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context,
|
||||
const gl::ImageIndex &imageIndex)
|
||||
{
|
||||
UNREACHABLE();
|
||||
return angle::Result::Stop;
|
||||
}
|
||||
|
||||
angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context)
|
||||
{
|
||||
if (mRenderTarget)
|
||||
return angle::Result::Continue;
|
||||
|
||||
Context11 *context11 = GetImplAs<Context11>(context);
|
||||
const d3d11::Format &formatInfo = mTexture.getFormatSet();
|
||||
|
||||
d3d11::RenderTargetView rtv;
|
||||
if (mIsRenderable)
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.Format = formatInfo.rtvFormat;
|
||||
rtvDesc.ViewDimension =
|
||||
mSamples == 0 ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv));
|
||||
rtv.setDebugName("getAttachmentRenderTarget.RTV");
|
||||
}
|
||||
|
||||
d3d11::SharedSRV srv;
|
||||
if (mIsTexturable)
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
srvDesc.Format = formatInfo.srvFormat;
|
||||
srvDesc.ViewDimension =
|
||||
mSamples == 0 ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
srvDesc.Texture2D.MipLevels = 1;
|
||||
|
||||
ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv));
|
||||
srv.setDebugName("getAttachmentRenderTarget.SRV");
|
||||
}
|
||||
d3d11::SharedSRV blitSrv = srv.makeCopy();
|
||||
|
||||
mRenderTarget = std::make_unique<TextureRenderTarget11>(
|
||||
std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), formatInfo.internalFormat,
|
||||
formatInfo, mSize.width, mSize.height, 1, 1);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
} // namespace rx
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
|
||||
#define LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
|
||||
|
||||
#include "libANGLE/renderer/ImageImpl.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class Renderer11;
|
||||
class RenderTargetD3D;
|
||||
|
||||
class ExternalImageSiblingImpl11 : public ExternalImageSiblingImpl
|
||||
{
|
||||
public:
|
||||
ExternalImageSiblingImpl11(Renderer11 *renderer, EGLClientBuffer clientBuffer);
|
||||
~ExternalImageSiblingImpl11() override;
|
||||
|
||||
// ExternalImageSiblingImpl interface
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
gl::Format getFormat() const override;
|
||||
bool isRenderable(const gl::Context *context) const override;
|
||||
bool isTexturable(const gl::Context *context) const override;
|
||||
gl::Extents getSize() const override;
|
||||
size_t getSamples() const override;
|
||||
|
||||
// FramebufferAttachmentObjectImpl interface
|
||||
angle::Result getAttachmentRenderTarget(const gl::Context *context,
|
||||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex,
|
||||
FramebufferAttachmentRenderTarget **rtOut) override;
|
||||
angle::Result initializeContents(const gl::Context *context,
|
||||
const gl::ImageIndex &imageIndex) override;
|
||||
|
||||
private:
|
||||
angle::Result createRenderTarget(const gl::Context *context);
|
||||
|
||||
Renderer11 *mRenderer;
|
||||
EGLClientBuffer mBuffer;
|
||||
TextureHelper11 mTexture;
|
||||
|
||||
gl::Format mFormat;
|
||||
bool mIsRenderable;
|
||||
bool mIsTexturable;
|
||||
gl::Extents mSize;
|
||||
size_t mSamples;
|
||||
|
||||
std::unique_ptr<RenderTargetD3D> mRenderTarget;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
||||
#endif // LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
|
|
@ -38,6 +38,7 @@
|
|||
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/Image11.h"
|
||||
|
@ -1102,6 +1103,7 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
|
|||
outExtensions->surfaceD3DTexture2DShareHandle = true;
|
||||
}
|
||||
outExtensions->d3dTextureClientBuffer = true;
|
||||
outExtensions->imageD3D11Texture = true;
|
||||
|
||||
outExtensions->keyedMutex = true;
|
||||
outExtensions->querySurfacePointer = true;
|
||||
|
@ -1242,6 +1244,7 @@ egl::Error Renderer11::getD3DTextureInfo(const egl::Config *configuration,
|
|||
IUnknown *d3dTexture,
|
||||
EGLint *width,
|
||||
EGLint *height,
|
||||
EGLint *samples,
|
||||
const angle::Format **angleFormat) const
|
||||
{
|
||||
ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(d3dTexture);
|
||||
|
@ -1271,17 +1274,25 @@ egl::Error Renderer11::getD3DTextureInfo(const egl::Config *configuration,
|
|||
{
|
||||
*height = static_cast<EGLint>(desc.Height);
|
||||
}
|
||||
if (static_cast<EGLint>(desc.SampleDesc.Count) != configuration->samples)
|
||||
|
||||
EGLint sampleCount = static_cast<EGLint>(desc.SampleDesc.Count);
|
||||
if (configuration && (configuration->samples != sampleCount))
|
||||
{
|
||||
// Both the texture and EGL config sample count may not be the same when multi-sampling
|
||||
// is disabled. The EGL sample count can be 0 but a D3D texture is always 1. Therefore,
|
||||
// we must only check for a invalid match when the EGL config is non-zero or the texture is
|
||||
// not one.
|
||||
if (configuration->samples != 0 || desc.SampleDesc.Count != 1)
|
||||
if (configuration->samples != 0 || sampleCount != 1)
|
||||
{
|
||||
return egl::EglBadParameter() << "Texture's sample count does not match.";
|
||||
}
|
||||
}
|
||||
if (samples)
|
||||
{
|
||||
// EGL samples 0 corresponds to D3D11 sample count 1.
|
||||
*samples = sampleCount != 1 ? sampleCount : 0;
|
||||
}
|
||||
|
||||
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
|
||||
switch (desc.Format)
|
||||
{
|
||||
|
@ -2923,6 +2934,22 @@ ImageD3D *Renderer11::createImage()
|
|||
return new Image11(this);
|
||||
}
|
||||
|
||||
ExternalImageSiblingImpl *Renderer11::createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case EGL_D3D11_TEXTURE_ANGLE:
|
||||
return new ExternalImageSiblingImpl11(this, buffer);
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
angle::Result Renderer11::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src)
|
||||
{
|
||||
Image11 *dest11 = GetAs<Image11>(dest);
|
||||
|
|
|
@ -143,6 +143,7 @@ class Renderer11 : public RendererD3D
|
|||
IUnknown *d3dTexture,
|
||||
EGLint *width,
|
||||
EGLint *height,
|
||||
EGLint *samples,
|
||||
const angle::Format **angleFormat) const override;
|
||||
egl::Error validateShareHandle(const egl::Config *config,
|
||||
HANDLE shareHandle,
|
||||
|
@ -249,6 +250,10 @@ class Renderer11 : public RendererD3D
|
|||
|
||||
// Image operations
|
||||
ImageD3D *createImage() override;
|
||||
ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs) override;
|
||||
angle::Result generateMipmap(const gl::Context *context,
|
||||
ImageD3D *dest,
|
||||
ImageD3D *source) override;
|
||||
|
|
|
@ -392,6 +392,7 @@ class TextureHelper11 : public Resource11Base<ID3D11Resource, std::shared_ptr, G
|
|||
void set(ResourceT *object, const d3d11::Format &format)
|
||||
{
|
||||
ASSERT(!valid());
|
||||
|
||||
mFormatSet = &format;
|
||||
mData->object = object;
|
||||
mData->manager = nullptr;
|
||||
|
|
|
@ -713,10 +713,11 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
|
|||
backBufferFormat, depthBufferFormat, orientation);
|
||||
}
|
||||
|
||||
egl::Error Renderer9::getD3DTextureInfo(const egl::Config *config,
|
||||
egl::Error Renderer9::getD3DTextureInfo(const egl::Config *configuration,
|
||||
IUnknown *d3dTexture,
|
||||
EGLint *width,
|
||||
EGLint *height,
|
||||
EGLint *samples,
|
||||
const angle::Format **angleFormat) const
|
||||
{
|
||||
IDirect3DTexture9 *texture = nullptr;
|
||||
|
@ -747,6 +748,17 @@ egl::Error Renderer9::getD3DTextureInfo(const egl::Config *config,
|
|||
*height = static_cast<EGLint>(desc.Height);
|
||||
}
|
||||
|
||||
// GetSamplesCount() returns 0 when multisampling isn't used.
|
||||
GLsizei sampleCount = d3d9_gl::GetSamplesCount(desc.MultiSampleType);
|
||||
if ((configuration && configuration->samples > 1) || sampleCount != 0)
|
||||
{
|
||||
return egl::EglBadParameter() << "Multisampling not supported for client buffer texture";
|
||||
}
|
||||
if (samples)
|
||||
{
|
||||
*samples = static_cast<EGLint>(sampleCount);
|
||||
}
|
||||
|
||||
// From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
|
||||
switch (desc.Format)
|
||||
{
|
||||
|
@ -2780,6 +2792,15 @@ ImageD3D *Renderer9::createImage()
|
|||
return new Image9(this);
|
||||
}
|
||||
|
||||
ExternalImageSiblingImpl *Renderer9::createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
angle::Result Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src)
|
||||
{
|
||||
Image9 *src9 = GetAs<Image9>(src);
|
||||
|
|
|
@ -98,6 +98,7 @@ class Renderer9 : public RendererD3D
|
|||
IUnknown *d3dTexture,
|
||||
EGLint *width,
|
||||
EGLint *height,
|
||||
EGLint *samples,
|
||||
const angle::Format **angleFormat) const override;
|
||||
egl::Error validateShareHandle(const egl::Config *config,
|
||||
HANDLE shareHandle,
|
||||
|
@ -274,6 +275,10 @@ class Renderer9 : public RendererD3D
|
|||
|
||||
// Image operations
|
||||
ImageD3D *createImage() override;
|
||||
ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs) override;
|
||||
angle::Result generateMipmap(const gl::Context *context,
|
||||
ImageD3D *dest,
|
||||
ImageD3D *source) override;
|
||||
|
|
|
@ -2071,6 +2071,20 @@ Error ValidateCreateImage(const Display *display,
|
|||
}
|
||||
break;
|
||||
|
||||
case EGL_D3D11_TEXTURE_ANGLE:
|
||||
if (!displayExtensions.imageD3D11Texture)
|
||||
{
|
||||
return EglBadParameter() << "EGL_ANGLE_image_d3d11_texture not supported.";
|
||||
}
|
||||
|
||||
if (context != nullptr)
|
||||
{
|
||||
return EglBadContext() << "ctx must be EGL_NO_CONTEXT.";
|
||||
}
|
||||
|
||||
ANGLE_TRY(display->validateImageClientBuffer(context, target, buffer, attributes));
|
||||
break;
|
||||
|
||||
default:
|
||||
return EglBadParameter()
|
||||
<< "invalid target: 0x" << std::hex << std::uppercase << target;
|
||||
|
|
|
@ -479,6 +479,8 @@ libangle_d3d11_sources = [
|
|||
"src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp",
|
||||
"src/libANGLE/renderer/d3d/d3d11/dxgi_support_table_autogen.cpp",
|
||||
"src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h",
|
||||
"src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp",
|
||||
"src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h",
|
||||
"src/libANGLE/renderer/d3d/d3d11/Fence11.cpp",
|
||||
"src/libANGLE/renderer/d3d/d3d11/Fence11.h",
|
||||
"src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp",
|
||||
|
|
|
@ -755,6 +755,7 @@ TEST_P(D3DTextureTest, Clear)
|
|||
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
|
||||
255, 255);
|
||||
|
||||
|
@ -1196,6 +1197,111 @@ TEST_P(D3DTextureTestMS, CopyTexSubImage2DTest)
|
|||
eglDestroySurface(display, pbuffer);
|
||||
}
|
||||
|
||||
TEST_P(D3DTextureTest, ClearTextureImage)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
|
||||
|
||||
EGLWindow *window = getEGLWindow();
|
||||
EGLDisplay display = window->getDisplay();
|
||||
|
||||
window->makeCurrent();
|
||||
|
||||
const UINT bufferSize = 32;
|
||||
EXPECT_TRUE(mD3D11Device != nullptr);
|
||||
ID3D11Texture2D *d3d11_texture = nullptr;
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));
|
||||
|
||||
const EGLint attribs[] = {EGL_NONE};
|
||||
|
||||
EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
|
||||
static_cast<EGLClientBuffer>(d3d11_texture), attribs);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(image, EGL_NO_IMAGE_KHR);
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLuint fbo;
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
|
||||
static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
|
||||
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
|
||||
255, 255);
|
||||
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &texture);
|
||||
|
||||
d3d11_texture->Release();
|
||||
}
|
||||
|
||||
TEST_P(D3DTextureTest, NonRenderableTextureImage)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
|
||||
|
||||
EGLWindow *window = getEGLWindow();
|
||||
EGLDisplay display = window->getDisplay();
|
||||
|
||||
window->makeCurrent();
|
||||
|
||||
const UINT bufferSize = 32;
|
||||
EXPECT_TRUE(mD3D11Device != nullptr);
|
||||
ID3D11Texture2D *d3d11_texture = nullptr;
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE);
|
||||
EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11_texture)));
|
||||
|
||||
const EGLint attribs[] = {EGL_NONE};
|
||||
|
||||
EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
|
||||
static_cast<EGLClientBuffer>(d3d11_texture), attribs);
|
||||
ASSERT_EGL_SUCCESS();
|
||||
ASSERT_NE(image, EGL_NO_IMAGE_KHR);
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLuint fbo;
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
|
||||
static_cast<unsigned>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &texture);
|
||||
|
||||
d3d11_texture->Release();
|
||||
}
|
||||
|
||||
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
|
||||
// tests should be run against.
|
||||
ANGLE_INSTANTIATE_TEST(D3DTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
|
||||
|
|
Загрузка…
Ссылка в новой задаче