Commit 80d4901a by Le Hoang Quyen Committed by Commit Bot

Metal: Support integer textures.

Bug: angleproject:2634 Bug: angleproject:5154 Change-Id: Iffea26fe2c683557b4fa7c13fddf3523294b47d4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2433329 Commit-Queue: Le Hoang Quyen <le.hoang.q@gmail.com> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 96714af8
...@@ -297,7 +297,7 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -297,7 +297,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
void queueEventSignal(const mtl::SharedEventRef &event, uint64_t value); void queueEventSignal(const mtl::SharedEventRef &event, uint64_t value);
void serverWaitEvent(const mtl::SharedEventRef &event, uint64_t value); void serverWaitEvent(const mtl::SharedEventRef &event, uint64_t value);
const MTLClearColor &getClearColorValue() const; const mtl::ClearColorValue &getClearColorValue() const;
MTLColorWriteMask getColorMask() const; MTLColorWriteMask getColorMask() const;
float getClearDepthValue() const; float getClearDepthValue() const;
uint32_t getClearStencilValue() const; uint32_t getClearStencilValue() const;
...@@ -529,7 +529,7 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -529,7 +529,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
mtl::RenderPipelineDesc mRenderPipelineDesc; mtl::RenderPipelineDesc mRenderPipelineDesc;
mtl::DepthStencilDesc mDepthStencilDesc; mtl::DepthStencilDesc mDepthStencilDesc;
mtl::BlendDesc mBlendDesc; mtl::BlendDesc mBlendDesc;
MTLClearColor mClearColor; mtl::ClearColorValue mClearColor;
uint32_t mClearStencil = 0; uint32_t mClearStencil = 0;
uint32_t mStencilRefFront = 0; uint32_t mStencilRefFront = 0;
uint32_t mStencilRefBack = 0; uint32_t mStencilRefBack = 0;
......
...@@ -780,10 +780,9 @@ angle::Result ContextMtl::syncState(const gl::Context *context, ...@@ -780,10 +780,9 @@ angle::Result ContextMtl::syncState(const gl::Context *context,
// NOTE(hqle): ES 3.0 feature. // NOTE(hqle): ES 3.0 feature.
break; break;
case gl::State::DIRTY_BIT_CLEAR_COLOR: case gl::State::DIRTY_BIT_CLEAR_COLOR:
mClearColor.red = glState.getColorClearValue().red; mClearColor = mtl::ClearColorValue(
mClearColor.green = glState.getColorClearValue().green; glState.getColorClearValue().red, glState.getColorClearValue().green,
mClearColor.blue = glState.getColorClearValue().blue; glState.getColorClearValue().blue, glState.getColorClearValue().alpha);
mClearColor.alpha = glState.getColorClearValue().alpha;
break; break;
case gl::State::DIRTY_BIT_CLEAR_DEPTH: case gl::State::DIRTY_BIT_CLEAR_DEPTH:
break; break;
...@@ -1123,7 +1122,7 @@ void ContextMtl::invalidateRenderPipeline() ...@@ -1123,7 +1122,7 @@ void ContextMtl::invalidateRenderPipeline()
mDirtyBits.set(DIRTY_BIT_RENDER_PIPELINE); mDirtyBits.set(DIRTY_BIT_RENDER_PIPELINE);
} }
const MTLClearColor &ContextMtl::getClearColorValue() const const mtl::ClearColorValue &ContextMtl::getClearColorValue() const
{ {
return mClearColor; return mClearColor;
} }
......
...@@ -120,6 +120,7 @@ class FramebufferMtl : public FramebufferImpl ...@@ -120,6 +120,7 @@ class FramebufferMtl : public FramebufferImpl
private: private:
void reset(); void reset();
bool checkPackedDepthStencilAttachment() const;
angle::Result invalidateImpl(ContextMtl *contextMtl, size_t count, const GLenum *attachments); angle::Result invalidateImpl(ContextMtl *contextMtl, size_t count, const GLenum *attachments);
angle::Result blitWithDraw(const gl::Context *context, angle::Result blitWithDraw(const gl::Context *context,
FramebufferMtl *srcFrameBuffer, FramebufferMtl *srcFrameBuffer,
...@@ -161,10 +162,6 @@ class FramebufferMtl : public FramebufferImpl ...@@ -161,10 +162,6 @@ class FramebufferMtl : public FramebufferImpl
mtl::RenderCommandEncoder *ensureRenderPassStarted(const gl::Context *context, mtl::RenderCommandEncoder *ensureRenderPassStarted(const gl::Context *context,
const mtl::RenderPassDesc &desc); const mtl::RenderPassDesc &desc);
void overrideClearColor(const mtl::TextureRef &texture,
MTLClearColor clearColor,
MTLClearColor *colorOut);
angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL); angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL);
angle::Result updateDepthRenderTarget(const gl::Context *context); angle::Result updateDepthRenderTarget(const gl::Context *context);
angle::Result updateStencilRenderTarget(const gl::Context *context); angle::Result updateStencilRenderTarget(const gl::Context *context);
...@@ -185,6 +182,9 @@ class FramebufferMtl : public FramebufferImpl ...@@ -185,6 +182,9 @@ class FramebufferMtl : public FramebufferImpl
RenderTargetMtl *mStencilRenderTarget = nullptr; RenderTargetMtl *mStencilRenderTarget = nullptr;
mtl::RenderPassDesc mRenderPassDesc; mtl::RenderPassDesc mRenderPassDesc;
const mtl::Format *mRenderPassFirstColorAttachmentFormat = nullptr;
bool mRenderPassAttachmentsSameColorType = false;
// Flag indicating the render pass start is a clean start or a resume from interruption such // Flag indicating the render pass start is a clean start or a resume from interruption such
// as by a compute pass. // as by a compute pass.
bool mRenderPassCleanStart = false; bool mRenderPassCleanStart = false;
......
...@@ -77,5 +77,6 @@ void RenderTargetMtl::toRenderPassAttachmentDesc(mtl::RenderPassAttachmentDesc * ...@@ -77,5 +77,6 @@ void RenderTargetMtl::toRenderPassAttachmentDesc(mtl::RenderPassAttachmentDesc *
rpaDescOut->implicitMSTexture = mImplicitMSTexture.lock(); rpaDescOut->implicitMSTexture = mImplicitMSTexture.lock();
rpaDescOut->level = mLevelIndex; rpaDescOut->level = mLevelIndex;
rpaDescOut->sliceOrDepth = mLayerIndex; rpaDescOut->sliceOrDepth = mLayerIndex;
rpaDescOut->blendable = mFormat ? mFormat->getCaps().blendable : false;
} }
} }
...@@ -546,8 +546,8 @@ angle::Result SurfaceMtl::resolveColorTextureIfNeeded(const gl::Context *context ...@@ -546,8 +546,8 @@ angle::Result SurfaceMtl::resolveColorTextureIfNeeded(const gl::Context *context
mColorFormat); mColorFormat);
mtl::RenderCommandEncoder *encoder = mtl::RenderCommandEncoder *encoder =
contextMtl->getRenderTargetCommandEncoder(mColorManualResolveRenderTarget); contextMtl->getRenderTargetCommandEncoder(mColorManualResolveRenderTarget);
ANGLE_TRY(contextMtl->getDisplay()->getUtils().blitColorWithDraw(context, encoder, ANGLE_TRY(contextMtl->getDisplay()->getUtils().blitColorWithDraw(
mMSColorTexture)); context, encoder, mColorFormat.actualAngleFormat(), mMSColorTexture));
contextMtl->endEncoding(true); contextMtl->endEncoding(true);
mColorManualResolveRenderTarget.reset(); mColorManualResolveRenderTarget.reset();
} }
......
...@@ -1780,7 +1780,8 @@ angle::Result TextureMtl::copySubImageWithDraw(const gl::Context *context, ...@@ -1780,7 +1780,8 @@ angle::Result TextureMtl::copySubImageWithDraw(const gl::Context *context,
blitParams.srcYFlipped = framebufferMtl->flipY(); blitParams.srcYFlipped = framebufferMtl->flipY();
blitParams.dstLuminance = internalFormat.isLUMA(); blitParams.dstLuminance = internalFormat.isLUMA();
return displayMtl->getUtils().blitColorWithDraw(context, cmdEncoder, blitParams); return displayMtl->getUtils().blitColorWithDraw(
context, cmdEncoder, colorReadRT->getFormat()->actualAngleFormat(), blitParams);
} }
angle::Result TextureMtl::copySubImageCPU(const gl::Context *context, angle::Result TextureMtl::copySubImageCPU(const gl::Context *context,
...@@ -1937,7 +1938,8 @@ angle::Result TextureMtl::copySubTextureWithDraw(const gl::Context *context, ...@@ -1937,7 +1938,8 @@ angle::Result TextureMtl::copySubTextureWithDraw(const gl::Context *context,
blitParams.unpackPremultiplyAlpha = unpackPremultiplyAlpha; blitParams.unpackPremultiplyAlpha = unpackPremultiplyAlpha;
blitParams.unpackUnmultiplyAlpha = unpackUnmultiplyAlpha; blitParams.unpackUnmultiplyAlpha = unpackUnmultiplyAlpha;
return displayMtl->getUtils().blitColorWithDraw(context, cmdEncoder, blitParams); return displayMtl->getUtils().copyTextureWithDraw(context, cmdEncoder, sourceAngleFormat,
mFormat.actualAngleFormat(), blitParams);
} }
angle::Result TextureMtl::copySubTextureCPU(const gl::Context *context, angle::Result TextureMtl::copySubTextureCPU(const gl::Context *context,
......
...@@ -156,7 +156,7 @@ constexpr uint32_t kStencilMaskAll = 0xff; // Only 8 bits stencil is supported ...@@ -156,7 +156,7 @@ constexpr uint32_t kStencilMaskAll = 0xff; // Only 8 bits stencil is supported
constexpr MTLVertexStepFunction kVertexStepFunctionInvalid = constexpr MTLVertexStepFunction kVertexStepFunctionInvalid =
static_cast<MTLVertexStepFunction>(0xff); static_cast<MTLVertexStepFunction>(0xff);
constexpr float kEmulatedAlphaValue = 1.0f; constexpr int kEmulatedAlphaValue = 1;
constexpr size_t kOcclusionQueryResultSize = sizeof(uint64_t); constexpr size_t kOcclusionQueryResultSize = sizeof(uint64_t);
...@@ -404,11 +404,59 @@ class ImageNativeIndexIterator final ...@@ -404,11 +404,59 @@ class ImageNativeIndexIterator final
gl::ImageIndexIterator mNativeIndexIte; gl::ImageIndexIterator mNativeIndexIte;
}; };
struct ClearOptions using ClearColorValueBytes = std::array<uint8_t, 4 * sizeof(float)>;
class ClearColorValue
{ {
Optional<MTLClearColor> clearColor; public:
Optional<float> clearDepth; constexpr ClearColorValue()
Optional<uint32_t> clearStencil; : mType(PixelType::Float), mRedF(0), mGreenF(0), mBlueF(0), mAlphaF(0)
{}
constexpr ClearColorValue(float r, float g, float b, float a)
: mType(PixelType::Float), mRedF(r), mGreenF(g), mBlueF(b), mAlphaF(a)
{}
constexpr ClearColorValue(int32_t r, int32_t g, int32_t b, int32_t a)
: mType(PixelType::Int), mRedI(r), mGreenI(g), mBlueI(b), mAlphaI(a)
{}
constexpr ClearColorValue(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
: mType(PixelType::UInt), mRedU(r), mGreenU(g), mBlueU(b), mAlphaU(a)
{}
constexpr ClearColorValue(const ClearColorValue &src)
: mType(src.mType), mValueBytes(src.mValueBytes)
{}
MTLClearColor toMTLClearColor() const;
PixelType getType() const { return mType; }
const ClearColorValueBytes &getValueBytes() const { return mValueBytes; }
ClearColorValue &operator=(const ClearColorValue &src);
void setAsFloat(float r, float g, float b, float a);
void setAsInt(int32_t r, int32_t g, int32_t b, int32_t a);
void setAsUInt(uint32_t r, uint32_t g, uint32_t b, uint32_t a);
private:
PixelType mType;
union
{
struct
{
float mRedF, mGreenF, mBlueF, mAlphaF;
};
struct
{
int32_t mRedI, mGreenI, mBlueI, mAlphaI;
};
struct
{
uint32_t mRedU, mGreenU, mBlueU, mAlphaU;
};
ClearColorValueBytes mValueBytes;
};
}; };
class CommandQueue; class CommandQueue;
......
...@@ -21,6 +21,58 @@ namespace rx ...@@ -21,6 +21,58 @@ namespace rx
namespace mtl namespace mtl
{ {
// ClearColorValue implementation
ClearColorValue &ClearColorValue::operator=(const ClearColorValue &src)
{
mType = src.mType;
mValueBytes = src.mValueBytes;
return *this;
}
void ClearColorValue::setAsFloat(float r, float g, float b, float a)
{
mType = PixelType::Float;
mRedF = r;
mGreenF = g;
mBlueF = b;
mAlphaF = a;
}
void ClearColorValue::setAsInt(int32_t r, int32_t g, int32_t b, int32_t a)
{
mType = PixelType::Int;
mRedI = r;
mGreenI = g;
mBlueI = b;
mAlphaI = a;
}
void ClearColorValue::setAsUInt(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
{
mType = PixelType::UInt;
mRedU = r;
mGreenU = g;
mBlueU = b;
mAlphaU = a;
}
MTLClearColor ClearColorValue::toMTLClearColor() const
{
switch (mType)
{
case PixelType::Int:
return MTLClearColorMake(mRedI, mGreenI, mBlueI, mAlphaI);
case PixelType::UInt:
return MTLClearColorMake(mRedU, mGreenU, mBlueU, mAlphaU);
case PixelType::Float:
return MTLClearColorMake(mRedF, mGreenF, mBlueF, mAlphaF);
default:
UNREACHABLE();
return MTLClearColorMake(0, 0, 0, 0);
}
}
// ImageNativeIndex implementation // ImageNativeIndex implementation
ImageNativeIndexIterator ImageNativeIndex::getLayerIterator(GLint layerCount) const ImageNativeIndexIterator ImageNativeIndex::getLayerIterator(GLint layerCount) const
{ {
......
...@@ -29,10 +29,16 @@ class VisibilityBufferOffsetsMtl; ...@@ -29,10 +29,16 @@ class VisibilityBufferOffsetsMtl;
namespace mtl namespace mtl
{ {
struct ClearRectParams : public ClearOptions
struct ClearRectParams
{ {
Optional<ClearColorValue> clearColor;
Optional<float> clearDepth;
Optional<uint32_t> clearStencil;
MTLColorWriteMask clearColorMask = MTLColorWriteMaskAll; MTLColorWriteMask clearColorMask = MTLColorWriteMaskAll;
const mtl::Format *colorFormat = nullptr;
gl::Extents dstTextureSize; gl::Extents dstTextureSize;
// Only clear enabled buffers // Only clear enabled buffers
...@@ -159,7 +165,9 @@ struct CopyPixelsToBufferParams : CopyPixelsCommonParams ...@@ -159,7 +165,9 @@ struct CopyPixelsToBufferParams : CopyPixelsCommonParams
class ClearUtils final : angle::NonCopyable class ClearUtils final : angle::NonCopyable
{ {
public: public:
ClearUtils(); ClearUtils() = delete;
ClearUtils(const std::string &fragmentShaderName);
ClearUtils(const ClearUtils &src);
void onDestroy(); void onDestroy();
...@@ -180,6 +188,8 @@ class ClearUtils final : angle::NonCopyable ...@@ -180,6 +188,8 @@ class ClearUtils final : angle::NonCopyable
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const ClearRectParams &params); const ClearRectParams &params);
const std::string mFragmentShaderName;
// Render pipeline cache for clear with draw: // Render pipeline cache for clear with draw:
std::array<RenderPipelineCache, kMaxRenderTargets + 1> mClearRenderPipelineCache; std::array<RenderPipelineCache, kMaxRenderTargets + 1> mClearRenderPipelineCache;
}; };
...@@ -187,7 +197,9 @@ class ClearUtils final : angle::NonCopyable ...@@ -187,7 +197,9 @@ class ClearUtils final : angle::NonCopyable
class ColorBlitUtils final : angle::NonCopyable class ColorBlitUtils final : angle::NonCopyable
{ {
public: public:
ColorBlitUtils(); ColorBlitUtils() = delete;
ColorBlitUtils(const std::string &fragmentShaderName);
ColorBlitUtils(const ColorBlitUtils &src);
void onDestroy(); void onDestroy();
...@@ -211,6 +223,8 @@ class ColorBlitUtils final : angle::NonCopyable ...@@ -211,6 +223,8 @@ class ColorBlitUtils final : angle::NonCopyable
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const ColorBlitParams &params); const ColorBlitParams &params);
const std::string mFragmentShaderName;
// Blit with draw pipeline caches: // Blit with draw pipeline caches:
// First array dimension: number of outputs. // First array dimension: number of outputs.
// Second array dimension: source texture type (2d, ms, array, 3d, etc) // Second array dimension: source texture type (2d, ms, array, 3d, etc)
...@@ -230,6 +244,7 @@ class DepthStencilBlitUtils final : angle::NonCopyable ...@@ -230,6 +244,7 @@ class DepthStencilBlitUtils final : angle::NonCopyable
angle::Result blitDepthStencilWithDraw(const gl::Context *context, angle::Result blitDepthStencilWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const DepthStencilBlitParams &params); const DepthStencilBlitParams &params);
// Blit stencil data using intermediate buffer. This function is used on devices with no // Blit stencil data using intermediate buffer. This function is used on devices with no
// support for direct stencil write in shader. Thus an intermediate buffer storing copied // support for direct stencil write in shader. Thus an intermediate buffer storing copied
// stencil data is needed. // stencil data is needed.
...@@ -431,12 +446,19 @@ class RenderUtils : public Context, angle::NonCopyable ...@@ -431,12 +446,19 @@ class RenderUtils : public Context, angle::NonCopyable
// Blit texture data to current framebuffer // Blit texture data to current framebuffer
angle::Result blitColorWithDraw(const gl::Context *context, angle::Result blitColorWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const ColorBlitParams &params); const ColorBlitParams &params);
// Same as above but blit the whole texture to the whole of current framebuffer. // Same as above but blit the whole texture to the whole of current framebuffer.
// This function assumes the framebuffer and the source texture have same size. // This function assumes the framebuffer and the source texture have same size.
angle::Result blitColorWithDraw(const gl::Context *context, angle::Result blitColorWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const TextureRef &srcTexture); const TextureRef &srcTexture);
angle::Result copyTextureWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const angle::Format &dstAngleFormat,
const ColorBlitParams &params);
angle::Result blitDepthStencilWithDraw(const gl::Context *context, angle::Result blitDepthStencilWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
...@@ -490,8 +512,11 @@ class RenderUtils : public Context, angle::NonCopyable ...@@ -490,8 +512,11 @@ class RenderUtils : public Context, angle::NonCopyable
const char *function, const char *function,
unsigned int line) override; unsigned int line) override;
ClearUtils mClearUtils; std::array<ClearUtils, angle::EnumSize<PixelType>()> mClearUtils;
ColorBlitUtils mColorBlitUtils;
std::array<ColorBlitUtils, angle::EnumSize<PixelType>()> mColorBlitUtils;
ColorBlitUtils mCopyTextureFloatToUIntUtils;
DepthStencilBlitUtils mDepthStencilBlitUtils; DepthStencilBlitUtils mDepthStencilBlitUtils;
IndexGeneratorUtils mIndexUtils; IndexGeneratorUtils mIndexUtils;
VisibilityResultUtils mVisibilityResultUtils; VisibilityResultUtils mVisibilityResultUtils;
......
...@@ -535,6 +535,11 @@ StencilBlitViaBufferParams::StencilBlitViaBufferParams(const DepthStencilBlitPar ...@@ -535,6 +535,11 @@ StencilBlitViaBufferParams::StencilBlitViaBufferParams(const DepthStencilBlitPar
// RenderUtils implementation // RenderUtils implementation
RenderUtils::RenderUtils(DisplayMtl *display) RenderUtils::RenderUtils(DisplayMtl *display)
: Context(display), : Context(display),
mClearUtils(
{ClearUtils("clearIntFS"), ClearUtils("clearUIntFS"), ClearUtils("clearFloatFS")}),
mColorBlitUtils({ColorBlitUtils("blitIntFS"), ColorBlitUtils("blitUIntFS"),
ColorBlitUtils("blitFloatFS")}),
mCopyTextureFloatToUIntUtils("copyTextureFloatToUIntFS"),
mCopyPixelsUtils( mCopyPixelsUtils(
{CopyPixelsUtils("readFromBufferToIntTexture", "writeFromIntTextureToBuffer"), {CopyPixelsUtils("readFromBufferToIntTexture", "writeFromIntTextureToBuffer"),
CopyPixelsUtils("readFromBufferToUIntTexture", "writeFromUIntTextureToBuffer"), CopyPixelsUtils("readFromBufferToUIntTexture", "writeFromUIntTextureToBuffer"),
...@@ -550,11 +555,20 @@ angle::Result RenderUtils::initialize() ...@@ -550,11 +555,20 @@ angle::Result RenderUtils::initialize()
void RenderUtils::onDestroy() void RenderUtils::onDestroy()
{ {
mIndexUtils.onDestroy();
mClearUtils.onDestroy();
mColorBlitUtils.onDestroy();
mDepthStencilBlitUtils.onDestroy(); mDepthStencilBlitUtils.onDestroy();
mIndexUtils.onDestroy();
mVisibilityResultUtils.onDestroy();
mMipmapUtils.onDestroy();
mCopyTextureFloatToUIntUtils.onDestroy();
for (ClearUtils &util : mClearUtils)
{
util.onDestroy();
}
for (ColorBlitUtils &util : mColorBlitUtils)
{
util.onDestroy();
}
for (CopyPixelsUtils &util : mCopyPixelsUtils) for (CopyPixelsUtils &util : mCopyPixelsUtils)
{ {
util.onDestroy(); util.onDestroy();
...@@ -590,19 +604,31 @@ angle::Result RenderUtils::clearWithDraw(const gl::Context *context, ...@@ -590,19 +604,31 @@ angle::Result RenderUtils::clearWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const ClearRectParams &params) const ClearRectParams &params)
{ {
return mClearUtils.clearWithDraw(context, cmdEncoder, params); int index = 0;
if (params.clearColor.valid())
{
index = static_cast<int>(params.clearColor.value().getType());
}
else if (params.colorFormat)
{
index = GetPixelTypeIndex(params.colorFormat->actualAngleFormat());
}
return mClearUtils[index].clearWithDraw(context, cmdEncoder, params);
} }
// Blit texture data to current framebuffer // Blit texture data to current framebuffer
angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context, angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const ColorBlitParams &params) const ColorBlitParams &params)
{ {
return mColorBlitUtils.blitColorWithDraw(context, cmdEncoder, params); int index = GetPixelTypeIndex(srcAngleFormat);
return mColorBlitUtils[index].blitColorWithDraw(context, cmdEncoder, params);
} }
angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context, angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder, RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const TextureRef &srcTexture) const TextureRef &srcTexture)
{ {
if (!srcTexture) if (!srcTexture)
...@@ -618,7 +644,22 @@ angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context, ...@@ -618,7 +644,22 @@ angle::Result RenderUtils::blitColorWithDraw(const gl::Context *context,
params.dstRect = params.dstScissorRect = params.srcRect = params.dstRect = params.dstScissorRect = params.srcRect =
gl::Rectangle(0, 0, params.dstTextureSize.width, params.dstTextureSize.height); gl::Rectangle(0, 0, params.dstTextureSize.width, params.dstTextureSize.height);
return blitColorWithDraw(context, cmdEncoder, params); return blitColorWithDraw(context, cmdEncoder, srcAngleFormat, params);
}
angle::Result RenderUtils::copyTextureWithDraw(const gl::Context *context,
RenderCommandEncoder *cmdEncoder,
const angle::Format &srcAngleFormat,
const angle::Format &dstAngleFormat,
const ColorBlitParams &params)
{
if (!srcAngleFormat.isInt() && dstAngleFormat.isUint())
{
return mCopyTextureFloatToUIntUtils.blitColorWithDraw(context, cmdEncoder, params);
}
ASSERT(srcAngleFormat.isSint() == dstAngleFormat.isSint() &&
srcAngleFormat.isUint() == dstAngleFormat.isUint());
return blitColorWithDraw(context, cmdEncoder, srcAngleFormat, params);
} }
angle::Result RenderUtils::blitDepthStencilWithDraw(const gl::Context *context, angle::Result RenderUtils::blitDepthStencilWithDraw(const gl::Context *context,
...@@ -705,7 +746,11 @@ angle::Result RenderUtils::packPixelsFromTextureToBuffer(ContextMtl *contextMtl, ...@@ -705,7 +746,11 @@ angle::Result RenderUtils::packPixelsFromTextureToBuffer(ContextMtl *contextMtl,
} }
// ClearUtils implementation // ClearUtils implementation
ClearUtils::ClearUtils() = default; ClearUtils::ClearUtils(const std::string &fragmentShaderName)
: mFragmentShaderName(fragmentShaderName)
{}
ClearUtils::ClearUtils(const ClearUtils &src) : ClearUtils(src.mFragmentShaderName) {}
void ClearUtils::onDestroy() void ClearUtils::onDestroy()
{ {
...@@ -736,9 +781,10 @@ void ClearUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, uint ...@@ -736,9 +781,10 @@ void ClearUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, uint
type:MTLDataTypeUInt type:MTLDataTypeUInt
withName:NUM_COLOR_OUTPUTS_CONSTANT_NAME]; withName:NUM_COLOR_OUTPUTS_CONSTANT_NAME];
id<MTLFunction> fragmentShader = id<MTLFunction> fragmentShader = [[shaderLib
[[shaderLib newFunctionWithName:@"clearFloatFS" constantValues:funcConstants newFunctionWithName:[NSString stringWithUTF8String:mFragmentShaderName.c_str()]
error:&err] ANGLE_MTL_AUTORELEASE]; constantValues:funcConstants
error:&err] ANGLE_MTL_AUTORELEASE];
ASSERT(fragmentShader); ASSERT(fragmentShader);
cache.setVertexShader(ctx, vertexShader); cache.setVertexShader(ctx, vertexShader);
...@@ -840,11 +886,15 @@ void ClearUtils::setupClearWithDraw(const gl::Context *context, ...@@ -840,11 +886,15 @@ void ClearUtils::setupClearWithDraw(const gl::Context *context,
// uniform // uniform
ClearParamsUniform uniformParams; ClearParamsUniform uniformParams;
uniformParams.clearColor[0] = static_cast<float>(params.clearColor.value().red); const ClearColorValue &clearValue = params.clearColor.value();
uniformParams.clearColor[1] = static_cast<float>(params.clearColor.value().green); // ClearColorValue is an int, uint, float union so it's safe to use only floats.
uniformParams.clearColor[2] = static_cast<float>(params.clearColor.value().blue); // The Shader will do the bit cast based on appropriate format type.
uniformParams.clearColor[3] = static_cast<float>(params.clearColor.value().alpha); // See shaders/clear.metal (3 variants ClearFloatFS, ClearIntFS and ClearUIntFS each does the
uniformParams.clearDepth = params.clearDepth.value(); // appropriate bit cast)
ASSERT(sizeof(uniformParams.clearColor) == clearValue.getValueBytes().size());
std::memcpy(uniformParams.clearColor, clearValue.getValueBytes().data(),
clearValue.getValueBytes().size());
uniformParams.clearDepth = params.clearDepth.value();
cmdEncoder->setVertexData(uniformParams, 0); cmdEncoder->setVertexData(uniformParams, 0);
cmdEncoder->setFragmentData(uniformParams, 0); cmdEncoder->setFragmentData(uniformParams, 0);
...@@ -893,7 +943,12 @@ angle::Result ClearUtils::clearWithDraw(const gl::Context *context, ...@@ -893,7 +943,12 @@ angle::Result ClearUtils::clearWithDraw(const gl::Context *context,
} }
// ColorBlitUtils implementation // ColorBlitUtils implementation
ColorBlitUtils::ColorBlitUtils() = default; ColorBlitUtils::ColorBlitUtils(const std::string &fragmentShaderName)
: mFragmentShaderName(fragmentShaderName)
{}
ColorBlitUtils::ColorBlitUtils(const ColorBlitUtils &src) : ColorBlitUtils(src.mFragmentShaderName)
{}
void ColorBlitUtils::onDestroy() void ColorBlitUtils::onDestroy()
{ {
...@@ -952,9 +1007,10 @@ void ColorBlitUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, ...@@ -952,9 +1007,10 @@ void ColorBlitUtils::ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx,
type:MTLDataTypeInt type:MTLDataTypeInt
withName:SOURCE_TEXTURE_TYPE_CONSTANT_NAME]; withName:SOURCE_TEXTURE_TYPE_CONSTANT_NAME];
id<MTLFunction> fragmentShader = id<MTLFunction> fragmentShader = [[shaderLib
[[shaderLib newFunctionWithName:@"blitFloatFS" constantValues:funcConstants newFunctionWithName:[NSString stringWithUTF8String:mFragmentShaderName.c_str()]
error:&err] ANGLE_MTL_AUTORELEASE]; constantValues:funcConstants
error:&err] ANGLE_MTL_AUTORELEASE];
ASSERT(vertexShader); ASSERT(vertexShader);
ASSERT(fragmentShader); ASSERT(fragmentShader);
......
...@@ -303,6 +303,9 @@ struct RenderPassAttachmentDesc ...@@ -303,6 +303,9 @@ struct RenderPassAttachmentDesc
MipmapNativeLevel level; MipmapNativeLevel level;
uint32_t sliceOrDepth; uint32_t sliceOrDepth;
// This attachment is blendable or not.
bool blendable;
MTLLoadAction loadAction; MTLLoadAction loadAction;
MTLStoreAction storeAction; MTLStoreAction storeAction;
MTLStoreActionOptions storeActionOptions; MTLStoreActionOptions storeActionOptions;
......
...@@ -693,6 +693,7 @@ void RenderPassAttachmentDesc::reset() ...@@ -693,6 +693,7 @@ void RenderPassAttachmentDesc::reset()
implicitMSTexture.reset(); implicitMSTexture.reset();
level = mtl::kZeroNativeMipLevel; level = mtl::kZeroNativeMipLevel;
sliceOrDepth = 0; sliceOrDepth = 0;
blendable = false;
loadAction = MTLLoadActionLoad; loadAction = MTLLoadActionLoad;
storeAction = MTLStoreActionStore; storeAction = MTLStoreActionStore;
storeActionOptions = MTLStoreActionOptionNone; storeActionOptions = MTLStoreActionOptionNone;
...@@ -746,6 +747,11 @@ void RenderPassDesc::populateRenderPipelineOutputDesc(const BlendDesc &blendStat ...@@ -746,6 +747,11 @@ void RenderPassDesc::populateRenderPipelineOutputDesc(const BlendDesc &blendStat
{ {
// Copy parameters from blend state // Copy parameters from blend state
outputDescriptor.colorAttachments[i].update(blendState); outputDescriptor.colorAttachments[i].update(blendState);
if (!renderPassColorAttachment.blendable)
{
// Disable blending if the attachment's render target doesn't support blending.
outputDescriptor.colorAttachments[i].blendingEnabled = false;
}
outputDescriptor.colorAttachments[i].pixelFormat = texture->pixelFormat(); outputDescriptor.colorAttachments[i].pixelFormat = texture->pixelFormat();
......
...@@ -210,17 +210,18 @@ angle::Result InitializeTextureContentsGPU(const gl::Context *context, ...@@ -210,17 +210,18 @@ angle::Result InitializeTextureContentsGPU(const gl::Context *context,
RenderTargetMtl tempRtt; RenderTargetMtl tempRtt;
tempRtt.set(texture, index.getNativeLevel(), sliceOrDepth, textureObjFormat); tempRtt.set(texture, index.getNativeLevel(), sliceOrDepth, textureObjFormat);
MTLClearColor blackColor = {}; int clearAlpha = 0;
if (!textureObjFormat.intendedAngleFormat().alphaBits) if (!textureObjFormat.intendedAngleFormat().alphaBits)
{ {
// if intended format doesn't have alpha, set it to 1.0. // if intended format doesn't have alpha, set it to 1.0.
blackColor.alpha = kEmulatedAlphaValue; clearAlpha = kEmulatedAlphaValue;
} }
RenderCommandEncoder *encoder; RenderCommandEncoder *encoder;
if (channelsToInit == MTLColorWriteMaskAll) if (channelsToInit == MTLColorWriteMaskAll)
{ {
// If all channels will be initialized, use clear loadOp. // If all channels will be initialized, use clear loadOp.
Optional<MTLClearColor> blackColor = MTLClearColorMake(0, 0, 0, clearAlpha);
encoder = contextMtl->getRenderTargetCommandEncoderWithClear(tempRtt, blackColor); encoder = contextMtl->getRenderTargetCommandEncoderWithClear(tempRtt, blackColor);
} }
else else
...@@ -233,8 +234,23 @@ angle::Result InitializeTextureContentsGPU(const gl::Context *context, ...@@ -233,8 +234,23 @@ angle::Result InitializeTextureContentsGPU(const gl::Context *context,
// If there are some channels don't need to be initialized, we must use clearWithDraw. // If there are some channels don't need to be initialized, we must use clearWithDraw.
encoder = contextMtl->getRenderTargetCommandEncoder(tempRtt); encoder = contextMtl->getRenderTargetCommandEncoder(tempRtt);
const angle::Format &angleFormat = textureObjFormat.actualAngleFormat();
ClearRectParams clearParams; ClearRectParams clearParams;
clearParams.clearColor = blackColor; ClearColorValue clearColor;
if (angleFormat.isSint())
{
clearColor.setAsInt(0, 0, 0, clearAlpha);
}
else if (angleFormat.isUint())
{
clearColor.setAsUInt(0, 0, 0, clearAlpha);
}
else
{
clearColor.setAsFloat(0, 0, 0, clearAlpha);
}
clearParams.clearColor = clearColor;
clearParams.dstTextureSize = texture->sizeAt0(); clearParams.dstTextureSize = texture->sizeAt0();
clearParams.enabledBuffers.set(0); clearParams.enabledBuffers.set(0);
clearParams.clearArea = gl::Rectangle(0, 0, texture->widthAt0(), texture->heightAt0()); clearParams.clearArea = gl::Rectangle(0, 0, texture->widthAt0(), texture->heightAt0());
......
...@@ -1100,6 +1100,142 @@ TEST_P(ClearTestES3, MaskedClearHeterogeneousAttachments) ...@@ -1100,6 +1100,142 @@ TEST_P(ClearTestES3, MaskedClearHeterogeneousAttachments)
verifyStencil(kStencilClearValue, kSize); verifyStencil(kStencilClearValue, kSize);
} }
// Test that clearing multiple attachments of different nature (float, int and uint) in the
// presence of a scissor test works correctly. In the Vulkan backend, this exercises clearWithDraw
// and the relevant internal shaders.
TEST_P(ClearTestES3, ScissoredClearHeterogeneousAttachments)
{
// http://anglebug.com/4855
ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
// http://anglebug.com/5116
ANGLE_SKIP_TEST_IF(IsWindows() && (IsOpenGL() || IsD3D11()) && IsAMD());
constexpr uint32_t kSize = 16;
constexpr uint32_t kHalfSize = kSize / 2;
constexpr uint32_t kAttachmentCount = 3;
constexpr float kDepthClearValue = 0.256f;
constexpr int32_t kStencilClearValue = 0x1D;
constexpr GLenum kAttachmentFormats[kAttachmentCount] = {
GL_RGBA8,
GL_RGBA8I,
GL_RGBA8UI,
};
constexpr GLenum kDataFormats[kAttachmentCount] = {
GL_RGBA,
GL_RGBA_INTEGER,
GL_RGBA_INTEGER,
};
constexpr GLenum kDataTypes[kAttachmentCount] = {
GL_UNSIGNED_BYTE,
GL_BYTE,
GL_UNSIGNED_BYTE,
};
std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
GLTexture textures[kAttachmentCount];
GLRenderbuffer depthStencil;
GLenum drawBuffers[kAttachmentCount];
for (uint32_t i = 0; i < kAttachmentCount; ++i)
{
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],
kDataTypes[i], pixelData.data());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
0);
drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
}
glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
depthStencil);
glDrawBuffers(kAttachmentCount, drawBuffers);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
// Enable scissor test
glScissor(0, 0, kHalfSize, kHalfSize);
glEnable(GL_SCISSOR_TEST);
GLColor clearValuef = {25, 50, 75, 100};
angle::Vector4 clearValuefv = clearValuef.toNormalizedVector();
glClearColor(clearValuefv.x(), clearValuefv.y(), clearValuefv.z(), clearValuefv.w());
glClearDepthf(kDepthClearValue);
// clear stencil.
glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
// clear float color attachment & depth together
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// clear integer attachment.
int clearValuei[4] = {10, -20, 30, -40};
glClearBufferiv(GL_COLOR, 1, clearValuei);
// clear unsigned integer attachment
uint32_t clearValueui[4] = {50, 60, 70, 80};
glClearBufferuiv(GL_COLOR, 2, clearValueui);
ASSERT_GL_NO_ERROR();
{
glReadBuffer(GL_COLOR_ATTACHMENT0);
ASSERT_GL_NO_ERROR();
GLColor expect = clearValuef;
EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
EXPECT_PIXEL_COLOR_EQ(0, kHalfSize - 1, expect);
EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, 0, expect);
EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, kHalfSize - 1, expect);
EXPECT_PIXEL_EQ(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
}
{
glReadBuffer(GL_COLOR_ATTACHMENT1);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_8I(0, 0, clearValuei[0], clearValuei[1], clearValuei[2], clearValuei[3]);
EXPECT_PIXEL_8I(0, kHalfSize - 1, clearValuei[0], clearValuei[1], clearValuei[2],
clearValuei[3]);
EXPECT_PIXEL_8I(kHalfSize - 1, 0, clearValuei[0], clearValuei[1], clearValuei[2],
clearValuei[3]);
EXPECT_PIXEL_8I(kHalfSize - 1, kHalfSize - 1, clearValuei[0], clearValuei[1],
clearValuei[2], clearValuei[3]);
EXPECT_PIXEL_8I(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
}
{
glReadBuffer(GL_COLOR_ATTACHMENT2);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_8UI(0, 0, clearValueui[0], clearValueui[1], clearValueui[2], clearValueui[3]);
EXPECT_PIXEL_8UI(0, kHalfSize - 1, clearValueui[0], clearValueui[1], clearValueui[2],
clearValueui[3]);
EXPECT_PIXEL_8UI(kHalfSize - 1, 0, clearValueui[0], clearValueui[1], clearValueui[2],
clearValueui[3]);
EXPECT_PIXEL_8UI(kHalfSize - 1, kHalfSize - 1, clearValueui[0], clearValueui[1],
clearValueui[2], clearValueui[3]);
EXPECT_PIXEL_8UI(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
}
glReadBuffer(GL_COLOR_ATTACHMENT0);
for (uint32_t i = 1; i < kAttachmentCount; ++i)
drawBuffers[i] = GL_NONE;
glDrawBuffers(kAttachmentCount, drawBuffers);
verifyDepth(kDepthClearValue, kHalfSize);
verifyStencil(kStencilClearValue, kHalfSize);
}
// This tests a bug where in a masked clear when calling "ClearBuffer", we would // This tests a bug where in a masked clear when calling "ClearBuffer", we would
// mistakenly clear every channel (including the masked-out ones) // mistakenly clear every channel (including the masked-out ones)
TEST_P(ClearTestES3, MaskedClearBufferBug) TEST_P(ClearTestES3, MaskedClearBufferBug)
...@@ -2140,7 +2276,7 @@ TEST_P(ClearTestES3, ClearBufferfiStencilMask) ...@@ -2140,7 +2276,7 @@ TEST_P(ClearTestES3, ClearBufferfiStencilMask)
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClearTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClearTest);
ANGLE_INSTANTIATE_TEST_ES3(ClearTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(ClearTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest, ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest,
MaskedScissoredClearVariationsTestPrint, MaskedScissoredClearVariationsTestPrint,
testing::Range(0, 3), testing::Range(0, 3),
...@@ -2155,7 +2291,9 @@ ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest, ...@@ -2155,7 +2291,9 @@ ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest,
ES2_OPENGLES(), ES2_OPENGLES(),
ES3_OPENGLES(), ES3_OPENGLES(),
ES2_VULKAN(), ES2_VULKAN(),
ES3_VULKAN()); ES3_VULKAN(),
ES2_METAL(),
ES3_METAL());
ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest, ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest,
MaskedScissoredClearVariationsTestPrint, MaskedScissoredClearVariationsTestPrint,
testing::Range(0, 3), testing::Range(0, 3),
...@@ -2166,6 +2304,12 @@ ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest, ...@@ -2166,6 +2304,12 @@ ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest,
ES3_VULKAN()); ES3_VULKAN());
// Not all ANGLE backends support RGB backbuffers // Not all ANGLE backends support RGB backbuffers
ANGLE_INSTANTIATE_TEST(ClearTestRGB, ES2_D3D11(), ES3_D3D11(), ES2_VULKAN(), ES3_VULKAN()); ANGLE_INSTANTIATE_TEST(ClearTestRGB,
ES2_D3D11(),
ES3_D3D11(),
ES2_VULKAN(),
ES3_VULKAN(),
ES2_METAL(),
ES3_METAL());
} // anonymous namespace } // anonymous namespace
...@@ -2541,6 +2541,6 @@ ANGLE_INSTANTIATE_TEST(CopyTextureTestDest, ...@@ -2541,6 +2541,6 @@ ANGLE_INSTANTIATE_TEST(CopyTextureTestDest,
ES2_OPENGLES(), ES2_OPENGLES(),
ES2_VULKAN(), ES2_VULKAN(),
ES2_METAL()); ES2_METAL());
ANGLE_INSTANTIATE_TEST_ES3(CopyTextureTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(CopyTextureTestES3, ES3_METAL());
} // namespace angle } // namespace angle
...@@ -301,6 +301,9 @@ TEST_P(DrawBuffersTest, BlendWithGaps) ...@@ -301,6 +301,9 @@ TEST_P(DrawBuffersTest, BlendWithGaps)
// Fails on Intel Ubuntu 19.04 Mesa 19.0.2 Vulkan. http://anglebug.com/3616 // Fails on Intel Ubuntu 19.04 Mesa 19.0.2 Vulkan. http://anglebug.com/3616
ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan()); ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
// http://anglebug.com/5154
ANGLE_SKIP_TEST_IF(IsOSX() && IsIntel() && IsDesktopOpenGL());
glBindTexture(GL_TEXTURE_2D, mTextures[0]); glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0);
......
...@@ -8116,12 +8116,12 @@ ANGLE_INSTANTIATE_TEST(Texture2DRGTest, ...@@ -8116,12 +8116,12 @@ ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3); ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2); ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3); ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DIntegerTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(TextureCubeIntegerTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(TextureCubeIntegerEdgeTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(TextureCubeIntegerEdgeTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerProjectiveOffsetTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DIntegerProjectiveOffsetTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DArrayIntegerTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(Texture3DIntegerTestES3, ES3_METAL());
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest); ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
......
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