diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/angle/src/libGLESv2 | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/angle/src/libGLESv2')
248 files changed, 47924 insertions, 16901 deletions
diff --git a/chromium/third_party/angle/src/libGLESv2/BinaryStream.h b/chromium/third_party/angle/src/libGLESv2/BinaryStream.h index 21c2f86ce82..253c1ebc5aa 100644 --- a/chromium/third_party/angle/src/libGLESv2/BinaryStream.h +++ b/chromium/third_party/angle/src/libGLESv2/BinaryStream.h @@ -10,6 +10,7 @@ #define LIBGLESV2_BINARYSTREAM_H_ #include "common/angleutils.h" +#include "common/mathutil.h" namespace gl { @@ -25,42 +26,49 @@ class BinaryInputStream mLength = length; } - template <typename T> - void read(T *v, size_t num) + // readInt will generate an error for bool types + template <class IntT> + IntT readInt() { - union - { - T dummy; // Compilation error for non-trivial types - } dummy; - (void) dummy; + int value; + read(&value); + return static_cast<IntT>(value); + } - if (mError) - { - return; - } + template <class IntT> + void readInt(IntT *outValue) + { + *outValue = readInt<IntT>(); + } - size_t length = num * sizeof(T); + bool readBool() + { + int value; + read(&value); + return (value > 0); + } - if (mOffset + length > mLength) - { - mError = true; - return; - } + void readBool(bool *outValue) + { + *outValue = readBool(); + } - memcpy(v, mData + mOffset, length); - mOffset += length; + void readBytes(unsigned char outArray[], size_t count) + { + read<unsigned char>(outArray, count); } - template <typename T> - void read(T * v) + std::string readString() { - read(v, 1); + std::string outString; + readString(&outString); + return outString; } - void read(std::string *v) + void readString(std::string *v) { size_t length; - read(&length); + readInt(&length); if (mError) { @@ -109,6 +117,30 @@ class BinaryInputStream size_t mOffset; const char *mData; size_t mLength; + + template <typename T> + void read(T *v, size_t num) + { + META_ASSERT(std::is_fundamental<T>::value); + + size_t length = num * sizeof(T); + + if (mOffset + length > mLength) + { + mError = true; + return; + } + + memcpy(v, mData + mOffset, length); + mOffset += length; + } + + template <typename T> + void read(T *v) + { + read(v, 1); + } + }; class BinaryOutputStream @@ -118,31 +150,24 @@ class BinaryOutputStream { } - template <typename T> - void write(const T *v, size_t num) + // writeInt also handles bool types + template <class IntT> + void writeInt(IntT param) { - union - { - T dummy; // Compilation error for non-trivial types - } dummy; - (void) dummy; - - const char *asBytes = reinterpret_cast<const char*>(v); - mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T)); + ASSERT(rx::IsIntegerCastSafe<int>(param)); + int intValue = static_cast<int>(param); + write(&intValue, 1); } - template <typename T> - void write(const T &v) + void writeString(const std::string &v) { - write(&v, 1); + writeInt(v.length()); + write(v.c_str(), v.length()); } - void write(const std::string &v) + void writeBytes(unsigned char *bytes, size_t count) { - size_t length = v.length(); - write(length); - - write(v.c_str(), length); + write(bytes, count); } size_t length() const @@ -158,6 +183,15 @@ class BinaryOutputStream private: DISALLOW_COPY_AND_ASSIGN(BinaryOutputStream); std::vector<char> mData; + + template <typename T> + void write(const T *v, size_t num) + { + META_ASSERT(std::is_fundamental<T>::value); + const char *asBytes = reinterpret_cast<const char*>(v); + mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T)); + } + }; } diff --git a/chromium/third_party/angle/src/libGLESv2/Buffer.cpp b/chromium/third_party/angle/src/libGLESv2/Buffer.cpp index c007d5d9e90..e7d2c00f005 100644 --- a/chromium/third_party/angle/src/libGLESv2/Buffer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Buffer.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -19,15 +19,21 @@ namespace gl { -Buffer::Buffer(rx::Renderer *renderer, GLuint id) : RefCountObject(id) +Buffer::Buffer(rx::Renderer *renderer, GLuint id) + : RefCountObject(id), + mRenderer(renderer), + mUsage(GL_DYNAMIC_DRAW), + mAccessFlags(0), + mMapped(GL_FALSE), + mMapPointer(NULL), + mMapOffset(0), + mMapLength(0), + mBufferStorage(NULL), + mStaticVertexBuffer(NULL), + mStaticIndexBuffer(NULL), + mUnmodifiedDataUse(0) { - mRenderer = renderer; - mUsage = GL_DYNAMIC_DRAW; - mBufferStorage = renderer->createBufferStorage(); - mStaticVertexBuffer = NULL; - mStaticIndexBuffer = NULL; - mUnmodifiedDataUse = 0; } Buffer::~Buffer() @@ -58,13 +64,41 @@ void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) { mBufferStorage->setData(data, size, offset); mIndexRangeCache.invalidateRange(offset, size); + invalidateStaticData(); +} - if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) - { - invalidateStaticData(); - } +void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +{ + mBufferStorage->copyData(source->mBufferStorage, size, sourceOffset, destOffset); + invalidateStaticData(); +} - mUnmodifiedDataUse = 0; +GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + ASSERT(!mMapped); + + void *dataPointer = mBufferStorage->map(access); + + mMapped = GL_TRUE; + mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer) + offset); + mMapOffset = static_cast<GLint64>(offset); + mMapLength = static_cast<GLint64>(length); + mAccessFlags = static_cast<GLint>(access); + + return mMapPointer; +} + +void Buffer::unmap() +{ + ASSERT(mMapped); + + mBufferStorage->unmap(); + + mMapped = GL_FALSE; + mMapPointer = NULL; + mMapOffset = 0; + mMapLength = 0; + mAccessFlags = 0; } rx::BufferStorage *Buffer::getStorage() const @@ -72,9 +106,9 @@ rx::BufferStorage *Buffer::getStorage() const return mBufferStorage; } -unsigned int Buffer::size() const +GLint64 Buffer::size() const { - return mBufferStorage->getSize(); + return static_cast<GLint64>(mBufferStorage->getSize()); } GLenum Buffer::usage() const @@ -82,6 +116,37 @@ GLenum Buffer::usage() const return mUsage; } +GLint Buffer::accessFlags() const +{ + return mAccessFlags; +} + +GLboolean Buffer::mapped() const +{ + return mMapped; +} + +GLvoid *Buffer::mapPointer() const +{ + return mMapPointer; +} + +GLint64 Buffer::mapOffset() const +{ + return mMapOffset; +} + +GLint64 Buffer::mapLength() const +{ + return mMapLength; +} + +void Buffer::markTransformFeedbackUsage() +{ + mBufferStorage->markTransformFeedbackUsage(); + invalidateStaticData(); +} + rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer() { return mStaticVertexBuffer; @@ -94,11 +159,14 @@ rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer() void Buffer::invalidateStaticData() { - delete mStaticVertexBuffer; - mStaticVertexBuffer = NULL; + if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) + { + delete mStaticVertexBuffer; + mStaticVertexBuffer = NULL; - delete mStaticIndexBuffer; - mStaticIndexBuffer = NULL; + delete mStaticIndexBuffer; + mStaticIndexBuffer = NULL; + } mUnmodifiedDataUse = 0; } diff --git a/chromium/third_party/angle/src/libGLESv2/Buffer.h b/chromium/third_party/angle/src/libGLESv2/Buffer.h index 4048f4b9064..55fbdeb1c9b 100644 --- a/chromium/third_party/angle/src/libGLESv2/Buffer.h +++ b/chromium/third_party/angle/src/libGLESv2/Buffer.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -35,11 +35,21 @@ class Buffer : public RefCountObject void bufferData(const void *data, GLsizeiptr size, GLenum usage); void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); + void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); + void unmap(); GLenum usage() const; + GLint accessFlags() const; + GLboolean mapped() const; + GLvoid *mapPointer() const; + GLint64 mapOffset() const; + GLint64 mapLength() const; rx::BufferStorage *getStorage() const; - unsigned int size() const; + GLint64 size() const; + + void markTransformFeedbackUsage(); rx::StaticVertexBufferInterface *getStaticVertexBuffer(); rx::StaticIndexBufferInterface *getStaticIndexBuffer(); @@ -53,6 +63,11 @@ class Buffer : public RefCountObject rx::Renderer *mRenderer; GLenum mUsage; + GLint mAccessFlags; + GLboolean mMapped; + GLvoid *mMapPointer; + GLint64 mMapOffset; + GLint64 mMapLength; rx::BufferStorage *mBufferStorage; diff --git a/chromium/third_party/angle/src/libGLESv2/Context.cpp b/chromium/third_party/angle/src/libGLESv2/Context.cpp index fba4104d1e1..879a560045c 100644 --- a/chromium/third_party/angle/src/libGLESv2/Context.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Context.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -11,7 +11,8 @@ #include "libGLESv2/Context.h" #include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Fence.h" #include "libGLESv2/Framebuffer.h" @@ -24,6 +25,10 @@ #include "libGLESv2/renderer/IndexDataManager.h" #include "libGLESv2/renderer/RenderTarget.h" #include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/Sampler.h" +#include "libGLESv2/validationES.h" +#include "libGLESv2/TransformFeedback.h" #include "libEGL/Surface.h" @@ -42,17 +47,20 @@ static const char* makeStaticString(const std::string& str) return strings.insert(str).first->c_str(); } -Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer) +Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer) { ASSERT(robustAccess == false); // Unimplemented - mFenceHandleAllocator.setBaseHandle(0); + mFenceNVHandleAllocator.setBaseHandle(0); setClearColor(0.0f, 0.0f, 0.0f, 0.0f); + mClientVersion = clientVersion; + mState.depthClearValue = 1.0f; mState.stencilClearValue = 0; + mState.rasterizer.rasterizerDiscard = false; mState.rasterizer.cullFace = false; mState.rasterizer.cullMode = GL_BACK; mState.rasterizer.frontFace = GL_CCW; @@ -122,6 +130,12 @@ Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool n mState.blend.colorMaskBlue = true; mState.blend.colorMaskAlpha = true; + const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) + { + mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); + } + if (shareContext != NULL) { mResourceManager = shareContext->mResourceManager; @@ -140,8 +154,16 @@ Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool n mTexture2DZero.set(new Texture2D(mRenderer, 0)); mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0)); + mTexture3DZero.set(new Texture3D(mRenderer, 0)); + mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0)); + + for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++) + { + mState.samplers[textureUnit] = 0; + } mState.activeSampler = 0; + bindVertexArray(0); bindArrayBuffer(0); bindElementArrayBuffer(0); bindTextureCubeMap(0); @@ -150,14 +172,38 @@ Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool n bindDrawFramebuffer(0); bindRenderbuffer(0); + mState.activeQueries[GL_ANY_SAMPLES_PASSED].set(NULL); + mState.activeQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL); + mState.activeQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL); + + bindGenericUniformBuffer(0); + for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + { + bindIndexedUniformBuffer(0, i, 0, -1); + } + + bindGenericTransformFeedbackBuffer(0); + for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + bindIndexedTransformFeedbackBuffer(0, i, 0, -1); + } + + bindCopyReadBuffer(0); + bindCopyWriteBuffer(0); + bindPixelPackBuffer(0); + bindPixelUnpackBuffer(0); + + // [OpenGL ES 3.0.2] section 2.14.1 pg 85: + // In the initial state, a default transform feedback object is bound and treated as + // a transform feedback object with a name of zero. That object is bound any time + // BindTransformFeedback is called with id of zero + mTransformFeedbackZero.set(new TransformFeedback(0)); + bindTransformFeedback(0); + mState.currentProgram = 0; mCurrentProgramBinary.set(NULL); - mState.packAlignment = 4; - mState.unpackAlignment = 4; - mState.packReverseRowOrder = false; - - mExtensionString = NULL; + mCombinedExtensionsString = NULL; mRendererString = NULL; mInvalidEnum = false; @@ -199,9 +245,9 @@ Context::~Context() deleteFramebuffer(mFramebufferMap.begin()->first); } - while (!mFenceMap.empty()) + while (!mFenceNVMap.empty()) { - deleteFence(mFenceMap.begin()->first); + deleteFenceNV(mFenceNVMap.begin()->first); } while (!mQueryMap.empty()) @@ -209,6 +255,17 @@ Context::~Context() deleteQuery(mQueryMap.begin()->first); } + while (!mVertexArrayMap.empty()) + { + deleteVertexArray(mVertexArrayMap.begin()->first); + } + + mTransformFeedbackZero.set(NULL); + while (!mTransformFeedbackMap.empty()) + { + deleteTransformFeedback(mTransformFeedbackMap.begin()->first); + } + for (int type = 0; type < TEXTURE_TYPE_COUNT; type++) { for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) @@ -222,22 +279,44 @@ Context::~Context() mIncompleteTextures[type].set(NULL); } - for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) - { - mState.vertexAttribute[i].mBoundBuffer.set(NULL); - } - - for (int i = 0; i < QUERY_TYPE_COUNT; i++) + const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) { - mState.activeQuery[i].set(NULL); + mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); } mState.arrayBuffer.set(NULL); - mState.elementArrayBuffer.set(NULL); mState.renderbuffer.set(NULL); + mState.transformFeedback.set(NULL); + mTexture2DZero.set(NULL); mTextureCubeMapZero.set(NULL); + mTexture3DZero.set(NULL); + mTexture2DArrayZero.set(NULL); + + for (State::ActiveQueryMap::iterator i = mState.activeQueries.begin(); i != mState.activeQueries.end(); i++) + { + i->second.set(NULL); + } + + mState.genericUniformBuffer.set(NULL); + for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + { + mState.uniformBuffers[i].set(NULL); + } + + mState.genericTransformFeedbackBuffer.set(NULL); + for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + mState.transformFeedbackBuffers[i].set(NULL); + } + + mState.copyReadBuffer.set(NULL); + mState.copyWriteBuffer.set(NULL); + + mState.pack.pixelBuffer.set(NULL); + mState.unpack.pixelBuffer.set(NULL); mResourceManager->release(); } @@ -253,14 +332,24 @@ void Context::makeCurrent(egl::Surface *surface) mSupportsInstancing = mRenderer->getInstancingSupport(); mMaxViewportDimension = mRenderer->getMaxViewportDimension(); - mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()), - (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE); - mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE); - mMaxRenderbufferDimension = mMaxTextureDimension; - mMaxTextureLevel = log2(mMaxTextureDimension) + 1; + mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()), + (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE); + mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE); + mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()), + (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE); + mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers(); + mMaxRenderbufferDimension = mMax2DTextureDimension; + mMax2DTextureLevel = log2(mMax2DTextureDimension) + 1; + mMaxCubeTextureLevel = log2(mMaxCubeTextureDimension) + 1; + mMax3DTextureLevel = log2(mMax3DTextureDimension) + 1; + mMax2DArrayTextureLevel = log2(mMax2DTextureDimension) + 1; mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy(); - TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f", - mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy); + TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, " + "Max2DTextureLevel=%d, MaxCubeTextureLevel=%d, Max3DTextureLevel=%d, Max2DArrayTextureLevel=%d, " + "MaxRenderbufferDimension=%d, MaxTextureAnisotropy=%f", + mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers, + mMax2DTextureLevel, mMaxCubeTextureLevel, mMax3DTextureLevel, mMax2DArrayTextureLevel, + mMaxRenderbufferDimension, mMaxTextureAnisotropy); mSupportsEventQueries = mRenderer->getEventQuerySupport(); mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport(); @@ -268,13 +357,19 @@ void Context::makeCurrent(egl::Surface *surface) mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport(); mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport(); mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport(); - mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures); - mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures); + mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(); + mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport(); + mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport(); + mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(); + mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport(); + mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport(); mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport(); mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport(); + mSupportsRGTextures = mRenderer->getRGTextureSupport(); mSupportsDepthTextures = mRenderer->getDepthTextureSupport(); mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport(); mSupports32bitIndices = mRenderer->get32BitIndexSupport(); + mSupportsPBOs = mRenderer->getPBOSupport(); mNumCompressedTextureFormats = 0; if (supportsDXT1Textures()) @@ -314,6 +409,9 @@ void Context::makeCurrent(egl::Surface *surface) Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero); setFramebufferZero(framebufferZero); + + // Store the current client version in the renderer + mRenderer->setCurrentClientVersion(mClientVersion); } // NOTE: this function should not assume that this context is current! @@ -329,6 +427,44 @@ bool Context::isContextLost() return mContextLost; } +void Context::setCap(GLenum cap, bool enabled) +{ + switch (cap) + { + case GL_CULL_FACE: setCullFace(enabled); break; + case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break; + case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break; + case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break; + case GL_SCISSOR_TEST: setScissorTest(enabled); break; + case GL_STENCIL_TEST: setStencilTest(enabled); break; + case GL_DEPTH_TEST: setDepthTest(enabled); break; + case GL_BLEND: setBlend(enabled); break; + case GL_DITHER: setDither(enabled); break; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break; + case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break; + default: UNREACHABLE(); + } +} + +bool Context::getCap(GLenum cap) +{ + switch (cap) + { + case GL_CULL_FACE: return isCullFaceEnabled(); + case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled(); + case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled(); + case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled(); + case GL_SCISSOR_TEST: return isScissorTestEnabled(); + case GL_STENCIL_TEST: return isStencilTestEnabled(); + case GL_DEPTH_TEST: return isDepthTestEnabled(); + case GL_BLEND: return isBlendEnabled(); + case GL_DITHER: return isDitherEnabled(); + case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false; + case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled(); + default: UNREACHABLE(); return false; + } +} + void Context::setClearColor(float red, float green, float blue, float alpha) { mState.colorClearValue.red = red; @@ -347,6 +483,16 @@ void Context::setClearStencil(int stencil) mState.stencilClearValue = stencil; } +void Context::setRasterizerDiscard(bool enabled) +{ + mState.rasterizer.rasterizerDiscard = enabled; +} + +bool Context::isRasterizerDiscardEnabled() const +{ + return mState.rasterizer.rasterizerDiscard; +} + void Context::setCullFace(bool enabled) { mState.rasterizer.cullFace = enabled; @@ -565,6 +711,14 @@ void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) mState.scissor.height = height; } +void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height) +{ + *x = mState.scissor.x; + *y = mState.scissor.y; + *width = mState.scissor.width; + *height = mState.scissor.height; +} + void Context::setColorMask(bool red, bool green, bool blue, bool alpha) { mState.blend.colorMaskRed = red; @@ -598,91 +752,120 @@ GLuint Context::getRenderbufferHandle() const return mState.renderbuffer.id(); } +GLuint Context::getVertexArrayHandle() const +{ + return mState.vertexArray; +} + +GLuint Context::getSamplerHandle(GLuint textureUnit) const +{ + ASSERT(textureUnit < ArraySize(mState.samplers)); + return mState.samplers[textureUnit]; +} + +unsigned int Context::getActiveSampler() const +{ + return mState.activeSampler; +} + GLuint Context::getArrayBufferHandle() const { return mState.arrayBuffer.id(); } -GLuint Context::getActiveQuery(GLenum target) const +bool Context::isQueryActive() const { - Query *queryObject = NULL; - - switch (target) + for (State::ActiveQueryMap::const_iterator i = mState.activeQueries.begin(); + i != mState.activeQueries.end(); i++) { - case GL_ANY_SAMPLES_PASSED_EXT: - queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get(); - break; - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get(); - break; - default: - ASSERT(false); + if (i->second.get() != NULL) + { + return true; + } } - if (queryObject) - { - return queryObject->id(); - } - else - { - return 0; - } + return false; +} + +const Query *Context::getActiveQuery(GLenum target) const +{ + // All query types should already exist in the activeQueries map + ASSERT(mState.activeQueries.find(target) != mState.activeQueries.end()); + + return mState.activeQueries.at(target).get(); +} + +GLuint Context::getActiveQueryId(GLenum target) const +{ + const Query *query = getActiveQuery(target); + return (query ? query->id() : 0u); } void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) { - mState.vertexAttribute[attribNum].mArrayEnabled = enabled; + getCurrentVertexArray()->enableAttribute(attribNum, enabled); +} + +const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const +{ + return getCurrentVertexArray()->getVertexAttribute(attribNum); } -const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) +const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const { - return mState.vertexAttribute[attribNum]; + ASSERT(attribNum < MAX_VERTEX_ATTRIBS); + return mState.vertexAttribCurrentValues[attribNum]; } void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, - GLsizei stride, const void *pointer) + bool pureInteger, GLsizei stride, const void *pointer) { - mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer); - mState.vertexAttribute[attribNum].mSize = size; - mState.vertexAttribute[attribNum].mType = type; - mState.vertexAttribute[attribNum].mNormalized = normalized; - mState.vertexAttribute[attribNum].mStride = stride; - mState.vertexAttribute[attribNum].mPointer = pointer; + getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer); } const void *Context::getVertexAttribPointer(unsigned int attribNum) const { - return mState.vertexAttribute[attribNum].mPointer; + return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer; } void Context::setPackAlignment(GLint alignment) { - mState.packAlignment = alignment; + mState.pack.alignment = alignment; } GLint Context::getPackAlignment() const { - return mState.packAlignment; + return mState.pack.alignment; } void Context::setUnpackAlignment(GLint alignment) { - mState.unpackAlignment = alignment; + mState.unpack.alignment = alignment; } GLint Context::getUnpackAlignment() const { - return mState.unpackAlignment; + return mState.unpack.alignment; } void Context::setPackReverseRowOrder(bool reverseRowOrder) { - mState.packReverseRowOrder = reverseRowOrder; + mState.pack.reverseRowOrder = reverseRowOrder; } bool Context::getPackReverseRowOrder() const { - return mState.packReverseRowOrder; + return mState.pack.reverseRowOrder; +} + +const PixelUnpackState &Context::getUnpackState() const +{ + return mState.unpack; +} + +const PixelPackState &Context::getPackState() const +{ + return mState.pack; } GLuint Context::createBuffer() @@ -710,6 +893,44 @@ GLuint Context::createRenderbuffer() return mResourceManager->createRenderbuffer(); } +GLsync Context::createFenceSync(GLenum condition) +{ + GLuint handle = mResourceManager->createFenceSync(); + + gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle); + ASSERT(fenceSync); + + fenceSync->set(condition); + + return reinterpret_cast<GLsync>(handle); +} + +GLuint Context::createVertexArray() +{ + GLuint handle = mVertexArrayHandleAllocator.allocate(); + + // Although the spec states VAO state is not initialized until the object is bound, + // we create it immediately. The resulting behaviour is transparent to the application, + // since it's not currently possible to access the state until the object is bound. + mVertexArrayMap[handle] = new VertexArray(mRenderer, handle); + + return handle; +} + +GLuint Context::createSampler() +{ + return mResourceManager->createSampler(); +} + +GLuint Context::createTransformFeedback() +{ + GLuint handle = mTransformFeedbackAllocator.allocate(); + TransformFeedback *transformFeedback = new TransformFeedback(handle); + transformFeedback->addRef(); + mTransformFeedbackMap[handle] = transformFeedback; + return handle; +} + // Returns an unused framebuffer name GLuint Context::createFramebuffer() { @@ -720,11 +941,11 @@ GLuint Context::createFramebuffer() return handle; } -GLuint Context::createFence() +GLuint Context::createFenceNV() { - GLuint handle = mFenceHandleAllocator.allocate(); + GLuint handle = mFenceNVHandleAllocator.allocate(); - mFenceMap[handle] = new Fence(mRenderer); + mFenceNVMap[handle] = new FenceNV(mRenderer); return handle; } @@ -745,7 +966,7 @@ void Context::deleteBuffer(GLuint buffer) { detachBuffer(buffer); } - + mResourceManager->deleteBuffer(buffer); } @@ -775,10 +996,55 @@ void Context::deleteRenderbuffer(GLuint renderbuffer) { detachRenderbuffer(renderbuffer); } - + mResourceManager->deleteRenderbuffer(renderbuffer); } +void Context::deleteFenceSync(GLsync fenceSync) +{ + // The spec specifies the underlying Fence object is not deleted until all current + // wait commands finish. However, since the name becomes invalid, we cannot query the fence, + // and since our API is currently designed for being called from a single thread, we can delete + // the fence immediately. + mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync)); +} + +void Context::deleteVertexArray(GLuint vertexArray) +{ + auto vertexArrayObject = mVertexArrayMap.find(vertexArray); + + if (vertexArrayObject != mVertexArrayMap.end()) + { + detachVertexArray(vertexArray); + + mVertexArrayHandleAllocator.release(vertexArrayObject->first); + delete vertexArrayObject->second; + mVertexArrayMap.erase(vertexArrayObject); + } +} + +void Context::deleteSampler(GLuint sampler) +{ + if (mResourceManager->getSampler(sampler)) + { + detachSampler(sampler); + } + + mResourceManager->deleteSampler(sampler); +} + +void Context::deleteTransformFeedback(GLuint transformFeedback) +{ + TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback); + if (iter != mTransformFeedbackMap.end()) + { + detachTransformFeedback(transformFeedback); + mTransformFeedbackAllocator.release(transformFeedback); + iter->second->release(); + mTransformFeedbackMap.erase(iter); + } +} + void Context::deleteFramebuffer(GLuint framebuffer) { FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); @@ -793,15 +1059,15 @@ void Context::deleteFramebuffer(GLuint framebuffer) } } -void Context::deleteFence(GLuint fence) +void Context::deleteFenceNV(GLuint fence) { - FenceMap::iterator fenceObject = mFenceMap.find(fence); + FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence); - if (fenceObject != mFenceMap.end()) + if (fenceObject != mFenceNVMap.end()) { - mFenceHandleAllocator.release(fenceObject->first); + mFenceNVHandleAllocator.release(fenceObject->first); delete fenceObject->second; - mFenceMap.erase(fenceObject); + mFenceNVMap.erase(fenceObject); } } @@ -824,12 +1090,12 @@ Buffer *Context::getBuffer(GLuint handle) return mResourceManager->getBuffer(handle); } -Shader *Context::getShader(GLuint handle) +Shader *Context::getShader(GLuint handle) const { return mResourceManager->getShader(handle); } -Program *Context::getProgram(GLuint handle) +Program *Context::getProgram(GLuint handle) const { return mResourceManager->getProgram(handle); } @@ -839,11 +1105,48 @@ Texture *Context::getTexture(GLuint handle) return mResourceManager->getTexture(handle); } -Renderbuffer *Context::getRenderbuffer(GLuint handle) +FramebufferAttachment *Context::getRenderbuffer(GLuint handle) { return mResourceManager->getRenderbuffer(handle); } +FenceSync *Context::getFenceSync(GLsync handle) const +{ + return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle)); +} + +VertexArray *Context::getVertexArray(GLuint handle) const +{ + auto vertexArray = mVertexArrayMap.find(handle); + + if (vertexArray == mVertexArrayMap.end()) + { + return NULL; + } + else + { + return vertexArray->second; + } +} + +Sampler *Context::getSampler(GLuint handle) const +{ + return mResourceManager->getSampler(handle); +} + +TransformFeedback *Context::getTransformFeedback(GLuint handle) const +{ + if (handle == 0) + { + return mTransformFeedbackZero.get(); + } + else + { + TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle); + return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL; + } +} + Framebuffer *Context::getReadFramebuffer() { return getFramebuffer(mState.readFramebuffer); @@ -854,6 +1157,23 @@ Framebuffer *Context::getDrawFramebuffer() return mBoundDrawFramebuffer; } +VertexArray *Context::getCurrentVertexArray() const +{ + VertexArray *vao = getVertexArray(mState.vertexArray); + ASSERT(vao != NULL); + return vao; +} + +TransformFeedback *Context::getCurrentTransformFeedback() const +{ + return mState.transformFeedback.get(); +} + +bool Context::isSampler(GLuint samplerName) const +{ + return mResourceManager->isSampler(samplerName); +} + void Context::bindArrayBuffer(unsigned int buffer) { mResourceManager->checkBufferAllocation(buffer); @@ -865,7 +1185,7 @@ void Context::bindElementArrayBuffer(unsigned int buffer) { mResourceManager->checkBufferAllocation(buffer); - mState.elementArrayBuffer.set(getBuffer(buffer)); + getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer)); } void Context::bindTexture2D(GLuint texture) @@ -882,6 +1202,20 @@ void Context::bindTextureCubeMap(GLuint texture) mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture)); } +void Context::bindTexture3D(GLuint texture) +{ + mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); + + mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture)); +} + +void Context::bindTexture2DArray(GLuint texture) +{ + mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY); + + mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture)); +} + void Context::bindReadFramebuffer(GLuint framebuffer) { if (!getFramebuffer(framebuffer)) @@ -911,6 +1245,80 @@ void Context::bindRenderbuffer(GLuint renderbuffer) mState.renderbuffer.set(getRenderbuffer(renderbuffer)); } +void Context::bindVertexArray(GLuint vertexArray) +{ + if (!getVertexArray(vertexArray)) + { + mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray); + } + + mState.vertexArray = vertexArray; +} + +void Context::bindSampler(GLuint textureUnit, GLuint sampler) +{ + ASSERT(textureUnit < ArraySize(mState.samplers)); + mResourceManager->checkSamplerAllocation(sampler); + + mState.samplers[textureUnit] = sampler; +} + +void Context::bindGenericUniformBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.genericUniformBuffer.set(getBuffer(buffer)); +} + +void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.uniformBuffers[index].set(getBuffer(buffer), offset, size); +} + +void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.genericTransformFeedbackBuffer.set(getBuffer(buffer)); +} + +void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size); +} + +void Context::bindCopyReadBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.copyReadBuffer.set(getBuffer(buffer)); +} + +void Context::bindCopyWriteBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.copyWriteBuffer.set(getBuffer(buffer)); +} + +void Context::bindPixelPackBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.pack.pixelBuffer.set(getBuffer(buffer)); +} + +void Context::bindPixelUnpackBuffer(GLuint buffer) +{ + mResourceManager->checkBufferAllocation(buffer); + + mState.unpack.pixelBuffer.set(getBuffer(buffer)); +} + void Context::useProgram(GLuint program) { GLuint priorProgram = mState.currentProgram; @@ -927,7 +1335,7 @@ void Context::useProgram(GLuint program) newProgram->addRef(); mCurrentProgramBinary.set(newProgram->getProgramBinary()); } - + if (oldProgram) { oldProgram->release(); @@ -964,61 +1372,19 @@ void Context::setProgramBinary(GLuint program, const void *binary, GLint length) } -void Context::beginQuery(GLenum target, GLuint query) +void Context::bindTransformFeedback(GLuint transformFeedback) { - // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> - // of zero, if the active query object name for <target> is non-zero (for the - // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if - // the active query for either target is non-zero), if <id> is the name of an - // existing query object whose type does not match <target>, or if <id> is the - // active query object name for any query type, the error INVALID_OPERATION is - // generated. - - // Ensure no other queries are active - // NOTE: If other queries than occlusion are supported, we will need to check - // separately that: - // a) The query ID passed is not the current active query for any target/type - // b) There are no active queries for the requested target (and in the case - // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, - // no query may be active for either if glBeginQuery targets either. - for (int i = 0; i < QUERY_TYPE_COUNT; i++) - { - if (mState.activeQuery[i].get() != NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - } - - QueryType qType; - switch (target) - { - case GL_ANY_SAMPLES_PASSED_EXT: - qType = QUERY_ANY_SAMPLES_PASSED; - break; - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; - break; - default: - ASSERT(false); - return; - } + TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback); + mState.transformFeedback.set(transformFeedbackObject); +} +void Context::beginQuery(GLenum target, GLuint query) +{ Query *queryObject = getQuery(query, true, target); - - // check that name was obtained with glGenQueries - if (!queryObject) - { - return gl::error(GL_INVALID_OPERATION); - } - - // check for type mismatch - if (queryObject->getType() != target) - { - return gl::error(GL_INVALID_OPERATION); - } + ASSERT(queryObject); // set query as active for specified target - mState.activeQuery[qType].set(queryObject); + mState.activeQueries[target].set(queryObject); // begin query queryObject->begin(); @@ -1026,31 +1392,12 @@ void Context::beginQuery(GLenum target, GLuint query) void Context::endQuery(GLenum target) { - QueryType qType; - - switch (target) - { - case GL_ANY_SAMPLES_PASSED_EXT: - qType = QUERY_ANY_SAMPLES_PASSED; - break; - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; - break; - default: - ASSERT(false); - return; - } - - Query *queryObject = mState.activeQuery[qType].get(); - - if (queryObject == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } + Query *queryObject = mState.activeQueries[target].get(); + ASSERT(queryObject); queryObject->end(); - mState.activeQuery[qType].set(NULL); + mState.activeQueries[target].set(NULL); } void Context::setFramebufferZero(Framebuffer *buffer) @@ -1065,36 +1412,41 @@ void Context::setFramebufferZero(Framebuffer *buffer) void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) { + const bool color = gl::IsColorRenderingSupported(internalformat, this); + const bool depth = gl::IsDepthRenderingSupported(internalformat, this); + const bool stencil = gl::IsStencilRenderingSupported(internalformat, this); + RenderbufferStorage *renderbuffer = NULL; - switch (internalformat) + + if (color) { - case GL_DEPTH_COMPONENT16: - renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples); - break; - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB565: - case GL_RGB8_OES: - case GL_RGBA8_OES: renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples); - break; - case GL_STENCIL_INDEX8: - renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples); - break; - case GL_DEPTH24_STENCIL8_OES: + } + else if (depth && stencil) + { renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples); - break; - default: - UNREACHABLE(); return; + } + else if (depth) + { + renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples); + } + else if (stencil) + { + renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples); + } + else + { + UNREACHABLE(); + return; } - Renderbuffer *renderbufferObject = mState.renderbuffer.get(); + FramebufferAttachment *renderbufferObject = mState.renderbuffer.get(); renderbufferObject->setStorage(renderbuffer); } -Framebuffer *Context::getFramebuffer(unsigned int handle) +Framebuffer *Context::getFramebuffer(unsigned int handle) const { - FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle); + FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); if (framebuffer == mFramebufferMap.end()) { @@ -1106,11 +1458,11 @@ Framebuffer *Context::getFramebuffer(unsigned int handle) } } -Fence *Context::getFence(unsigned int handle) +FenceNV *Context::getFenceNV(unsigned int handle) { - FenceMap::iterator fence = mFenceMap.find(handle); + FenceNVMap::iterator fence = mFenceNVMap.find(handle); - if (fence == mFenceMap.end()) + if (fence == mFenceNVMap.end()) { return NULL; } @@ -1139,14 +1491,30 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type) } } +Buffer *Context::getTargetBuffer(GLenum target) const +{ + switch (target) + { + case GL_ARRAY_BUFFER: return mState.arrayBuffer.get(); + case GL_COPY_READ_BUFFER: return mState.copyReadBuffer.get(); + case GL_COPY_WRITE_BUFFER: return mState.copyWriteBuffer.get(); + case GL_ELEMENT_ARRAY_BUFFER: return getCurrentVertexArray()->getElementArrayBuffer(); + case GL_PIXEL_PACK_BUFFER: return mState.pack.pixelBuffer.get(); + case GL_PIXEL_UNPACK_BUFFER: return mState.unpack.pixelBuffer.get(); + case GL_TRANSFORM_FEEDBACK_BUFFER: return mState.genericTransformFeedbackBuffer.get(); + case GL_UNIFORM_BUFFER: return mState.genericUniformBuffer.get(); + default: UNREACHABLE(); return NULL; + } +} + Buffer *Context::getArrayBuffer() { return mState.arrayBuffer.get(); } -Buffer *Context::getElementArrayBuffer() +Buffer *Context::getElementArrayBuffer() const { - return mState.elementArrayBuffer.get(); + return getCurrentVertexArray()->getElementArrayBuffer(); } ProgramBinary *Context::getCurrentProgramBinary() @@ -1154,17 +1522,97 @@ ProgramBinary *Context::getCurrentProgramBinary() return mCurrentProgramBinary.get(); } -Texture2D *Context::getTexture2D() +Texture *Context::getTargetTexture(GLenum target) const +{ + if (!ValidTextureTarget(this, target)) + { + return NULL; + } + + switch (target) + { + case GL_TEXTURE_2D: return getTexture2D(); + case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap(); + case GL_TEXTURE_3D: return getTexture3D(); + case GL_TEXTURE_2D_ARRAY: return getTexture2DArray(); + default: return NULL; + } +} + +GLuint Context::getTargetFramebufferHandle(GLenum target) const +{ + if (!ValidFramebufferTarget(target)) + { + return GL_INVALID_INDEX; + } + + if (target == GL_READ_FRAMEBUFFER_ANGLE) + { + return mState.readFramebuffer; + } + else + { + return mState.drawFramebuffer; + } +} + +Framebuffer *Context::getTargetFramebuffer(GLenum target) const +{ + GLuint framebufferHandle = getTargetFramebufferHandle(target); + return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle)); +} + +Texture2D *Context::getTexture2D() const { return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); } -TextureCubeMap *Context::getTextureCubeMap() +TextureCubeMap *Context::getTextureCubeMap() const { return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); } -Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) +Texture3D *Context::getTexture3D() const +{ + return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); +} + +Texture2DArray *Context::getTexture2DArray() const +{ + return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY)); +} + +Buffer *Context::getGenericUniformBuffer() +{ + return mState.genericUniformBuffer.get(); +} + +Buffer *Context::getGenericTransformFeedbackBuffer() +{ + return mState.genericTransformFeedbackBuffer.get(); +} + +Buffer *Context::getCopyReadBuffer() +{ + return mState.copyReadBuffer.get(); +} + +Buffer *Context::getCopyWriteBuffer() +{ + return mState.copyWriteBuffer.get(); +} + +Buffer *Context::getPixelPackBuffer() +{ + return mState.pack.pixelBuffer.get(); +} + +Buffer *Context::getPixelUnpackBuffer() +{ + return mState.unpack.pixelBuffer.get(); +} + +Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const { GLuint texid = mState.samplerTexture[type][sampler].id(); @@ -1173,15 +1621,17 @@ Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) switch (type) { default: UNREACHABLE(); - case TEXTURE_2D: return mTexture2DZero.get(); - case TEXTURE_CUBE: return mTextureCubeMapZero.get(); + case TEXTURE_2D: return mTexture2DZero.get(); + case TEXTURE_CUBE: return mTextureCubeMapZero.get(); + case TEXTURE_3D: return mTexture3DZero.get(); + case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get(); } } return mState.samplerTexture[type][sampler].get(); } -bool Context::getBooleanv(GLenum pname, GLboolean *params) +void Context::getBooleanv(GLenum pname, GLboolean *params) { switch (pname) { @@ -1204,14 +1654,15 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params) case GL_BLEND: *params = mState.blend.blend; break; case GL_DITHER: *params = mState.blend.dither; break; case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break; + case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break; + case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break; default: - return false; + UNREACHABLE(); + break; } - - return true; } -bool Context::getFloatv(GLenum pname, GLfloat *params) +void Context::getFloatv(GLenum pname, GLfloat *params) { // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation // because it is stored as a float, despite the fact that the GL ES 2.0 spec names @@ -1249,112 +1700,108 @@ bool Context::getFloatv(GLenum pname, GLfloat *params) params[3] = mState.blendColor.alpha; break; case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - if (!supportsTextureFilterAnisotropy()) - { - return false; - } + ASSERT(supportsTextureFilterAnisotropy()); *params = mMaxTextureAnisotropy; break; default: - return false; + UNREACHABLE(); + break; } - - return true; } -bool Context::getIntegerv(GLenum pname, GLint *params) +void Context::getIntegerv(GLenum pname, GLint *params) { if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) { unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT); - - if (colorAttachment >= mRenderer->getMaxRenderTargets()) - { - // return true to stop further operation in the parent call - return gl::error(GL_INVALID_OPERATION, true); - } - + ASSERT(colorAttachment < mRenderer->getMaxRenderTargets()); Framebuffer *framebuffer = getDrawFramebuffer(); - *params = framebuffer->getDrawBufferState(colorAttachment); - return true; + return; } // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation // because it is stored as a float, despite the fact that the GL ES 2.0 spec names // GetIntegerv as its native query function. As it would require conversion in any - // case, this should make no difference to the calling application. You may find it in + // case, this should make no difference to the calling application. You may find it in // Context::getFloatv. switch (pname) { - case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break; - case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break; - case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break; - case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break; - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break; - case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break; - case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mRenderer->getMaxRenderTargets(); break; - case GL_MAX_DRAW_BUFFERS_EXT: *params = mRenderer->getMaxRenderTargets(); break; - case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; - case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; - case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break; - //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE - case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; - case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; - case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break; - case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; - case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; - case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mState.packReverseRowOrder; break; - case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; - case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; - case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; - case GL_STENCIL_FUNC: *params = mState.depthStencil.stencilFunc; break; - case GL_STENCIL_REF: *params = mState.stencilRef; break; - case GL_STENCIL_VALUE_MASK: *params = mState.depthStencil.stencilMask; break; - case GL_STENCIL_BACK_FUNC: *params = mState.depthStencil.stencilBackFunc; break; - case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; - case GL_STENCIL_BACK_VALUE_MASK: *params = mState.depthStencil.stencilBackMask; break; - case GL_STENCIL_FAIL: *params = mState.depthStencil.stencilFail; break; - case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilPassDepthFail; break; - case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilPassDepthPass; break; - case GL_STENCIL_BACK_FAIL: *params = mState.depthStencil.stencilBackFail; break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilBackPassDepthFail; break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilBackPassDepthPass; break; - case GL_DEPTH_FUNC: *params = mState.depthStencil.depthFunc; break; - case GL_BLEND_SRC_RGB: *params = mState.blend.sourceBlendRGB; break; - case GL_BLEND_SRC_ALPHA: *params = mState.blend.sourceBlendAlpha; break; - case GL_BLEND_DST_RGB: *params = mState.blend.destBlendRGB; break; - case GL_BLEND_DST_ALPHA: *params = mState.blend.destBlendAlpha; break; - case GL_BLEND_EQUATION_RGB: *params = mState.blend.blendEquationRGB; break; - case GL_BLEND_EQUATION_ALPHA: *params = mState.blend.blendEquationAlpha; break; - case GL_STENCIL_WRITEMASK: *params = mState.depthStencil.stencilWritemask; break; - case GL_STENCIL_BACK_WRITEMASK: *params = mState.depthStencil.stencilBackWritemask; break; - case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; - case GL_SUBPIXEL_BITS: *params = 4; break; - case GL_MAX_TEXTURE_SIZE: *params = getMaximumTextureDimension(); break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = getMaximumCubeTextureDimension(); break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break; + case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break; + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break; + case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break; + case GL_MAX_VARYING_COMPONENTS: *params = mRenderer->getMaxVaryingVectors() * 4; break; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break; + case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break; + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break; + case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break; + case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mRenderer->getMaxRenderTargets(); break; + case GL_MAX_DRAW_BUFFERS_EXT: *params = mRenderer->getMaxRenderTargets(); break; + case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; + case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; + case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getCurrentVertexArray()->getElementArrayBufferId(); break; + //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE + case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; + case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; + case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break; + case GL_VERTEX_ARRAY_BINDING: *params = mState.vertexArray; break; + case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; + case GL_PACK_ALIGNMENT: *params = mState.pack.alignment; break; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mState.pack.reverseRowOrder; break; + case GL_UNPACK_ALIGNMENT: *params = mState.unpack.alignment; break; + case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; + case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; + case GL_STENCIL_FUNC: *params = mState.depthStencil.stencilFunc; break; + case GL_STENCIL_REF: *params = mState.stencilRef; break; + case GL_STENCIL_VALUE_MASK: *params = clampToInt(mState.depthStencil.stencilMask); break; + case GL_STENCIL_BACK_FUNC: *params = mState.depthStencil.stencilBackFunc; break; + case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; + case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mState.depthStencil.stencilBackMask); break; + case GL_STENCIL_FAIL: *params = mState.depthStencil.stencilFail; break; + case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilPassDepthFail; break; + case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilPassDepthPass; break; + case GL_STENCIL_BACK_FAIL: *params = mState.depthStencil.stencilBackFail; break; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilBackPassDepthFail; break; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilBackPassDepthPass; break; + case GL_DEPTH_FUNC: *params = mState.depthStencil.depthFunc; break; + case GL_BLEND_SRC_RGB: *params = mState.blend.sourceBlendRGB; break; + case GL_BLEND_SRC_ALPHA: *params = mState.blend.sourceBlendAlpha; break; + case GL_BLEND_DST_RGB: *params = mState.blend.destBlendRGB; break; + case GL_BLEND_DST_ALPHA: *params = mState.blend.destBlendAlpha; break; + case GL_BLEND_EQUATION_RGB: *params = mState.blend.blendEquationRGB; break; + case GL_BLEND_EQUATION_ALPHA: *params = mState.blend.blendEquationAlpha; break; + case GL_STENCIL_WRITEMASK: *params = clampToInt(mState.depthStencil.stencilWritemask); break; + case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mState.depthStencil.stencilBackWritemask); break; + case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; + case GL_SUBPIXEL_BITS: *params = 4; break; + case GL_MAX_TEXTURE_SIZE: *params = getMaximum2DTextureDimension(); break; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = getMaximumCubeTextureDimension(); break; + case GL_MAX_3D_TEXTURE_SIZE: *params = getMaximum3DTextureDimension(); break; + case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = getMaximum2DArrayTextureLayers(); break; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break; + case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break; + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break; + case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break; + case GL_MAJOR_VERSION: *params = mClientVersion; break; + case GL_MINOR_VERSION: *params = 0; break; + case GL_MAX_ELEMENTS_INDICES: *params = mRenderer->getMaxRecommendedElementsIndices(); break; + case GL_MAX_ELEMENTS_VERTICES: *params = mRenderer->getMaxRecommendedElementsVertices(); break; + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mRenderer->getMaxTransformFeedbackBuffers(); break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackSeparateComponents(); break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: params[0] = mNumCompressedTextureFormats; break; case GL_MAX_SAMPLES_ANGLE: - { - GLsizei maxSamples = getMaxSupportedSamples(); - if (maxSamples != 0) - { - *params = maxSamples; - } - else - { - return false; - } - - break; - } - case GL_SAMPLE_BUFFERS: + *params = static_cast<GLint>(getMaxSupportedSamples()); + break; + case GL_SAMPLE_BUFFERS: case GL_SAMPLES: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); @@ -1377,7 +1824,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) break; } } - else + else { *params = 0; } @@ -1386,14 +1833,12 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_FORMAT: { - GLenum format, type; - if (getCurrentReadFormatType(&format, &type)) - { - if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT) - *params = format; - else - *params = type; - } + GLenum internalFormat, format, type; + getCurrentReadFormatType(&internalFormat, &format, &type); + if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT) + *params = format; + else + *params = type; } break; case GL_MAX_VIEWPORT_DIMS: @@ -1439,7 +1884,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_ALPHA_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer(); + gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer(); if (colorbuffer) { @@ -1460,7 +1905,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_DEPTH_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); + gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer(); if (depthbuffer) { @@ -1475,7 +1920,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_STENCIL_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); + gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer(); if (stencilbuffer) { @@ -1488,26 +1933,20 @@ bool Context::getIntegerv(GLenum pname, GLint *params) } break; case GL_TEXTURE_BINDING_2D: - { - if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1) - { - gl::error(GL_INVALID_OPERATION); - return false; - } - - *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); - } + ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits()); + *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); break; case GL_TEXTURE_BINDING_CUBE_MAP: - { - if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1) - { - gl::error(GL_INVALID_OPERATION); - return false; - } - - *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); - } + ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits()); + *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); + break; + case GL_TEXTURE_BINDING_3D: + ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits()); + *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id(); + break; + case GL_TEXTURE_BINDING_2D_ARRAY: + ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits()); + *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id(); break; case GL_RESET_NOTIFICATION_STRATEGY_EXT: *params = mResetStrategy; @@ -1518,6 +1957,118 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_PROGRAM_BINARY_FORMATS_OES: *params = GL_PROGRAM_BINARY_ANGLE; break; + case GL_UNIFORM_BUFFER_BINDING: + *params = mState.genericUniformBuffer.id(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + *params = mState.genericTransformFeedbackBuffer.id(); + break; + case GL_COPY_READ_BUFFER_BINDING: + *params = mState.copyReadBuffer.id(); + break; + case GL_COPY_WRITE_BUFFER_BINDING: + *params = mState.copyWriteBuffer.id(); + break; + case GL_PIXEL_PACK_BUFFER_BINDING: + *params = mState.pack.pixelBuffer.id(); + break; + case GL_PIXEL_UNPACK_BUFFER_BINDING: + *params = mState.unpack.pixelBuffer.id(); + break; + case GL_NUM_EXTENSIONS: + *params = static_cast<GLint>(getNumExtensions()); + break; + default: + UNREACHABLE(); + break; + } +} + +void Context::getInteger64v(GLenum pname, GLint64 *params) +{ + switch (pname) + { + case GL_MAX_ELEMENT_INDEX: + *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max()); + break; + case GL_MAX_UNIFORM_BLOCK_SIZE: + *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize()); + break; + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + { + GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4); + GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4); + *params = uniformBufferComponents + defaultBufferComponents; + } + break; + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + { + GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4); + GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4); + *params = uniformBufferComponents + defaultBufferComponents; + } + break; + case GL_MAX_SERVER_WAIT_TIMEOUT: + // We do not wait for server fence objects internally, so report a max timeout of zero. + *params = 0; + break; + default: + UNREACHABLE(); + break; + } +} + +bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) +{ + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + { + *data = mState.transformFeedbackBuffers[index].id(); + } + break; + case GL_UNIFORM_BUFFER_BINDING: + if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + { + *data = mState.uniformBuffers[index].id(); + } + break; + default: + return false; + } + + return true; +} + +bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) +{ + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + { + *data = mState.transformFeedbackBuffers[index].getOffset(); + } + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + { + *data = mState.transformFeedbackBuffers[index].getSize(); + } + break; + case GL_UNIFORM_BUFFER_START: + if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + { + *data = mState.uniformBuffers[index].getOffset(); + } + break; + case GL_UNIFORM_BUFFER_SIZE: + if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + { + *data = mState.uniformBuffers[index].getSize(); + } + break; default: return false; } @@ -1537,7 +2088,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due // to the fact that it is stored internally as a float, and so would require conversion - // if returned from Context::getIntegerv. Since this conversion is already implemented + // if returned from Context::getIntegerv. Since this conversion is already implemented // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling // application. @@ -1548,13 +2099,13 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_INT; *numParams = mNumCompressedTextureFormats; } - break; + return true; case GL_SHADER_BINARY_FORMATS: { *type = GL_INT; *numParams = 0; } - break; + return true; case GL_MAX_VERTEX_ATTRIBS: case GL_MAX_VERTEX_UNIFORM_VECTORS: case GL_MAX_VARYING_VECTORS: @@ -1568,7 +2119,9 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu case GL_NUM_SHADER_BINARY_FORMATS: case GL_NUM_COMPRESSED_TEXTURE_FORMATS: case GL_ARRAY_BUFFER_BINDING: - case GL_FRAMEBUFFER_BINDING: + //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE + case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: + case GL_READ_FRAMEBUFFER_BINDING_ANGLE: case GL_RENDERBUFFER_BINDING: case GL_CURRENT_PROGRAM: case GL_PACK_ALIGNMENT: @@ -1624,7 +2177,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_INT; *numParams = 1; } - break; + return true; case GL_MAX_SAMPLES_ANGLE: { if (getMaxSupportedSamples() != 0) @@ -1637,20 +2190,34 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu return false; } } - break; + return true; + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + { + if (supportsPBOs()) + { + *type = GL_INT; + *numParams = 1; + } + else + { + return false; + } + } + return true; case GL_MAX_VIEWPORT_DIMS: { *type = GL_INT; *numParams = 2; } - break; + return true; case GL_VIEWPORT: case GL_SCISSOR_BOX: { *type = GL_INT; *numParams = 4; } - break; + return true; case GL_SHADER_COMPILER: case GL_SAMPLE_COVERAGE_INVERT: case GL_DEPTH_WRITEMASK: @@ -1668,13 +2235,13 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_BOOL; *numParams = 1; } - break; + return true; case GL_COLOR_WRITEMASK: { *type = GL_BOOL; *numParams = 4; } - break; + return true; case GL_POLYGON_OFFSET_FACTOR: case GL_POLYGON_OFFSET_UNITS: case GL_SAMPLE_COVERAGE_VALUE: @@ -1684,7 +2251,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_FLOAT; *numParams = 1; } - break; + return true; case GL_ALIASED_LINE_WIDTH_RANGE: case GL_ALIASED_POINT_SIZE_RANGE: case GL_DEPTH_RANGE: @@ -1692,14 +2259,14 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_FLOAT; *numParams = 2; } - break; + return true; case GL_COLOR_CLEAR_VALUE: case GL_BLEND_COLOR: { *type = GL_FLOAT; *numParams = 4; } - break; + return true; case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: if (!supportsTextureFilterAnisotropy()) { @@ -1707,12 +2274,98 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu } *type = GL_FLOAT; *numParams = 1; - break; - default: + return true; + } + + if (mClientVersion < 3) + { return false; } - return true; + // Check for ES3.0+ parameter names + switch (pname) + { + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + case GL_UNIFORM_BUFFER_BINDING: + case GL_TRANSFORM_FEEDBACK_BINDING: + case GL_COPY_READ_BUFFER_BINDING: + case GL_COPY_WRITE_BUFFER_BINDING: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_MAX_3D_TEXTURE_SIZE: + case GL_MAX_ARRAY_TEXTURE_LAYERS: + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + case GL_MAX_VARYING_COMPONENTS: + case GL_VERTEX_ARRAY_BINDING: + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + case GL_NUM_EXTENSIONS: + case GL_MAJOR_VERSION: + case GL_MINOR_VERSION: + case GL_MAX_ELEMENTS_INDICES: + case GL_MAX_ELEMENTS_VERTICES: + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + { + *type = GL_INT; + *numParams = 1; + } + return true; + + case GL_MAX_ELEMENT_INDEX: + case GL_MAX_UNIFORM_BLOCK_SIZE: + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MAX_SERVER_WAIT_TIMEOUT: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + } + return true; + + case GL_TRANSFORM_FEEDBACK_ACTIVE: + case GL_TRANSFORM_FEEDBACK_PAUSED: + { + *type = GL_BOOL; + *numParams = 1; + } + return true; + } + + return false; +} + +bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) +{ + if (mClientVersion < 3) + { + return false; + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_UNIFORM_BUFFER_BINDING: + { + *type = GL_INT; + *numParams = 1; + } + return true; + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + } + } + + return false; } // Applies the render target surface, depth stencil surface, viewport rectangle and @@ -1754,7 +2407,7 @@ void Context::applyState(GLenum drawMode) { if (mState.sampleCoverageValue != 0) { - + float threshold = 0.5f; for (int i = 0; i < samples; ++i) @@ -1778,146 +2431,217 @@ void Context::applyState(GLenum drawMode) { mask = 0xFFFFFFFF; } - mRenderer->setBlendState(mState.blend, mState.blendColor, mask); + mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask); mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef, mState.rasterizer.frontFace == GL_CCW); } // Applies the shaders and shader constants to the Direct3D 9 device -void Context::applyShaders() +void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive) { - ProgramBinary *programBinary = getCurrentProgramBinary(); + const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes(); + + VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; + VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues); + + mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, transformFeedbackActive, inputLayout); - mRenderer->applyShaders(programBinary); - programBinary->applyUniforms(); } -// Applies the textures and sampler states to the Direct3D 9 device -void Context::applyTextures() +size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures, + TextureType *outTextureTypes, SamplerState *outSamplers) { - applyTextures(SAMPLER_PIXEL); + size_t samplerRange = programBinary->getUsedSamplerRange(type); + for (size_t i = 0; i < samplerRange; i++) + { + outTextureTypes[i] = programBinary->getSamplerTextureType(type, i); + GLint textureUnit = programBinary->getSamplerMapping(type, i); // OpenGL texture image unit index + if (textureUnit != -1) + { + outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]); + outTextures[i]->getSamplerState(&outSamplers[i]); + if (mState.samplers[textureUnit] != 0) + { + Sampler *samplerObject = getSampler(mState.samplers[textureUnit]); + samplerObject->getState(&outSamplers[i]); + } + } + else + { + outTextures[i] = NULL; + } + } + + return samplerRange; +} - if (mSupportsVertexTexture) +void Context::generateSwizzles(Texture *textures[], size_t count) +{ + for (size_t i = 0; i < count; i++) { - applyTextures(SAMPLER_VERTEX); + if (textures[i] && textures[i]->isSwizzled()) + { + mRenderer->generateSwizzle(textures[i]); + } } } -// For each Direct3D 9 sampler of either the pixel or vertex stage, +// For each Direct3D sampler of either the pixel or vertex stage, // looks up the corresponding OpenGL texture image unit and texture type, // and sets the texture and its addressing/filtering state (or NULL when inactive). -void Context::applyTextures(SamplerType type) +void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers, + size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials, + size_t framebufferSerialCount) { - ProgramBinary *programBinary = getCurrentProgramBinary(); - - FramebufferTextureSerialSet boundFramebufferTextures = getBoundFramebufferTextureSerials(); - // Range of Direct3D samplers of given sampler type - int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits(); - int samplerRange = programBinary->getUsedSamplerRange(type); + size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS + : mRenderer->getMaxVertexTextureImageUnits(); - for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++) { - int textureUnit = programBinary->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index + Texture *texture = textures[samplerIndex]; + const SamplerState &sampler = samplers[samplerIndex]; + TextureType textureType = textureTypes[samplerIndex]; - if (textureUnit != -1) + if (texture) { - TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex); - Texture *texture = getSamplerTexture(textureUnit, textureType); - - if (texture->isSamplerComplete() && - boundFramebufferTextures.find(texture->getTextureSerial()) == boundFramebufferTextures.end()) + // TODO: std::binary_search may become unavailable using older versions of GCC + if (texture->isSamplerComplete(sampler) && + !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) { - SamplerState samplerState; - texture->getSamplerState(&samplerState); - mRenderer->setSamplerState(type, samplerIndex, samplerState); - - mRenderer->setTexture(type, samplerIndex, texture); - + mRenderer->setSamplerState(shaderType, samplerIndex, sampler); + mRenderer->setTexture(shaderType, samplerIndex, texture); texture->resetDirty(); } else { - mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType)); + Texture *incompleteTexture = getIncompleteTexture(textureType); + mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture); + incompleteTexture->resetDirty(); } } else { - mRenderer->setTexture(type, samplerIndex, NULL); + mRenderer->setTexture(shaderType, samplerIndex, NULL); } } - for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) + for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++) { - mRenderer->setTexture(type, samplerIndex, NULL); + mRenderer->setTexture(shaderType, samplerIndex, NULL); } } -void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei *bufSize, void* pixels) +bool Context::applyUniformBuffers() { - Framebuffer *framebuffer = getReadFramebuffer(); + Program *programObject = getProgram(mState.currentProgram); + ProgramBinary *programBinary = programObject->getProgramBinary(); + + std::vector<gl::Buffer*> boundBuffers; - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++) { - return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); + GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex); + const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding]; + if (boundBuffer.id() == 0) + { + // undefined behaviour + return false; + } + else + { + gl::Buffer *uniformBuffer = boundBuffer.get(); + ASSERT(uniformBuffer); + boundBuffers.push_back(uniformBuffer); + } } - if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) + return programBinary->applyUniformBuffers(boundBuffers); +} + +bool Context::applyTransformFeedbackBuffers() +{ + TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) { - return gl::error(GL_INVALID_OPERATION); + Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + transformFeedbackBuffers[i] = mState.transformFeedbackBuffers[i].get(); + transformFeedbackOffsets[i] = mState.transformFeedbackBuffers[i].getOffset(); + } + mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets); + return true; } + else + { + return false; + } +} - GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment()); - // sized query sanity check - if (bufSize) +void Context::markTransformFeedbackUsage() +{ + for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) { - int requiredSize = outputPitch * height; - if (requiredSize > *bufSize) + Buffer *buffer = mState.transformFeedbackBuffers[i].get(); + if (buffer) { - return gl::error(GL_INVALID_OPERATION); + buffer->markTransformFeedbackUsage(); } } - - mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels); } void Context::clear(GLbitfield mask) { - Framebuffer *framebufferObject = getDrawFramebuffer(); - - if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (isRasterizerDiscardEnabled()) { - return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); + return; } - DWORD flags = 0; - GLbitfield finalMask = 0; + ClearParameters clearParams = { 0 }; + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = false; + } + clearParams.colorFClearValue = mState.colorClearValue; + clearParams.colorClearType = GL_FLOAT; + clearParams.colorMaskRed = mState.blend.colorMaskRed; + clearParams.colorMaskGreen = mState.blend.colorMaskGreen; + clearParams.colorMaskBlue = mState.blend.colorMaskBlue; + clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha; + clearParams.clearDepth = false; + clearParams.depthClearValue = mState.depthClearValue; + clearParams.clearStencil = false; + clearParams.stencilClearValue = mState.stencilClearValue; + clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask; + clearParams.scissorEnabled = mState.scissorTest; + clearParams.scissor = mState.scissor; + Framebuffer *framebufferObject = getDrawFramebuffer(); if (mask & GL_COLOR_BUFFER_BIT) { - mask &= ~GL_COLOR_BUFFER_BIT; - if (framebufferObject->hasEnabledColorAttachment()) { - finalMask |= GL_COLOR_BUFFER_BIT; + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = true; + } } } if (mask & GL_DEPTH_BUFFER_BIT) { - mask &= ~GL_DEPTH_BUFFER_BIT; if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE) { - finalMask |= GL_DEPTH_BUFFER_BIT; + clearParams.clearDepth = true; } } if (mask & GL_STENCIL_BUFFER_BIT) { - mask &= ~GL_STENCIL_BUFFER_BIT; if (framebufferObject->getStencilbufferType() != GL_NONE) { rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil(); @@ -1927,35 +2651,221 @@ void Context::clear(GLbitfield mask) return; } - if (GetStencilSize(depthStencil->getActualFormat()) > 0) + if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0) { - finalMask |= GL_STENCIL_BUFFER_BIT; + clearParams.clearStencil = true; } } } - if (mask != 0) + + if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport + { + return; + } + + mRenderer->clear(clearParams, framebufferObject); +} + +void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) +{ + if (isRasterizerDiscardEnabled()) + { + return; + } + + // glClearBufferfv can be called to clear the color buffer or depth buffer + ClearParameters clearParams = { 0 }; + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); + } + clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_FLOAT; + } + else + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = false; + } + clearParams.colorFClearValue = mState.colorClearValue; + clearParams.colorClearType = GL_FLOAT; + } + + clearParams.colorMaskRed = mState.blend.colorMaskRed; + clearParams.colorMaskGreen = mState.blend.colorMaskGreen; + clearParams.colorMaskBlue = mState.blend.colorMaskBlue; + clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha; + + if (buffer == GL_DEPTH) + { + clearParams.clearDepth = true; + clearParams.depthClearValue = values[0]; + } + else { - return gl::error(GL_INVALID_VALUE); + clearParams.clearDepth = false; + clearParams.depthClearValue = mState.depthClearValue; } + clearParams.clearStencil = false; + clearParams.stencilClearValue = mState.stencilClearValue; + clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask; + clearParams.scissorEnabled = mState.scissorTest; + clearParams.scissor = mState.scissor; + if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport { return; } - ClearParameters clearParams; - clearParams.mask = finalMask; - clearParams.colorClearValue = mState.colorClearValue; + mRenderer->clear(clearParams, getDrawFramebuffer()); +} + +void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values) +{ + if (isRasterizerDiscardEnabled()) + { + return; + } + + // glClearBufferuv can only be called to clear a color buffer + ClearParameters clearParams = { 0 }; + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); + } + clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_UNSIGNED_INT; clearParams.colorMaskRed = mState.blend.colorMaskRed; clearParams.colorMaskGreen = mState.blend.colorMaskGreen; clearParams.colorMaskBlue = mState.blend.colorMaskBlue; clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha; + clearParams.clearDepth = false; clearParams.depthClearValue = mState.depthClearValue; + clearParams.clearStencil = false; clearParams.stencilClearValue = mState.stencilClearValue; clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask; + clearParams.scissorEnabled = mState.scissorTest; + clearParams.scissor = mState.scissor; - mRenderer->clear(clearParams, framebufferObject); + if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport + { + return; + } + + mRenderer->clear(clearParams, getDrawFramebuffer()); +} + +void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) +{ + if (isRasterizerDiscardEnabled()) + { + return; + } + + // glClearBufferfv can be called to clear the color buffer or stencil buffer + ClearParameters clearParams = { 0 }; + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); + } + clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_INT; + } + else + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = false; + } + clearParams.colorFClearValue = mState.colorClearValue; + clearParams.colorClearType = GL_FLOAT; + } + + clearParams.colorMaskRed = mState.blend.colorMaskRed; + clearParams.colorMaskGreen = mState.blend.colorMaskGreen; + clearParams.colorMaskBlue = mState.blend.colorMaskBlue; + clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha; + + clearParams.clearDepth = false; + clearParams.depthClearValue = mState.depthClearValue; + + if (buffer == GL_STENCIL) + { + clearParams.clearStencil = true; + clearParams.stencilClearValue = values[1]; + } + else + { + clearParams.clearStencil = false; + clearParams.stencilClearValue = mState.stencilClearValue; + } + clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask; + + clearParams.scissorEnabled = mState.scissorTest; + clearParams.scissor = mState.scissor; + + if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport + { + return; + } + + mRenderer->clear(clearParams, getDrawFramebuffer()); +} + +void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil) +{ + if (isRasterizerDiscardEnabled()) + { + return; + } + + // glClearBufferfi can only be called to clear a depth stencil buffer + ClearParameters clearParams = { 0 }; + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = false; + } + clearParams.colorFClearValue = mState.colorClearValue; + clearParams.colorClearType = GL_FLOAT; + clearParams.colorMaskRed = mState.blend.colorMaskRed; + clearParams.colorMaskGreen = mState.blend.colorMaskGreen; + clearParams.colorMaskBlue = mState.blend.colorMaskBlue; + clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha; + clearParams.clearDepth = true; + clearParams.depthClearValue = depth; + clearParams.clearStencil = true; + clearParams.stencilClearValue = stencil; + clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask; + clearParams.scissorEnabled = mState.scissorTest; + clearParams.scissor = mState.scissor; + + if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport + { + return; + } + + mRenderer->clear(clearParams, getDrawFramebuffer()); +} + +void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) +{ + gl::Framebuffer *framebuffer = getReadFramebuffer(); + + bool isSized = IsSizedInternalFormat(format, mClientVersion); + GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type, mClientVersion)); + GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, mState.pack.alignment); + + mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.pack, pixels); } void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) @@ -1965,6 +2875,22 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan return gl::error(GL_INVALID_OPERATION); } + ProgramBinary *programBinary = getCurrentProgramBinary(); + programBinary->applyUniforms(); + + Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers); + + Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS]; + TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS]; + SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS]; + size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers); + + generateSwizzles(vsTextures, vsTextureCount); + generateSwizzles(psTextures, psTextureCount); + if (!mRenderer->applyPrimitiveType(mode, count)) { return; @@ -1977,16 +2903,26 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan applyState(mode); - ProgramBinary *programBinary = getCurrentProgramBinary(); - - GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances); + GLenum err = mRenderer->applyVertexBuffer(programBinary, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, first, count, instances); if (err != GL_NO_ERROR) { return gl::error(err); } - applyShaders(); - applyTextures(); + bool transformFeedbackActive = applyTransformFeedbackBuffers(); + + applyShaders(programBinary, transformFeedbackActive); + + FramebufferTextureSerialArray frameBufferSerials; + size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials); + + applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount); + applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount); + + if (!applyUniformBuffers()) + { + return; + } if (!programBinary->validateSamplers(NULL)) { @@ -1995,7 +2931,12 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan if (!skipDraw(mode)) { - mRenderer->drawArrays(mode, count, instances); + mRenderer->drawArrays(mode, count, instances, transformFeedbackActive); + + if (transformFeedbackActive) + { + markTransformFeedbackUsage(); + } } } @@ -2006,11 +2947,28 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid return gl::error(GL_INVALID_OPERATION); } - if (!indices && !mState.elementArrayBuffer) + VertexArray *vao = getCurrentVertexArray(); + if (!indices && !vao->getElementArrayBuffer()) { return gl::error(GL_INVALID_OPERATION); } - + + ProgramBinary *programBinary = getCurrentProgramBinary(); + programBinary->applyUniforms(); + + Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers); + + Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS]; + TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS]; + SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS]; + size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers); + + generateSwizzles(vsTextures, vsTextureCount); + generateSwizzles(psTextures, psTextureCount); + if (!mRenderer->applyPrimitiveType(mode, count)) { return; @@ -2024,23 +2982,36 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid applyState(mode); rx::TranslatedIndexData indexInfo; - GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo); + GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); if (err != GL_NO_ERROR) { return gl::error(err); } - ProgramBinary *programBinary = getCurrentProgramBinary(); - GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; - err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances); + err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances); if (err != GL_NO_ERROR) { return gl::error(err); } - applyShaders(); - applyTextures(); + bool transformFeedbackActive = applyTransformFeedbackBuffers(); + // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation + // layer. + ASSERT(!transformFeedbackActive); + + applyShaders(programBinary, transformFeedbackActive); + + FramebufferTextureSerialArray frameBufferSerials; + size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials); + + applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount); + applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount); + + if (!applyUniformBuffers()) + { + return; + } if (!programBinary->validateSamplers(NULL)) { @@ -2049,7 +3020,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid if (!skipDraw(mode)) { - mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances); + mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); } } @@ -2146,7 +3117,7 @@ GLenum Context::getResetStatus() mResetStatus = GL_NO_ERROR; } } - + return status; } @@ -2155,6 +3126,11 @@ bool Context::isResetNotificationEnabled() return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); } +int Context::getClientVersion() const +{ + return mClientVersion; +} + int Context::getMajorShaderModel() const { return mMajorShaderModel; @@ -2170,11 +3146,43 @@ unsigned int Context::getMaximumCombinedTextureImageUnits() const return mRenderer->getMaxCombinedTextureImageUnits(); } +unsigned int Context::getMaximumCombinedUniformBufferBindings() const +{ + return mRenderer->getMaxVertexShaderUniformBuffers() + + mRenderer->getMaxFragmentShaderUniformBuffers(); +} + int Context::getMaxSupportedSamples() const { return mRenderer->getMaxSupportedSamples(); } +GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const +{ + return mRenderer->getMaxSupportedFormatSamples(internalFormat); +} + +GLsizei Context::getNumSampleCounts(GLenum internalFormat) const +{ + return mRenderer->getNumSampleCounts(internalFormat); +} + +void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const +{ + mRenderer->getSampleCounts(internalFormat, bufSize, params); +} + +unsigned int Context::getMaxTransformFeedbackBufferBindings() const +{ + return mRenderer->getMaxTransformFeedbackBuffers(); +} + +GLintptr Context::getUniformBufferOffsetAlignment() const +{ + // setting a large alignment forces uniform buffers to bind with zero offset + return static_cast<GLintptr>(std::numeric_limits<GLint>::max()); +} + unsigned int Context::getMaximumRenderTargets() const { return mRenderer->getMaxRenderTargets(); @@ -2245,9 +3253,9 @@ int Context::getMaximumRenderbufferDimension() const return mMaxRenderbufferDimension; } -int Context::getMaximumTextureDimension() const +int Context::getMaximum2DTextureDimension() const { - return mMaxTextureDimension; + return mMax2DTextureDimension; } int Context::getMaximumCubeTextureDimension() const @@ -2255,9 +3263,34 @@ int Context::getMaximumCubeTextureDimension() const return mMaxCubeTextureDimension; } -int Context::getMaximumTextureLevel() const +int Context::getMaximum3DTextureDimension() const +{ + return mMax3DTextureDimension; +} + +int Context::getMaximum2DArrayTextureLayers() const { - return mMaxTextureLevel; + return mMax2DArrayTextureLayers; +} + +int Context::getMaximum2DTextureLevel() const +{ + return mMax2DTextureLevel; +} + +int Context::getMaximumCubeTextureLevel() const +{ + return mMaxCubeTextureLevel; +} + +int Context::getMaximum3DTextureLevel() const +{ + return mMax3DTextureLevel; +} + +int Context::getMaximum2DArrayTextureLevel() const +{ + return mMax2DArrayTextureLevel; } bool Context::supportsLuminanceTextures() const @@ -2270,6 +3303,11 @@ bool Context::supportsLuminanceAlphaTextures() const return mSupportsLuminanceAlphaTextures; } +bool Context::supportsRGTextures() const +{ + return mSupportsRGTextures; +} + bool Context::supportsDepthTextures() const { return mSupportsDepthTextures; @@ -2295,29 +3333,27 @@ bool Context::supportsTextureFilterAnisotropy() const return mSupportsTextureFilterAnisotropy; } +bool Context::supportsPBOs() const +{ + return mSupportsPBOs; +} + float Context::getTextureMaxAnisotropy() const { return mMaxTextureAnisotropy; } -bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type) +void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type) { Framebuffer *framebuffer = getReadFramebuffer(); - if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) - { - return gl::error(GL_INVALID_OPERATION, false); - } + ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE); - Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer(); - if (!renderbuffer) - { - return gl::error(GL_INVALID_OPERATION, false); - } + FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); + ASSERT(attachment); - *format = gl::ExtractFormat(renderbuffer->getActualFormat()); - *type = gl::ExtractType(renderbuffer->getActualFormat()); - - return true; + *internalFormat = attachment->getActualFormat(); + *format = gl::GetFormat(attachment->getActualFormat(), mClientVersion); + *type = gl::GetType(attachment->getActualFormat(), mClientVersion); } void Context::detachBuffer(GLuint buffer) @@ -2331,17 +3367,10 @@ void Context::detachBuffer(GLuint buffer) mState.arrayBuffer.set(NULL); } - if (mState.elementArrayBuffer.id() == buffer) + // mark as freed among the vertex array objects + for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++) { - mState.elementArrayBuffer.set(NULL); - } - - for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) - { - if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer) - { - mState.vertexAttribute[attribute].mBoundBuffer.set(NULL); - } + vaoIt->second->detachBuffer(buffer); } } @@ -2364,7 +3393,7 @@ void Context::detachTexture(GLuint texture) // [OpenGL ES 2.0.24] section 4.4 page 112: // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is - // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this + // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this // image was attached in the currently bound framebuffer. Framebuffer *readFramebuffer = getReadFramebuffer(); @@ -2428,13 +3457,48 @@ void Context::detachRenderbuffer(GLuint renderbuffer) } } +void Context::detachVertexArray(GLuint vertexArray) +{ + // [OpenGL ES 3.0.2] section 2.10 page 43: + // If a vertex array object that is currently bound is deleted, the binding + // for that object reverts to zero and the default vertex array becomes current. + if (mState.vertexArray == vertexArray) + { + bindVertexArray(0); + } +} + +void Context::detachTransformFeedback(GLuint transformFeedback) +{ + if (mState.transformFeedback.id() == transformFeedback) + { + bindTransformFeedback(0); + } +} + +void Context::detachSampler(GLuint sampler) +{ + // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: + // If a sampler object that is currently bound to one or more texture units is + // deleted, it is as though BindSampler is called once for each texture unit to + // which the sampler is bound, with unit set to the texture unit and sampler set to zero. + for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++) + { + if (mState.samplers[textureUnit] == sampler) + { + mState.samplers[textureUnit] = 0; + } + } +} + Texture *Context::getIncompleteTexture(TextureType type) { Texture *t = mIncompleteTextures[type].get(); if (t == NULL) { - static const GLubyte color[] = { 0, 0, 0, 255 }; + const GLubyte color[] = { 0, 0, 0, 255 }; + const PixelUnpackState incompleteUnpackState(1); switch (type) { @@ -2445,7 +3509,7 @@ Texture *Context::getIncompleteTexture(TextureType type) case TEXTURE_2D: { Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID); - incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); t = incomplete2d; } break; @@ -2454,16 +3518,34 @@ Texture *Context::getIncompleteTexture(TextureType type) { TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID); - incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); t = incompleteCube; } break; + + case TEXTURE_3D: + { + Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID); + incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + + t = incomplete3d; + } + break; + + case TEXTURE_2D_ARRAY: + { + Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID); + incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + + t = incomplete2darray; + } + break; } mIncompleteTextures[type].set(t); @@ -2481,7 +3563,7 @@ bool Context::skipDraw(GLenum drawMode) // undefined when not written, just skip drawing to avoid unexpected results. if (!getCurrentProgramBinary()->usesPointSize()) { - // This is stictly speaking not an error, but developers should be + // This is stictly speaking not an error, but developers should be // notified of risking undefined behavior. ERR("Point rendering without writing to gl_PointSize."); @@ -2499,148 +3581,284 @@ bool Context::skipDraw(GLenum drawMode) return false; } -void Context::setVertexAttrib(GLuint index, const GLfloat *values) +void Context::setVertexAttribf(GLuint index, const GLfloat values[4]) { ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + mState.vertexAttribCurrentValues[index].setFloatValues(values); +} - mState.vertexAttribute[index].mCurrentValue[0] = values[0]; - mState.vertexAttribute[index].mCurrentValue[1] = values[1]; - mState.vertexAttribute[index].mCurrentValue[2] = values[2]; - mState.vertexAttribute[index].mCurrentValue[3] = values[3]; +void Context::setVertexAttribu(GLuint index, const GLuint values[4]) +{ + ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values); } -void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) +void Context::setVertexAttribi(GLuint index, const GLint values[4]) { ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + mState.vertexAttribCurrentValues[index].setIntValues(values); +} - mState.vertexAttribute[index].mDivisor = divisor; +void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) +{ + getCurrentVertexArray()->setVertexAttribDivisor(index, divisor); } -// keep list sorted in following order -// OES extensions -// EXT extensions -// Vendor extensions -void Context::initExtensionString() +void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) { - std::string extensionString = ""; + mResourceManager->checkSamplerAllocation(sampler); - // OES extensions - if (supports32bitIndices()) - { - extensionString += "GL_OES_element_index_uint "; - } + Sampler *samplerObject = getSampler(sampler); + ASSERT(samplerObject); - extensionString += "GL_OES_packed_depth_stencil "; - extensionString += "GL_OES_get_program_binary "; - extensionString += "GL_OES_rgb8_rgba8 "; - if (mRenderer->getDerivativeInstructionSupport()) + switch (pname) { - extensionString += "GL_OES_standard_derivatives "; + case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break; + case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break; + case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break; + case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break; + case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break; + case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break; + case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break; + case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast<GLenum>(param)); break; + case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast<GLenum>(param)); break; + default: UNREACHABLE(); break; } +} - if (supportsFloat16Textures()) - { - extensionString += "GL_OES_texture_half_float "; - } - if (supportsFloat16LinearFilter()) - { - extensionString += "GL_OES_texture_half_float_linear "; - } - if (supportsFloat32Textures()) - { - extensionString += "GL_OES_texture_float "; - } - if (supportsFloat32LinearFilter()) - { - extensionString += "GL_OES_texture_float_linear "; - } +void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + mResourceManager->checkSamplerAllocation(sampler); - if (supportsNonPower2Texture()) - { - extensionString += "GL_OES_texture_npot "; - } + Sampler *samplerObject = getSampler(sampler); + ASSERT(samplerObject); - // Multi-vendor (EXT) extensions - if (supportsOcclusionQueries()) + switch (pname) { - extensionString += "GL_EXT_occlusion_query_boolean "; + case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break; + case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break; + case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break; + case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break; + case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break; + case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break; + case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break; + case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround<GLenum>(param)); break; + case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround<GLenum>(param)); break; + default: UNREACHABLE(); break; } +} - extensionString += "GL_EXT_read_format_bgra "; - extensionString += "GL_EXT_robustness "; +GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname) +{ + mResourceManager->checkSamplerAllocation(sampler); - if (supportsDXT1Textures()) - { - extensionString += "GL_EXT_texture_compression_dxt1 "; - } + Sampler *samplerObject = getSampler(sampler); + ASSERT(samplerObject); - if (supportsTextureFilterAnisotropy()) + switch (pname) { - extensionString += "GL_EXT_texture_filter_anisotropic "; + case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter()); + case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter()); + case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS()); + case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT()); + case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR()); + case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod()); + case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod()); + case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getComparisonMode()); + case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getComparisonFunc()); + default: UNREACHABLE(); return 0; } +} - if (supportsBGRATextures()) +GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname) +{ + mResourceManager->checkSamplerAllocation(sampler); + + Sampler *samplerObject = getSampler(sampler); + ASSERT(samplerObject); + + switch (pname) { - extensionString += "GL_EXT_texture_format_BGRA8888 "; + case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter()); + case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter()); + case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS()); + case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT()); + case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR()); + case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod(); + case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod(); + case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getComparisonMode()); + case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getComparisonFunc()); + default: UNREACHABLE(); return 0; } +} - if (mRenderer->getMaxRenderTargets() > 1) +// keep list sorted in following order +// OES extensions +// EXT extensions +// Vendor extensions +void Context::initExtensionString() +{ + // Do not report extension in GLES 3 contexts for now + if (mClientVersion == 2) { - extensionString += "GL_EXT_draw_buffers "; - } + // OES extensions + if (supports32bitIndices()) + { + mExtensionStringList.push_back("GL_OES_element_index_uint"); + } - extensionString += "GL_EXT_texture_storage "; - extensionString += "GL_EXT_frag_depth "; + mExtensionStringList.push_back("GL_OES_packed_depth_stencil"); + mExtensionStringList.push_back("GL_OES_get_program_binary"); + mExtensionStringList.push_back("GL_OES_rgb8_rgba8"); - // ANGLE-specific extensions - if (supportsDepthTextures()) - { - extensionString += "GL_ANGLE_depth_texture "; - } + if (supportsPBOs()) + { + mExtensionStringList.push_back("NV_pixel_buffer_object"); + mExtensionStringList.push_back("GL_OES_mapbuffer"); + mExtensionStringList.push_back("GL_EXT_map_buffer_range"); + } - extensionString += "GL_ANGLE_framebuffer_blit "; - if (getMaxSupportedSamples() != 0) - { - extensionString += "GL_ANGLE_framebuffer_multisample "; - } + if (mRenderer->getDerivativeInstructionSupport()) + { + mExtensionStringList.push_back("GL_OES_standard_derivatives"); + } - if (supportsInstancing()) - { - extensionString += "GL_ANGLE_instanced_arrays "; - } + if (supportsFloat16Textures()) + { + mExtensionStringList.push_back("GL_OES_texture_half_float"); + } + if (supportsFloat16LinearFilter()) + { + mExtensionStringList.push_back("GL_OES_texture_half_float_linear"); + } + if (supportsFloat32Textures()) + { + mExtensionStringList.push_back("GL_OES_texture_float"); + } + if (supportsFloat32LinearFilter()) + { + mExtensionStringList.push_back("GL_OES_texture_float_linear"); + } + + if (supportsRGTextures()) + { + mExtensionStringList.push_back("GL_EXT_texture_rg"); + } - extensionString += "GL_ANGLE_pack_reverse_row_order "; + if (supportsNonPower2Texture()) + { + mExtensionStringList.push_back("GL_OES_texture_npot"); + } - if (supportsDXT3Textures()) - { - extensionString += "GL_ANGLE_texture_compression_dxt3 "; + // Multi-vendor (EXT) extensions + if (supportsOcclusionQueries()) + { + mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean"); + } + + mExtensionStringList.push_back("GL_EXT_read_format_bgra"); + mExtensionStringList.push_back("GL_EXT_robustness"); + mExtensionStringList.push_back("GL_EXT_shader_texture_lod"); + + if (supportsDXT1Textures()) + { + mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1"); + } + + if (supportsTextureFilterAnisotropy()) + { + mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic"); + } + + if (supportsBGRATextures()) + { + mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888"); + } + + if (mRenderer->getMaxRenderTargets() > 1) + { + mExtensionStringList.push_back("GL_EXT_draw_buffers"); + } + + mExtensionStringList.push_back("GL_EXT_texture_storage"); + mExtensionStringList.push_back("GL_EXT_frag_depth"); + mExtensionStringList.push_back("GL_EXT_blend_minmax"); + + // ANGLE-specific extensions + if (supportsDepthTextures()) + { + mExtensionStringList.push_back("GL_ANGLE_depth_texture"); + } + + mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit"); + if (getMaxSupportedSamples() != 0) + { + mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample"); + } + + if (supportsInstancing()) + { + mExtensionStringList.push_back("GL_ANGLE_instanced_arrays"); + } + + mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order"); + + if (supportsDXT3Textures()) + { + mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3"); + } + if (supportsDXT5Textures()) + { + mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5"); + } + + mExtensionStringList.push_back("GL_ANGLE_texture_usage"); + mExtensionStringList.push_back("GL_ANGLE_translated_shader_source"); + + // Other vendor-specific extensions + if (supportsEventQueries()) + { + mExtensionStringList.push_back("GL_NV_fence"); + } } - if (supportsDXT5Textures()) + + if (mClientVersion == 3) { - extensionString += "GL_ANGLE_texture_compression_dxt5 "; - } + mExtensionStringList.push_back("GL_EXT_color_buffer_float"); - extensionString += "GL_ANGLE_texture_usage "; - extensionString += "GL_ANGLE_translated_shader_source "; + mExtensionStringList.push_back("GL_EXT_read_format_bgra"); - // Other vendor-specific extensions - if (supportsEventQueries()) - { - extensionString += "GL_NV_fence "; + if (supportsBGRATextures()) + { + mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888"); + } } - std::string::size_type end = extensionString.find_last_not_of(' '); - if (end != std::string::npos) + // Join the extension strings to one long string for use with GetString + std::stringstream strstr; + for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++) { - extensionString.resize(end+1); + strstr << mExtensionStringList[extensionIndex]; + strstr << " "; } - mExtensionString = makeStaticString(extensionString); + mCombinedExtensionsString = makeStaticString(strstr.str()); +} + +const char *Context::getCombinedExtensionsString() const +{ + return mCombinedExtensionsString; +} + +const char *Context::getExtensionString(const GLuint index) const +{ + ASSERT(index < mExtensionStringList.size()); + return mExtensionStringList[index].c_str(); } -const char *Context::getExtensionString() const +unsigned int Context::getNumExtensions() const { - return mExtensionString; + return mExtensionStringList.size(); } void Context::initRendererString() @@ -2658,321 +3876,170 @@ const char *Context::getRendererString() const return mRendererString; } -Context::FramebufferTextureSerialSet Context::getBoundFramebufferTextureSerials() +size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray) { - FramebufferTextureSerialSet set; + size_t serialCount = 0; Framebuffer *drawFramebuffer = getDrawFramebuffer(); for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) { - Renderbuffer *renderBuffer = drawFramebuffer->getColorbuffer(i); - if (renderBuffer && renderBuffer->getTextureSerial() != 0) + FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); + if (attachment && attachment->isTexture()) { - set.insert(renderBuffer->getTextureSerial()); + (*outSerialArray)[serialCount++] = attachment->getTextureSerial(); } } - Renderbuffer *depthStencilBuffer = drawFramebuffer->getDepthOrStencilbuffer(); - if (depthStencilBuffer && depthStencilBuffer->getTextureSerial() != 0) + FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); + if (depthStencilAttachment && depthStencilAttachment->isTexture()) { - set.insert(depthStencilBuffer->getTextureSerial()); + (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial(); } - return set; + std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); + + return serialCount; } -void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask) +void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { Framebuffer *readFramebuffer = getReadFramebuffer(); Framebuffer *drawFramebuffer = getDrawFramebuffer(); - if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE || - !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) - { - return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); - } - - if (drawFramebuffer->getSamples() != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - - Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer(); - Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer(); - - if (drawColorBuffer == NULL) - { - ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE"); - return gl::error(GL_INVALID_OPERATION); - } - - int readBufferWidth = readColorBuffer->getWidth(); - int readBufferHeight = readColorBuffer->getHeight(); - int drawBufferWidth = drawColorBuffer->getWidth(); - int drawBufferHeight = drawColorBuffer->getHeight(); - - Rectangle sourceRect; - Rectangle destRect; - - if (srcX0 < srcX1) - { - sourceRect.x = srcX0; - destRect.x = dstX0; - sourceRect.width = srcX1 - srcX0; - destRect.width = dstX1 - dstX0; - } - else - { - sourceRect.x = srcX1; - destRect.x = dstX1; - sourceRect.width = srcX0 - srcX1; - destRect.width = dstX0 - dstX1; - } - - if (srcY0 < srcY1) - { - sourceRect.height = srcY1 - srcY0; - destRect.height = dstY1 - dstY0; - sourceRect.y = srcY0; - destRect.y = dstY0; - } - else - { - sourceRect.height = srcY0 - srcY1; - destRect.height = dstY0 - srcY1; - sourceRect.y = srcY1; - destRect.y = dstY1; - } - - Rectangle sourceScissoredRect = sourceRect; - Rectangle destScissoredRect = destRect; - - if (mState.scissorTest) - { - // Only write to parts of the destination framebuffer which pass the scissor test. - if (destRect.x < mState.scissor.x) - { - int xDiff = mState.scissor.x - destRect.x; - destScissoredRect.x = mState.scissor.x; - destScissoredRect.width -= xDiff; - sourceScissoredRect.x += xDiff; - sourceScissoredRect.width -= xDiff; - - } - - if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width) - { - int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width); - destScissoredRect.width -= xDiff; - sourceScissoredRect.width -= xDiff; - } - - if (destRect.y < mState.scissor.y) - { - int yDiff = mState.scissor.y - destRect.y; - destScissoredRect.y = mState.scissor.y; - destScissoredRect.height -= yDiff; - sourceScissoredRect.y += yDiff; - sourceScissoredRect.height -= yDiff; - } - - if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height) - { - int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height); - destScissoredRect.height -= yDiff; - sourceScissoredRect.height -= yDiff; - } - } - bool blitRenderTarget = false; - bool blitDepthStencil = false; - - Rectangle sourceTrimmedRect = sourceScissoredRect; - Rectangle destTrimmedRect = destScissoredRect; - - // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of - // the actual draw and read surfaces. - if (sourceTrimmedRect.x < 0) + bool blitDepth = false; + bool blitStencil = false; + if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer()) { - int xDiff = 0 - sourceTrimmedRect.x; - sourceTrimmedRect.x = 0; - sourceTrimmedRect.width -= xDiff; - destTrimmedRect.x += xDiff; - destTrimmedRect.width -= xDiff; - } - - if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth) - { - int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth; - sourceTrimmedRect.width -= xDiff; - destTrimmedRect.width -= xDiff; - } - - if (sourceTrimmedRect.y < 0) - { - int yDiff = 0 - sourceTrimmedRect.y; - sourceTrimmedRect.y = 0; - sourceTrimmedRect.height -= yDiff; - destTrimmedRect.y += yDiff; - destTrimmedRect.height -= yDiff; - } - - if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight) - { - int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight; - sourceTrimmedRect.height -= yDiff; - destTrimmedRect.height -= yDiff; - } - - if (destTrimmedRect.x < 0) - { - int xDiff = 0 - destTrimmedRect.x; - destTrimmedRect.x = 0; - destTrimmedRect.width -= xDiff; - sourceTrimmedRect.x += xDiff; - sourceTrimmedRect.width -= xDiff; + blitRenderTarget = true; } - - if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth) + if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) { - int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth; - destTrimmedRect.width -= xDiff; - sourceTrimmedRect.width -= xDiff; + blitStencil = true; } - - if (destTrimmedRect.y < 0) + if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) { - int yDiff = 0 - destTrimmedRect.y; - destTrimmedRect.y = 0; - destTrimmedRect.height -= yDiff; - sourceTrimmedRect.y += yDiff; - sourceTrimmedRect.height -= yDiff; + blitDepth = true; } - if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight) + gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); + gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); + if (blitRenderTarget || blitDepth || blitStencil) { - int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight; - destTrimmedRect.height -= yDiff; - sourceTrimmedRect.height -= yDiff; + const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL; + mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor, + blitRenderTarget, blitDepth, blitStencil, filter); } +} - bool partialBufferCopy = false; - if (sourceTrimmedRect.height < readBufferHeight || - sourceTrimmedRect.width < readBufferWidth || - destTrimmedRect.height < drawBufferHeight || - destTrimmedRect.width < drawBufferWidth || - sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0) +void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + Framebuffer *frameBuffer = NULL; + switch (target) { - partialBufferCopy = true; + case GL_FRAMEBUFFER: + case GL_DRAW_FRAMEBUFFER: + frameBuffer = getDrawFramebuffer(); + break; + case GL_READ_FRAMEBUFFER: + frameBuffer = getReadFramebuffer(); + break; + default: + UNREACHABLE(); } - if (mask & GL_COLOR_BUFFER_BIT) + if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) { - const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType(); - const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER); - bool validDrawType = true; - bool validDrawFormat = true; - - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + for (int i = 0; i < numAttachments; ++i) { - if (drawFramebuffer->isEnabledColorAttachment(colorAttachment)) - { - if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D && - drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER) - { - validDrawType = false; - } + rx::RenderTarget *renderTarget = NULL; - if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat()) + if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) + { + gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0); + if (attachment) { - validDrawFormat = false; + renderTarget = attachment->getRenderTarget(); } } - } - - if (!validReadType || !validDrawType || !validDrawFormat) - { - ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation"); - return gl::error(GL_INVALID_OPERATION); - } - - if (partialBufferCopy && readFramebuffer->getSamples() != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - - blitRenderTarget = true; - - } - - if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) - { - Renderbuffer *readDSBuffer = NULL; - Renderbuffer *drawDSBuffer = NULL; - - // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have - // both a depth and stencil buffer, it will be the same buffer. - - if (mask & GL_DEPTH_BUFFER_BIT) - { - if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) + else if (attachments[i] == GL_COLOR) { - if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() || - readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat()) - { - return gl::error(GL_INVALID_OPERATION); - } - - blitDepthStencil = true; - readDSBuffer = readFramebuffer->getDepthbuffer(); - drawDSBuffer = drawFramebuffer->getDepthbuffer(); + gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0); + if (attachment) + { + renderTarget = attachment->getRenderTarget(); + } } - } - - if (mask & GL_STENCIL_BUFFER_BIT) - { - if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) + else { - if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() || - readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat()) + gl::FramebufferAttachment *attachment = NULL; + switch (attachments[i]) { - return gl::error(GL_INVALID_OPERATION); + case GL_DEPTH_ATTACHMENT: + case GL_DEPTH: + attachment = frameBuffer->getDepthbuffer(); + break; + case GL_STENCIL_ATTACHMENT: + case GL_STENCIL: + attachment = frameBuffer->getStencilbuffer(); + break; + case GL_DEPTH_STENCIL_ATTACHMENT: + attachment = frameBuffer->getDepthOrStencilbuffer(); + break; + default: + UNREACHABLE(); } - blitDepthStencil = true; - readDSBuffer = readFramebuffer->getStencilbuffer(); - drawDSBuffer = drawFramebuffer->getStencilbuffer(); + if (attachment) + { + renderTarget = attachment->getDepthStencil(); + } } - } - if (partialBufferCopy) - { - ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); - return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted + if (renderTarget) + { + renderTarget->invalidate(x, y, width, height); + } } + } +} - if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) || - (readDSBuffer && readDSBuffer->getSamples() != 0)) +bool Context::hasMappedBuffer(GLenum target) const +{ + if (target == GL_ARRAY_BUFFER) + { + for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++) { - return gl::error(GL_INVALID_OPERATION); + const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex); + gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get(); + if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped()) + { + return true; + } } } - - if (blitRenderTarget || blitDepthStencil) + else if (target == GL_ELEMENT_ARRAY_BUFFER) + { + Buffer *elementBuffer = getElementArrayBuffer(); + return (elementBuffer && elementBuffer->mapped()); + } + else if (target == GL_TRANSFORM_FEEDBACK_BUFFER) { - mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil); + UNIMPLEMENTED(); } + else UNREACHABLE(); + return false; } } extern "C" { -gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) +gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) { - return new gl::Context(shareContext, renderer, notifyResets, robustAccess); + return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess); } void glDestroyContext(gl::Context *context) diff --git a/chromium/third_party/angle/src/libGLESv2/Context.h b/chromium/third_party/angle/src/libGLESv2/Context.h index 09eede9ff94..ab790042596 100644 --- a/chromium/third_party/angle/src/libGLESv2/Context.h +++ b/chromium/third_party/angle/src/libGLESv2/Context.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -10,26 +10,24 @@ #ifndef LIBGLESV2_CONTEXT_H_ #define LIBGLESV2_CONTEXT_H_ -#define GL_APICALL +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#define EGLAPI #include <EGL/egl.h> #include <string> -#include <map> #include <set> -#ifdef _MSC_VER -#include <hash_map> -#else +#include <map> #include <unordered_map> -#endif +#include <array> #include "common/angleutils.h" #include "common/RefCountObject.h" #include "libGLESv2/HandleAllocator.h" #include "libGLESv2/angletypes.h" #include "libGLESv2/Constants.h" +#include "libGLESv2/VertexAttribute.h" namespace rx { @@ -49,80 +47,29 @@ class ProgramBinary; class Texture; class Texture2D; class TextureCubeMap; +class Texture3D; +class Texture2DArray; class Framebuffer; -class Renderbuffer; +class FramebufferAttachment; class RenderbufferStorage; class Colorbuffer; class Depthbuffer; class Stencilbuffer; class DepthStencilbuffer; -class Fence; +class FenceNV; +class FenceSync; class Query; class ResourceManager; class Buffer; - -enum QueryType -{ - QUERY_ANY_SAMPLES_PASSED, - QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE, - - QUERY_TYPE_COUNT -}; - -// Helper structure describing a single vertex attribute -class VertexAttribute -{ - public: - VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0) - { - mCurrentValue[0] = 0.0f; - mCurrentValue[1] = 0.0f; - mCurrentValue[2] = 0.0f; - mCurrentValue[3] = 1.0f; - } - - int typeSize() const - { - switch (mType) - { - case GL_BYTE: return mSize * sizeof(GLbyte); - case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte); - case GL_SHORT: return mSize * sizeof(GLshort); - case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort); - case GL_FIXED: return mSize * sizeof(GLfixed); - case GL_FLOAT: return mSize * sizeof(GLfloat); - default: UNREACHABLE(); return mSize * sizeof(GLfloat); - } - } - - GLsizei stride() const - { - return mStride ? mStride : typeSize(); - } - - // From glVertexAttribPointer - GLenum mType; - GLint mSize; - bool mNormalized; - GLsizei mStride; // 0 means natural stride - - union - { - const void *mPointer; - intptr_t mOffset; - }; - - BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called. - - bool mArrayEnabled; // From glEnable/DisableVertexAttribArray - float mCurrentValue[4]; // From glVertexAttrib - unsigned int mDivisor; -}; +class VertexAttribute; +class VertexArray; +class Sampler; +class TransformFeedback; // Helper structure to store all raw state struct State { - Color colorClearValue; + ColorF colorClearValue; GLclampf depthClearValue; int stencilClearValue; @@ -131,7 +78,7 @@ struct State Rectangle scissor; BlendState blend; - Color blendColor; + ColorF blendColor; bool sampleCoverage; GLclampf sampleCoverageValue; bool sampleCoverageInvert; @@ -151,27 +98,40 @@ struct State unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0 BindingPointer<Buffer> arrayBuffer; - BindingPointer<Buffer> elementArrayBuffer; GLuint readFramebuffer; GLuint drawFramebuffer; - BindingPointer<Renderbuffer> renderbuffer; + BindingPointer<FramebufferAttachment> renderbuffer; GLuint currentProgram; - VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS]; + VertexAttribCurrentValueData vertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib + unsigned int vertexArray; + BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT]; + GLuint samplers[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + + typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap; + ActiveQueryMap activeQueries; + + BindingPointer<Buffer> genericUniformBuffer; + OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; - GLint unpackAlignment; - GLint packAlignment; - bool packReverseRowOrder; + BindingPointer<TransformFeedback> transformFeedback; + BindingPointer<Buffer> genericTransformFeedbackBuffer; + OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + + BindingPointer<Buffer> copyReadBuffer; + BindingPointer<Buffer> copyWriteBuffer; + + PixelUnpackState unpack; + PixelPackState pack; }; class Context { public: - Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); + Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); - ~Context(); + virtual ~Context(); void makeCurrent(egl::Surface *surface); @@ -179,12 +139,18 @@ class Context bool isContextLost(); // State manipulation + void setCap(GLenum cap, bool enabled); + bool getCap(GLenum cap); + void setClearColor(float red, float green, float blue, float alpha); void setClearDepth(float depth); void setClearStencil(int stencil); + void setRasterizerDiscard(bool enabled); + bool isRasterizerDiscardEnabled() const; + void setCullFace(bool enabled); bool isCullFaceEnabled() const; @@ -243,6 +209,7 @@ class Context void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height); + void getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height); void setColorMask(bool red, bool green, bool blue, bool alpha); void setDepthMask(bool mask); @@ -252,22 +219,30 @@ class Context GLuint getReadFramebufferHandle() const; GLuint getDrawFramebufferHandle() const; GLuint getRenderbufferHandle() const; + GLuint getVertexArrayHandle() const; + GLuint getSamplerHandle(GLuint textureUnit) const; + unsigned int getActiveSampler() const; GLuint getArrayBufferHandle() const; - GLuint getActiveQuery(GLenum target) const; + bool isQueryActive() const; + const Query *getActiveQuery(GLenum target) const; + GLuint getActiveQueryId(GLenum target) const; void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); - const VertexAttribute &getVertexAttribState(unsigned int attribNum); + const VertexAttribute &getVertexAttribState(unsigned int attribNum) const; + const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const; void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, - bool normalized, GLsizei stride, const void *pointer); + bool normalized, bool pureInteger, GLsizei stride, const void *pointer); const void *getVertexAttribPointer(unsigned int attribNum) const; void setUnpackAlignment(GLint alignment); GLint getUnpackAlignment() const; + const PixelUnpackState &getUnpackState() const; void setPackAlignment(GLint alignment); GLint getPackAlignment() const; + const PixelPackState &getPackState() const; void setPackReverseRowOrder(bool reverseRowOrder); bool getPackReverseRowOrder() const; @@ -279,35 +254,58 @@ class Context GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); + GLuint createSampler(); + GLuint createTransformFeedback(); + GLsync createFenceSync(GLenum condition); void deleteBuffer(GLuint buffer); void deleteShader(GLuint shader); void deleteProgram(GLuint program); void deleteTexture(GLuint texture); void deleteRenderbuffer(GLuint renderbuffer); + void deleteSampler(GLuint sampler); + void deleteTransformFeedback(GLuint transformFeedback); + void deleteFenceSync(GLsync fenceSync); // Framebuffers are owned by the Context, so these methods do not pass through GLuint createFramebuffer(); void deleteFramebuffer(GLuint framebuffer); - // Fences are owned by the Context. - GLuint createFence(); - void deleteFence(GLuint fence); + // NV Fences are owned by the Context. + GLuint createFenceNV(); + void deleteFenceNV(GLuint fence); // Queries are owned by the Context; GLuint createQuery(); void deleteQuery(GLuint query); + // Vertex arrays are owned by the Context + GLuint createVertexArray(); + void deleteVertexArray(GLuint vertexArray); + void bindArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint buffer); void bindTexture2D(GLuint texture); void bindTextureCubeMap(GLuint texture); + void bindTexture3D(GLuint texture); + void bindTexture2DArray(GLuint texture); void bindReadFramebuffer(GLuint framebuffer); void bindDrawFramebuffer(GLuint framebuffer); void bindRenderbuffer(GLuint renderbuffer); + void bindVertexArray(GLuint vertexArray); + void bindSampler(GLuint textureUnit, GLuint sampler); + void bindGenericUniformBuffer(GLuint buffer); + void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); + void bindGenericTransformFeedbackBuffer(GLuint buffer); + void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); + void bindCopyReadBuffer(GLuint buffer); + void bindCopyWriteBuffer(GLuint buffer); + void bindPixelPackBuffer(GLuint buffer); + void bindPixelUnpackBuffer(GLuint buffer); void useProgram(GLuint program); void linkProgram(GLuint program); void setProgramBinary(GLuint program, const void *binary, GLint length); + void bindTransformFeedback(GLuint transformFeedback); void beginQuery(GLenum target, GLuint query); void endQuery(GLenum target); @@ -316,35 +314,75 @@ class Context void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples); - void setVertexAttrib(GLuint index, const GLfloat *values); + void setVertexAttribf(GLuint index, const GLfloat values[4]); + void setVertexAttribu(GLuint index, const GLuint values[4]); + void setVertexAttribi(GLuint index, const GLint values[4]); void setVertexAttribDivisor(GLuint index, GLuint divisor); + void samplerParameteri(GLuint sampler, GLenum pname, GLint param); + void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param); + GLint getSamplerParameteri(GLuint sampler, GLenum pname); + GLfloat getSamplerParameterf(GLuint sampler, GLenum pname); + Buffer *getBuffer(GLuint handle); - Fence *getFence(GLuint handle); - Shader *getShader(GLuint handle); - Program *getProgram(GLuint handle); + FenceNV *getFenceNV(GLuint handle); + FenceSync *getFenceSync(GLsync handle) const; + Shader *getShader(GLuint handle) const; + Program *getProgram(GLuint handle) const; Texture *getTexture(GLuint handle); - Framebuffer *getFramebuffer(GLuint handle); - Renderbuffer *getRenderbuffer(GLuint handle); + Framebuffer *getFramebuffer(GLuint handle) const; + FramebufferAttachment *getRenderbuffer(GLuint handle); + VertexArray *getVertexArray(GLuint handle) const; + Sampler *getSampler(GLuint handle) const; Query *getQuery(GLuint handle, bool create, GLenum type); + TransformFeedback *getTransformFeedback(GLuint handle) const; + Buffer *getTargetBuffer(GLenum target) const; Buffer *getArrayBuffer(); - Buffer *getElementArrayBuffer(); + Buffer *getElementArrayBuffer() const; ProgramBinary *getCurrentProgramBinary(); - Texture2D *getTexture2D(); - TextureCubeMap *getTextureCubeMap(); - Texture *getSamplerTexture(unsigned int sampler, TextureType type); + + Texture *getTargetTexture(GLenum target) const; + Texture2D *getTexture2D() const; + TextureCubeMap *getTextureCubeMap() const; + Texture3D *getTexture3D() const; + Texture2DArray *getTexture2DArray() const; + + Buffer *getGenericUniformBuffer(); + Buffer *getGenericTransformFeedbackBuffer(); + Buffer *getCopyReadBuffer(); + Buffer *getCopyWriteBuffer(); + Buffer *getPixelPackBuffer(); + Buffer *getPixelUnpackBuffer(); + Texture *getSamplerTexture(unsigned int sampler, TextureType type) const; + + Framebuffer *getTargetFramebuffer(GLenum target) const; + GLuint getTargetFramebufferHandle(GLenum target) const; Framebuffer *getReadFramebuffer(); Framebuffer *getDrawFramebuffer(); + VertexArray *getCurrentVertexArray() const; + TransformFeedback *getCurrentTransformFeedback() const; + + bool isSampler(GLuint samplerName) const; - bool getFloatv(GLenum pname, GLfloat *params); - bool getIntegerv(GLenum pname, GLint *params); - bool getBooleanv(GLenum pname, GLboolean *params); + void getBooleanv(GLenum pname, GLboolean *params); + void getFloatv(GLenum pname, GLfloat *params); + void getIntegerv(GLenum pname, GLint *params); + void getInteger64v(GLenum pname, GLint64 *params); + + bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); + bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); + bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels); void clear(GLbitfield mask); + void clearBufferfv(GLenum buffer, int drawbuffer, const float *values); + void clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values); + void clearBufferiv(GLenum buffer, int drawbuffer, const int *values); + void clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil); + + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels); void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances); void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances); void sync(bool block); // flush/finish @@ -359,16 +397,31 @@ class Context GLenum getResetStatus(); virtual bool isResetNotificationEnabled(); + virtual int getClientVersion() const; + int getMajorShaderModel() const; float getMaximumPointSize() const; unsigned int getMaximumCombinedTextureImageUnits() const; + unsigned int getMaximumCombinedUniformBufferBindings() const; int getMaximumRenderbufferDimension() const; - int getMaximumTextureDimension() const; + int getMaximum2DTextureDimension() const; int getMaximumCubeTextureDimension() const; - int getMaximumTextureLevel() const; + int getMaximum3DTextureDimension() const; + int getMaximum2DArrayTextureLayers() const; + int getMaximum2DTextureLevel() const; + int getMaximumCubeTextureLevel() const; + int getMaximum3DTextureLevel() const; + int getMaximum2DArrayTextureLevel() const; unsigned int getMaximumRenderTargets() const; GLsizei getMaxSupportedSamples() const; - const char *getExtensionString() const; + GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const; + GLsizei getNumSampleCounts(GLenum internalFormat) const; + void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const; + unsigned int getMaxTransformFeedbackBufferBindings() const; + GLintptr getUniformBufferOffsetAlignment() const; + const char *getCombinedExtensionsString() const; + const char *getExtensionString(const GLuint index) const; + unsigned int getNumExtensions() const; const char *getRendererString() const; bool supportsEventQueries() const; bool supportsOcclusionQueries() const; @@ -384,36 +437,55 @@ class Context bool supportsFloat16RenderableTextures() const; bool supportsLuminanceTextures() const; bool supportsLuminanceAlphaTextures() const; + bool supportsRGTextures() const; bool supportsDepthTextures() const; bool supports32bitIndices() const; bool supportsNonPower2Texture() const; bool supportsInstancing() const; bool supportsTextureFilterAnisotropy() const; + bool supportsPBOs() const; - bool getCurrentReadFormatType(GLenum *format, GLenum *type); + void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type); float getTextureMaxAnisotropy() const; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask); + void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + + void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, + GLint x, GLint y, GLsizei width, GLsizei height); + + bool hasMappedBuffer(GLenum target) const; rx::Renderer *getRenderer() { return mRenderer; } private: DISALLOW_COPY_AND_ASSIGN(Context); + // TODO: std::array may become unavailable using older versions of GCC + typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray; + bool applyRenderTarget(GLenum drawMode, bool ignoreViewport); void applyState(GLenum drawMode); - void applyShaders(); - void applyTextures(); - void applyTextures(SamplerType type); + void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive); + void applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers, + size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials, + size_t framebufferSerialCount); + bool applyUniformBuffers(); + bool applyTransformFeedbackBuffers(); + void markTransformFeedbackUsage(); void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); void detachFramebuffer(GLuint framebuffer); void detachRenderbuffer(GLuint renderbuffer); + void detachVertexArray(GLuint vertexArray); + void detachTransformFeedback(GLuint transformFeedback); + void detachSampler(GLuint sampler); + void generateSwizzles(Texture *textures[], size_t count); + size_t getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures, + TextureType *outTextureTypes, SamplerState *outSamplers); Texture *getIncompleteTexture(TextureType type); bool skipDraw(GLenum drawMode); @@ -421,37 +493,42 @@ class Context void initExtensionString(); void initRendererString(); - typedef std::set<unsigned> FramebufferTextureSerialSet; - FramebufferTextureSerialSet getBoundFramebufferTextureSerials(); + size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray); rx::Renderer *const mRenderer; + int mClientVersion; + State mState; BindingPointer<Texture2D> mTexture2DZero; BindingPointer<TextureCubeMap> mTextureCubeMapZero; + BindingPointer<Texture3D> mTexture3DZero; + BindingPointer<Texture2DArray> mTexture2DArrayZero; -#ifndef HASH_MAP -# ifdef _MSC_VER -# define HASH_MAP stdext::hash_map -# else -# define HASH_MAP std::unordered_map -# endif -#endif - - typedef HASH_MAP<GLuint, Framebuffer*> FramebufferMap; + typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap; FramebufferMap mFramebufferMap; HandleAllocator mFramebufferHandleAllocator; - typedef HASH_MAP<GLuint, Fence*> FenceMap; - FenceMap mFenceMap; - HandleAllocator mFenceHandleAllocator; + typedef std::unordered_map<GLuint, FenceNV*> FenceNVMap; + FenceNVMap mFenceNVMap; + HandleAllocator mFenceNVHandleAllocator; - typedef HASH_MAP<GLuint, Query*> QueryMap; + typedef std::unordered_map<GLuint, Query*> QueryMap; QueryMap mQueryMap; HandleAllocator mQueryHandleAllocator; - const char *mExtensionString; + typedef std::unordered_map<GLuint, VertexArray*> VertexArrayMap; + VertexArrayMap mVertexArrayMap; + HandleAllocator mVertexArrayHandleAllocator; + + BindingPointer<TransformFeedback> mTransformFeedbackZero; + typedef std::unordered_map<GLuint, TransformFeedback*> TransformFeedbackMap; + TransformFeedbackMap mTransformFeedbackMap; + HandleAllocator mTransformFeedbackAllocator; + + std::vector<std::string> mExtensionStringList; + const char *mCombinedExtensionsString; const char *mRendererString; BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT]; @@ -480,9 +557,14 @@ class Context bool mSupportsInstancing; int mMaxViewportDimension; int mMaxRenderbufferDimension; - int mMaxTextureDimension; + int mMax2DTextureDimension; int mMaxCubeTextureDimension; - int mMaxTextureLevel; + int mMax3DTextureDimension; + int mMax2DArrayTextureLayers; + int mMax2DTextureLevel; + int mMaxCubeTextureLevel; + int mMax3DTextureLevel; + int mMax2DArrayTextureLevel; float mMaxTextureAnisotropy; bool mSupportsEventQueries; bool mSupportsOcclusionQueries; @@ -498,9 +580,11 @@ class Context bool mSupportsFloat16RenderableTextures; bool mSupportsLuminanceTextures; bool mSupportsLuminanceAlphaTextures; + bool mSupportsRGTextures; bool mSupportsDepthTextures; bool mSupports32bitIndices; bool mSupportsTextureFilterAnisotropy; + bool mSupportsPBOs; int mNumCompressedTextureFormats; ResourceManager *mResourceManager; diff --git a/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.cpp b/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.cpp new file mode 100644 index 00000000000..20e4a205488 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.cpp @@ -0,0 +1,1057 @@ +// +// Copyright (c) 2014 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. +// +// DynamicHLSL.cpp: Implementation for link and run-time HLSL generation +// + +#include "precompiled.h" + +#include "libGLESv2/DynamicHLSL.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/Program.h" +#include "libGLESv2/renderer/Renderer.h" +#include "common/utilities.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/formatutils.h" +#include "common/blocklayout.h" + +static std::string Str(int i) +{ + char buffer[20]; + snprintf(buffer, sizeof(buffer), "%d", i); + return buffer; +} + +namespace gl_d3d +{ + +std::string HLSLComponentTypeString(GLenum componentType) +{ + switch (componentType) + { + case GL_UNSIGNED_INT: return "uint"; + case GL_INT: return "int"; + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: return "float"; + default: UNREACHABLE(); return "not-component-type"; + } +} + +std::string HLSLComponentTypeString(GLenum componentType, int componentCount) +{ + return HLSLComponentTypeString(componentType) + (componentCount > 1 ? Str(componentCount) : ""); +} + +std::string HLSLMatrixTypeString(GLenum type) +{ + switch (type) + { + case GL_FLOAT_MAT2: return "float2x2"; + case GL_FLOAT_MAT3: return "float3x3"; + case GL_FLOAT_MAT4: return "float4x4"; + case GL_FLOAT_MAT2x3: return "float2x3"; + case GL_FLOAT_MAT3x2: return "float3x2"; + case GL_FLOAT_MAT2x4: return "float2x4"; + case GL_FLOAT_MAT4x2: return "float4x2"; + case GL_FLOAT_MAT3x4: return "float3x4"; + case GL_FLOAT_MAT4x3: return "float4x3"; + default: UNREACHABLE(); return "not-matrix-type"; + } +} + +std::string HLSLTypeString(GLenum type) +{ + if (gl::IsMatrixType(type)) + { + return HLSLMatrixTypeString(type); + } + + return HLSLComponentTypeString(gl::UniformComponentType(type), gl::UniformComponentCount(type)); +} + +} + +namespace gl +{ + +std::string ArrayString(unsigned int i) +{ + return (i == GL_INVALID_INDEX ? "" : "[" + Str(i) + "]"); +} + +const std::string DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; + +DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer) + : mRenderer(renderer) +{ +} + +static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, VaryingPacking packing) +{ + GLenum transposedType = TransposeMatrixType(varying->type); + + // matrices within varying structs are not transposed + int registers = (varying->isStruct() ? HLSLVariableRegisterCount(*varying) : VariableRowCount(transposedType)) * varying->elementCount(); + int elements = (varying->isStruct() ? 4 : VariableColumnCount(transposedType)); + + if (elements >= 2 && elements <= 4) + { + for (int r = 0; r <= maxVaryingVectors - registers; r++) + { + bool available = true; + + for (int y = 0; y < registers && available; y++) + { + for (int x = 0; x < elements && available; x++) + { + if (packing[r + y][x]) + { + available = false; + } + } + } + + if (available) + { + varying->registerIndex = r; + + for (int y = 0; y < registers; y++) + { + for (int x = 0; x < elements; x++) + { + packing[r + y][x] = &*varying; + } + } + + return true; + } + } + + if (elements == 2) + { + for (int r = maxVaryingVectors - registers; r >= 0; r--) + { + bool available = true; + + for (int y = 0; y < registers && available; y++) + { + for (int x = 2; x < 4 && available; x++) + { + if (packing[r + y][x]) + { + available = false; + } + } + } + + if (available) + { + varying->registerIndex = r; + + for (int y = 0; y < registers; y++) + { + for (int x = 2; x < 4; x++) + { + packing[r + y][x] = &*varying; + } + } + + return true; + } + } + } + } + else if (elements == 1) + { + int space[4] = { 0 }; + + for (int y = 0; y < maxVaryingVectors; y++) + { + for (int x = 0; x < 4; x++) + { + space[x] += packing[y][x] ? 0 : 1; + } + } + + int column = 0; + + for (int x = 0; x < 4; x++) + { + if (space[x] >= registers && space[x] < space[column]) + { + column = x; + } + } + + if (space[column] >= registers) + { + for (int r = 0; r < maxVaryingVectors; r++) + { + if (!packing[r][column]) + { + varying->registerIndex = r; + + for (int y = r; y < r + registers; y++) + { + packing[y][column] = &*varying; + } + + break; + } + } + + return true; + } + } + else UNREACHABLE(); + + return false; +} + +// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 +// Returns the number of used varying registers, or -1 if unsuccesful +int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader, + VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings) +{ + const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); + + vertexShader->resetVaryingsRegisterAssignment(); + fragmentShader->resetVaryingsRegisterAssignment(); + + std::set<std::string> packedVaryings; + + for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++) + { + PackedVarying *varying = &fragmentShader->mVaryings[varyingIndex]; + if (packVarying(varying, maxVaryingVectors, packing)) + { + packedVaryings.insert(varying->name); + } + else + { + infoLog.append("Could not pack varying %s", varying->name.c_str()); + return -1; + } + } + + for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++) + { + const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex]; + if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end()) + { + bool found = false; + for (unsigned int varyingIndex = 0; varyingIndex < vertexShader->mVaryings.size(); varyingIndex++) + { + PackedVarying *varying = &vertexShader->mVaryings[varyingIndex]; + if (transformFeedbackVarying == varying->name) + { + if (!packVarying(varying, maxVaryingVectors, packing)) + { + infoLog.append("Could not pack varying %s", varying->name.c_str()); + return -1; + } + + found = true; + break; + } + } + + if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize") + { + infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str()); + return -1; + } + } + } + + // Return the number of used registers + int registers = 0; + + for (int r = 0; r < maxVaryingVectors; r++) + { + if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) + { + registers++; + } + } + + return registers; +} + +std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader, const std::string &varyingSemantic, + std::vector<LinkedVarying> *linkedVaryings) const +{ + std::string varyingHLSL; + + for (unsigned int varyingIndex = 0; varyingIndex < shader->mVaryings.size(); varyingIndex++) + { + const PackedVarying &varying = shader->mVaryings[varyingIndex]; + if (varying.registerAssigned()) + { + GLenum transposedType = TransposeMatrixType(varying.type); + int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); + + for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) + { + for (int row = 0; row < variableRows; row++) + { + switch (varying.interpolation) + { + case INTERPOLATION_SMOOTH: varyingHLSL += " "; break; + case INTERPOLATION_FLAT: varyingHLSL += " nointerpolation "; break; + case INTERPOLATION_CENTROID: varyingHLSL += " centroid "; break; + default: UNREACHABLE(); + } + + unsigned int semanticIndex = elementIndex * variableRows + varying.registerIndex + row; + std::string n = Str(semanticIndex); + + std::string typeString; + + if (varying.isStruct()) + { + // matrices within structs are not transposed, so + // do not use the special struct prefix "rm" + typeString = decorateVariable(varying.structName); + } + else + { + GLenum componentType = UniformComponentType(transposedType); + int columnCount = VariableColumnCount(transposedType); + typeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount); + } + varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n"; + } + } + + if (linkedVaryings) + { + linkedVaryings->push_back(LinkedVarying(varying.name, varying.type, varying.elementCount(), + varyingSemantic, varying.registerIndex, + variableRows * varying.elementCount())); + } + } + } + + return varyingHLSL; +} + +std::string DynamicHLSL::generateInputLayoutHLSL(const VertexFormat inputLayout[], const Attribute shaderAttributes[]) const +{ + std::string structHLSL, initHLSL; + + int semanticIndex = 0; + unsigned int inputIndex = 0; + + for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + ASSERT(inputIndex < MAX_VERTEX_ATTRIBS); + + const VertexFormat &vertexFormat = inputLayout[inputIndex]; + const Attribute &shaderAttribute = shaderAttributes[attributeIndex]; + + if (!shaderAttribute.name.empty()) + { + // HLSL code for input structure + if (IsMatrixType(shaderAttribute.type)) + { + // Matrix types are always transposed + structHLSL += " " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type)); + } + else + { + GLenum componentType = mRenderer->getVertexComponentType(vertexFormat); + structHLSL += " " + gl_d3d::HLSLComponentTypeString(componentType, UniformComponentCount(shaderAttribute.type)); + } + + structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n"; + semanticIndex += AttributeRegisterCount(shaderAttribute.type); + + // HLSL code for initialization + initHLSL += " " + decorateVariable(shaderAttribute.name) + " = "; + + // Mismatched vertex attribute to vertex input may result in an undefined + // data reinterpretation (eg for pure integer->float, float->pure integer) + // TODO: issue warning with gl debug info extension, when supported + if (IsMatrixType(shaderAttribute.type) || + (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0) + { + initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute); + } + else + { + initHLSL += "input." + decorateVariable(shaderAttribute.name); + } + + initHLSL += ";\n"; + + inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type)); + } + } + + return "struct VS_INPUT\n" + "{\n" + + structHLSL + + "};\n" + "\n" + "void initAttributes(VS_INPUT input)\n" + "{\n" + + initHLSL + + "}\n"; +} + +bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing, + std::string& pixelHLSL, std::string& vertexHLSL, + FragmentShader *fragmentShader, VertexShader *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, + std::vector<LinkedVarying> *linkedVaryings, + std::map<int, VariableLocation> *programOutputVars) const +{ + if (pixelHLSL.empty() || vertexHLSL.empty()) + { + return false; + } + + bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; + bool usesFragColor = fragmentShader->mUsesFragColor; + bool usesFragData = fragmentShader->mUsesFragData; + if (usesFragColor && usesFragData) + { + infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader."); + return false; + } + + // Write the HLSL input/output declarations + const int shaderModel = mRenderer->getMajorShaderModel(); + const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); + + const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0); + + // Two cases when writing to gl_FragColor and using ESSL 1.0: + // - with a 3.0 context, the output color is copied to channel 0 + // - with a 2.0 context, the output color is broadcast to all channels + const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3); + const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1); + + int shaderVersion = vertexShader->getShaderVersion(); + + if (registersNeeded > maxVaryingVectors) + { + infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); + + return false; + } + + std::string varyingSemantic = (vertexShader->mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD"; + std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR"; + std::string dxPositionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION"; + std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + + std::string varyingHLSL = generateVaryingHLSL(vertexShader, varyingSemantic, linkedVaryings); + + // special varyings that use reserved registers + int reservedRegisterIndex = registers; + + unsigned int glPositionSemanticIndex = reservedRegisterIndex++; + std::string glPositionSemantic = varyingSemantic; + + std::string fragCoordSemantic; + unsigned int fragCoordSemanticIndex = 0; + if (fragmentShader->mUsesFragCoord) + { + fragCoordSemanticIndex = reservedRegisterIndex++; + fragCoordSemantic = varyingSemantic; + } + + std::string pointCoordSemantic; + unsigned int pointCoordSemanticIndex = 0; + if (fragmentShader->mUsesPointCoord) + { + // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords. + // In DX11 we compute this in the GS. + if (shaderModel == 3) + { + pointCoordSemanticIndex = 0; + pointCoordSemantic = "TEXCOORD0"; + } + else if (shaderModel >= 4) + { + pointCoordSemanticIndex = reservedRegisterIndex++; + pointCoordSemantic = varyingSemantic; + } + } + + // Add stub string to be replaced when shader is dynamically defined by its layout + vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n"; + + vertexHLSL += "struct VS_OUTPUT\n" + "{\n"; + + if (shaderModel < 4) + { + vertexHLSL += " float4 _dx_Position : " + dxPositionSemantic + ";\n"; + vertexHLSL += " float4 gl_Position : " + glPositionSemantic + Str(glPositionSemanticIndex) + ";\n"; + linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, glPositionSemantic, glPositionSemanticIndex, 1)); + + } + + vertexHLSL += varyingHLSL; + + if (fragmentShader->mUsesFragCoord) + { + vertexHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + Str(fragCoordSemanticIndex) + ";\n"; + linkedVaryings->push_back(LinkedVarying("gl_FragCoord", GL_FLOAT_VEC4, 1, fragCoordSemantic, fragCoordSemanticIndex, 1)); + } + + if (vertexShader->mUsesPointSize && shaderModel >= 3) + { + vertexHLSL += " float gl_PointSize : PSIZE;\n"; + linkedVaryings->push_back(LinkedVarying("gl_PointSize", GL_FLOAT, 1, "PSIZE", 0, 1)); + } + + if (shaderModel >= 4) + { + vertexHLSL += " float4 _dx_Position : " + dxPositionSemantic + ";\n"; + vertexHLSL += " float4 gl_Position : " + glPositionSemantic + Str(glPositionSemanticIndex) + ";\n"; + linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, glPositionSemantic, glPositionSemanticIndex, 1)); + } + + vertexHLSL += "};\n" + "\n" + "VS_OUTPUT main(VS_INPUT input)\n" + "{\n" + " initAttributes(input);\n"; + + if (shaderModel >= 4) + { + vertexHLSL += "\n" + " gl_main();\n" + "\n" + " VS_OUTPUT output;\n" + " output.gl_Position = gl_Position;\n" + " output._dx_Position.x = gl_Position.x;\n" + " output._dx_Position.y = -gl_Position.y;\n" + " output._dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + " output._dx_Position.w = gl_Position.w;\n"; + } + else + { + vertexHLSL += "\n" + " gl_main();\n" + "\n" + " VS_OUTPUT output;\n" + " output.gl_Position = gl_Position;\n" + " output._dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n" + " output._dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n" + " output._dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + " output._dx_Position.w = gl_Position.w;\n"; + } + + if (vertexShader->mUsesPointSize && shaderModel >= 3) + { + vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; + } + + for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexShader->mVaryings.size(); vertVaryingIndex++) + { + const PackedVarying &varying = vertexShader->mVaryings[vertVaryingIndex]; + if (varying.registerAssigned()) + { + for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) + { + int variableRows = (varying.isStruct() ? 1 : VariableRowCount(TransposeMatrixType(varying.type))); + + for (int row = 0; row < variableRows; row++) + { + int r = varying.registerIndex + elementIndex * variableRows + row; + vertexHLSL += " output.v" + Str(r); + + bool sharedRegister = false; // Register used by multiple varyings + + for (int x = 0; x < 4; x++) + { + if (packing[r][x] && packing[r][x] != packing[r][0]) + { + sharedRegister = true; + break; + } + } + + if(sharedRegister) + { + vertexHLSL += "."; + + for (int x = 0; x < 4; x++) + { + if (packing[r][x] == &varying) + { + switch(x) + { + case 0: vertexHLSL += "x"; break; + case 1: vertexHLSL += "y"; break; + case 2: vertexHLSL += "z"; break; + case 3: vertexHLSL += "w"; break; + } + } + } + } + + vertexHLSL += " = _" + varying.name; + + if (varying.isArray()) + { + vertexHLSL += ArrayString(elementIndex); + } + + if (variableRows > 1) + { + vertexHLSL += ArrayString(row); + } + + vertexHLSL += ";\n"; + } + } + } + } + + vertexHLSL += "\n" + " return output;\n" + "}\n"; + + pixelHLSL += "struct PS_INPUT\n" + "{\n"; + + pixelHLSL += varyingHLSL; + + if (fragmentShader->mUsesFragCoord) + { + pixelHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + Str(fragCoordSemanticIndex) + ";\n"; + } + + if (fragmentShader->mUsesPointCoord && shaderModel >= 3) + { + pixelHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + Str(pointCoordSemanticIndex) + ";\n"; + } + + // Must consume the PSIZE element if the geometry shader is not active + // We won't know if we use a GS until we draw + if (vertexShader->mUsesPointSize && shaderModel >= 4) + { + pixelHLSL += " float gl_PointSize : PSIZE;\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + if (shaderModel >= 4) + { + pixelHLSL += " float4 dx_VPos : SV_Position;\n"; + } + else if (shaderModel >= 3) + { + pixelHLSL += " float2 dx_VPos : VPOS;\n"; + } + } + + pixelHLSL += "};\n" + "\n" + "struct PS_OUTPUT\n" + "{\n"; + + if (shaderVersion < 300) + { + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + { + pixelHLSL += " float4 gl_Color" + Str(renderTargetIndex) + " : " + targetSemantic + Str(renderTargetIndex) + ";\n"; + } + + if (fragmentShader->mUsesFragDepth) + { + pixelHLSL += " float gl_Depth : " + depthSemantic + ";\n"; + } + } + else + { + defineOutputVariables(fragmentShader, programOutputVars); + + const std::vector<Attribute> &shaderOutputVars = fragmentShader->getOutputVariables(); + for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++) + { + const VariableLocation &outputLocation = locationIt->second; + const ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; + const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); + + pixelHLSL += " " + gl_d3d::HLSLTypeString(outputVariable.type) + + " out_" + outputLocation.name + elementString + + " : " + targetSemantic + Str(locationIt->first) + ";\n"; + } + } + + pixelHLSL += "};\n" + "\n"; + + if (fragmentShader->mUsesFrontFacing) + { + if (shaderModel >= 4) + { + pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n" + "{\n"; + } + else + { + pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n" + "{\n"; + } + } + else + { + pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n" + "{\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; + + if (shaderModel >= 4) + { + pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n" + " gl_FragCoord.y = input.dx_VPos.y;\n"; + } + else if (shaderModel >= 3) + { + pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" + " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n"; + } + else + { + // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport() + pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n" + " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n"; + } + + pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n" + " gl_FragCoord.w = rhw;\n"; + } + + if (fragmentShader->mUsesPointCoord && shaderModel >= 3) + { + pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n"; + pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; + } + + if (fragmentShader->mUsesFrontFacing) + { + if (shaderModel <= 3) + { + pixelHLSL += " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; + } + else + { + pixelHLSL += " gl_FrontFacing = isFrontFace;\n"; + } + } + + for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++) + { + const PackedVarying &varying = fragmentShader->mVaryings[varyingIndex]; + if (varying.registerAssigned()) + { + for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) + { + GLenum transposedType = TransposeMatrixType(varying.type); + int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); + for (int row = 0; row < variableRows; row++) + { + std::string n = Str(varying.registerIndex + elementIndex * variableRows + row); + pixelHLSL += " _" + varying.name; + + if (varying.isArray()) + { + pixelHLSL += ArrayString(elementIndex); + } + + if (variableRows > 1) + { + pixelHLSL += ArrayString(row); + } + + if (varying.isStruct()) + { + pixelHLSL += " = input.v" + n + ";\n"; break; + } + else + { + switch (VariableColumnCount(transposedType)) + { + case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break; + case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break; + case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break; + case 4: pixelHLSL += " = input.v" + n + ";\n"; break; + default: UNREACHABLE(); + } + } + } + } + } + else UNREACHABLE(); + } + + pixelHLSL += "\n" + " gl_main();\n" + "\n" + " PS_OUTPUT output;\n"; + + if (shaderVersion < 300) + { + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + { + unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex; + + pixelHLSL += " output.gl_Color" + Str(renderTargetIndex) + " = gl_Color[" + Str(sourceColorIndex) + "];\n"; + } + + if (fragmentShader->mUsesFragDepth) + { + pixelHLSL += " output.gl_Depth = gl_Depth;\n"; + } + } + else + { + for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++) + { + const VariableLocation &outputLocation = locationIt->second; + const std::string &variableName = "out_" + outputLocation.name; + const std::string &outVariableName = variableName + (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); + const std::string &staticVariableName = variableName + ArrayString(outputLocation.element); + + pixelHLSL += " output." + outVariableName + " = " + staticVariableName + ";\n"; + } + } + + pixelHLSL += "\n" + " return output;\n" + "}\n"; + + return true; +} + +void DynamicHLSL::defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const +{ + const std::vector<Attribute> &shaderOutputVars = fragmentShader->getOutputVariables(); + + for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); outputVariableIndex++) + { + const Attribute &outputVariable = shaderOutputVars[outputVariableIndex]; + const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location; + + if (outputVariable.arraySize > 0) + { + for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++) + { + const int location = baseLocation + elementIndex; + ASSERT(programOutputVars->count(location) == 0); + (*programOutputVars)[location] = VariableLocation(outputVariable.name, elementIndex, outputVariableIndex); + } + } + else + { + ASSERT(programOutputVars->count(baseLocation) == 0); + (*programOutputVars)[baseLocation] = VariableLocation(outputVariable.name, GL_INVALID_INDEX, outputVariableIndex); + } + } +} + +std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const +{ + // for now we only handle point sprite emulation + ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4); + return generatePointSpriteHLSL(registers, fragmentShader, vertexShader); +} + +std::string DynamicHLSL::generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const +{ + ASSERT(registers >= 0); + ASSERT(vertexShader->mUsesPointSize); + ASSERT(mRenderer->getMajorShaderModel() >= 4); + + std::string geomHLSL; + + std::string varyingSemantic = "TEXCOORD"; + + std::string fragCoordSemantic; + std::string pointCoordSemantic; + + int reservedRegisterIndex = registers; + + if (fragmentShader->mUsesFragCoord) + { + fragCoordSemantic = varyingSemantic + Str(reservedRegisterIndex++); + } + + if (fragmentShader->mUsesPointCoord) + { + pointCoordSemantic = varyingSemantic + Str(reservedRegisterIndex++); + } + + geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n" + "\n" + "struct GS_INPUT\n" + "{\n"; + + std::string varyingHLSL = generateVaryingHLSL(vertexShader, varyingSemantic, NULL); + + geomHLSL += varyingHLSL; + + if (fragmentShader->mUsesFragCoord) + { + geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; + } + + geomHLSL += " float gl_PointSize : PSIZE;\n" + " float4 gl_Position : SV_Position;\n" + "};\n" + "\n" + "struct GS_OUTPUT\n" + "{\n"; + + geomHLSL += varyingHLSL; + + if (fragmentShader->mUsesFragCoord) + { + geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; + } + + if (fragmentShader->mUsesPointCoord) + { + geomHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n"; + } + + geomHLSL += " float gl_PointSize : PSIZE;\n" + " float4 gl_Position : SV_Position;\n" + "};\n" + "\n" + "static float2 pointSpriteCorners[] = \n" + "{\n" + " float2( 0.5f, -0.5f),\n" + " float2( 0.5f, 0.5f),\n" + " float2(-0.5f, -0.5f),\n" + " float2(-0.5f, 0.5f)\n" + "};\n" + "\n" + "static float2 pointSpriteTexcoords[] = \n" + "{\n" + " float2(1.0f, 1.0f),\n" + " float2(1.0f, 0.0f),\n" + " float2(0.0f, 1.0f),\n" + " float2(0.0f, 0.0f)\n" + "};\n" + "\n" + "static float minPointSize = " + Str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n" + "static float maxPointSize = " + Str(mRenderer->getMaxPointSize()) + ".0f;\n" + "\n" + "[maxvertexcount(4)]\n" + "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n" + "{\n" + " GS_OUTPUT output = (GS_OUTPUT)0;\n" + " output.gl_PointSize = input[0].gl_PointSize;\n"; + + for (int r = 0; r < registers; r++) + { + geomHLSL += " output.v" + Str(r) + " = input[0].v" + Str(r) + ";\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + geomHLSL += " output.gl_FragCoord = input[0].gl_FragCoord;\n"; + } + + geomHLSL += " \n" + " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n" + " float4 gl_Position = input[0].gl_Position;\n" + " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n"; + + for (int corner = 0; corner < 4; corner++) + { + geomHLSL += " \n" + " output.gl_Position = gl_Position + float4(pointSpriteCorners[" + Str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; + + if (fragmentShader->mUsesPointCoord) + { + geomHLSL += " output.gl_PointCoord = pointSpriteTexcoords[" + Str(corner) + "];\n"; + } + + geomHLSL += " outStream.Append(output);\n"; + } + + geomHLSL += " \n" + " outStream.RestartStrip();\n" + "}\n"; + + return geomHLSL; +} + +// This method needs to match OutputHLSL::decorate +std::string DynamicHLSL::decorateVariable(const std::string &name) +{ + if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) + { + return "_" + name; + } + + return name; +} + +std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const ShaderVariable &shaderAttrib) const +{ + std::string attribString = "input." + decorateVariable(shaderAttrib.name); + + // Matrix + if (IsMatrixType(shaderAttrib.type)) + { + return "transpose(" + attribString + ")"; + } + + GLenum shaderComponentType = UniformComponentType(shaderAttrib.type); + int shaderComponentCount = UniformComponentCount(shaderAttrib.type); + + // Perform integer to float conversion (if necessary) + bool requiresTypeConversion = (shaderComponentType == GL_FLOAT && vertexFormat.mType != GL_FLOAT); + + if (requiresTypeConversion) + { + // TODO: normalization for 32-bit integer formats + ASSERT(!vertexFormat.mNormalized && !vertexFormat.mPureInteger); + return "float" + Str(shaderComponentCount) + "(" + attribString + ")"; + } + + // No conversion necessary + return attribString; +} + +void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const +{ + for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) + { + const VertexFormat &vertexFormat = inputLayout[inputIndex]; + + if (vertexFormat.mType == GL_NONE) + { + signature[inputIndex] = GL_NONE; + } + else + { + bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0); + signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE); + } + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.h b/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.h new file mode 100644 index 00000000000..07c2a2f2bbc --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/DynamicHLSL.h @@ -0,0 +1,78 @@ +// +// Copyright (c) 2014 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. +// +// DynamicHLSL.h: Interface for link and run-time HLSL generation +// + +#ifndef LIBGLESV2_DYNAMIC_HLSL_H_ +#define LIBGLESV2_DYNAMIC_HLSL_H_ + +#include "common/angleutils.h" +#include "libGLESv2/constants.h" + +namespace rx +{ +class Renderer; +} + +namespace gl +{ + +class InfoLog; +class FragmentShader; +class VertexShader; +struct VariableLocation; +struct LinkedVarying; +class VertexAttribute; +struct VertexFormat; +struct ShaderVariable; +struct Varying; +struct Attribute; +struct PackedVarying; + +typedef const PackedVarying *VaryingPacking[IMPLEMENTATION_MAX_VARYING_VECTORS][4]; + +class DynamicHLSL +{ + public: + explicit DynamicHLSL(rx::Renderer *const renderer); + + int packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader, + VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings); + std::string generateInputLayoutHLSL(const VertexFormat inputLayout[], const Attribute shaderAttributes[]) const; + bool generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing, + std::string& pixelHLSL, std::string& vertexHLSL, + FragmentShader *fragmentShader, VertexShader *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, + std::vector<LinkedVarying> *linkedVaryings, + std::map<int, VariableLocation> *programOutputVars) const; + + std::string generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const; + void getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const; + + static const std::string VERTEX_ATTRIBUTE_STUB_STRING; + + private: + DISALLOW_COPY_AND_ASSIGN(DynamicHLSL); + + rx::Renderer *const mRenderer; + + std::string generateVaryingHLSL(VertexShader *shader, const std::string &varyingSemantic, + std::vector<LinkedVarying> *linkedVaryings) const; + void defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const; + std::string generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const; + + // Prepend an underscore + static std::string decorateVariable(const std::string &name); + + std::string generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const ShaderVariable &shaderAttrib) const; +}; + +// Utility method shared between ProgramBinary and DynamicHLSL +std::string ArrayString(unsigned int i); + +} + +#endif // LIBGLESV2_DYNAMIC_HLSL_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/Fence.cpp b/chromium/third_party/angle/src/libGLESv2/Fence.cpp index e4218bbeec2..31d149d629f 100644 --- a/chromium/third_party/angle/src/libGLESv2/Fence.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Fence.cpp @@ -7,46 +7,187 @@ // Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension. +// Important note on accurate timers in Windows: +// +// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call +// as timeGetTime on laptops and "jumping" during certain hardware events. +// +// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" +// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc +// +// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer +// from buggy implementations. + #include "libGLESv2/Fence.h" #include "libGLESv2/renderer/FenceImpl.h" #include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/main.h" namespace gl { -Fence::Fence(rx::Renderer *renderer) +FenceNV::FenceNV(rx::Renderer *renderer) { mFence = renderer->createFence(); } -Fence::~Fence() +FenceNV::~FenceNV() { delete mFence; } -GLboolean Fence::isFence() +GLboolean FenceNV::isFence() const +{ + // GL_NV_fence spec: + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. + return (mFence->isSet() ? GL_TRUE : GL_FALSE); +} + +void FenceNV::setFence(GLenum condition) +{ + mFence->set(); + + mCondition = condition; + mStatus = GL_FALSE; +} + +GLboolean FenceNV::testFence() +{ + // Flush the command buffer by default + bool result = mFence->test(true); + + mStatus = (result ? GL_TRUE : GL_FALSE); + return mStatus; +} + +void FenceNV::finishFence() +{ + ASSERT(mFence->isSet()); + + while (!mFence->test(true)) + { + Sleep(0); + } +} + +GLint FenceNV::getFencei(GLenum pname) +{ + ASSERT(mFence->isSet()); + + switch (pname) + { + case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + if (mStatus == GL_TRUE) + { + return GL_TRUE; + } + + mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE); + return mStatus; + } + + case GL_FENCE_CONDITION_NV: + return mCondition; + + default: UNREACHABLE(); return 0; + } +} + +FenceSync::FenceSync(rx::Renderer *renderer, GLuint id) + : RefCountObject(id) { - return mFence->isFence(); + mFence = renderer->createFence(); + + LARGE_INTEGER counterFreqency = { 0 }; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + mCounterFrequency = counterFreqency.QuadPart; +} + +FenceSync::~FenceSync() +{ + delete mFence; } -void Fence::setFence(GLenum condition) +void FenceSync::set(GLenum condition) { - mFence->setFence(condition); + mCondition = condition; + mFence->set(); } -GLboolean Fence::testFence() +GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout) { - return mFence->testFence(); + ASSERT(mFence->isSet()); + + bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); + + if (mFence->test(flushCommandBuffer)) + { + return GL_ALREADY_SIGNALED; + } + + if (mFence->hasError()) + { + return GL_WAIT_FAILED; + } + + if (timeout == 0) + { + return GL_TIMEOUT_EXPIRED; + } + + LARGE_INTEGER currentCounter = { 0 }; + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll); + LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + + while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer)) + { + Sleep(0); + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + } + + if (mFence->hasError()) + { + return GL_WAIT_FAILED; + } + + if (currentCounter.QuadPart >= endCounter) + { + return GL_TIMEOUT_EXPIRED; + } + + return GL_CONDITION_SATISFIED; } -void Fence::finishFence() +void FenceSync::serverWait() { - mFence->finishFence(); + // Because our API is currently designed to be called from a single thread, we don't need to do + // extra work for a server-side fence. GPU commands issued after the fence is created will always + // be processed after the fence is signaled. } -void Fence::getFenceiv(GLenum pname, GLint *params) +GLenum FenceSync::getStatus() const { - mFence->getFenceiv(pname, params); + if (mFence->test(false)) + { + // The spec does not specify any way to report errors during the status test (e.g. device lost) + // so we report the fence is unblocked in case of error or signaled. + return GL_SIGNALED; + } + + return GL_UNSIGNALED; } } diff --git a/chromium/third_party/angle/src/libGLESv2/Fence.h b/chromium/third_party/angle/src/libGLESv2/Fence.h index 1cedebb112d..291edb3de12 100644 --- a/chromium/third_party/angle/src/libGLESv2/Fence.h +++ b/chromium/third_party/angle/src/libGLESv2/Fence.h @@ -10,6 +10,7 @@ #define LIBGLESV2_FENCE_H_ #include "common/angleutils.h" +#include "common/RefCountObject.h" namespace rx { @@ -20,22 +21,50 @@ class FenceImpl; namespace gl { -class Fence +class FenceNV { public: - explicit Fence(rx::Renderer *renderer); - virtual ~Fence(); + explicit FenceNV(rx::Renderer *renderer); + virtual ~FenceNV(); - GLboolean isFence(); + GLboolean isFence() const; void setFence(GLenum condition); GLboolean testFence(); void finishFence(); - void getFenceiv(GLenum pname, GLint *params); + GLint getFencei(GLenum pname); + + GLboolean getStatus() const { return mStatus; } + GLuint getCondition() const { return mCondition; } private: - DISALLOW_COPY_AND_ASSIGN(Fence); + DISALLOW_COPY_AND_ASSIGN(FenceNV); rx::FenceImpl *mFence; + + GLboolean mStatus; + GLenum mCondition; +}; + +class FenceSync : public RefCountObject +{ + public: + explicit FenceSync(rx::Renderer *renderer, GLuint id); + virtual ~FenceSync(); + + void set(GLenum condition); + GLenum clientWait(GLbitfield flags, GLuint64 timeout); + void serverWait(); + GLenum getStatus() const; + + GLuint getCondition() const { return mCondition; } + + private: + DISALLOW_COPY_AND_ASSIGN(FenceSync); + + rx::FenceImpl *mFence; + LONGLONG mCounterFrequency; + + GLenum mCondition; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/Framebuffer.cpp b/chromium/third_party/angle/src/libGLESv2/Framebuffer.cpp index b0abba0ac44..b78419fc40a 100644 --- a/chromium/third_party/angle/src/libGLESv2/Framebuffer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Framebuffer.cpp @@ -11,7 +11,8 @@ #include "libGLESv2/Framebuffer.h" #include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/Texture.h" #include "libGLESv2/Context.h" #include "libGLESv2/renderer/Renderer.h" @@ -25,91 +26,171 @@ Framebuffer::Framebuffer(rx::Renderer *renderer) { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - mColorbufferTypes[colorAttachment] = GL_NONE; mDrawBufferStates[colorAttachment] = GL_NONE; } mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; mReadBufferState = GL_COLOR_ATTACHMENT0_EXT; - - mDepthbufferType = GL_NONE; - mStencilbufferType = GL_NONE; } Framebuffer::~Framebuffer() { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - mColorbufferPointers[colorAttachment].set(NULL); + mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0); } - mDepthbufferPointer.set(NULL); - mStencilbufferPointer.set(NULL); + mDepthbuffer.set(NULL, GL_NONE, 0, 0); + mStencilbuffer.set(NULL, GL_NONE, 0, 0); } -Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const +FramebufferAttachment *Framebuffer::lookupAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const { gl::Context *context = gl::getContext(); - Renderbuffer *buffer = NULL; - if (type == GL_NONE) - { - buffer = NULL; - } - else if (type == GL_RENDERBUFFER) + switch (type) { - buffer = context->getRenderbuffer(handle); + case GL_NONE: + return NULL; + + case GL_RENDERBUFFER: + return context->getRenderbuffer(handle); + + case GL_TEXTURE_2D: + { + Texture *texture = context->getTexture(handle); + if (texture && texture->getTarget() == GL_TEXTURE_2D) + { + return static_cast<Texture2D*>(texture)->getAttachment(level); + } + else + { + return NULL; + } + } + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + Texture *texture = context->getTexture(handle); + if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP) + { + return static_cast<TextureCubeMap*>(texture)->getAttachment(type, level); + } + else + { + return NULL; + } + } + + case GL_TEXTURE_3D: + { + Texture *texture = context->getTexture(handle); + if (texture && texture->getTarget() == GL_TEXTURE_3D) + { + return static_cast<Texture3D*>(texture)->getAttachment(level, layer); + } + else + { + return NULL; + } + } + + case GL_TEXTURE_2D_ARRAY: + { + Texture *texture = context->getTexture(handle); + if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY) + { + return static_cast<Texture2DArray*>(texture)->getAttachment(level, layer); + } + else + { + return NULL; + } + } + + default: + UNREACHABLE(); + return NULL; } - else if (IsInternalTextureTarget(type)) +} + +void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer) +{ + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); + FramebufferAttachment *attachment = lookupAttachment(type, colorbuffer, level, layer); + if (attachment) { - buffer = context->getTexture(handle)->getRenderbuffer(type); + mColorbuffers[colorAttachment].set(attachment, type, level, layer); } else { - UNREACHABLE(); + mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0); } - - return buffer; } -void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer) +void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) { - ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - mColorbufferTypes[colorAttachment] = (colorbuffer != 0) ? type : GL_NONE; - mColorbufferPointers[colorAttachment].set(lookupRenderbuffer(type, colorbuffer)); + FramebufferAttachment *attachment = lookupAttachment(type, depthbuffer, level, layer); + if (attachment) + { + mDepthbuffer.set(attachment, type, level, layer); + } + else + { + mDepthbuffer.set(NULL, GL_NONE, 0, 0); + } } -void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer) +void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) { - mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; - mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer)); + FramebufferAttachment *attachment = lookupAttachment(type, stencilbuffer, level, layer); + if (attachment) + { + mStencilbuffer.set(attachment, type, level, layer); + } + else + { + mStencilbuffer.set(NULL, GL_NONE, 0, 0); + } } -void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer) +void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer) { - mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; - mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer)); + FramebufferAttachment *attachment = lookupAttachment(type, depthStencilBuffer, level, layer); + if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0) + { + mDepthbuffer.set(attachment, type, level, layer); + mStencilbuffer.set(attachment, type, level, layer); + } + else + { + mDepthbuffer.set(NULL, GL_NONE, 0, 0); + mStencilbuffer.set(NULL, GL_NONE, 0, 0); + } } void Framebuffer::detachTexture(GLuint texture) { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - if (mColorbufferPointers[colorAttachment].id() == texture && IsInternalTextureTarget(mColorbufferTypes[colorAttachment])) + if (mColorbuffers[colorAttachment].id() == texture && + IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion())) { - mColorbufferTypes[colorAttachment] = GL_NONE; - mColorbufferPointers[colorAttachment].set(NULL); + mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0); } } - if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType)) + if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion())) { - mDepthbufferType = GL_NONE; - mDepthbufferPointer.set(NULL); + mDepthbuffer.set(NULL, GL_NONE, 0, 0); } - if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType)) + if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion())) { - mStencilbufferType = GL_NONE; - mStencilbufferPointer.set(NULL); + mStencilbuffer.set(NULL, GL_NONE, 0, 0); } } @@ -117,23 +198,20 @@ void Framebuffer::detachRenderbuffer(GLuint renderbuffer) { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - if (mColorbufferPointers[colorAttachment].id() == renderbuffer && mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER) + if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER) { - mColorbufferTypes[colorAttachment] = GL_NONE; - mColorbufferPointers[colorAttachment].set(NULL); + mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0); } } - if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER) + if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER) { - mDepthbufferType = GL_NONE; - mDepthbufferPointer.set(NULL); + mDepthbuffer.set(NULL, GL_NONE, 0, 0); } - if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER) + if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER) { - mStencilbufferType = GL_NONE; - mStencilbufferPointer.set(NULL); + mStencilbuffer.set(NULL, GL_NONE, 0, 0); } } @@ -141,7 +219,7 @@ unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) co { ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - Renderbuffer *colorbuffer = mColorbufferPointers[colorAttachment].get(); + FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get(); if (colorbuffer) { @@ -153,7 +231,7 @@ unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) co unsigned int Framebuffer::getDepthbufferSerial() const { - Renderbuffer *depthbuffer = mDepthbufferPointer.get(); + FramebufferAttachment *depthbuffer = mDepthbuffer.get(); if (depthbuffer) { @@ -165,7 +243,7 @@ unsigned int Framebuffer::getDepthbufferSerial() const unsigned int Framebuffer::getStencilbufferSerial() const { - Renderbuffer *stencilbuffer = mStencilbufferPointer.get(); + FramebufferAttachment *stencilbuffer = mStencilbuffer.get(); if (stencilbuffer) { @@ -175,53 +253,58 @@ unsigned int Framebuffer::getStencilbufferSerial() const return 0; } -Renderbuffer *Framebuffer::getColorbuffer(unsigned int colorAttachment) const +FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const { ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - return mColorbufferPointers[colorAttachment].get(); + return mColorbuffers[colorAttachment].get(); } -Renderbuffer *Framebuffer::getDepthbuffer() const +FramebufferAttachment *Framebuffer::getDepthbuffer() const { - return mDepthbufferPointer.get(); + return mDepthbuffer.get(); } -Renderbuffer *Framebuffer::getStencilbuffer() const +FramebufferAttachment *Framebuffer::getStencilbuffer() const { - return mStencilbufferPointer.get(); + return mStencilbuffer.get(); } -Renderbuffer *Framebuffer::getDepthOrStencilbuffer() const +FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const { - Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get(); + return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL; +} + +FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const +{ + FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get(); if (!depthstencilbuffer) { - depthstencilbuffer = mStencilbufferPointer.get(); + depthstencilbuffer = mStencilbuffer.get(); } return depthstencilbuffer; } -Renderbuffer *Framebuffer::getReadColorbuffer() const +FramebufferAttachment *Framebuffer::getReadColorbuffer() const { // Will require more logic if glReadBuffers is supported - return mColorbufferPointers[0].get(); + return mColorbuffers[0].get(); } GLenum Framebuffer::getReadColorbufferType() const { // Will require more logic if glReadBuffers is supported - return mColorbufferTypes[0]; + return mColorbuffers[0].type(); } -Renderbuffer *Framebuffer::getFirstColorbuffer() const +FramebufferAttachment *Framebuffer::getFirstColorbuffer() const { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - if (mColorbufferTypes[colorAttachment] != GL_NONE) + if (mColorbuffers[colorAttachment].type() != GL_NONE) { - return mColorbufferPointers[colorAttachment].get(); + return mColorbuffers[colorAttachment].get(); } } @@ -231,33 +314,85 @@ Renderbuffer *Framebuffer::getFirstColorbuffer() const GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const { ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - return mColorbufferTypes[colorAttachment]; + return mColorbuffers[colorAttachment].type(); } GLenum Framebuffer::getDepthbufferType() const { - return mDepthbufferType; + return mDepthbuffer.type(); } GLenum Framebuffer::getStencilbufferType() const { - return mStencilbufferType; + return mStencilbuffer.type(); +} + +GLenum Framebuffer::getDepthStencilbufferType() const +{ + return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE; } GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const { ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - return mColorbufferPointers[colorAttachment].id(); + return mColorbuffers[colorAttachment].id(); } GLuint Framebuffer::getDepthbufferHandle() const { - return mDepthbufferPointer.id(); + return mDepthbuffer.id(); } GLuint Framebuffer::getStencilbufferHandle() const { - return mStencilbufferPointer.id(); + return mStencilbuffer.id(); +} + +GLenum Framebuffer::getDepthStencilbufferHandle() const +{ + return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0; +} + +GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const +{ + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); + return mColorbuffers[colorAttachment].mipLevel(); +} + +GLenum Framebuffer::getDepthbufferMipLevel() const +{ + return mDepthbuffer.mipLevel(); +} + +GLenum Framebuffer::getStencilbufferMipLevel() const +{ + return mStencilbuffer.mipLevel(); +} + +GLenum Framebuffer::getDepthStencilbufferMipLevel() const +{ + return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0; +} + +GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const +{ + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); + return mColorbuffers[colorAttachment].layer(); +} + +GLenum Framebuffer::getDepthbufferLayer() const +{ + return mDepthbuffer.layer(); +} + +GLenum Framebuffer::getStencilbufferLayer() const +{ + return mStencilbuffer.layer(); +} + +GLenum Framebuffer::getDepthStencilbufferLayer() const +{ + return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0; } GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const @@ -272,7 +407,7 @@ void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBu bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const { - return (mColorbufferTypes[colorAttachment] != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE); + return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE); } bool Framebuffer::hasEnabledColorAttachment() const @@ -290,9 +425,9 @@ bool Framebuffer::hasEnabledColorAttachment() const bool Framebuffer::hasStencil() const { - if (mStencilbufferType != GL_NONE) + if (mStencilbuffer.type() != GL_NONE) { - const Renderbuffer *stencilbufferObject = getStencilbuffer(); + const FramebufferAttachment *stencilbufferObject = getStencilbuffer(); if (stencilbufferObject) { @@ -320,15 +455,16 @@ GLenum Framebuffer::completeness() const { int width = 0; int height = 0; - int colorbufferSize = 0; + unsigned int colorbufferSize = 0; int samples = -1; bool missingAttachment = true; + GLuint clientVersion = mRenderer->getCurrentClientVersion(); for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - if (mColorbufferTypes[colorAttachment] != GL_NONE) + if (mColorbuffers[colorAttachment].type() != GL_NONE) { - const Renderbuffer *colorbuffer = getColorbuffer(colorAttachment); + const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment); if (!colorbuffer) { @@ -340,35 +476,24 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER) + if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER) { - if (!gl::IsColorRenderable(colorbuffer->getInternalFormat())) + if (!gl::IsColorRenderingSupported(colorbuffer->getInternalFormat(), mRenderer)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - else if (IsInternalTextureTarget(mColorbufferTypes[colorAttachment])) + else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion())) { - GLint internalformat = colorbuffer->getInternalFormat(); - GLenum format = gl::ExtractFormat(internalformat); + GLenum internalformat = colorbuffer->getInternalFormat(); - if (IsCompressed(format) || - format == GL_ALPHA || - format == GL_LUMINANCE || - format == GL_LUMINANCE_ALPHA) + if (!gl::IsColorRenderingSupported(internalformat, mRenderer)) { return GL_FRAMEBUFFER_UNSUPPORTED; } - bool filtering, renderable; - - if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) || - (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable))) - { - return GL_FRAMEBUFFER_UNSUPPORTED; - } - - if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat)) + if (gl::GetDepthBits(internalformat, clientVersion) > 0 || + gl::GetStencilBits(internalformat, clientVersion) > 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -394,16 +519,20 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT; } - // all color attachments attachments must have the same number of bitplanes - if (gl::ComputePixelSize(colorbuffer->getInternalFormat()) != colorbufferSize) + // in GLES 2.0, all color attachments attachments must have the same number of bitplanes + // in GLES 3.0, there is no such restriction + if (clientVersion < 3) { - return GL_FRAMEBUFFER_UNSUPPORTED; + if (gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion) != colorbufferSize) + { + return GL_FRAMEBUFFER_UNSUPPORTED; + } } // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++) { - if (mColorbufferPointers[colorAttachment].get() == mColorbufferPointers[previousColorAttachment].get()) + if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get()) { return GL_FRAMEBUFFER_UNSUPPORTED; } @@ -414,16 +543,16 @@ GLenum Framebuffer::completeness() const width = colorbuffer->getWidth(); height = colorbuffer->getHeight(); samples = colorbuffer->getSamples(); - colorbufferSize = gl::ComputePixelSize(colorbuffer->getInternalFormat()); + colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat(), clientVersion); missingAttachment = false; } } } - const Renderbuffer *depthbuffer = NULL; - const Renderbuffer *stencilbuffer = NULL; + const FramebufferAttachment *depthbuffer = NULL; + const FramebufferAttachment *stencilbuffer = NULL; - if (mDepthbufferType != GL_NONE) + if (mDepthbuffer.type() != GL_NONE) { depthbuffer = getDepthbuffer(); @@ -437,16 +566,16 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (mDepthbufferType == GL_RENDERBUFFER) + if (mDepthbuffer.type() == GL_RENDERBUFFER) { - if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat())) + if (!gl::IsDepthRenderingSupported(depthbuffer->getInternalFormat(), mRenderer)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - else if (IsInternalTextureTarget(mDepthbufferType)) + else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion())) { - GLint internalformat = depthbuffer->getInternalFormat(); + GLenum internalformat = depthbuffer->getInternalFormat(); // depth texture attachments require OES/ANGLE_depth_texture if (!mRenderer->getDepthTextureSupport()) @@ -454,7 +583,7 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (!gl::IsDepthTexture(internalformat)) + if (gl::GetDepthBits(internalformat, clientVersion) == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -482,7 +611,7 @@ GLenum Framebuffer::completeness() const } } - if (mStencilbufferType != GL_NONE) + if (mStencilbuffer.type() != GL_NONE) { stencilbuffer = getStencilbuffer(); @@ -496,16 +625,16 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (mStencilbufferType == GL_RENDERBUFFER) + if (mStencilbuffer.type() == GL_RENDERBUFFER) { - if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat())) + if (!gl::IsStencilRenderingSupported(stencilbuffer->getInternalFormat(), mRenderer)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - else if (IsInternalTextureTarget(mStencilbufferType)) + else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion())) { - GLint internalformat = stencilbuffer->getInternalFormat(); + GLenum internalformat = stencilbuffer->getInternalFormat(); // texture stencil attachments come along as part // of OES_packed_depth_stencil + OES/ANGLE_depth_texture @@ -514,7 +643,7 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (!gl::IsStencilTexture(internalformat)) + if (gl::GetStencilBits(internalformat, clientVersion) == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -561,15 +690,11 @@ GLenum Framebuffer::completeness() const DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) : Framebuffer(renderer) { - mColorbufferPointers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer)); - - Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil); - mDepthbufferPointer.set(depthStencilRenderbuffer); - mStencilbufferPointer.set(depthStencilRenderbuffer); + mColorbuffers[0].set(new FramebufferAttachment(mRenderer, 0, colorbuffer), GL_RENDERBUFFER, 0, 0); - mColorbufferTypes[0] = GL_RENDERBUFFER; - mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE; - mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE; + FramebufferAttachment *depthStencilRenderbuffer = new FramebufferAttachment(mRenderer, 0, depthStencil); + mDepthbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0); + mStencilbuffer.set(depthStencilRenderbuffer, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0); mDrawBufferStates[0] = GL_BACK; mReadBufferState = GL_BACK; @@ -583,7 +708,7 @@ int Framebuffer::getSamples() const // in this case return the first nonzero sample size for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { - if (mColorbufferTypes[colorAttachment] != GL_NONE) + if (mColorbuffers[colorAttachment].type() != GL_NONE) { return getColorbuffer(colorAttachment)->getSamples(); } diff --git a/chromium/third_party/angle/src/libGLESv2/Framebuffer.h b/chromium/third_party/angle/src/libGLESv2/Framebuffer.h index 50bfd4fd0f8..1a5e2b6801c 100644 --- a/chromium/third_party/angle/src/libGLESv2/Framebuffer.h +++ b/chromium/third_party/angle/src/libGLESv2/Framebuffer.h @@ -12,7 +12,7 @@ #include "common/angleutils.h" #include "common/RefCountObject.h" -#include "Constants.h" +#include "constants.h" namespace rx { @@ -21,7 +21,7 @@ class Renderer; namespace gl { -class Renderbuffer; +class FramebufferAttachment; class Colorbuffer; class Depthbuffer; class Stencilbuffer; @@ -34,9 +34,10 @@ class Framebuffer virtual ~Framebuffer(); - void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer); - void setDepthbuffer(GLenum type, GLuint depthbuffer); - void setStencilbuffer(GLenum type, GLuint stencilbuffer); + void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer); + void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer); + void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer); + void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer); void detachTexture(GLuint texture); void detachRenderbuffer(GLuint renderbuffer); @@ -45,21 +46,34 @@ class Framebuffer unsigned int getDepthbufferSerial() const; unsigned int getStencilbufferSerial() const; - Renderbuffer *getColorbuffer(unsigned int colorAttachment) const; - Renderbuffer *getDepthbuffer() const; - Renderbuffer *getStencilbuffer() const; - Renderbuffer *getDepthOrStencilbuffer() const; - Renderbuffer *getReadColorbuffer() const; + FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const; + FramebufferAttachment *getDepthbuffer() const; + FramebufferAttachment *getStencilbuffer() const; + FramebufferAttachment *getDepthStencilBuffer() const; + FramebufferAttachment *getDepthOrStencilbuffer() const; + FramebufferAttachment *getReadColorbuffer() const; GLenum getReadColorbufferType() const; - Renderbuffer *getFirstColorbuffer() const; + FramebufferAttachment *getFirstColorbuffer() const; GLenum getColorbufferType(unsigned int colorAttachment) const; GLenum getDepthbufferType() const; GLenum getStencilbufferType() const; + GLenum getDepthStencilbufferType() const; GLuint getColorbufferHandle(unsigned int colorAttachment) const; GLuint getDepthbufferHandle() const; GLuint getStencilbufferHandle() const; + GLenum getDepthStencilbufferHandle() const; + + GLenum getColorbufferMipLevel(unsigned int colorAttachment) const; + GLenum getDepthbufferMipLevel() const; + GLenum getStencilbufferMipLevel() const; + GLenum getDepthStencilbufferMipLevel() const; + + GLenum getColorbufferLayer(unsigned int colorAttachment) const; + GLenum getDepthbufferLayer() const; + GLenum getStencilbufferLayer() const; + GLenum getDepthStencilbufferLayer() const; GLenum getDrawBufferState(unsigned int colorAttachment) const; void setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer); @@ -73,23 +87,19 @@ class Framebuffer virtual GLenum completeness() const; protected: - GLenum mColorbufferTypes[IMPLEMENTATION_MAX_DRAW_BUFFERS]; - BindingPointer<Renderbuffer> mColorbufferPointers[IMPLEMENTATION_MAX_DRAW_BUFFERS]; + FramebufferTextureBindingPointer<FramebufferAttachment> mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS]; GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS]; GLenum mReadBufferState; - GLenum mDepthbufferType; - BindingPointer<Renderbuffer> mDepthbufferPointer; - - GLenum mStencilbufferType; - BindingPointer<Renderbuffer> mStencilbufferPointer; + FramebufferTextureBindingPointer<FramebufferAttachment> mDepthbuffer; + FramebufferTextureBindingPointer<FramebufferAttachment> mStencilbuffer; rx::Renderer *mRenderer; private: DISALLOW_COPY_AND_ASSIGN(Framebuffer); - Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const; + FramebufferAttachment *lookupAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const; }; class DefaultFramebuffer : public Framebuffer diff --git a/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.cpp b/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.cpp new file mode 100644 index 00000000000..574ce7ee912 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.cpp @@ -0,0 +1,491 @@ +#include "precompiled.h" +// +// Copyright (c) 2014 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. +// + +// FramebufferAttachment.cpp: the gl::FramebufferAttachment class and its derived classes +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/renderer/RenderTarget.h" + +#include "libGLESv2/Texture.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/TextureStorage.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Renderbuffer.h" + +namespace gl +{ + +FramebufferAttachmentInterface::FramebufferAttachmentInterface() +{ +} + +// The default case for classes inherited from FramebufferAttachmentInterface is not to +// need to do anything upon the reference count to the parent FramebufferAttachment incrementing +// or decrementing. +void FramebufferAttachmentInterface::addProxyRef(const FramebufferAttachment *proxy) +{ +} + +void FramebufferAttachmentInterface::releaseProxy(const FramebufferAttachment *proxy) +{ +} + +///// Texture2DAttachment Implementation //////// + +Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level) +{ + mTexture2D.set(texture); +} + +Texture2DAttachment::~Texture2DAttachment() +{ + mTexture2D.set(NULL); +} + +// Textures need to maintain their own reference count for references via +// Renderbuffers acting as proxies. Here, we notify the texture of a reference. +void Texture2DAttachment::addProxyRef(const FramebufferAttachment *proxy) +{ + mTexture2D->addProxyRef(proxy); +} + +void Texture2DAttachment::releaseProxy(const FramebufferAttachment *proxy) +{ + mTexture2D->releaseProxy(proxy); +} + +rx::RenderTarget *Texture2DAttachment::getRenderTarget() +{ + return mTexture2D->getRenderTarget(mLevel); +} + +rx::RenderTarget *Texture2DAttachment::getDepthStencil() +{ + return mTexture2D->getDepthSencil(mLevel); +} + +rx::TextureStorage *Texture2DAttachment::getTextureStorage() +{ + return mTexture2D->getNativeTexture()->getStorageInstance(); +} + +GLsizei Texture2DAttachment::getWidth() const +{ + return mTexture2D->getWidth(mLevel); +} + +GLsizei Texture2DAttachment::getHeight() const +{ + return mTexture2D->getHeight(mLevel); +} + +GLenum Texture2DAttachment::getInternalFormat() const +{ + return mTexture2D->getInternalFormat(mLevel); +} + +GLenum Texture2DAttachment::getActualFormat() const +{ + return mTexture2D->getActualFormat(mLevel); +} + +GLsizei Texture2DAttachment::getSamples() const +{ + return 0; +} + +unsigned int Texture2DAttachment::getSerial() const +{ + return mTexture2D->getRenderTargetSerial(mLevel); +} + +bool Texture2DAttachment::isTexture() const +{ + return true; +} + +unsigned int Texture2DAttachment::getTextureSerial() const +{ + return mTexture2D->getTextureSerial(); +} + +///// TextureCubeMapAttachment Implementation //////// + +TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level) + : mFaceTarget(faceTarget), mLevel(level) +{ + mTextureCubeMap.set(texture); +} + +TextureCubeMapAttachment::~TextureCubeMapAttachment() +{ + mTextureCubeMap.set(NULL); +} + +// Textures need to maintain their own reference count for references via +// Renderbuffers acting as proxies. Here, we notify the texture of a reference. +void TextureCubeMapAttachment::addProxyRef(const FramebufferAttachment *proxy) +{ + mTextureCubeMap->addProxyRef(proxy); +} + +void TextureCubeMapAttachment::releaseProxy(const FramebufferAttachment *proxy) +{ + mTextureCubeMap->releaseProxy(proxy); +} + +rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget() +{ + return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel); +} + +rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil() +{ + return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel); +} + +rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage() +{ + return mTextureCubeMap->getNativeTexture()->getStorageInstance(); +} + +GLsizei TextureCubeMapAttachment::getWidth() const +{ + return mTextureCubeMap->getWidth(mFaceTarget, mLevel); +} + +GLsizei TextureCubeMapAttachment::getHeight() const +{ + return mTextureCubeMap->getHeight(mFaceTarget, mLevel); +} + +GLenum TextureCubeMapAttachment::getInternalFormat() const +{ + return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel); +} + +GLenum TextureCubeMapAttachment::getActualFormat() const +{ + return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel); +} + +GLsizei TextureCubeMapAttachment::getSamples() const +{ + return 0; +} + +unsigned int TextureCubeMapAttachment::getSerial() const +{ + return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel); +} + +bool TextureCubeMapAttachment::isTexture() const +{ + return true; +} + +unsigned int TextureCubeMapAttachment::getTextureSerial() const +{ + return mTextureCubeMap->getTextureSerial(); +} + +///// Texture3DAttachment Implementation //////// + +Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer) + : mLevel(level), mLayer(layer) +{ + mTexture3D.set(texture); +} + +Texture3DAttachment::~Texture3DAttachment() +{ + mTexture3D.set(NULL); +} + +// Textures need to maintain their own reference count for references via +// Renderbuffers acting as proxies. Here, we notify the texture of a reference. +void Texture3DAttachment::addProxyRef(const FramebufferAttachment *proxy) +{ + mTexture3D->addProxyRef(proxy); +} + +void Texture3DAttachment::releaseProxy(const FramebufferAttachment *proxy) +{ + mTexture3D->releaseProxy(proxy); +} + +rx::RenderTarget *Texture3DAttachment::getRenderTarget() +{ + return mTexture3D->getRenderTarget(mLevel, mLayer); +} + +rx::RenderTarget *Texture3DAttachment::getDepthStencil() +{ + return mTexture3D->getDepthStencil(mLevel, mLayer); +} + +rx::TextureStorage *Texture3DAttachment::getTextureStorage() +{ + return mTexture3D->getNativeTexture()->getStorageInstance(); +} + +GLsizei Texture3DAttachment::getWidth() const +{ + return mTexture3D->getWidth(mLevel); +} + +GLsizei Texture3DAttachment::getHeight() const +{ + return mTexture3D->getHeight(mLevel); +} + +GLenum Texture3DAttachment::getInternalFormat() const +{ + return mTexture3D->getInternalFormat(mLevel); +} + +GLenum Texture3DAttachment::getActualFormat() const +{ + return mTexture3D->getActualFormat(mLevel); +} + +GLsizei Texture3DAttachment::getSamples() const +{ + return 0; +} + +unsigned int Texture3DAttachment::getSerial() const +{ + return mTexture3D->getRenderTargetSerial(mLevel, mLayer); +} + +bool Texture3DAttachment::isTexture() const +{ + return true; +} + +unsigned int Texture3DAttachment::getTextureSerial() const +{ + return mTexture3D->getTextureSerial(); +} + +////// Texture2DArrayAttachment Implementation ////// + +Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer) + : mLevel(level), mLayer(layer) +{ + mTexture2DArray.set(texture); +} + +Texture2DArrayAttachment::~Texture2DArrayAttachment() +{ + mTexture2DArray.set(NULL); +} + +void Texture2DArrayAttachment::addProxyRef(const FramebufferAttachment *proxy) +{ + mTexture2DArray->addProxyRef(proxy); +} + +void Texture2DArrayAttachment::releaseProxy(const FramebufferAttachment *proxy) +{ + mTexture2DArray->releaseProxy(proxy); +} + +rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget() +{ + return mTexture2DArray->getRenderTarget(mLevel, mLayer); +} + +rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil() +{ + return mTexture2DArray->getDepthStencil(mLevel, mLayer); +} + +rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage() +{ + return mTexture2DArray->getNativeTexture()->getStorageInstance(); +} + +GLsizei Texture2DArrayAttachment::getWidth() const +{ + return mTexture2DArray->getWidth(mLevel); +} + +GLsizei Texture2DArrayAttachment::getHeight() const +{ + return mTexture2DArray->getHeight(mLevel); +} + +GLenum Texture2DArrayAttachment::getInternalFormat() const +{ + return mTexture2DArray->getInternalFormat(mLevel); +} + +GLenum Texture2DArrayAttachment::getActualFormat() const +{ + return mTexture2DArray->getActualFormat(mLevel); +} + +GLsizei Texture2DArrayAttachment::getSamples() const +{ + return 0; +} + +unsigned int Texture2DArrayAttachment::getSerial() const +{ + return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer); +} + +bool Texture2DArrayAttachment::isTexture() const +{ + return true; +} + +unsigned int Texture2DArrayAttachment::getTextureSerial() const +{ + return mTexture2DArray->getTextureSerial(); +} + +////// FramebufferAttachment Implementation ////// + +FramebufferAttachment::FramebufferAttachment(rx::Renderer *renderer, GLuint id, FramebufferAttachmentInterface *instance) : RefCountObject(id) +{ + ASSERT(instance != NULL); + mInstance = instance; + + ASSERT(renderer != NULL); + mRenderer = renderer; +} + +FramebufferAttachment::~FramebufferAttachment() +{ + delete mInstance; +} + +// The FramebufferAttachmentInterface contained in this FramebufferAttachment may need to maintain +// its own reference count, so we pass it on here. +void FramebufferAttachment::addRef() const +{ + mInstance->addProxyRef(this); + + RefCountObject::addRef(); +} + +void FramebufferAttachment::release() const +{ + mInstance->releaseProxy(this); + + RefCountObject::release(); +} + +rx::RenderTarget *FramebufferAttachment::getRenderTarget() +{ + return mInstance->getRenderTarget(); +} + +rx::RenderTarget *FramebufferAttachment::getDepthStencil() +{ + return mInstance->getDepthStencil(); +} + +rx::TextureStorage *FramebufferAttachment::getTextureStorage() +{ + return mInstance->getTextureStorage(); +} + +GLsizei FramebufferAttachment::getWidth() const +{ + return mInstance->getWidth(); +} + +GLsizei FramebufferAttachment::getHeight() const +{ + return mInstance->getHeight(); +} + +GLenum FramebufferAttachment::getInternalFormat() const +{ + return mInstance->getInternalFormat(); +} + +GLenum FramebufferAttachment::getActualFormat() const +{ + return mInstance->getActualFormat(); +} + +GLuint FramebufferAttachment::getRedSize() const +{ + return gl::GetRedBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLuint FramebufferAttachment::getGreenSize() const +{ + return gl::GetGreenBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLuint FramebufferAttachment::getBlueSize() const +{ + return gl::GetBlueBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLuint FramebufferAttachment::getAlphaSize() const +{ + return gl::GetAlphaBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLuint FramebufferAttachment::getDepthSize() const +{ + return gl::GetDepthBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLuint FramebufferAttachment::getStencilSize() const +{ + return gl::GetStencilBits(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLenum FramebufferAttachment::getComponentType() const +{ + return gl::GetComponentType(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLenum FramebufferAttachment::getColorEncoding() const +{ + return gl::GetColorEncoding(getActualFormat(), mRenderer->getCurrentClientVersion()); +} + +GLsizei FramebufferAttachment::getSamples() const +{ + return mInstance->getSamples(); +} + +unsigned int FramebufferAttachment::getSerial() const +{ + return mInstance->getSerial(); +} + +bool FramebufferAttachment::isTexture() const +{ + return mInstance->isTexture(); +} + +unsigned int FramebufferAttachment::getTextureSerial() const +{ + return mInstance->getTextureSerial(); +} + +void FramebufferAttachment::setStorage(RenderbufferStorage *newStorage) +{ + ASSERT(newStorage != NULL); + + delete mInstance; + mInstance = newStorage; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.h b/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.h new file mode 100644 index 00000000000..9ba63cc3aac --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/FramebufferAttachment.h @@ -0,0 +1,247 @@ +// +// Copyright (c) 2014 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. +// + +// FramebufferAttachment.h: Defines the wrapper class gl::FramebufferAttachment, as well as the +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. + +#ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_ +#define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_ + +#include <GLES3/gl3.h> +#include <GLES2/gl2.h> + +#include "common/angleutils.h" +#include "common/RefCountObject.h" + +namespace rx +{ +class Renderer; +class RenderTarget; +class TextureStorage; +} + +namespace gl +{ +class Texture2D; +class TextureCubeMap; +class Texture3D; +class Texture2DArray; +class FramebufferAttachment; +class FramebufferAttachmentInterface; +class RenderbufferStorage; + +// FramebufferAttachment implements the GL renderbuffer object. +// It's only a proxy for a FramebufferAttachmentInterface instance; the internal object +// can change whenever glRenderbufferStorage is called. +class FramebufferAttachment : public RefCountObject +{ + public: + FramebufferAttachment(rx::Renderer *renderer, GLuint id, FramebufferAttachmentInterface *storage); + + virtual ~FramebufferAttachment(); + + // These functions from RefCountObject are overloaded here because + // Textures need to maintain their own count of references to them via + // Renderbuffers/RenderbufferTextures. These functions invoke those + // reference counting functions on the FramebufferAttachmentInterface. + void addRef() const; + void release() const; + + rx::RenderTarget *getRenderTarget(); + rx::RenderTarget *getDepthStencil(); + rx::TextureStorage *getTextureStorage(); + + GLsizei getWidth() const; + GLsizei getHeight() const; + GLenum getInternalFormat() const; + GLenum getActualFormat() const; + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + GLenum getComponentType() const; + GLenum getColorEncoding() const; + GLsizei getSamples() const; + + unsigned int getSerial() const; + + bool isTexture() const; + unsigned int getTextureSerial() const; + + void setStorage(RenderbufferStorage *newStorage); + + private: + DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment); + + rx::Renderer const *mRenderer; + FramebufferAttachmentInterface *mInstance; +}; + +class FramebufferAttachmentInterface +{ + public: + FramebufferAttachmentInterface(); + + virtual ~FramebufferAttachmentInterface() {}; + + virtual void addProxyRef(const FramebufferAttachment *proxy); + virtual void releaseProxy(const FramebufferAttachment *proxy); + + virtual rx::RenderTarget *getRenderTarget() = 0; + virtual rx::RenderTarget *getDepthStencil() = 0; + virtual rx::TextureStorage *getTextureStorage() = 0; + + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getActualFormat() const = 0; + virtual GLsizei getSamples() const = 0; + + virtual unsigned int getSerial() const = 0; + + virtual bool isTexture() const = 0; + virtual unsigned int getTextureSerial() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(FramebufferAttachmentInterface); +}; + +class Texture2DAttachment : public FramebufferAttachmentInterface +{ + public: + Texture2DAttachment(Texture2D *texture, GLint level); + + virtual ~Texture2DAttachment(); + + void addProxyRef(const FramebufferAttachment *proxy); + void releaseProxy(const FramebufferAttachment *proxy); + + rx::RenderTarget *getRenderTarget(); + rx::RenderTarget *getDepthStencil(); + rx::TextureStorage *getTextureStorage(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual GLenum getActualFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + virtual bool isTexture() const; + virtual unsigned int getTextureSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Texture2DAttachment); + + BindingPointer <Texture2D> mTexture2D; + const GLint mLevel; +}; + +class TextureCubeMapAttachment : public FramebufferAttachmentInterface +{ + public: + TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level); + + virtual ~TextureCubeMapAttachment(); + + void addProxyRef(const FramebufferAttachment *proxy); + void releaseProxy(const FramebufferAttachment *proxy); + + rx::RenderTarget *getRenderTarget(); + rx::RenderTarget *getDepthStencil(); + rx::TextureStorage *getTextureStorage(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual GLenum getActualFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + virtual bool isTexture() const; + virtual unsigned int getTextureSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment); + + BindingPointer <TextureCubeMap> mTextureCubeMap; + const GLint mLevel; + const GLenum mFaceTarget; +}; + +class Texture3DAttachment : public FramebufferAttachmentInterface +{ + public: + Texture3DAttachment(Texture3D *texture, GLint level, GLint layer); + + virtual ~Texture3DAttachment(); + + void addProxyRef(const FramebufferAttachment *proxy); + void releaseProxy(const FramebufferAttachment *proxy); + + rx::RenderTarget *getRenderTarget(); + rx::RenderTarget *getDepthStencil(); + rx::TextureStorage *getTextureStorage(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual GLenum getActualFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + virtual bool isTexture() const; + virtual unsigned int getTextureSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Texture3DAttachment); + + BindingPointer<Texture3D> mTexture3D; + const GLint mLevel; + const GLint mLayer; +}; + +class Texture2DArrayAttachment : public FramebufferAttachmentInterface +{ + public: + Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer); + + virtual ~Texture2DArrayAttachment(); + + void addProxyRef(const FramebufferAttachment *proxy); + void releaseProxy(const FramebufferAttachment *proxy); + + rx::RenderTarget *getRenderTarget(); + rx::RenderTarget *getDepthStencil(); + rx::TextureStorage *getTextureStorage(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual GLenum getActualFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + virtual bool isTexture() const; + virtual unsigned int getTextureSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Texture2DArrayAttachment); + + BindingPointer<Texture2DArray> mTexture2DArray; + const GLint mLevel; + const GLint mLayer; +}; + +} + +#endif // LIBGLESV2_FRAMEBUFFERATTACHMENT_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/HandleAllocator.h b/chromium/third_party/angle/src/libGLESv2/HandleAllocator.h index a92e1684d4f..e23010d918b 100644 --- a/chromium/third_party/angle/src/libGLESv2/HandleAllocator.h +++ b/chromium/third_party/angle/src/libGLESv2/HandleAllocator.h @@ -10,7 +10,7 @@ #ifndef LIBGLESV2_HANDLEALLOCATOR_H_ #define LIBGLESV2_HANDLEALLOCATOR_H_ -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include <vector> diff --git a/chromium/third_party/angle/src/libGLESv2/Program.cpp b/chromium/third_party/angle/src/libGLESv2/Program.cpp index c38aa5a61aa..8a9fb048007 100644 --- a/chromium/third_party/angle/src/libGLESv2/Program.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Program.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -95,32 +95,36 @@ void InfoLog::append(const char *format, ...) return; } - char info[1024]; - va_list vararg; va_start(vararg, format); - vsnprintf(info, sizeof(info), format, vararg); + size_t infoLength = vsnprintf(NULL, 0, format, vararg); va_end(vararg); - size_t infoLength = strlen(info); + char *logPointer = NULL; if (!mInfoLog) { mInfoLog = new char[infoLength + 2]; - strcpy(mInfoLog, info); - strcpy(mInfoLog + infoLength, "\n"); + logPointer = mInfoLog; } else { - size_t logLength = strlen(mInfoLog); - char *newLog = new char[logLength + infoLength + 2]; + size_t currentlogLength = strlen(mInfoLog); + char *newLog = new char[currentlogLength + infoLength + 2]; strcpy(newLog, mInfoLog); - strcpy(newLog + logLength, info); - strcpy(newLog + logLength + infoLength, "\n"); delete[] mInfoLog; mInfoLog = newLog; + + logPointer = mInfoLog + currentlogLength; } + + va_start(vararg, format); + vsnprintf(logPointer, infoLength, format, vararg); + va_end(vararg); + + logPointer[infoLength] = 0; + strcpy(logPointer + infoLength, "\n"); } void InfoLog::reset() @@ -141,6 +145,8 @@ Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle mLinked = false; mRefCount = 0; mRenderer = renderer; + + resetUniformBlockBindings(); } Program::~Program() @@ -243,9 +249,11 @@ bool Program::link() unlink(false); mInfoLog.reset(); + resetUniformBlockBindings(); mProgramBinary.set(new ProgramBinary(mRenderer)); - mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader); + mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader, + mTransformFeedbackVaryings, mTransformFeedbackBufferMode); return mLinked; } @@ -290,7 +298,7 @@ bool Program::isLinked() return mLinked; } -ProgramBinary* Program::getProgramBinary() +ProgramBinary* Program::getProgramBinary() const { return mProgramBinary.get(); } @@ -522,4 +530,132 @@ bool Program::isValidated() const } } +GLint Program::getActiveUniformBlockCount() +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary) + { + return static_cast<GLint>(programBinary->getActiveUniformBlockCount()); + } + else + { + return 0; + } +} + +GLint Program::getActiveUniformBlockMaxLength() +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary) + { + return static_cast<GLint>(programBinary->getActiveUniformBlockMaxLength()); + } + else + { + return 0; + } +} + +void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; +} + +GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const +{ + return mUniformBlockBindings[uniformBlockIndex]; +} + +void Program::resetUniformBlockBindings() +{ + for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++) + { + mUniformBlockBindings[blockId] = 0; + } +} + +void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode) +{ + mTransformFeedbackVaryings.resize(count); + for (GLsizei i = 0; i < count; i++) + { + mTransformFeedbackVaryings[i] = varyings[i]; + } + + mTransformFeedbackBufferMode = bufferMode; +} + +void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary && index < programBinary->getTransformFeedbackVaryingCount()) + { + const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(index); + GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length())); + if (length) + { + *length = lastNameIdx; + } + if (size) + { + *size = varying.size; + } + if (type) + { + *type = varying.type; + } + if (name) + { + memcpy(name, varying.name.c_str(), lastNameIdx); + name[lastNameIdx] = '\0'; + } + } +} + +GLsizei Program::getTransformFeedbackVaryingCount() const +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary) + { + return static_cast<GLsizei>(programBinary->getTransformFeedbackVaryingCount()); + } + else + { + return 0; + } +} + +GLsizei Program::getTransformFeedbackVaryingMaxLength() const +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary) + { + GLsizei maxSize = 0; + for (size_t i = 0; i < programBinary->getTransformFeedbackVaryingCount(); i++) + { + const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(i); + maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1)); + } + + return maxSize; + } + else + { + return 0; + } +} + +GLenum Program::getTransformFeedbackBufferMode() const +{ + ProgramBinary *programBinary = getProgramBinary(); + if (programBinary) + { + return programBinary->getTransformFeedbackBufferMode(); + } + else + { + return mTransformFeedbackBufferMode; + } +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/Program.h b/chromium/third_party/angle/src/libGLESv2/Program.h index a9db83403d9..7576be43c0f 100644 --- a/chromium/third_party/angle/src/libGLESv2/Program.h +++ b/chromium/third_party/angle/src/libGLESv2/Program.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -78,7 +78,7 @@ class Program bool link(); bool isLinked(); bool setProgramBinary(const void *binary, GLsizei length); - ProgramBinary *getProgramBinary(); + ProgramBinary *getProgramBinary() const; int getInfoLogLength() const; void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); @@ -92,6 +92,18 @@ class Program GLint getActiveUniformCount(); GLint getActiveUniformMaxLength(); + GLint getActiveUniformBlockCount(); + GLint getActiveUniformBlockMaxLength(); + + void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; + + void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); + void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; + GLsizei getTransformFeedbackVaryingCount() const; + GLsizei getTransformFeedbackVaryingMaxLength() const; + GLenum getTransformFeedbackBufferMode() const; + void addRef(); void release(); unsigned int getRefCount() const; @@ -107,12 +119,18 @@ class Program DISALLOW_COPY_AND_ASSIGN(Program); void unlink(bool destroy = false); + void resetUniformBlockBindings(); FragmentShader *mFragmentShader; VertexShader *mVertexShader; AttributeBindings mAttributeBindings; + GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; + + std::vector<std::string> mTransformFeedbackVaryings; + GLuint mTransformFeedbackBufferMode; + BindingPointer<ProgramBinary> mProgramBinary; bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use diff --git a/chromium/third_party/angle/src/libGLESv2/ProgramBinary.cpp b/chromium/third_party/angle/src/libGLESv2/ProgramBinary.cpp index ee0ec8e03f1..e3ffa47964a 100644 --- a/chromium/third_party/angle/src/libGLESv2/ProgramBinary.cpp +++ b/chromium/third_party/angle/src/libGLESv2/ProgramBinary.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -14,46 +14,135 @@ #include "common/debug.h" #include "common/version.h" -#include "utilities.h" +#include "common/utilities.h" #include "libGLESv2/main.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/VertexDataManager.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/DynamicHLSL.h" +#include "common/blocklayout.h" #undef near #undef far namespace gl { -std::string str(int i) + +namespace +{ + +unsigned int ParseAndStripArrayIndex(std::string* name) { - char buffer[20]; - snprintf(buffer, sizeof(buffer), "%d", i); - return buffer; + unsigned int subscript = GL_INVALID_INDEX; + + // Strip any trailing array operator and retrieve the subscript + size_t open = name->find_last_of('['); + size_t close = name->find_last_of(']'); + if (open != std::string::npos && close == name->length() - 1) + { + subscript = atoi(name->substr(open + 1).c_str()); + name->erase(open); + } + + return subscript; } -static rx::D3DWorkaroundType DiscardWorkaround(bool usesDiscard) +void GetInputLayoutFromShader(const std::vector<gl::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) { - return (usesDiscard ? rx::ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER : rx::ANGLE_D3D_WORKAROUND_NONE); + size_t layoutIndex = 0; + for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + { + ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS); + + const gl::Attribute &shaderAttr = shaderAttributes[attributeIndex]; + + if (shaderAttr.type != GL_NONE) + { + GLenum transposedType = TransposeMatrixType(shaderAttr.type); + + for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++) + { + VertexFormat *defaultFormat = &inputLayout[layoutIndex]; + + defaultFormat->mType = UniformComponentType(transposedType); + defaultFormat->mNormalized = false; + defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool + defaultFormat->mComponents = VariableColumnCount(transposedType); + } + } + } } -UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) +} + +VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index) { } -unsigned int ProgramBinary::mCurrentSerial = 1; +ProgramBinary::VertexExecutable::VertexExecutable(rx::Renderer *const renderer, + const VertexFormat inputLayout[], + const GLenum signature[], + rx::ShaderExecutable *shaderExecutable) + : mShaderExecutable(shaderExecutable) +{ + for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + mInputs[attributeIndex] = inputLayout[attributeIndex]; + mSignature[attributeIndex] = signature[attributeIndex]; + } +} + +ProgramBinary::VertexExecutable::~VertexExecutable() +{ + delete mShaderExecutable; +} + +bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const +{ + for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + if (mSignature[attributeIndex] != signature[attributeIndex]) + { + return false; + } + } + + return true; +} -ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial()) +LinkedVarying::LinkedVarying() { - mPixelExecutable = NULL; - mVertexExecutable = NULL; - mGeometryExecutable = NULL; +} - mValidated = false; +LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, + unsigned int semanticIndex, unsigned int semanticIndexCount) + : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount) +{ +} +unsigned int ProgramBinary::mCurrentSerial = 1; + +ProgramBinary::ProgramBinary(rx::Renderer *renderer) + : RefCountObject(0), + mRenderer(renderer), + mDynamicHLSL(NULL), + mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), + mPixelExecutable(NULL), + mGeometryExecutable(NULL), + mUsedVertexSamplerRange(0), + mUsedPixelSamplerRange(0), + mUsesPointSize(false), + mShaderVersion(100), + mVertexUniformStorage(NULL), + mFragmentUniformStorage(NULL), + mValidated(false), + mSerial(issueSerial()) +{ for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) { mSemanticIndex[index] = -1; @@ -69,27 +158,35 @@ ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefC mSamplersVS[index].active = false; } - mUsedVertexSamplerRange = 0; - mUsedPixelSamplerRange = 0; - mUsesPointSize = false; + mDynamicHLSL = new DynamicHLSL(renderer); } ProgramBinary::~ProgramBinary() { - delete mPixelExecutable; - mPixelExecutable = NULL; - - delete mVertexExecutable; - mVertexExecutable = NULL; + while (!mVertexExecutables.empty()) + { + delete mVertexExecutables.back(); + mVertexExecutables.pop_back(); + } - delete mGeometryExecutable; - mGeometryExecutable = NULL; + SafeDelete(mGeometryExecutable); + SafeDelete(mPixelExecutable); while (!mUniforms.empty()) { delete mUniforms.back(); mUniforms.pop_back(); } + + while (!mUniformBlocks.empty()) + { + delete mUniformBlocks.back(); + mUniformBlocks.pop_back(); + } + + SafeDelete(mVertexUniformStorage); + SafeDelete(mFragmentUniformStorage); + SafeDelete(mDynamicHLSL); } unsigned int ProgramBinary::getSerial() const @@ -97,22 +194,65 @@ unsigned int ProgramBinary::getSerial() const return mSerial; } +int ProgramBinary::getShaderVersion() const +{ + return mShaderVersion; +} + unsigned int ProgramBinary::issueSerial() { return mCurrentSerial++; } -rx::ShaderExecutable *ProgramBinary::getPixelExecutable() +rx::ShaderExecutable *ProgramBinary::getPixelExecutable() const { return mPixelExecutable; } -rx::ShaderExecutable *ProgramBinary::getVertexExecutable() +rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) { - return mVertexExecutable; + GLenum signature[MAX_VERTEX_ATTRIBS]; + mDynamicHLSL->getInputLayoutSignature(inputLayout, signature); + + for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + { + if (mVertexExecutables[executableIndex]->matchesSignature(signature)) + { + return mVertexExecutables[executableIndex]->shaderExecutable(); + } + } + + // Generate new dynamic layout with attribute conversions + const std::string &layoutHLSL = mDynamicHLSL->generateInputLayoutHLSL(inputLayout, mShaderAttributes); + + // Generate new shader source by replacing the attributes stub with the defined input layout + std::string vertexHLSL = mVertexHLSL; + size_t insertPos = vertexHLSL.find(DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING); + vertexHLSL.replace(insertPos, DynamicHLSL::VERTEX_ATTRIBUTE_STUB_STRING.length(), layoutHLSL); + + // Generate new vertex executable + InfoLog tempInfoLog; + rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, vertexHLSL.c_str(), + rx::SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + mVertexWorkarounds); + + if (!vertexExecutable) + { + std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3); + tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); + } + else + { + mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, signature, vertexExecutable)); + } + + return vertexExecutable; } -rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() +rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const { return mGeometryExecutable; } @@ -136,7 +276,7 @@ GLuint ProgramBinary::getAttributeLocation(const char *name) int ProgramBinary::getSemanticIndex(int attributeIndex) { ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); - + return mSemanticIndex[attributeIndex]; } @@ -227,402 +367,352 @@ TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int GLint ProgramBinary::getUniformLocation(std::string name) { - unsigned int subscript = 0; - - // Strip any trailing array operator and retrieve the subscript - size_t open = name.find_last_of('['); - size_t close = name.find_last_of(']'); - if (open != std::string::npos && close == name.length() - 1) - { - subscript = atoi(name.substr(open + 1).c_str()); - name.erase(open); - } + unsigned int subscript = ParseAndStripArrayIndex(&name); unsigned int numUniforms = mUniformIndex.size(); for (unsigned int location = 0; location < numUniforms; location++) { - if (mUniformIndex[location].name == name && - mUniformIndex[location].element == subscript) + if (mUniformIndex[location].name == name) { - return location; + const int index = mUniformIndex[location].index; + const bool isArray = mUniforms[index]->isArray(); + + if ((isArray && mUniformIndex[location].element == subscript) || + (subscript == GL_INVALID_INDEX)) + { + return location; + } } } return -1; } -bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) +GLuint ProgramBinary::getUniformIndex(std::string name) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; + unsigned int subscript = ParseAndStripArrayIndex(&name); - int elementCount = targetUniform->elementCount(); - - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == GL_FLOAT) + // The app is not allowed to specify array indices other than 0 for arrays of basic types + if (subscript != 0 && subscript != GL_INVALID_INDEX) { - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = 0; - target[2] = 0; - target[3] = 0; - target += 4; - v += 1; - } + return GL_INVALID_INDEX; } - else if (targetUniform->type == GL_BOOL) - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - for (int i = 0; i < count; i++) + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + if (mUniforms[index]->name == name) { - boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[1] = GL_FALSE; - boolParams[2] = GL_FALSE; - boolParams[3] = GL_FALSE; - boolParams += 4; - v += 1; + if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) + { + return index; + } } } - else - { - return false; - } - return true; + return GL_INVALID_INDEX; } -bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +GLuint ProgramBinary::getUniformBlockIndex(std::string name) { - if (location < 0 || location >= (int)mUniformIndex.size()) + unsigned int subscript = ParseAndStripArrayIndex(&name); + + unsigned int numUniformBlocks = mUniformBlocks.size(); + for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) { - return false; + const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; + if (uniformBlock.name == name) + { + const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); + if (subscript == uniformBlock.elementIndex || arrayElementZero) + { + return blockIndex; + } + } } - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - int elementCount = targetUniform->elementCount(); + return GL_INVALID_INDEX; +} - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION +UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex) +{ + ASSERT(blockIndex < mUniformBlocks.size()); + return mUniformBlocks[blockIndex]; +} - count = std::min(elementCount - (int)mUniformIndex[location].element, count); +GLint ProgramBinary::getFragDataLocation(const char *name) const +{ + std::string baseName(name); + unsigned int arrayIndex; + arrayIndex = ParseAndStripArrayIndex(&baseName); - if (targetUniform->type == GL_FLOAT_VEC2) + for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++) { - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + const VariableLocation &outputVariable = locationIt->second; - for (int i = 0; i < count; i++) + if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element)) { - target[0] = v[0]; - target[1] = v[1]; - target[2] = 0; - target[3] = 0; - target += 4; - v += 2; + return static_cast<GLint>(locationIt->first); } } - else if (targetUniform->type == GL_BOOL_VEC2) - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - for (int i = 0; i < count; i++) - { - boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[2] = GL_FALSE; - boolParams[3] = GL_FALSE; - boolParams += 4; - v += 2; - } - } - else - { - return false; - } + return -1; +} - return true; +size_t ProgramBinary::getTransformFeedbackVaryingCount() const +{ + return mTransformFeedbackLinkedVaryings.size(); } -bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } + return mTransformFeedbackLinkedVaryings[idx]; +} - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; +GLenum ProgramBinary::getTransformFeedbackBufferMode() const +{ + return mTransformFeedbackBufferMode; +} - int elementCount = targetUniform->elementCount(); +template <typename T> +static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) +{ + ASSERT(dest != NULL); + ASSERT(dirtyFlag != NULL); + + *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); + *dest = source; +} - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION +template <typename T> +void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) +{ + const int components = UniformComponentCount(targetUniformType); + const GLenum targetBoolType = UniformBoolVectorType(targetUniformType); + + LinkedUniform *targetUniform = getUniformByLocation(location); + + int elementCount = targetUniform->elementCount(); count = std::min(elementCount - (int)mUniformIndex[location].element, count); - if (targetUniform->type == GL_FLOAT_VEC3) + if (targetUniform->type == targetUniformType) { - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + T *target = (T*)targetUniform->data + mUniformIndex[location].element * 4; for (int i = 0; i < count; i++) { - target[0] = v[0]; - target[1] = v[1]; - target[2] = v[2]; - target[3] = 0; + for (int c = 0; c < components; c++) + { + SetIfDirty(target + c, v[c], &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(target + c, T(0), &targetUniform->dirty); + } target += 4; - v += 3; + v += components; } } - else if (targetUniform->type == GL_BOOL_VEC3) + else if (targetUniform->type == targetBoolType) { GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; for (int i = 0; i < count; i++) { - boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[3] = GL_FALSE; + for (int c = 0; c < components; c++) + { + SetIfDirty(boolParams + c, (v[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(boolParams + c, GL_FALSE, &targetUniform->dirty); + } boolParams += 4; - v += 3; + v += components; } } - else - { - return false; - } - - return true; + else UNREACHABLE(); } -bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } + setUniform(location, count, v, GL_FLOAT); +} - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; +void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC2); +} - int elementCount = targetUniform->elementCount(); +void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC3); +} - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION +void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC4); +} - count = std::min(elementCount - (int)mUniformIndex[location].element, count); +template<typename T> +bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetHeight, srcWidth); + int copyHeight = std::min(targetWidth, srcHeight); - if (targetUniform->type == GL_FLOAT_VEC4) + for (int x = 0; x < copyWidth; x++) { - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) + for (int y = 0; y < copyHeight; y++) { - target[0] = v[0]; - target[1] = v[1]; - target[2] = v[2]; - target[3] = v[3]; - target += 4; - v += 4; + SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty); } } - else if (targetUniform->type == GL_BOOL_VEC4) + // clear unfilled right side + for (int y = 0; y < copyWidth; y++) { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) + for (int x = copyHeight; x < targetWidth; x++) { - boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE; - boolParams += 4; - v += 4; + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); } } - else + // clear unfilled bottom. + for (int y = copyWidth; y < targetHeight; y++) { - return false; + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); + } } - return true; + return dirty; } -template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight> -void transposeMatrix(T *target, const GLfloat *value) +template<typename T> +bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) { + bool dirty = false; int copyWidth = std::min(targetWidth, srcWidth); int copyHeight = std::min(targetHeight, srcHeight); - for (int x = 0; x < copyWidth; x++) + for (int y = 0; y < copyHeight; y++) { - for (int y = 0; y < copyHeight; y++) + for (int x = 0; x < copyWidth; x++) { - target[x * targetWidth + y] = (T)value[y * srcWidth + x]; + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty); } } // clear unfilled right side for (int y = 0; y < copyHeight; y++) { - for (int x = srcWidth; x < targetWidth; x++) + for (int x = copyWidth; x < targetWidth; x++) { - target[y * targetWidth + x] = (T)0; + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); } } // clear unfilled bottom. - for (int y = srcHeight; y < targetHeight; y++) + for (int y = copyHeight; y < targetHeight; y++) { for (int x = 0; x < targetWidth; x++) { - target[y * targetWidth + x] = (T)0; + SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); } } + + return dirty; } -bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) +template <int cols, int rows> +void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type != GL_FLOAT_MAT2) - { - return false; - } + LinkedUniform *targetUniform = getUniformByLocation(location); int elementCount = targetUniform->elementCount(); - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8; + const unsigned int targetMatrixStride = (4 * rows); + GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); for (int i = 0; i < count; i++) { - transposeMatrix<GLfloat,4,2,2,2>(target, value); - target += 8; - value += 4; + // Internally store matrices as transposed versions to accomodate HLSL matrix indexing + if (transpose == GL_FALSE) + { + targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty; + } + else + { + targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty; + } + target += targetMatrixStride; + value += cols * rows; } - - return true; } -bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) +void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type != GL_FLOAT_MAT3) - { - return false; - } - - int elementCount = targetUniform->elementCount(); - - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12; - - for (int i = 0; i < count; i++) - { - transposeMatrix<GLfloat,4,3,3,3>(target, value); - target += 12; - value += 9; - } - - return true; + setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); } - -bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) +void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; + setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); +} - if (targetUniform->type != GL_FLOAT_MAT4) - { - return false; - } +void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); +} - int elementCount = targetUniform->elementCount(); +void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); +} - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION +void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); +} - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16); +void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); +} - for (int i = 0; i < count; i++) - { - transposeMatrix<GLfloat,4,4,4,4>(target, value); - target += 16; - value += 16; - } +void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); +} - return true; +void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); } -bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) +void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } + setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); +} - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; +void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; int elementCount = targetUniform->elementCount(); - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - if (targetUniform->type == GL_INT || - targetUniform->type == GL_SAMPLER_2D || - targetUniform->type == GL_SAMPLER_CUBE) + if (targetUniform->type == GL_INT || IsSampler(targetUniform->type)) { GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; for (int i = 0; i < count; i++) { - target[0] = v[0]; - target[1] = 0; - target[2] = 0; - target[3] = 0; + SetIfDirty(target + 0, v[0], &targetUniform->dirty); + SetIfDirty(target + 1, 0, &targetUniform->dirty); + SetIfDirty(target + 2, 0, &targetUniform->dirty); + SetIfDirty(target + 3, 0, &targetUniform->dirty); target += 4; v += 1; } @@ -633,189 +723,56 @@ bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) for (int i = 0; i < count; i++) { - boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; - boolParams[1] = GL_FALSE; - boolParams[2] = GL_FALSE; - boolParams[3] = GL_FALSE; + SetIfDirty(boolParams + 0, (v[0] == 0) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); + SetIfDirty(boolParams + 1, GL_FALSE, &targetUniform->dirty); + SetIfDirty(boolParams + 2, GL_FALSE, &targetUniform->dirty); + SetIfDirty(boolParams + 3, GL_FALSE, &targetUniform->dirty); boolParams += 4; v += 1; } } - else - { - return false; - } - - return true; + else UNREACHABLE(); } -bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) +void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - int elementCount = targetUniform->elementCount(); - - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == GL_INT_VEC2) - { - GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = v[1]; - target[2] = 0; - target[3] = 0; - target += 4; - v += 2; - } - } - else if (targetUniform->type == GL_BOOL_VEC2) - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; - boolParams[2] = GL_FALSE; - boolParams[3] = GL_FALSE; - boolParams += 4; - v += 2; - } - } - else - { - return false; - } - - return true; + setUniform(location, count, v, GL_INT_VEC2); } -bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) +void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - int elementCount = targetUniform->elementCount(); - - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == GL_INT_VEC3) - { - GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = v[1]; - target[2] = v[2]; - target[3] = 0; - target += 4; - v += 3; - } - } - else if (targetUniform->type == GL_BOOL_VEC3) - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; - boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE; - boolParams[3] = GL_FALSE; - boolParams += 4; - v += 3; - } - } - else - { - return false; - } - - return true; + setUniform(location, count, v, GL_INT_VEC3); } -bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) +void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - int elementCount = targetUniform->elementCount(); - - if (elementCount == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == GL_INT_VEC4) - { - GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + setUniform(location, count, v, GL_INT_VEC4); +} - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = v[1]; - target[2] = v[2]; - target[3] = v[3]; - target += 4; - v += 4; - } - } - else if (targetUniform->type == GL_BOOL_VEC4) - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; +void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT); +} - for (int i = 0; i < count; i++) - { - boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; - boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; - boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE; - boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE; - boolParams += 4; - v += 4; - } - } - else - { - return false; - } +void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); +} - return true; +void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); } -bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) +void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } + setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); +} - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; +template <typename T> +bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType) +{ + LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; // sized queries -- ensure the provided buffer is large enough if (bufSize) @@ -827,123 +784,89 @@ bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *para } } - switch (targetUniform->type) + if (IsMatrixType(targetUniform->type)) { - case GL_FLOAT_MAT2: - transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); - break; - case GL_FLOAT_MAT3: - transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); - break; - case GL_FLOAT_MAT4: - transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); - break; - default: + const int rows = VariableRowCount(targetUniform->type); + const int cols = VariableColumnCount(targetUniform->type); + transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); + } + else if (uniformType == UniformComponentType(targetUniform->type)) + { + unsigned int size = UniformComponentCount(targetUniform->type); + memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), + size * sizeof(T)); + } + else + { + unsigned int size = UniformComponentCount(targetUniform->type); + switch (UniformComponentType(targetUniform->type)) { - unsigned int size = UniformComponentCount(targetUniform->type); - - switch (UniformComponentType(targetUniform->type)) + case GL_BOOL: { - case GL_BOOL: - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - for (unsigned int i = 0; i < size; i++) - { - params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; - } - } - break; - case GL_FLOAT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLfloat), - size * sizeof(GLfloat)); - break; - case GL_INT: + for (unsigned int i = 0; i < size; i++) { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = (float)intParams[i]; - } + params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1); } - break; - default: UNREACHABLE(); } - } - } - - return true; -} + break; -bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } + case GL_FLOAT: + { + GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast<T>(floatParams[i]); + } + } + break; - // sized queries -- ensure the provided buffer is large enough - if (bufSize) - { - int requiredBytes = UniformExternalSize(targetUniform->type); - if (*bufSize < requiredBytes) - { - return false; - } - } + case GL_INT: + { + GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - switch (targetUniform->type) - { - case GL_FLOAT_MAT2: - transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); - break; - case GL_FLOAT_MAT3: - transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); - break; - case GL_FLOAT_MAT4: - transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); - break; - default: - { - unsigned int size = VariableColumnCount(targetUniform->type); + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast<T>(intParams[i]); + } + } + break; - switch (UniformComponentType(targetUniform->type)) + case GL_UNSIGNED_INT: { - case GL_BOOL: - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; - for (unsigned int i = 0; i < size; i++) - { - params[i] = boolParams[i]; - } - } - break; - case GL_FLOAT: + for (unsigned int i = 0; i < size; i++) { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = (GLint)floatParams[i]; - } + params[i] = static_cast<T>(uintParams[i]); } - break; - case GL_INT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLint), - size * sizeof(GLint)); - break; - default: UNREACHABLE(); } + break; + + default: UNREACHABLE(); } } return true; } +bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) +{ + return getUniformv(location, bufSize, params, GL_FLOAT); +} + +bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) +{ + return getUniformv(location, bufSize, params, GL_INT); +} + +bool ProgramBinary::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params) +{ + return getUniformv(location, bufSize, params, GL_UNSIGNED_INT); +} + void ProgramBinary::dirtyAllUniforms() { unsigned int numUniforms = mUniforms.size(); @@ -957,19 +880,18 @@ void ProgramBinary::dirtyAllUniforms() void ProgramBinary::applyUniforms() { // Retrieve sampler uniform values - for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { - Uniform *targetUniform = *ub; + LinkedUniform *targetUniform = mUniforms[uniformIndex]; if (targetUniform->dirty) { - if (targetUniform->type == GL_SAMPLER_2D || - targetUniform->type == GL_SAMPLER_CUBE) + if (IsSampler(targetUniform->type)) { int count = targetUniform->elementCount(); GLint (*v)[4] = (GLint(*)[4])targetUniform->data; - if (targetUniform->psRegisterIndex >= 0) + if (targetUniform->isReferencedByFragmentShader()) { unsigned int firstIndex = targetUniform->psRegisterIndex; @@ -985,7 +907,7 @@ void ProgramBinary::applyUniforms() } } - if (targetUniform->vsRegisterIndex >= 0) + if (targetUniform->isReferencedByVertexShader()) { unsigned int firstIndex = targetUniform->vsRegisterIndex; @@ -1004,214 +926,80 @@ void ProgramBinary::applyUniforms() } } - mRenderer->applyUniforms(this, &mUniforms); -} - -// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 -// Returns the number of used varying registers, or -1 if unsuccesful -int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader) -{ - const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); + mRenderer->applyUniforms(*this); - fragmentShader->resetVaryingsRegisterAssignment(); - - for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { - int n = VariableRowCount(varying->type) * varying->size; - int m = VariableColumnCount(varying->type); - bool success = false; - - if (m == 2 || m == 3 || m == 4) - { - for (int r = 0; r <= maxVaryingVectors - n && !success; r++) - { - bool available = true; - - for (int y = 0; y < n && available; y++) - { - for (int x = 0; x < m && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } - - if (available) - { - varying->reg = r; - varying->col = 0; - - for (int y = 0; y < n; y++) - { - for (int x = 0; x < m; x++) - { - packing[r + y][x] = &*varying; - } - } + mUniforms[uniformIndex]->dirty = false; + } +} - success = true; - } - } +bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers) +{ + const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; + const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; - if (!success && m == 2) - { - for (int r = maxVaryingVectors - n; r >= 0 && !success; r--) - { - bool available = true; + const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers(); + const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers(); - for (int y = 0; y < n && available; y++) - { - for (int x = 2; x < 4 && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } + ASSERT(boundBuffers.size() == mUniformBlocks.size()); - if (available) - { - varying->reg = r; - varying->col = 2; + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) + { + gl::UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex); + gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; - for (int y = 0; y < n; y++) - { - for (int x = 2; x < 4; x++) - { - packing[r + y][x] = &*varying; - } - } + ASSERT(uniformBlock && uniformBuffer); - success = true; - } - } - } - } - else if (m == 1) + if (uniformBuffer->size() < uniformBlock->dataSize) { - int space[4] = {0}; - - for (int y = 0; y < maxVaryingVectors; y++) - { - for (int x = 0; x < 4; x++) - { - space[x] += packing[y][x] ? 0 : 1; - } - } - - int column = 0; - - for (int x = 0; x < 4; x++) - { - if (space[x] >= n && space[x] < space[column]) - { - column = x; - } - } - - if (space[column] >= n) - { - for (int r = 0; r < maxVaryingVectors; r++) - { - if (!packing[r][column]) - { - varying->reg = r; - - for (int y = r; y < r + n; y++) - { - packing[y][column] = &*varying; - } - - break; - } - } - - varying->col = column; - - success = true; - } + // undefined behaviour + return false; } - else UNREACHABLE(); - if (!success) - { - infoLog.append("Could not pack varying %s", varying->name.c_str()); + ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader()); - return -1; + if (uniformBlock->isReferencedByVertexShader()) + { + unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; + ASSERT(vertexUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers()); + vertexUniformBuffers[registerIndex] = uniformBuffer; } - } - - // Return the number of used registers - int registers = 0; - for (int r = 0; r < maxVaryingVectors; r++) - { - if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) + if (uniformBlock->isReferencedByFragmentShader()) { - registers++; + unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; + ASSERT(fragmentUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers()); + fragmentUniformBuffers[registerIndex] = uniformBuffer; } } - return registers; + return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); } -bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4], - std::string& pixelHLSL, std::string& vertexHLSL, - FragmentShader *fragmentShader, VertexShader *vertexShader) +bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader) { - if (pixelHLSL.empty() || vertexHLSL.empty()) - { - return false; - } + std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings(); + std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings(); - bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; - bool usesFragColor = fragmentShader->mUsesFragColor; - bool usesFragData = fragmentShader->mUsesFragData; - if (usesFragColor && usesFragData) - { - infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader."); - return false; - } - - // Write the HLSL input/output declarations - const int shaderModel = mRenderer->getMajorShaderModel(); - const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); - - const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0); - - // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor - const bool broadcast = fragmentShader->mUsesFragColor; - const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1); - - if (registersNeeded > maxVaryingVectors) - { - infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); - - return false; - } - - vertexShader->resetVaryingsRegisterAssignment(); - - for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++) + for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++) { + PackedVarying *input = &fragmentVaryings[fragVaryingIndex]; bool matched = false; - for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++) + for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++) { + PackedVarying *output = &vertexVaryings[vertVaryingIndex]; if (output->name == input->name) { - if (output->type != input->type || output->size != input->size) + if (!linkValidateVariables(infoLog, output->name, *input, *output)) { - infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); - return false; } - output->reg = input->reg; - output->col = input->col; + output->registerIndex = input->registerIndex; matched = true; break; @@ -1221,645 +1009,409 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying if (!matched) { infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str()); - return false; } } - mUsesPointSize = vertexShader->mUsesPointSize; - std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD"; - std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR"; - std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION"; - std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + return true; +} - // special varyings that use reserved registers - int reservedRegisterIndex = registers; - std::string fragCoordSemantic; - std::string pointCoordSemantic; +bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) +{ +#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD + return false; +#else + BinaryInputStream stream(binary, length); - if (fragmentShader->mUsesFragCoord) + int format = stream.readInt<int>(); + if (format != GL_PROGRAM_BINARY_ANGLE) { - fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); + infoLog.append("Invalid program binary format."); + return false; } - if (fragmentShader->mUsesPointCoord) + int majorVersion = stream.readInt<int>(); + int minorVersion = stream.readInt<int>(); + if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) { - // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords. - // In DX11 we compute this in the GS. - if (shaderModel == 3) - { - pointCoordSemantic = "TEXCOORD0"; - } - else if (shaderModel >= 4) - { - pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); - } + infoLog.append("Invalid program binary version."); + return false; } - vertexHLSL += "struct VS_INPUT\n" - "{\n"; - - int semanticIndex = 0; - for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; + stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE); + if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) { - switch (attribute->type) - { - case GL_FLOAT: vertexHLSL += " float "; break; - case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break; - case GL_FLOAT_VEC3: vertexHLSL += " float3 "; break; - case GL_FLOAT_VEC4: vertexHLSL += " float4 "; break; - case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break; - case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break; - case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break; - default: UNREACHABLE(); - } - - vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; - - semanticIndex += VariableRowCount(attribute->type); + infoLog.append("Invalid program binary version."); + return false; } - vertexHLSL += "};\n" - "\n" - "struct VS_OUTPUT\n" - "{\n"; - - if (shaderModel < 4) + int compileFlags = stream.readInt<int>(); + if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) { - vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n"; + infoLog.append("Mismatched compilation flags."); + return false; } - for (int r = 0; r < registers; r++) + for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { - int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); - - vertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; + stream.readInt(&mLinkedAttribute[i].type); + stream.readString(&mLinkedAttribute[i].name); + stream.readInt(&mShaderAttributes[i].type); + stream.readString(&mShaderAttributes[i].name); + stream.readInt(&mSemanticIndex[i]); } - if (fragmentShader->mUsesFragCoord) + initAttributesByLayout(); + + for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) { - vertexHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; + stream.readBool(&mSamplersPS[i].active); + stream.readInt(&mSamplersPS[i].logicalTextureUnit); + stream.readInt(&mSamplersPS[i].textureType); } - if (vertexShader->mUsesPointSize && shaderModel >= 3) + for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) { - vertexHLSL += " float gl_PointSize : PSIZE;\n"; + stream.readBool(&mSamplersVS[i].active); + stream.readInt(&mSamplersVS[i].logicalTextureUnit); + stream.readInt(&mSamplersVS[i].textureType); } - if (shaderModel >= 4) + stream.readInt(&mUsedVertexSamplerRange); + stream.readInt(&mUsedPixelSamplerRange); + stream.readBool(&mUsesPointSize); + stream.readInt(&mShaderVersion); + + const unsigned int uniformCount = stream.readInt<unsigned int>(); + if (stream.error()) { - vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n"; + infoLog.append("Invalid program binary."); + return false; } - vertexHLSL += "};\n" - "\n" - "VS_OUTPUT main(VS_INPUT input)\n" - "{\n"; - - for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + mUniforms.resize(uniformCount); + for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) { - vertexHLSL += " " + decorateAttribute(attribute->name) + " = "; + GLenum type = stream.readInt<GLenum>(); + GLenum precision = stream.readInt<GLenum>(); + std::string name = stream.readString(); + unsigned int arraySize = stream.readInt<unsigned int>(); + int blockIndex = stream.readInt<int>(); - if (VariableRowCount(attribute->type) > 1) // Matrix - { - vertexHLSL += "transpose"; - } + int offset = stream.readInt<int>(); + int arrayStride = stream.readInt<int>(); + int matrixStride = stream.readInt<int>(); + bool isRowMajorMatrix = stream.readBool(); - vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n"; - } + const gl::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); - if (shaderModel >= 4) - { - vertexHLSL += "\n" - " gl_main();\n" - "\n" - " VS_OUTPUT output;\n" - " output.gl_Position.x = gl_Position.x;\n" - " output.gl_Position.y = -gl_Position.y;\n" - " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" - " output.gl_Position.w = gl_Position.w;\n"; - } - else - { - vertexHLSL += "\n" - " gl_main();\n" - "\n" - " VS_OUTPUT output;\n" - " output.gl_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n" - " output.gl_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n" - " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" - " output.gl_Position.w = gl_Position.w;\n"; - } + LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); - if (vertexShader->mUsesPointSize && shaderModel >= 3) - { - vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; + stream.readInt(&uniform->psRegisterIndex); + stream.readInt(&uniform->vsRegisterIndex); + stream.readInt(&uniform->registerCount); + stream.readInt(&uniform->registerElement); + + mUniforms[uniformIndex] = uniform; } - if (fragmentShader->mUsesFragCoord) + unsigned int uniformBlockCount = stream.readInt<unsigned int>(); + if (stream.error()) { - vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; + infoLog.append("Invalid program binary."); + return false; } - for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++) + mUniformBlocks.resize(uniformBlockCount); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) { - if (varying->reg >= 0) - { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - - for (int j = 0; j < rows; j++) - { - int r = varying->reg + i * rows + j; - vertexHLSL += " output.v" + str(r); - - bool sharedRegister = false; // Register used by multiple varyings - - for (int x = 0; x < 4; x++) - { - if (packing[r][x] && packing[r][x] != packing[r][0]) - { - sharedRegister = true; - break; - } - } - - if(sharedRegister) - { - vertexHLSL += "."; - - for (int x = 0; x < 4; x++) - { - if (packing[r][x] == &*varying) - { - switch(x) - { - case 0: vertexHLSL += "x"; break; - case 1: vertexHLSL += "y"; break; - case 2: vertexHLSL += "z"; break; - case 3: vertexHLSL += "w"; break; - } - } - } - } + std::string name = stream.readString(); + unsigned int elementIndex = stream.readInt<unsigned int>(); + unsigned int dataSize = stream.readInt<unsigned int>(); - vertexHLSL += " = " + varying->name; - - if (varying->array) - { - vertexHLSL += "[" + str(i) + "]"; - } - - if (rows > 1) - { - vertexHLSL += "[" + str(j) + "]"; - } - - vertexHLSL += ";\n"; - } - } - } - } + UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize); - vertexHLSL += "\n" - " return output;\n" - "}\n"; + stream.readInt(&uniformBlock->psRegisterIndex); + stream.readInt(&uniformBlock->vsRegisterIndex); - pixelHLSL += "struct PS_INPUT\n" - "{\n"; - - for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) - { - if (varying->reg >= 0) + unsigned int numMembers = stream.readInt<unsigned int>(); + uniformBlock->memberUniformIndexes.resize(numMembers); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - for (int j = 0; j < rows; j++) - { - std::string n = str(varying->reg + i * rows + j); - pixelHLSL += " float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n"; - } - } + stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); } - else UNREACHABLE(); - } - if (fragmentShader->mUsesFragCoord) - { - pixelHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; - } - - if (fragmentShader->mUsesPointCoord && shaderModel >= 3) - { - pixelHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n"; + mUniformBlocks[uniformBlockIndex] = uniformBlock; } - // Must consume the PSIZE element if the geometry shader is not active - // We won't know if we use a GS until we draw - if (vertexShader->mUsesPointSize && shaderModel >= 4) + const unsigned int uniformIndexCount = stream.readInt<unsigned int>(); + if (stream.error()) { - pixelHLSL += " float gl_PointSize : PSIZE;\n"; + infoLog.append("Invalid program binary."); + return false; } - if (fragmentShader->mUsesFragCoord) + mUniformIndex.resize(uniformIndexCount); + for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) { - if (shaderModel >= 4) - { - pixelHLSL += " float4 dx_VPos : SV_Position;\n"; - } - else if (shaderModel >= 3) - { - pixelHLSL += " float2 dx_VPos : VPOS;\n"; - } + stream.readString(&mUniformIndex[uniformIndexIndex].name); + stream.readInt(&mUniformIndex[uniformIndexIndex].element); + stream.readInt(&mUniformIndex[uniformIndexIndex].index); } - pixelHLSL += "};\n" - "\n" - "struct PS_OUTPUT\n" - "{\n"; - - for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + stream.readInt(&mTransformFeedbackBufferMode); + const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>(); + mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); + for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) { - pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n"; - } + LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; - if (fragmentShader->mUsesFragDepth) - { - pixelHLSL += " float gl_Depth : " + depthSemantic + ";\n"; + stream.readString(&varying.name); + stream.readInt(&varying.type); + stream.readInt(&varying.size); + stream.readString(&varying.semanticName); + stream.readInt(&varying.semanticIndex); + stream.readInt(&varying.semanticIndexCount); } - pixelHLSL += "};\n" - "\n"; + stream.readString(&mVertexHLSL); - if (fragmentShader->mUsesFrontFacing) - { - if (shaderModel >= 4) - { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n" - "{\n"; - } - else - { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n" - "{\n"; - } - } - else - { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n" - "{\n"; - } + stream.readInt(&mVertexWorkarounds); - if (fragmentShader->mUsesFragCoord) + const unsigned int vertexShaderCount = stream.readInt<unsigned int>(); + + for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) { - pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; - - if (shaderModel >= 4) - { - pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n" - " gl_FragCoord.y = input.dx_VPos.y;\n"; - } - else if (shaderModel >= 3) + VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; + + for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) { - pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" - " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n"; + VertexFormat *vertexInput = &inputLayout[inputIndex]; + stream.readInt(&vertexInput->mType); + stream.readInt(&vertexInput->mNormalized); + stream.readInt(&vertexInput->mComponents); + stream.readBool(&vertexInput->mPureInteger); } - else + + unsigned int vertexShaderSize = stream.readInt<unsigned int>(); + + const char *vertexShaderFunction = (const char*) binary + stream.offset(); + + rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction), + vertexShaderSize, rx::SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); + if (!shaderExecutable) { - // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport() - pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n" - " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n"; + infoLog.append("Could not create vertex shader."); + return false; } - - pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n" - " gl_FragCoord.w = rhw;\n"; - } - if (fragmentShader->mUsesPointCoord && shaderModel >= 3) - { - pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n"; - pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; + // generated converted input layout + GLenum signature[MAX_VERTEX_ATTRIBS]; + mDynamicHLSL->getInputLayoutSignature(inputLayout, signature); + + // add new binary + mVertexExecutables.push_back(new VertexExecutable(mRenderer, inputLayout, signature, shaderExecutable)); + + stream.skip(vertexShaderSize); } - if (fragmentShader->mUsesFrontFacing) + unsigned int pixelShaderSize = stream.readInt<unsigned int>(); + + const char *pixelShaderFunction = (const char*) binary + stream.offset(); + mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction), + pixelShaderSize, rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); + if (!mPixelExecutable) { - if (shaderModel <= 3) - { - pixelHLSL += " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; - } - else - { - pixelHLSL += " gl_FrontFacing = isFrontFace;\n"; - } + infoLog.append("Could not create pixel shader."); + return false; } + stream.skip(pixelShaderSize); + + unsigned int geometryShaderSize = stream.readInt<unsigned int>(); - for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) + if (geometryShaderSize > 0) { - if (varying->reg >= 0) + const char *geometryShaderFunction = (const char*) binary + stream.offset(); + mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction), + geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); + if (!mGeometryExecutable) { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - for (int j = 0; j < rows; j++) - { - std::string n = str(varying->reg + i * rows + j); - pixelHLSL += " " + varying->name; - - if (varying->array) - { - pixelHLSL += "[" + str(i) + "]"; - } - - if (rows > 1) - { - pixelHLSL += "[" + str(j) + "]"; - } - - switch (VariableColumnCount(varying->type)) - { - case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break; - case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break; - case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break; - case 4: pixelHLSL += " = input.v" + n + ";\n"; break; - default: UNREACHABLE(); - } - } - } + infoLog.append("Could not create geometry shader."); + SafeDelete(mPixelExecutable); + return false; } - else UNREACHABLE(); + stream.skip(geometryShaderSize); } - pixelHLSL += "\n" - " gl_main();\n" - "\n" - " PS_OUTPUT output;\n"; - - for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) - { - unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex; + const char *ptr = (const char*) binary + stream.offset(); - pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n"; - } + const GUID *binaryIdentifier = (const GUID *) ptr; + ptr += sizeof(GUID); - if (fragmentShader->mUsesFragDepth) + GUID identifier = mRenderer->getAdapterIdentifier(); + if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) { - pixelHLSL += " output.gl_Depth = gl_Depth;\n"; + infoLog.append("Invalid program binary."); + return false; } - pixelHLSL += "\n" - " return output;\n" - "}\n"; + initializeUniformStorage(); return true; +#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD } -bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) +bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) { - BinaryInputStream stream(binary, length); - - int format = 0; - stream.read(&format); - if (format != GL_PROGRAM_BINARY_ANGLE) - { - infoLog.append("Invalid program binary format."); - return false; - } + BinaryOutputStream stream; - int version = 0; - stream.read(&version); - if (version != VERSION_DWORD) - { - infoLog.append("Invalid program binary version."); - return false; - } + stream.writeInt(GL_PROGRAM_BINARY_ANGLE); + stream.writeInt(ANGLE_MAJOR_VERSION); + stream.writeInt(ANGLE_MINOR_VERSION); + stream.writeBytes(reinterpret_cast<unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE); + stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL); - int compileFlags = 0; - stream.read(&compileFlags); - if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) - { - infoLog.append("Mismatched compilation flags."); - return false; - } - - for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) + for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { - stream.read(&mLinkedAttribute[i].type); - std::string name; - stream.read(&name); - mLinkedAttribute[i].name = name; - stream.read(&mSemanticIndex[i]); + stream.writeInt(mLinkedAttribute[i].type); + stream.writeString(mLinkedAttribute[i].name); + stream.writeInt(mShaderAttributes[i].type); + stream.writeString(mShaderAttributes[i].name); + stream.writeInt(mSemanticIndex[i]); } - initAttributesByLayout(); - for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) { - stream.read(&mSamplersPS[i].active); - stream.read(&mSamplersPS[i].logicalTextureUnit); - - int textureType; - stream.read(&textureType); - mSamplersPS[i].textureType = (TextureType) textureType; + stream.writeInt(mSamplersPS[i].active); + stream.writeInt(mSamplersPS[i].logicalTextureUnit); + stream.writeInt(mSamplersPS[i].textureType); } for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) { - stream.read(&mSamplersVS[i].active); - stream.read(&mSamplersVS[i].logicalTextureUnit); - - int textureType; - stream.read(&textureType); - mSamplersVS[i].textureType = (TextureType) textureType; + stream.writeInt(mSamplersVS[i].active); + stream.writeInt(mSamplersVS[i].logicalTextureUnit); + stream.writeInt(mSamplersVS[i].textureType); } - stream.read(&mUsedVertexSamplerRange); - stream.read(&mUsedPixelSamplerRange); - stream.read(&mUsesPointSize); + stream.writeInt(mUsedVertexSamplerRange); + stream.writeInt(mUsedPixelSamplerRange); + stream.writeInt(mUsesPointSize); + stream.writeInt(mShaderVersion); - size_t size; - stream.read(&size); - if (stream.error()) + stream.writeInt(mUniforms.size()); + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) { - infoLog.append("Invalid program binary."); - return false; - } + const LinkedUniform &uniform = *mUniforms[uniformIndex]; - mUniforms.resize(size); - for (unsigned int i = 0; i < size; ++i) - { - GLenum type; - GLenum precision; - std::string name; - unsigned int arraySize; + stream.writeInt(uniform.type); + stream.writeInt(uniform.precision); + stream.writeString(uniform.name); + stream.writeInt(uniform.arraySize); + stream.writeInt(uniform.blockIndex); - stream.read(&type); - stream.read(&precision); - stream.read(&name); - stream.read(&arraySize); + stream.writeInt(uniform.blockInfo.offset); + stream.writeInt(uniform.blockInfo.arrayStride); + stream.writeInt(uniform.blockInfo.matrixStride); + stream.writeInt(uniform.blockInfo.isRowMajorMatrix); - mUniforms[i] = new Uniform(type, precision, name, arraySize); - - stream.read(&mUniforms[i]->psRegisterIndex); - stream.read(&mUniforms[i]->vsRegisterIndex); - stream.read(&mUniforms[i]->registerCount); - } - - stream.read(&size); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; + stream.writeInt(uniform.psRegisterIndex); + stream.writeInt(uniform.vsRegisterIndex); + stream.writeInt(uniform.registerCount); + stream.writeInt(uniform.registerElement); } - mUniformIndex.resize(size); - for (unsigned int i = 0; i < size; ++i) + stream.writeInt(mUniformBlocks.size()); + for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) { - stream.read(&mUniformIndex[i].name); - stream.read(&mUniformIndex[i].element); - stream.read(&mUniformIndex[i].index); - } - - unsigned int pixelShaderSize; - stream.read(&pixelShaderSize); - - unsigned int vertexShaderSize; - stream.read(&vertexShaderSize); + const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; - unsigned int geometryShaderSize; - stream.read(&geometryShaderSize); + stream.writeString(uniformBlock.name); + stream.writeInt(uniformBlock.elementIndex); + stream.writeInt(uniformBlock.dataSize); - const char *ptr = (const char*) binary + stream.offset(); - - const GUID *binaryIdentifier = (const GUID *) ptr; - ptr += sizeof(GUID); + stream.writeInt(uniformBlock.memberUniformIndexes.size()); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) + { + stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); + } - GUID identifier = mRenderer->getAdapterIdentifier(); - if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) - { - infoLog.append("Invalid program binary."); - return false; + stream.writeInt(uniformBlock.psRegisterIndex); + stream.writeInt(uniformBlock.vsRegisterIndex); } - const char *pixelShaderFunction = ptr; - ptr += pixelShaderSize; - - const char *vertexShaderFunction = ptr; - ptr += vertexShaderSize; - - const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL; - ptr += geometryShaderSize; - - mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction), - pixelShaderSize, rx::SHADER_PIXEL); - if (!mPixelExecutable) + stream.writeInt(mUniformIndex.size()); + for (size_t i = 0; i < mUniformIndex.size(); ++i) { - infoLog.append("Could not create pixel shader."); - return false; + stream.writeString(mUniformIndex[i].name); + stream.writeInt(mUniformIndex[i].element); + stream.writeInt(mUniformIndex[i].index); } - mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction), - vertexShaderSize, rx::SHADER_VERTEX); - if (!mVertexExecutable) + stream.writeInt(mTransformFeedbackBufferMode); + stream.writeInt(mTransformFeedbackLinkedVaryings.size()); + for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) { - infoLog.append("Could not create vertex shader."); - delete mPixelExecutable; - mPixelExecutable = NULL; - return false; - } + const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; - if (geometryShaderFunction != NULL && geometryShaderSize > 0) - { - mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction), - geometryShaderSize, rx::SHADER_GEOMETRY); - if (!mGeometryExecutable) - { - infoLog.append("Could not create geometry shader."); - delete mPixelExecutable; - mPixelExecutable = NULL; - delete mVertexExecutable; - mVertexExecutable = NULL; - return false; - } - } - else - { - mGeometryExecutable = NULL; + stream.writeString(varying.name); + stream.writeInt(varying.type); + stream.writeInt(varying.size); + stream.writeString(varying.semanticName); + stream.writeInt(varying.semanticIndex); + stream.writeInt(varying.semanticIndexCount); } - return true; -} - -bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) -{ - BinaryOutputStream stream; + stream.writeString(mVertexHLSL); + stream.writeInt(mVertexWorkarounds); - stream.write(GL_PROGRAM_BINARY_ANGLE); - stream.write(VERSION_DWORD); - stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL); - - for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) + stream.writeInt(mVertexExecutables.size()); + for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) { - stream.write(mLinkedAttribute[i].type); - stream.write(mLinkedAttribute[i].name); - stream.write(mSemanticIndex[i]); - } + VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; - for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) - { - stream.write(mSamplersPS[i].active); - stream.write(mSamplersPS[i].logicalTextureUnit); - stream.write((int) mSamplersPS[i].textureType); - } + for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + { + const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; + stream.writeInt(vertexInput.mType); + stream.writeInt(vertexInput.mNormalized); + stream.writeInt(vertexInput.mComponents); + stream.writeInt(vertexInput.mPureInteger); + } - for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) - { - stream.write(mSamplersVS[i].active); - stream.write(mSamplersVS[i].logicalTextureUnit); - stream.write((int) mSamplersVS[i].textureType); + size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); + stream.writeInt(vertexShaderSize); + + unsigned char *vertexBlob = static_cast<unsigned char *>(vertexExecutable->shaderExecutable()->getFunction()); + stream.writeBytes(vertexBlob, vertexShaderSize); } - stream.write(mUsedVertexSamplerRange); - stream.write(mUsedPixelSamplerRange); - stream.write(mUsesPointSize); + size_t pixelShaderSize = mPixelExecutable->getLength(); + stream.writeInt(pixelShaderSize); - stream.write(mUniforms.size()); - for (unsigned int i = 0; i < mUniforms.size(); ++i) - { - stream.write(mUniforms[i]->type); - stream.write(mUniforms[i]->precision); - stream.write(mUniforms[i]->name); - stream.write(mUniforms[i]->arraySize); + unsigned char *pixelBlob = static_cast<unsigned char *>(mPixelExecutable->getFunction()); + stream.writeBytes(pixelBlob, pixelShaderSize); - stream.write(mUniforms[i]->psRegisterIndex); - stream.write(mUniforms[i]->vsRegisterIndex); - stream.write(mUniforms[i]->registerCount); - } + size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; + stream.writeInt(geometryShaderSize); - stream.write(mUniformIndex.size()); - for (unsigned int i = 0; i < mUniformIndex.size(); ++i) + if (mGeometryExecutable != NULL && geometryShaderSize > 0) { - stream.write(mUniformIndex[i].name); - stream.write(mUniformIndex[i].element); - stream.write(mUniformIndex[i].index); + unsigned char *geometryBlob = static_cast<unsigned char *>(mGeometryExecutable->getFunction()); + stream.writeBytes(geometryBlob, geometryShaderSize); } - UINT pixelShaderSize = mPixelExecutable->getLength(); - stream.write(pixelShaderSize); - - UINT vertexShaderSize = mVertexExecutable->getLength(); - stream.write(vertexShaderSize); - - UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; - stream.write(geometryShaderSize); - GUID identifier = mRenderer->getAdapterIdentifier(); GLsizei streamLength = stream.length(); const void *streamData = stream.data(); - GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize; + GLsizei totalLength = streamLength + sizeof(GUID); if (totalLength > bufSize) { if (length) @@ -1880,18 +1432,6 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) memcpy(ptr, &identifier, sizeof(GUID)); ptr += sizeof(GUID); - memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize); - ptr += pixelShaderSize; - - memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize); - ptr += vertexShaderSize; - - if (mGeometryExecutable != NULL && geometryShaderSize > 0) - { - memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize); - ptr += geometryShaderSize; - } - ASSERT(ptr - totalLength == binary); } @@ -1916,7 +1456,8 @@ GLint ProgramBinary::getLength() } } -bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) +bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode) { if (!fragmentShader || !fragmentShader->isCompiled()) { @@ -1928,19 +1469,34 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin return false; } + mTransformFeedbackLinkedVaryings.clear(); + mTransformFeedbackBufferMode = transformFeedbackBufferMode; + + mShaderVersion = vertexShader->getShaderVersion(); + std::string pixelHLSL = fragmentShader->getHLSL(); - std::string vertexHLSL = vertexShader->getHLSL(); + mVertexHLSL = vertexShader->getHLSL(); + mVertexWorkarounds = vertexShader->getD3DWorkarounds(); // Map the varyings to the register file - const Varying *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL}; - int registers = packVaryings(infoLog, packing, fragmentShader); + VaryingPacking packing = { NULL }; + int registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShader, vertexShader, transformFeedbackVaryings); if (registers < 0) { return false; } - if (!linkVaryings(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader)) + if (!linkVaryings(infoLog, fragmentShader, vertexShader)) + { + return false; + } + + mUsesPointSize = vertexShader->usesPointSize(); + std::vector<LinkedVarying> linkedVaryings; + if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, pixelHLSL, mVertexHLSL, + fragmentShader, vertexShader, transformFeedbackVaryings, + &linkedVaryings, &mOutputVariables)) { return false; } @@ -1958,35 +1514,59 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin } // special case for gl_DepthRange, the only built-in uniform (also a struct) - if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange) + if (vertexShader->usesDepthRange() || fragmentShader->usesDepthRange()) + { + mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, BlockMemberInfo::getDefaultBlockInfo())); + mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, BlockMemberInfo::getDefaultBlockInfo())); + mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, BlockMemberInfo::getDefaultBlockInfo())); + } + + if (!linkUniformBlocks(infoLog, vertexShader->getInterfaceBlocks(), fragmentShader->getInterfaceBlocks())) { - mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0)); - mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0)); - mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0)); + success = false; + } + + if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, + transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings)) + { + success = false; } if (success) { - mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->mUsesDiscardRewriting)); - mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting)); + VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS]; + GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout); + + rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout); + mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + fragmentShader->getD3DWorkarounds()); if (usesGeometryShader()) { - std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader); - mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY, rx::ANGLE_D3D_WORKAROUND_NONE); + std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShader, vertexShader); + mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + rx::ANGLE_D3D_WORKAROUND_NONE); } - if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) + if (!defaultVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) { infoLog.append("Failed to create D3D shaders."); success = false; - delete mVertexExecutable; - mVertexExecutable = NULL; - delete mPixelExecutable; - mPixelExecutable = NULL; - delete mGeometryExecutable; - mGeometryExecutable = NULL; + while (!mVertexExecutables.empty()) + { + delete mVertexExecutables.back(); + mVertexExecutables.pop_back(); + } + + SafeDelete(mGeometryExecutable); + SafeDelete(mPixelExecutable); + + mTransformFeedbackLinkedVaryings.clear(); } } @@ -1997,62 +1577,75 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) { unsigned int usedLocations = 0; + const std::vector<gl::Attribute> &activeAttributes = vertexShader->activeAttributes(); // Link attributes that have a binding location - for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) { - int location = attributeBindings.getAttributeBinding(attribute->name); - - if (location != -1) // Set by glBindAttribLocation - { - if (!mLinkedAttribute[location].name.empty()) - { - // Multiple active attributes bound to the same location; not an error - } + const gl::Attribute &attribute = activeAttributes[attributeIndex]; + const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - mLinkedAttribute[location] = *attribute; + mShaderAttributes[attributeIndex] = attribute; - int rows = VariableRowCount(attribute->type); + if (location != -1) // Set by glBindAttribLocation or by location layout qualifier + { + const int rows = AttributeRegisterCount(attribute.type); if (rows + location > MAX_VERTEX_ATTRIBS) { - infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); + infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location); return false; } - for (int i = 0; i < rows; i++) + for (int row = 0; row < rows; row++) { - usedLocations |= 1 << (location + i); + const int rowLocation = location + row; + gl::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation]; + + // In GLSL 3.00, attribute aliasing produces a link error + // In GLSL 1.00, attribute aliasing is allowed + if (mShaderVersion >= 300) + { + if (!linkedAttribute.name.empty()) + { + infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation); + return false; + } + } + + linkedAttribute = attribute; + usedLocations |= 1 << rowLocation; } } } // Link attributes that don't have a binding location - for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) { - int location = attributeBindings.getAttributeBinding(attribute->name); + const gl::Attribute &attribute = activeAttributes[attributeIndex]; + const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - if (location == -1) // Not set by glBindAttribLocation + if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier { - int rows = VariableRowCount(attribute->type); + int rows = AttributeRegisterCount(attribute.type); int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) { - infoLog.append("Too many active attributes (%s)", attribute->name.c_str()); + infoLog.append("Too many active attributes (%s)", attribute.name.c_str()); return false; // Fail to link } - mLinkedAttribute[availableIndex] = *attribute; + mLinkedAttribute[availableIndex] = attribute; } } for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) { int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); - int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); + int rows = AttributeRegisterCount(mLinkedAttribute[attributeIndex].type); for (int r = 0; r < rows; r++) { @@ -2065,34 +1658,248 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at return true; } -bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms) +bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const gl::ShaderVariable &vertexVariable, const gl::ShaderVariable &fragmentVariable, bool validatePrecision) +{ + if (vertexVariable.type != fragmentVariable.type) + { + infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str()); + return false; + } + if (vertexVariable.arraySize != fragmentVariable.arraySize) + { + infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str()); + return false; + } + if (validatePrecision && vertexVariable.precision != fragmentVariable.precision) + { + infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str()); + return false; + } + + return true; +} + +template <class ShaderVarType> +bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar) { - for (sh::ActiveUniforms::const_iterator uniform = vertexUniforms.begin(); uniform != vertexUniforms.end(); uniform++) + if (vertexVar.fields.size() != fragmentVar.fields.size()) { - if (!defineUniform(GL_VERTEX_SHADER, *uniform, infoLog)) + infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", varName.c_str()); + return false; + } + const unsigned int numMembers = vertexVar.fields.size(); + for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++) + { + const ShaderVarType &vertexMember = vertexVar.fields[memberIndex]; + const ShaderVarType &fragmentMember = fragmentVar.fields[memberIndex]; + + if (vertexMember.name != fragmentMember.name) + { + infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')", + memberIndex, varName.c_str(), vertexMember.name.c_str(), fragmentMember.name.c_str()); + return false; + } + + const std::string memberName = varName.substr(0, varName.length()-1) + "." + vertexVar.name + "'"; + if (!linkValidateVariables(infoLog, memberName, vertexMember, fragmentMember)) { return false; } } - for (sh::ActiveUniforms::const_iterator uniform = fragmentUniforms.begin(); uniform != fragmentUniforms.end(); uniform++) + return true; +} + +bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const gl::Uniform &vertexUniform, const gl::Uniform &fragmentUniform) +{ + if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) + { + return false; + } + + if (!linkValidateFields<gl::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform)) { - if (!defineUniform(GL_FRAGMENT_SHADER, *uniform, infoLog)) + return false; + } + + return true; +} + +bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const gl::Varying &vertexVarying, const gl::Varying &fragmentVarying) +{ + if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false)) + { + return false; + } + + if (vertexVarying.interpolation != fragmentVarying.interpolation) + { + infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str()); + return false; + } + + if (!linkValidateFields<gl::Varying>(infoLog, varyingName, vertexVarying, fragmentVarying)) + { + return false; + } + + return true; +} + +bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const gl::InterfaceBlockField &vertexUniform, const gl::InterfaceBlockField &fragmentUniform) +{ + if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) + { + return false; + } + + if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix) + { + infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str()); + return false; + } + + if (!linkValidateFields<gl::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform)) + { + return false; + } + + return true; +} + +bool ProgramBinary::linkUniforms(InfoLog &infoLog, const std::vector<gl::Uniform> &vertexUniforms, const std::vector<gl::Uniform> &fragmentUniforms) +{ + // Check that uniforms defined in the vertex and fragment shaders are identical + typedef std::map<std::string, const gl::Uniform*> UniformMap; + UniformMap linkedUniforms; + + for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) + { + const gl::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; + linkedUniforms[vertexUniform.name] = &vertexUniform; + } + + for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) + { + const gl::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; + UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); + if (entry != linkedUniforms.end()) + { + const gl::Uniform &vertexUniform = *entry->second; + const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; + if (!linkValidateVariables(infoLog, uniformName, vertexUniform, fragmentUniform)) + { + return false; + } + } + } + + for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) + { + if (!defineUniform(GL_VERTEX_SHADER, vertexUniforms[uniformIndex], infoLog)) { return false; } } + for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) + { + if (!defineUniform(GL_FRAGMENT_SHADER, fragmentUniforms[uniformIndex], infoLog)) + { + return false; + } + } + + initializeUniformStorage(); + return true; } -bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog) +TextureType ProgramBinary::getTextureType(GLenum samplerType, InfoLog &infoLog) { - if (constant.type == GL_SAMPLER_2D || - constant.type == GL_SAMPLER_CUBE) + switch(samplerType) + { + case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + return TEXTURE_2D; + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: + return TEXTURE_3D; + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return TEXTURE_CUBE; + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + return TEXTURE_CUBE; + case GL_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + return TEXTURE_2D_ARRAY; + default: UNREACHABLE(); + } + + return TEXTURE_2D; +} + +bool ProgramBinary::defineUniform(GLenum shader, const gl::Uniform &constant, InfoLog &infoLog) +{ + if (constant.isStruct()) + { + if (constant.arraySize > 0) + { + ShShaderOutput outputType = Shader::getCompilerOutputType(shader); + const unsigned int elementRegisterCount = HLSLVariableRegisterCount(constant, outputType) / constant.arraySize; + + for (unsigned int elementIndex = 0; elementIndex < constant.arraySize; elementIndex++) + { + const unsigned int elementRegisterOffset = elementRegisterCount * elementIndex; + + for (size_t fieldIndex = 0; fieldIndex < constant.fields.size(); fieldIndex++) + { + const gl::Uniform &field = constant.fields[fieldIndex]; + const std::string &uniformName = constant.name + ArrayString(elementIndex) + "." + field.name; + const unsigned int fieldRegisterIndex = field.registerIndex + elementRegisterOffset; + gl::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, + fieldRegisterIndex, field.elementIndex); + + fieldUniform.fields = field.fields; + if (!defineUniform(shader, fieldUniform, infoLog)) + { + return false; + } + } + } + } + else + { + for (size_t fieldIndex = 0; fieldIndex < constant.fields.size(); fieldIndex++) + { + const gl::Uniform &field = constant.fields[fieldIndex]; + const std::string &uniformName = constant.name + "." + field.name; + + gl::Uniform fieldUniform(field.type, field.precision, uniformName.c_str(), field.arraySize, + field.registerIndex, field.elementIndex); + + fieldUniform.fields = field.fields; + + if (!defineUniform(shader, fieldUniform, infoLog)) + { + return false; + } + } + } + + return true; + } + + if (IsSampler(constant.type)) { unsigned int samplerIndex = constant.registerIndex; - + do { if (shader == GL_VERTEX_SHADER) @@ -2100,7 +1907,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits()) { mSamplersVS[samplerIndex].active = true; - mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersVS[samplerIndex].textureType = getTextureType(constant.type, infoLog); mSamplersVS[samplerIndex].logicalTextureUnit = 0; mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange); } @@ -2115,7 +1922,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) { mSamplersPS[samplerIndex].active = true; - mSamplersPS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersPS[samplerIndex].textureType = getTextureType(constant.type, infoLog); mSamplersPS[samplerIndex].logicalTextureUnit = 0; mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange); } @@ -2132,28 +1939,18 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In while (samplerIndex < constant.registerIndex + constant.arraySize); } - Uniform *uniform = NULL; + LinkedUniform *uniform = NULL; GLint location = getUniformLocation(constant.name); if (location >= 0) // Previously defined, type and precision must match { uniform = mUniforms[mUniformIndex[location].index]; - - if (uniform->type != constant.type) - { - infoLog.append("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); - return false; - } - - if (uniform->precision != constant.precision) - { - infoLog.append("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); - return false; - } } else { - uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize); + uniform = new LinkedUniform(constant.type, constant.precision, constant.name, constant.arraySize, + -1, BlockMemberInfo::getDefaultBlockInfo()); + uniform->registerElement = constant.elementIndex; } if (!uniform) @@ -2179,9 +1976,9 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In mUniforms.push_back(uniform); unsigned int uniformIndex = mUniforms.size() - 1; - for (unsigned int i = 0; i < uniform->elementCount(); i++) + for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform->elementCount(); arrayElementIndex++) { - mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex)); + mUniformIndex.push_back(VariableLocation(uniform->name, arrayElementIndex, uniformIndex)); } if (shader == GL_VERTEX_SHADER) @@ -2205,155 +2002,271 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In return true; } -std::string ProgramBinary::generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const +bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const gl::InterfaceBlock &vertexInterfaceBlock, const gl::InterfaceBlock &fragmentInterfaceBlock) { - // for now we only handle point sprite emulation - ASSERT(usesPointSpriteEmulation()); - return generatePointSpriteHLSL(registers, packing, fragmentShader, vertexShader); -} + const char* blockName = vertexInterfaceBlock.name.c_str(); -std::string ProgramBinary::generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const -{ - ASSERT(registers >= 0); - ASSERT(vertexShader->mUsesPointSize); - ASSERT(mRenderer->getMajorShaderModel() >= 4); + // validate blocks for the same member types + if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) + { + infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); + return false; + } - std::string geomHLSL; + if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) + { + infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } - std::string varyingSemantic = "TEXCOORD"; + if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) + { + infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } - std::string fragCoordSemantic; - std::string pointCoordSemantic; + const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) + { + const gl::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; + const gl::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; - int reservedRegisterIndex = registers; + if (vertexMember.name != fragmentMember.name) + { + infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", + blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); + return false; + } - if (fragmentShader->mUsesFragCoord) - { - fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); + std::string uniformName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; + if (!linkValidateVariables(infoLog, uniformName, vertexMember, fragmentMember)) + { + return false; + } } - if (fragmentShader->mUsesPointCoord) + return true; +} + +bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const std::vector<gl::InterfaceBlock> &vertexInterfaceBlocks, + const std::vector<gl::InterfaceBlock> &fragmentInterfaceBlocks) +{ + // Check that interface blocks defined in the vertex and fragment shaders are identical + typedef std::map<std::string, const gl::InterfaceBlock*> UniformBlockMap; + UniformBlockMap linkedUniformBlocks; + + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) { - pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); + const gl::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; + linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; } - geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n" - "\n" - "struct GS_INPUT\n" - "{\n"; - - for (int r = 0; r < registers; r++) + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) { - int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); + const gl::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; + UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); + if (entry != linkedUniformBlocks.end()) + { + const gl::InterfaceBlock &vertexInterfaceBlock = *entry->second; + if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) + { + return false; + } + } + } - geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) + { + if (!defineUniformBlock(infoLog, GL_VERTEX_SHADER, vertexInterfaceBlocks[blockIndex])) + { + return false; + } } - if (fragmentShader->mUsesFragCoord) + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) { - geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; + if (!defineUniformBlock(infoLog, GL_FRAGMENT_SHADER, fragmentInterfaceBlocks[blockIndex])) + { + return false; + } } - geomHLSL += " float gl_PointSize : PSIZE;\n" - " float4 gl_Position : SV_Position;\n" - "};\n" - "\n" - "struct GS_OUTPUT\n" - "{\n"; + return true; +} + +bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, + const std::vector<std::string> &transformFeedbackVaryingNames, + GLenum transformFeedbackBufferMode, + std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const +{ + size_t totalComponents = 0; + const size_t maxSeparateComponents = mRenderer->getMaxTransformFeedbackSeparateComponents(); + const size_t maxInterleavedComponents = mRenderer->getMaxTransformFeedbackInterleavedComponents(); - for (int r = 0; r < registers; r++) + // Gather the linked varyings that are used for transform feedback, they should all exist. + outTransformFeedbackLinkedVaryings->clear(); + for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++) { - int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); + bool found = false; + for (size_t j = 0; j < linkedVaryings.size(); j++) + { + if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name) + { + for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++) + { + if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name) + { + infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str()); + return false; + } + } - geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; - } + size_t componentCount = linkedVaryings[j].semanticIndexCount * 4; + if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && + componentCount > maxSeparateComponents) + { + infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).", + linkedVaryings[j].name.c_str(), componentCount, maxSeparateComponents); + return false; + } - if (fragmentShader->mUsesFragCoord) - { - geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; + totalComponents += componentCount; + + outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]); + found = true; + break; + } + } + + // All transform feedback varyings are expected to exist since packVaryings checks for them. + ASSERT(found); } - if (fragmentShader->mUsesPointCoord) + if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > maxInterleavedComponents) { - geomHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n"; + infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).", + totalComponents, maxInterleavedComponents); + return false; } - geomHLSL += " float gl_PointSize : PSIZE;\n" - " float4 gl_Position : SV_Position;\n" - "};\n" - "\n" - "static float2 pointSpriteCorners[] = \n" - "{\n" - " float2( 0.5f, -0.5f),\n" - " float2( 0.5f, 0.5f),\n" - " float2(-0.5f, -0.5f),\n" - " float2(-0.5f, 0.5f)\n" - "};\n" - "\n" - "static float2 pointSpriteTexcoords[] = \n" - "{\n" - " float2(1.0f, 1.0f),\n" - " float2(1.0f, 0.0f),\n" - " float2(0.0f, 1.0f),\n" - " float2(0.0f, 0.0f)\n" - "};\n" - "\n" - "static float minPointSize = " + str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n" - "static float maxPointSize = " + str(mRenderer->getMaxPointSize()) + ".0f;\n" - "\n" - "[maxvertexcount(4)]\n" - "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n" - "{\n" - " GS_OUTPUT output = (GS_OUTPUT)0;\n" - " output.gl_PointSize = input[0].gl_PointSize;\n"; + return true; +} - for (int r = 0; r < registers; r++) +void ProgramBinary::defineUniformBlockMembers(const std::vector<gl::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes) +{ + for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) { - geomHLSL += " output.v" + str(r) + " = input[0].v" + str(r) + ";\n"; + const gl::InterfaceBlockField &field = fields[uniformIndex]; + const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); + + if (!field.fields.empty()) + { + if (field.arraySize > 0) + { + for (unsigned int arrayElement = 0; arrayElement < field.arraySize; arrayElement++) + { + const std::string uniformElementName = fieldName + ArrayString(arrayElement); + defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, blockInfoItr, blockUniformIndexes); + } + } + else + { + defineUniformBlockMembers(field.fields, fieldName, blockIndex, blockInfoItr, blockUniformIndexes); + } + } + else + { + LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize, + blockIndex, **blockInfoItr); + + // add to uniform list, but not index, since uniform block uniforms have no location + blockUniformIndexes->push_back(mUniforms.size()); + mUniforms.push_back(newUniform); + (*blockInfoItr)++; + } } +} - if (fragmentShader->mUsesFragCoord) +bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, GLenum shader, const gl::InterfaceBlock &interfaceBlock) +{ + // create uniform block entries if they do not exist + if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) { - geomHLSL += " output.gl_FragCoord = input[0].gl_FragCoord;\n"; + std::vector<unsigned int> blockUniformIndexes; + const unsigned int blockIndex = mUniformBlocks.size(); + + // define member uniforms + BlockInfoItr blockInfoItr = interfaceBlock.blockInfo.cbegin(); + defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, &blockInfoItr, &blockUniformIndexes); + + // create all the uniform blocks + if (interfaceBlock.arraySize > 0) + { + for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) + { + gl::UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, interfaceBlock.dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } + } + else + { + gl::UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, interfaceBlock.dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } } - geomHLSL += " \n" - " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n" - " float4 gl_Position = input[0].gl_Position;\n" - " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n"; + // Assign registers to the uniform blocks + const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); + const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); + ASSERT(blockIndex != GL_INVALID_INDEX); + ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); - for (int corner = 0; corner < 4; corner++) + for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) { - geomHLSL += " \n" - " output.gl_Position = gl_Position + float4(pointSpriteCorners[" + str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; + gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; + ASSERT(uniformBlock->name == interfaceBlock.name); - if (fragmentShader->mUsesPointCoord) + if (!assignUniformBlockRegister(infoLog, uniformBlock, shader, interfaceBlock.registerIndex + uniformBlockElement)) { - geomHLSL += " output.gl_PointCoord = pointSpriteTexcoords[" + str(corner) + "];\n"; + return false; } - - geomHLSL += " outStream.Append(output);\n"; } - geomHLSL += " \n" - " outStream.RestartStrip();\n" - "}\n"; - - return geomHLSL; + return true; } -// This method needs to match OutputHLSL::decorate -std::string ProgramBinary::decorateAttribute(const std::string &name) +bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex) { - if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) + if (shader == GL_VERTEX_SHADER) { - return "_" + name; + uniformBlock->vsRegisterIndex = registerIndex; + unsigned int maximumBlocks = mRenderer->getMaxVertexShaderUniformBuffers(); + + if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= maximumBlocks) + { + infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", maximumBlocks); + return false; + } } - - return name; + else if (shader == GL_FRAGMENT_SHADER) + { + uniformBlock->psRegisterIndex = registerIndex; + unsigned int maximumBlocks = mRenderer->getMaxFragmentShaderUniformBuffers(); + + if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= maximumBlocks) + { + infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", maximumBlocks); + return false; + } + } + else UNREACHABLE(); + + return true; } -bool ProgramBinary::isValidated() const +bool ProgramBinary::isValidated() const { return mValidated; } @@ -2479,6 +2392,128 @@ GLint ProgramBinary::getActiveUniformMaxLength() const return maxLength; } +GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const +{ + const gl::LinkedUniform& uniform = *mUniforms[index]; + + switch (pname) + { + case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type); + case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount()); + case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0)); + case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex; + + case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset; + case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride; + case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride; + case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix); + + default: + UNREACHABLE(); + break; + } + return 0; +} + +bool ProgramBinary::isValidUniformLocation(GLint location) const +{ + ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size())); + return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size())); +} + +LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const +{ + ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size()); + return mUniforms[mUniformIndex[location].index]; +} + +void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const +{ + ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + + const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + + if (bufSize > 0) + { + std::string string = uniformBlock.name; + + if (uniformBlock.isArrayElement()) + { + string += ArrayString(uniformBlock.elementIndex); + } + + strncpy(uniformBlockName, string.c_str(), bufSize); + uniformBlockName[bufSize - 1] = '\0'; + + if (length) + { + *length = strlen(uniformBlockName); + } + } +} + +void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const +{ + ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + + const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + + switch (pname) + { + case GL_UNIFORM_BLOCK_DATA_SIZE: + *params = static_cast<GLint>(uniformBlock.dataSize); + break; + case GL_UNIFORM_BLOCK_NAME_LENGTH: + *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0)); + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size()); + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + { + for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) + { + params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]); + } + } + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader()); + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader()); + break; + default: UNREACHABLE(); + } +} + +GLuint ProgramBinary::getActiveUniformBlockCount() const +{ + return mUniformBlocks.size(); +} + +GLuint ProgramBinary::getActiveUniformBlockMaxLength() const +{ + unsigned int maxLength = 0; + + unsigned int numUniformBlocks = mUniformBlocks.size(); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) + { + const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + if (!uniformBlock.name.empty()) + { + const unsigned int length = uniformBlock.name.length() + 1; + + // Counting in "[0]". + const unsigned int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0); + + maxLength = std::max(length + arrayLength, maxLength); + } + } + + return maxLength; +} + void ProgramBinary::validate(InfoLog &infoLog) { applyUniforms(); @@ -2511,7 +2546,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog) if (mSamplersPS[i].active) { unsigned int unit = mSamplersPS[i].logicalTextureUnit; - + if (unit >= maxCombinedTextureImageUnits) { if (infoLog) @@ -2546,7 +2581,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog) if (mSamplersVS[i].active) { unsigned int unit = mSamplersVS[i].logicalTextureUnit; - + if (unit >= maxCombinedTextureImageUnits) { if (infoLog) @@ -2592,7 +2627,9 @@ struct AttributeSorter bool operator()(int a, int b) { - return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b]; + if (originalIndices[a] == -1) return false; + if (originalIndices[b] == -1) return true; + return (originalIndices[a] < originalIndices[b]); } const int (&originalIndices)[MAX_VERTEX_ATTRIBS]; @@ -2625,4 +2662,30 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA } } +void ProgramBinary::initializeUniformStorage() +{ + // Compute total default block size + unsigned int vertexRegisters = 0; + unsigned int fragmentRegisters = 0; + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const LinkedUniform &uniform = *mUniforms[uniformIndex]; + + if (!IsSampler(uniform.type)) + { + if (uniform.isReferencedByVertexShader()) + { + vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount); + } + if (uniform.isReferencedByFragmentShader()) + { + fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount); + } + } + } + + mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u); + mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/ProgramBinary.h b/chromium/third_party/angle/src/libGLESv2/ProgramBinary.h index d6320863f2b..839923b68c2 100644 --- a/chromium/third_party/angle/src/libGLESv2/ProgramBinary.h +++ b/chromium/third_party/angle/src/libGLESv2/ProgramBinary.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -10,7 +10,8 @@ #ifndef LIBGLESV2_PROGRAM_BINARY_H_ #define LIBGLESV2_PROGRAM_BINARY_H_ -#define GL_APICALL +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> @@ -19,16 +20,19 @@ #include "common/RefCountObject.h" #include "angletypes.h" -#include "libGLESv2/mathutil.h" +#include "common/mathutil.h" #include "libGLESv2/Uniform.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Constants.h" +#include "libGLESv2/renderer/VertexDataManager.h" namespace rx { class ShaderExecutable; class Renderer; struct TranslatedAttribute; +class UniformStorage; +class DynamicHLSL; } namespace gl @@ -37,22 +41,40 @@ class FragmentShader; class VertexShader; class InfoLog; class AttributeBindings; -struct Varying; +class Buffer; // Struct used for correlating uniforms/elements of uniform arrays to handles -struct UniformLocation +struct VariableLocation { - UniformLocation() + VariableLocation() { } - UniformLocation(const std::string &name, unsigned int element, unsigned int index); + VariableLocation(const std::string &name, unsigned int element, unsigned int index); std::string name; unsigned int element; unsigned int index; }; +struct LinkedVarying +{ + LinkedVarying(); + LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, + unsigned int semanticIndex, unsigned int semanticIndexCount); + + // Original GL name + std::string name; + + GLenum type; + GLsizei size; + + // DirectX semantic information + std::string semanticName; + unsigned int semanticIndex; + unsigned int semanticIndexCount; +}; + // This is the result of linking a program. It is the state that would be passed to ProgramBinary. class ProgramBinary : public RefCountObject { @@ -60,9 +82,9 @@ class ProgramBinary : public RefCountObject explicit ProgramBinary(rx::Renderer *renderer); ~ProgramBinary(); - rx::ShaderExecutable *getPixelExecutable(); - rx::ShaderExecutable *getVertexExecutable(); - rx::ShaderExecutable *getGeometryExecutable(); + rx::ShaderExecutable *getPixelExecutable() const; + rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]); + rx::ShaderExecutable *getGeometryExecutable() const; GLuint getAttributeLocation(const char *name); int getSemanticIndex(int attributeIndex); @@ -75,29 +97,44 @@ class ProgramBinary : public RefCountObject bool usesGeometryShader() const; GLint getUniformLocation(std::string name); - bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniform1iv(GLint location, GLsizei count, const GLint *v); - bool setUniform2iv(GLint location, GLsizei count, const GLint *v); - bool setUniform3iv(GLint location, GLsizei count, const GLint *v); - bool setUniform4iv(GLint location, GLsizei count, const GLint *v); + GLuint getUniformIndex(std::string name); + GLuint getUniformBlockIndex(std::string name); + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform1iv(GLint location, GLsizei count, const GLint *v); + void setUniform2iv(GLint location, GLsizei count, const GLint *v); + void setUniform3iv(GLint location, GLsizei count, const GLint *v); + void setUniform4iv(GLint location, GLsizei count, const GLint *v); + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); + void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); + bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params); void dirtyAllUniforms(); void applyUniforms(); + bool applyUniformBuffers(const std::vector<Buffer*> boundBuffers); bool load(InfoLog &infoLog, const void *binary, GLsizei length); bool save(void* binary, GLsizei bufSize, GLsizei *length); GLint getLength(); - bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); + bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; @@ -107,44 +144,114 @@ class ProgramBinary : public RefCountObject void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; GLint getActiveUniformCount() const; GLint getActiveUniformMaxLength() const; + GLint getActiveUniformi(GLuint index, GLenum pname) const; + bool isValidUniformLocation(GLint location) const; + LinkedUniform *getUniformByLocation(GLint location) const; + + void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; + void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; + GLuint getActiveUniformBlockCount() const; + GLuint getActiveUniformBlockMaxLength() const; + UniformBlock *getUniformBlockByIndex(GLuint blockIndex); + + GLint getFragDataLocation(const char *name) const; + + size_t getTransformFeedbackVaryingCount() const; + const LinkedVarying &getTransformFeedbackVarying(size_t idx) const; + GLenum getTransformFeedbackBufferMode() const; void validate(InfoLog &infoLog); bool validateSamplers(InfoLog *infoLog); bool isValidated() const; unsigned int getSerial() const; + int getShaderVersion() const; void initAttributesByLayout(); - void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; + void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; - static std::string decorateAttribute(const std::string &name); // Prepend an underscore + const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; } + const rx::UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; } + const rx::UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } private: DISALLOW_COPY_AND_ASSIGN(ProgramBinary); - int packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader); - bool linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4], - std::string& pixelHLSL, std::string& vertexHLSL, - FragmentShader *fragmentShader, VertexShader *vertexShader); - + bool linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader); bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); - bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms); - bool defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog); - - std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const; - std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const; + typedef std::vector<BlockMemberInfo>::const_iterator BlockInfoItr; + + template <class ShaderVarType> + bool linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar); + bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const ShaderVariable &vertexVariable, const ShaderVariable &fragmentVariable, bool validatePrecision); + + bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const Uniform &vertexUniform, const Uniform &fragmentUniform); + bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const Varying &vertexVarying, const Varying &fragmentVarying); + bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const InterfaceBlockField &vertexUniform, const InterfaceBlockField &fragmentUniform); + bool linkUniforms(InfoLog &infoLog, const std::vector<Uniform> &vertexUniforms, const std::vector<Uniform> &fragmentUniforms); + bool defineUniform(GLenum shader, const Uniform &constant, InfoLog &infoLog); + bool areMatchingInterfaceBlocks(InfoLog &infoLog, const InterfaceBlock &vertexInterfaceBlock, const InterfaceBlock &fragmentInterfaceBlock); + bool linkUniformBlocks(InfoLog &infoLog, const std::vector<InterfaceBlock> &vertexUniformBlocks, const std::vector<InterfaceBlock> &fragmentUniformBlocks); + bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, + const std::vector<std::string> &transformFeedbackVaryingNames, + GLenum transformFeedbackBufferMode, + std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const; + void defineUniformBlockMembers(const std::vector<InterfaceBlockField> &fields, const std::string &prefix, int blockIndex, BlockInfoItr *blockInfoItr, std::vector<unsigned int> *blockUniformIndexes); + bool defineUniformBlock(InfoLog &infoLog, GLenum shader, const InterfaceBlock &interfaceBlock); + bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex); + void defineOutputVariables(FragmentShader *fragmentShader); + void initializeUniformStorage(); + + template <typename T> + void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); + + template <int cols, int rows> + void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); + + template <typename T> + bool getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType); + + static TextureType getTextureType(GLenum samplerType, InfoLog &infoLog); + + class VertexExecutable + { + public: + VertexExecutable(rx::Renderer *const renderer, + const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS], + const GLenum signature[MAX_VERTEX_ATTRIBS], + rx::ShaderExecutable *shaderExecutable); + ~VertexExecutable(); + + bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const; + + const VertexFormat *inputs() const { return mInputs; } + const GLenum *signature() const { return mSignature; } + rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } + + private: + VertexFormat mInputs[MAX_VERTEX_ATTRIBS]; + GLenum mSignature[MAX_VERTEX_ATTRIBS]; + rx::ShaderExecutable *mShaderExecutable; + }; rx::Renderer *const mRenderer; + DynamicHLSL *mDynamicHLSL; - rx::ShaderExecutable *mPixelExecutable; - rx::ShaderExecutable *mVertexExecutable; + std::string mVertexHLSL; + rx::D3DWorkaroundType mVertexWorkarounds; + std::vector<VertexExecutable *> mVertexExecutables; rx::ShaderExecutable *mGeometryExecutable; + rx::ShaderExecutable *mPixelExecutable; Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; + Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; + GLenum mTransformFeedbackBufferMode; + std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings; + struct Sampler { Sampler(); @@ -159,10 +266,14 @@ class ProgramBinary : public RefCountObject GLuint mUsedVertexSamplerRange; GLuint mUsedPixelSamplerRange; bool mUsesPointSize; + int mShaderVersion; - UniformArray mUniforms; - typedef std::vector<UniformLocation> UniformIndex; - UniformIndex mUniformIndex; + std::vector<LinkedUniform*> mUniforms; + std::vector<UniformBlock*> mUniformBlocks; + std::vector<VariableLocation> mUniformIndex; + std::map<int, VariableLocation> mOutputVariables; + rx::UniformStorage *mVertexUniformStorage; + rx::UniformStorage *mFragmentUniformStorage; bool mValidated; @@ -171,6 +282,7 @@ class ProgramBinary : public RefCountObject static unsigned int issueSerial(); static unsigned int mCurrentSerial; }; + } #endif // LIBGLESV2_PROGRAM_BINARY_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/Query.cpp b/chromium/third_party/angle/src/libGLESv2/Query.cpp index bd987954f1f..6546d06c34c 100644 --- a/chromium/third_party/angle/src/libGLESv2/Query.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Query.cpp @@ -49,4 +49,9 @@ GLenum Query::getType() const return mQuery->getType(); } +bool Query::isStarted() const +{ + return mQuery->isStarted(); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/Query.h b/chromium/third_party/angle/src/libGLESv2/Query.h index e9b95b729b6..4eb236f1041 100644 --- a/chromium/third_party/angle/src/libGLESv2/Query.h +++ b/chromium/third_party/angle/src/libGLESv2/Query.h @@ -9,7 +9,7 @@ #ifndef LIBGLESV2_QUERY_H_ #define LIBGLESV2_QUERY_H_ -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include "common/angleutils.h" @@ -37,6 +37,7 @@ class Query : public RefCountObject GLboolean isResultAvailable(); GLenum getType() const; + bool isStarted() const; private: DISALLOW_COPY_AND_ASSIGN(Query); diff --git a/chromium/third_party/angle/src/libGLESv2/Renderbuffer.cpp b/chromium/third_party/angle/src/libGLESv2/Renderbuffer.cpp index 98d33ec6c38..dade014b830 100644 --- a/chromium/third_party/angle/src/libGLESv2/Renderbuffer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Renderbuffer.cpp @@ -14,308 +14,15 @@ #include "libGLESv2/Texture.h" #include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/utilities.h" +#include "libGLESv2/renderer/TextureStorage.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" namespace gl { unsigned int RenderbufferStorage::mCurrentSerial = 1; -RenderbufferInterface::RenderbufferInterface() -{ -} - -// The default case for classes inherited from RenderbufferInterface is not to -// need to do anything upon the reference count to the parent Renderbuffer incrementing -// or decrementing. -void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy) -{ -} - -void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy) -{ -} - -GLuint RenderbufferInterface::getRedSize() const -{ - return gl::GetRedSize(getActualFormat()); -} - -GLuint RenderbufferInterface::getGreenSize() const -{ - return gl::GetGreenSize(getActualFormat()); -} - -GLuint RenderbufferInterface::getBlueSize() const -{ - return gl::GetBlueSize(getActualFormat()); -} - -GLuint RenderbufferInterface::getAlphaSize() const -{ - return gl::GetAlphaSize(getActualFormat()); -} - -GLuint RenderbufferInterface::getDepthSize() const -{ - return gl::GetDepthSize(getActualFormat()); -} - -GLuint RenderbufferInterface::getStencilSize() const -{ - return gl::GetStencilSize(getActualFormat()); -} - -///// RenderbufferTexture2D Implementation //////// - -RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLenum target) : mTarget(target) -{ - mTexture2D.set(texture); -} - -RenderbufferTexture2D::~RenderbufferTexture2D() -{ - mTexture2D.set(NULL); -} - -// Textures need to maintain their own reference count for references via -// Renderbuffers acting as proxies. Here, we notify the texture of a reference. -void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy) -{ - mTexture2D->addProxyRef(proxy); -} - -void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) -{ - mTexture2D->releaseProxy(proxy); -} - -rx::RenderTarget *RenderbufferTexture2D::getRenderTarget() -{ - return mTexture2D->getRenderTarget(mTarget); -} - -rx::RenderTarget *RenderbufferTexture2D::getDepthStencil() -{ - return mTexture2D->getDepthStencil(mTarget); -} - -GLsizei RenderbufferTexture2D::getWidth() const -{ - return mTexture2D->getWidth(0); -} - -GLsizei RenderbufferTexture2D::getHeight() const -{ - return mTexture2D->getHeight(0); -} - -GLenum RenderbufferTexture2D::getInternalFormat() const -{ - return mTexture2D->getInternalFormat(0); -} - -GLenum RenderbufferTexture2D::getActualFormat() const -{ - return mTexture2D->getActualFormat(0); -} - -GLsizei RenderbufferTexture2D::getSamples() const -{ - return 0; -} - -unsigned int RenderbufferTexture2D::getSerial() const -{ - return mTexture2D->getRenderTargetSerial(mTarget); -} - -unsigned int RenderbufferTexture2D::getTextureSerial() const -{ - return mTexture2D->getTextureSerial(); -} - -///// RenderbufferTextureCubeMap Implementation //////// - -RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target) -{ - mTextureCubeMap.set(texture); -} - -RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap() -{ - mTextureCubeMap.set(NULL); -} - -// Textures need to maintain their own reference count for references via -// Renderbuffers acting as proxies. Here, we notify the texture of a reference. -void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy) -{ - mTextureCubeMap->addProxyRef(proxy); -} - -void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy) -{ - mTextureCubeMap->releaseProxy(proxy); -} - -rx::RenderTarget *RenderbufferTextureCubeMap::getRenderTarget() -{ - return mTextureCubeMap->getRenderTarget(mTarget); -} - -rx::RenderTarget *RenderbufferTextureCubeMap::getDepthStencil() -{ - return NULL; -} - -GLsizei RenderbufferTextureCubeMap::getWidth() const -{ - return mTextureCubeMap->getWidth(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); -} - -GLsizei RenderbufferTextureCubeMap::getHeight() const -{ - return mTextureCubeMap->getHeight(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); -} - -GLenum RenderbufferTextureCubeMap::getInternalFormat() const -{ - return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); -} - -GLenum RenderbufferTextureCubeMap::getActualFormat() const -{ - return mTextureCubeMap->getActualFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); -} - -GLsizei RenderbufferTextureCubeMap::getSamples() const -{ - return 0; -} - -unsigned int RenderbufferTextureCubeMap::getSerial() const -{ - return mTextureCubeMap->getRenderTargetSerial(mTarget); -} - -unsigned int RenderbufferTextureCubeMap::getTextureSerial() const -{ - return mTextureCubeMap->getTextureSerial(); -} - -////// Renderbuffer Implementation ////// - -Renderbuffer::Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *instance) : RefCountObject(id) -{ - ASSERT(instance != NULL); - mInstance = instance; -} - -Renderbuffer::~Renderbuffer() -{ - delete mInstance; -} - -// The RenderbufferInterface contained in this Renderbuffer may need to maintain -// its own reference count, so we pass it on here. -void Renderbuffer::addRef() const -{ - mInstance->addProxyRef(this); - - RefCountObject::addRef(); -} - -void Renderbuffer::release() const -{ - mInstance->releaseProxy(this); - - RefCountObject::release(); -} - -rx::RenderTarget *Renderbuffer::getRenderTarget() -{ - return mInstance->getRenderTarget(); -} - -rx::RenderTarget *Renderbuffer::getDepthStencil() -{ - return mInstance->getDepthStencil(); -} - -GLsizei Renderbuffer::getWidth() const -{ - return mInstance->getWidth(); -} - -GLsizei Renderbuffer::getHeight() const -{ - return mInstance->getHeight(); -} - -GLenum Renderbuffer::getInternalFormat() const -{ - return mInstance->getInternalFormat(); -} - -GLenum Renderbuffer::getActualFormat() const -{ - return mInstance->getActualFormat(); -} - -GLuint Renderbuffer::getRedSize() const -{ - return mInstance->getRedSize(); -} - -GLuint Renderbuffer::getGreenSize() const -{ - return mInstance->getGreenSize(); -} - -GLuint Renderbuffer::getBlueSize() const -{ - return mInstance->getBlueSize(); -} - -GLuint Renderbuffer::getAlphaSize() const -{ - return mInstance->getAlphaSize(); -} - -GLuint Renderbuffer::getDepthSize() const -{ - return mInstance->getDepthSize(); -} - -GLuint Renderbuffer::getStencilSize() const -{ - return mInstance->getStencilSize(); -} - -GLsizei Renderbuffer::getSamples() const -{ - return mInstance->getSamples(); -} - -unsigned int Renderbuffer::getSerial() const -{ - return mInstance->getSerial(); -} - -unsigned int Renderbuffer::getTextureSerial() const -{ - return mInstance->getTextureSerial(); -} - -void Renderbuffer::setStorage(RenderbufferStorage *newStorage) -{ - ASSERT(newStorage != NULL); - - delete mInstance; - mInstance = newStorage; -} - -RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) +RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1)) { mWidth = 0; mHeight = 0; @@ -338,6 +45,11 @@ rx::RenderTarget *RenderbufferStorage::getDepthStencil() return NULL; } +rx::TextureStorage *RenderbufferStorage::getTextureStorage() +{ + return NULL; +} + GLsizei RenderbufferStorage::getWidth() const { return mWidth; @@ -368,16 +80,21 @@ unsigned int RenderbufferStorage::getSerial() const return mSerial; } -unsigned int RenderbufferStorage::issueSerial() +unsigned int RenderbufferStorage::issueSerials(GLuint count) { - return mCurrentSerial++; + unsigned int firstSerial = mCurrentSerial; + mCurrentSerial += count; + return firstSerial; } -unsigned int RenderbufferStorage::issueCubeSerials() +bool RenderbufferStorage::isTexture() const { - unsigned int firstSerial = mCurrentSerial; - mCurrentSerial += 6; - return firstSerial; + return false; +} + +unsigned int RenderbufferStorage::getTextureSerial() const +{ + return -1; } Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) @@ -396,7 +113,7 @@ Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL) { - mRenderTarget = renderer->createRenderTarget(width, height, format, samples, false); + mRenderTarget = renderer->createRenderTarget(width, height, format, samples); if (mRenderTarget) { @@ -418,12 +135,7 @@ Colorbuffer::~Colorbuffer() rx::RenderTarget *Colorbuffer::getRenderTarget() { - if (mRenderTarget) - { - return mRenderTarget; - } - - return NULL; + return mRenderTarget; } DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) @@ -442,7 +154,7 @@ DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *sw DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) { - mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples, true); + mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples); mWidth = mDepthStencil->getWidth(); mHeight = mDepthStencil->getHeight(); @@ -461,12 +173,7 @@ DepthStencilbuffer::~DepthStencilbuffer() rx::RenderTarget *DepthStencilbuffer::getDepthStencil() { - if (mDepthStencil) - { - return mDepthStencil; - } - - return NULL; + return mDepthStencil; } Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) diff --git a/chromium/third_party/angle/src/libGLESv2/Renderbuffer.h b/chromium/third_party/angle/src/libGLESv2/Renderbuffer.h index d46fd44557c..4da447ae93c 100644 --- a/chromium/third_party/angle/src/libGLESv2/Renderbuffer.h +++ b/chromium/third_party/angle/src/libGLESv2/Renderbuffer.h @@ -12,122 +12,28 @@ #ifndef LIBGLESV2_RENDERBUFFER_H_ #define LIBGLESV2_RENDERBUFFER_H_ -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include "common/angleutils.h" #include "common/RefCountObject.h" +#include "libGLESv2/FramebufferAttachment.h" namespace rx { class Renderer; class SwapChain; class RenderTarget; +class TextureStorage; } namespace gl { -class Texture2D; -class TextureCubeMap; -class Renderbuffer; -class Colorbuffer; -class DepthStencilbuffer; - -class RenderbufferInterface -{ - public: - RenderbufferInterface(); - - virtual ~RenderbufferInterface() {}; - - virtual void addProxyRef(const Renderbuffer *proxy); - virtual void releaseProxy(const Renderbuffer *proxy); - - virtual rx::RenderTarget *getRenderTarget() = 0; - virtual rx::RenderTarget *getDepthStencil() = 0; - - virtual GLsizei getWidth() const = 0; - virtual GLsizei getHeight() const = 0; - virtual GLenum getInternalFormat() const = 0; - virtual GLenum getActualFormat() const = 0; - virtual GLsizei getSamples() const = 0; - - GLuint getRedSize() const; - GLuint getGreenSize() const; - GLuint getBlueSize() const; - GLuint getAlphaSize() const; - GLuint getDepthSize() const; - GLuint getStencilSize() const; - - virtual unsigned int getSerial() const = 0; - virtual unsigned int getTextureSerial() const = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferInterface); -}; - -class RenderbufferTexture2D : public RenderbufferInterface -{ - public: - RenderbufferTexture2D(Texture2D *texture, GLenum target); - - virtual ~RenderbufferTexture2D(); - - void addProxyRef(const Renderbuffer *proxy); - void releaseProxy(const Renderbuffer *proxy); - - rx::RenderTarget *getRenderTarget(); - rx::RenderTarget *getDepthStencil(); - - virtual GLsizei getWidth() const; - virtual GLsizei getHeight() const; - virtual GLenum getInternalFormat() const; - virtual GLenum getActualFormat() const; - virtual GLsizei getSamples() const; - - virtual unsigned int getSerial() const; - virtual unsigned int getTextureSerial() const; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture2D); - - BindingPointer <Texture2D> mTexture2D; - GLenum mTarget; -}; - -class RenderbufferTextureCubeMap : public RenderbufferInterface -{ - public: - RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target); - - virtual ~RenderbufferTextureCubeMap(); - - void addProxyRef(const Renderbuffer *proxy); - void releaseProxy(const Renderbuffer *proxy); - - rx::RenderTarget *getRenderTarget(); - rx::RenderTarget *getDepthStencil(); - - virtual GLsizei getWidth() const; - virtual GLsizei getHeight() const; - virtual GLenum getInternalFormat() const; - virtual GLenum getActualFormat() const; - virtual GLsizei getSamples() const; - - virtual unsigned int getSerial() const; - virtual unsigned int getTextureSerial() const; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferTextureCubeMap); - - BindingPointer <TextureCubeMap> mTextureCubeMap; - GLenum mTarget; -}; // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage // is called. The specific concrete type depends on whether the internal format is // colour depth, stencil or packed depth/stencil. -class RenderbufferStorage : public RenderbufferInterface +class RenderbufferStorage : public FramebufferAttachmentInterface { public: RenderbufferStorage(); @@ -136,6 +42,7 @@ class RenderbufferStorage : public RenderbufferInterface virtual rx::RenderTarget *getRenderTarget(); virtual rx::RenderTarget *getDepthStencil(); + virtual rx::TextureStorage *getTextureStorage(); virtual GLsizei getWidth() const; virtual GLsizei getHeight() const; @@ -144,10 +51,11 @@ class RenderbufferStorage : public RenderbufferInterface virtual GLsizei getSamples() const; virtual unsigned int getSerial() const; - virtual unsigned int getTextureSerial() const { return 0; } - static unsigned int issueSerial(); - static unsigned int issueCubeSerials(); + virtual bool isTexture() const; + virtual unsigned int getTextureSerial() const; + + static unsigned int issueSerials(GLuint count); protected: GLsizei mWidth; @@ -164,49 +72,6 @@ class RenderbufferStorage : public RenderbufferInterface static unsigned int mCurrentSerial; }; -// Renderbuffer implements the GL renderbuffer object. -// It's only a proxy for a RenderbufferInterface instance; the internal object -// can change whenever glRenderbufferStorage is called. -class Renderbuffer : public RefCountObject -{ - public: - Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *storage); - - virtual ~Renderbuffer(); - - // These functions from RefCountObject are overloaded here because - // Textures need to maintain their own count of references to them via - // Renderbuffers/RenderbufferTextures. These functions invoke those - // reference counting functions on the RenderbufferInterface. - void addRef() const; - void release() const; - - rx::RenderTarget *getRenderTarget(); - rx::RenderTarget *getDepthStencil(); - - GLsizei getWidth() const; - GLsizei getHeight() const; - GLenum getInternalFormat() const; - GLenum getActualFormat() const; - GLuint getRedSize() const; - GLuint getGreenSize() const; - GLuint getBlueSize() const; - GLuint getAlphaSize() const; - GLuint getDepthSize() const; - GLuint getStencilSize() const; - GLsizei getSamples() const; - - unsigned int getSerial() const; - unsigned int getTextureSerial() const; - - void setStorage(RenderbufferStorage *newStorage); - - private: - DISALLOW_COPY_AND_ASSIGN(Renderbuffer); - - RenderbufferInterface *mInstance; -}; - class Colorbuffer : public RenderbufferStorage { public: diff --git a/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.cpp b/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.cpp new file mode 100644 index 00000000000..f4fbe513254 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.cpp @@ -0,0 +1,87 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// RenderbufferProxySet.cpp: Implements the gl::RenderbufferProxySet, a class for +// maintaining a Texture's weak references to the Renderbuffers that represent it. + +#include "libGLESv2/RenderbufferProxySet.h" +#include "common/debug.h" + +namespace gl +{ + +void RenderbufferProxySet::addRef(const FramebufferAttachment *proxy) +{ + RefCountMap::iterator i = mRefCountMap.find(proxy); + if (i != mRefCountMap.end()) + { + i->second++; + } +} + +void RenderbufferProxySet::release(const FramebufferAttachment *proxy) +{ + RefCountMap::iterator i = mRefCountMap.find(proxy); + if (i != mRefCountMap.end()) + { + if (i->second > 0) + { + i->second--; + } + + if (i->second == 0) + { + // Clear the buffer map of references to this FramebufferAttachment + BufferMap::iterator j = mBufferMap.begin(); + while (j != mBufferMap.end()) + { + if (j->second == proxy) + { + j = mBufferMap.erase(j); + } + else + { + ++j; + } + } + + mRefCountMap.erase(i); + } + } +} + +void RenderbufferProxySet::add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer) +{ + if (mRefCountMap.find(renderBuffer) == mRefCountMap.end()) + { + mRefCountMap.insert(std::make_pair(renderBuffer, 0)); + } + + RenderbufferKey key; + key.mipLevel = mipLevel; + key.layer = layer; + if (mBufferMap.find(key) == mBufferMap.end()) + { + mBufferMap.insert(std::make_pair(key, renderBuffer)); + } +} + +FramebufferAttachment *RenderbufferProxySet::get(unsigned int mipLevel, unsigned int layer) const +{ + RenderbufferKey key; + key.mipLevel = mipLevel; + key.layer = layer; + BufferMap::const_iterator i = mBufferMap.find(key); + return (i != mBufferMap.end()) ? i->second : NULL; +} + +bool RenderbufferProxySet::RenderbufferKey::operator<(const RenderbufferKey &other) const +{ + return (mipLevel != other.mipLevel) ? mipLevel < other.mipLevel : layer < other.layer; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.h b/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.h new file mode 100644 index 00000000000..f1511515197 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/RenderbufferProxySet.h @@ -0,0 +1,46 @@ +// +// Copyright (c) 2013 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. +// + +// RenderbufferProxySet.h: Defines the gl::RenderbufferProxySet, a class for +// maintaining a Texture's weak references to the Renderbuffers that represent it. + +#ifndef LIBGLESV2_RENDERBUFFERPROXYSET_H_ +#define LIBGLESV2_RENDERBUFFERPROXYSET_H_ + +#include <map> + +namespace gl +{ +class FramebufferAttachment; + +class RenderbufferProxySet +{ + public: + void addRef(const FramebufferAttachment *proxy); + void release(const FramebufferAttachment *proxy); + + void add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer); + FramebufferAttachment *get(unsigned int mipLevel, unsigned int layer) const; + + private: + struct RenderbufferKey + { + unsigned int mipLevel; + unsigned int layer; + + bool operator<(const RenderbufferKey &other) const; + }; + + typedef std::map<RenderbufferKey, FramebufferAttachment*> BufferMap; + BufferMap mBufferMap; + + typedef std::map<const FramebufferAttachment*, unsigned int> RefCountMap; + RefCountMap mRefCountMap; +}; + +} + +#endif // LIBGLESV2_RENDERBUFFERPROXYSET_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/ResourceManager.cpp b/chromium/third_party/angle/src/libGLESv2/ResourceManager.cpp index 58dd44fd955..cf0812d7361 100644 --- a/chromium/third_party/angle/src/libGLESv2/ResourceManager.cpp +++ b/chromium/third_party/angle/src/libGLESv2/ResourceManager.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -15,6 +15,8 @@ #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Texture.h" +#include "libGLESv2/Sampler.h" +#include "libGLESv2/Fence.h" namespace gl { @@ -50,6 +52,16 @@ ResourceManager::~ResourceManager() { deleteTexture(mTextureMap.begin()->first); } + + while (!mSamplerMap.empty()) + { + deleteSampler(mSamplerMap.begin()->first); + } + + while (!mFenceSyncMap.empty()) + { + deleteFenceSync(mFenceSyncMap.begin()->first); + } } void ResourceManager::addRef() @@ -123,6 +135,26 @@ GLuint ResourceManager::createRenderbuffer() return handle; } +// Returns an unused sampler name +GLuint ResourceManager::createSampler() +{ + GLuint handle = mSamplerHandleAllocator.allocate(); + + mSamplerMap[handle] = NULL; + + return handle; +} + +// Returns the next unused fence name, and allocates the fence +GLuint ResourceManager::createFenceSync() +{ + GLuint handle = mFenceSyncHandleAllocator.allocate(); + + mFenceSyncMap[handle] = new FenceSync(mRenderer, handle); + + return handle; +} + void ResourceManager::deleteBuffer(GLuint buffer) { BufferMap::iterator bufferObject = mBufferMap.find(buffer); @@ -197,6 +229,30 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) } } +void ResourceManager::deleteSampler(GLuint sampler) +{ + auto samplerObject = mSamplerMap.find(sampler); + + if (samplerObject != mSamplerMap.end()) + { + mSamplerHandleAllocator.release(samplerObject->first); + if (samplerObject->second) samplerObject->second->release(); + mSamplerMap.erase(samplerObject); + } +} + +void ResourceManager::deleteFenceSync(GLuint fenceSync) +{ + auto fenceObjectIt = mFenceSyncMap.find(fenceSync); + + if (fenceObjectIt != mFenceSyncMap.end()) + { + mFenceSyncHandleAllocator.release(fenceObjectIt->first); + if (fenceObjectIt->second) fenceObjectIt->second->release(); + mFenceSyncMap.erase(fenceObjectIt); + } +} + Buffer *ResourceManager::getBuffer(unsigned int handle) { BufferMap::iterator buffer = mBufferMap.find(handle); @@ -255,7 +311,7 @@ Program *ResourceManager::getProgram(unsigned int handle) } } -Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) +FramebufferAttachment *ResourceManager::getRenderbuffer(unsigned int handle) { RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); @@ -269,7 +325,35 @@ Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) } } -void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) +Sampler *ResourceManager::getSampler(unsigned int handle) +{ + auto sampler = mSamplerMap.find(handle); + + if (sampler == mSamplerMap.end()) + { + return NULL; + } + else + { + return sampler->second; + } +} + +FenceSync *ResourceManager::getFenceSync(unsigned int handle) +{ + auto fenceObjectIt = mFenceSyncMap.find(handle); + + if (fenceObjectIt == mFenceSyncMap.end()) + { + return NULL; + } + else + { + return fenceObjectIt->second; + } +} + +void ResourceManager::setRenderbuffer(GLuint handle, FramebufferAttachment *buffer) { mRenderbufferMap[handle] = buffer; } @@ -298,6 +382,14 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) { textureObject = new TextureCubeMap(mRenderer, texture); } + else if (type == TEXTURE_3D) + { + textureObject = new Texture3D(mRenderer, texture); + } + else if (type == TEXTURE_2D_ARRAY) + { + textureObject = new Texture2DArray(mRenderer, texture); + } else { UNREACHABLE(); @@ -313,10 +405,25 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) { if (renderbuffer != 0 && !getRenderbuffer(renderbuffer)) { - Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); + FramebufferAttachment *renderbufferObject = new FramebufferAttachment(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); mRenderbufferMap[renderbuffer] = renderbufferObject; renderbufferObject->addRef(); } } +void ResourceManager::checkSamplerAllocation(GLuint sampler) +{ + if (sampler != 0 && !getSampler(sampler)) + { + Sampler *samplerObject = new Sampler(sampler); + mSamplerMap[sampler] = samplerObject; + samplerObject->addRef(); + } +} + +bool ResourceManager::isSampler(GLuint sampler) +{ + return mSamplerMap.find(sampler) != mSamplerMap.end(); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/ResourceManager.h b/chromium/third_party/angle/src/libGLESv2/ResourceManager.h index e99c77c35d2..a08a6aae1ed 100644 --- a/chromium/third_party/angle/src/libGLESv2/ResourceManager.h +++ b/chromium/third_party/angle/src/libGLESv2/ResourceManager.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -10,14 +10,10 @@ #ifndef LIBGLESV2_RESOURCEMANAGER_H_ #define LIBGLESV2_RESOURCEMANAGER_H_ -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> -#ifdef _MSC_VER -#include <hash_map> -#else #include <unordered_map> -#endif #include "common/angleutils.h" #include "libGLESv2/angletypes.h" @@ -34,7 +30,9 @@ class Buffer; class Shader; class Program; class Texture; -class Renderbuffer; +class FramebufferAttachment; +class Sampler; +class FenceSync; class ResourceManager { @@ -50,24 +48,33 @@ class ResourceManager GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); + GLuint createSampler(); + GLuint createFenceSync(); void deleteBuffer(GLuint buffer); void deleteShader(GLuint shader); void deleteProgram(GLuint program); void deleteTexture(GLuint texture); void deleteRenderbuffer(GLuint renderbuffer); + void deleteSampler(GLuint sampler); + void deleteFenceSync(GLuint fenceSync); Buffer *getBuffer(GLuint handle); Shader *getShader(GLuint handle); Program *getProgram(GLuint handle); Texture *getTexture(GLuint handle); - Renderbuffer *getRenderbuffer(GLuint handle); + FramebufferAttachment *getRenderbuffer(GLuint handle); + Sampler *getSampler(GLuint handle); + FenceSync *getFenceSync(GLuint handle); - void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); + void setRenderbuffer(GLuint handle, FramebufferAttachment *renderbuffer); void checkBufferAllocation(unsigned int buffer); void checkTextureAllocation(GLuint texture, TextureType type); void checkRenderbufferAllocation(GLuint renderbuffer); + void checkSamplerAllocation(GLuint sampler); + + bool isSampler(GLuint sampler); private: DISALLOW_COPY_AND_ASSIGN(ResourceManager); @@ -75,32 +82,32 @@ class ResourceManager std::size_t mRefCount; rx::Renderer *mRenderer; -#ifndef HASH_MAP -# ifdef _MSC_VER -# define HASH_MAP stdext::hash_map -# else -# define HASH_MAP std::unordered_map -# endif -#endif - - typedef HASH_MAP<GLuint, Buffer*> BufferMap; + typedef std::unordered_map<GLuint, Buffer*> BufferMap; BufferMap mBufferMap; HandleAllocator mBufferHandleAllocator; - typedef HASH_MAP<GLuint, Shader*> ShaderMap; + typedef std::unordered_map<GLuint, Shader*> ShaderMap; ShaderMap mShaderMap; - typedef HASH_MAP<GLuint, Program*> ProgramMap; + typedef std::unordered_map<GLuint, Program*> ProgramMap; ProgramMap mProgramMap; HandleAllocator mProgramShaderHandleAllocator; - typedef HASH_MAP<GLuint, Texture*> TextureMap; + typedef std::unordered_map<GLuint, Texture*> TextureMap; TextureMap mTextureMap; HandleAllocator mTextureHandleAllocator; - typedef HASH_MAP<GLuint, Renderbuffer*> RenderbufferMap; + typedef std::unordered_map<GLuint, FramebufferAttachment*> RenderbufferMap; RenderbufferMap mRenderbufferMap; HandleAllocator mRenderbufferHandleAllocator; + + typedef std::unordered_map<GLuint, Sampler*> SamplerMap; + SamplerMap mSamplerMap; + HandleAllocator mSamplerHandleAllocator; + + typedef std::unordered_map<GLuint, FenceSync*> FenceMap; + FenceMap mFenceSyncMap; + HandleAllocator mFenceSyncHandleAllocator; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/Sampler.cpp b/chromium/third_party/angle/src/libGLESv2/Sampler.cpp new file mode 100644 index 00000000000..ed6e29f89ef --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/Sampler.cpp @@ -0,0 +1,44 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Sampler.cpp : Implements the Sampler class, which represents a GLES 3 +// sampler object. Sampler objects store some state needed to sample textures. + +#include "libGLESv2/Sampler.h" +#include "libGLESv2/angletypes.h" + +namespace gl +{ + +Sampler::Sampler(GLuint id) + : RefCountObject(id), + mMinFilter(GL_NEAREST_MIPMAP_LINEAR), + mMagFilter(GL_LINEAR), + mWrapS(GL_REPEAT), + mWrapT(GL_REPEAT), + mWrapR(GL_REPEAT), + mMinLod(-1000.0f), + mMaxLod(1000.0f), + mComparisonMode(GL_NONE), + mComparisonFunc(GL_LEQUAL) +{ +} + +void Sampler::getState(SamplerState *samplerState) const +{ + samplerState->minFilter = mMinFilter; + samplerState->magFilter = mMagFilter; + samplerState->wrapS = mWrapS; + samplerState->wrapT = mWrapT; + samplerState->wrapR = mWrapR; + samplerState->minLod = mMinLod; + samplerState->maxLod = mMaxLod; + samplerState->compareMode = mComparisonMode; + samplerState->compareFunc = mComparisonFunc; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/Sampler.h b/chromium/third_party/angle/src/libGLESv2/Sampler.h new file mode 100644 index 00000000000..257bc25d22a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/Sampler.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2013 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. +// + +// Sampler.h : Defines the Sampler class, which represents a GLES 3 +// sampler object. Sampler objects store some state needed to sample textures. + +#ifndef LIBGLESV2_SAMPLER_H_ +#define LIBGLESV2_SAMPLER_H_ + +#include "common/RefCountObject.h" + +namespace gl +{ +struct SamplerState; + +class Sampler : public RefCountObject +{ + public: + Sampler(GLuint id); + + void setMinFilter(GLenum minFilter) { mMinFilter = minFilter; } + void setMagFilter(GLenum magFilter) { mMagFilter = magFilter; } + void setWrapS(GLenum wrapS) { mWrapS = wrapS; } + void setWrapT(GLenum wrapT) { mWrapT = wrapT; } + void setWrapR(GLenum wrapR) { mWrapR = wrapR; } + void setMinLod(GLfloat minLod) { mMinLod = minLod; } + void setMaxLod(GLfloat maxLod) { mMaxLod = maxLod; } + void setComparisonMode(GLenum comparisonMode) { mComparisonMode = comparisonMode; } + void setComparisonFunc(GLenum comparisonFunc) { mComparisonFunc = comparisonFunc; } + + GLenum getMinFilter() const { return mMinFilter; } + GLenum getMagFilter() const { return mMagFilter; } + GLenum getWrapS() const { return mWrapS; } + GLenum getWrapT() const { return mWrapT; } + GLenum getWrapR() const { return mWrapR; } + GLfloat getMinLod() const { return mMinLod; } + GLfloat getMaxLod() const { return mMaxLod; } + GLenum getComparisonMode() const { return mComparisonMode; } + GLenum getComparisonFunc() const { return mComparisonFunc; } + + void getState(SamplerState *samplerState) const; + + private: + GLenum mMinFilter; + GLenum mMagFilter; + GLenum mWrapS; + GLenum mWrapT; + GLenum mWrapR; + GLfloat mMinLod; + GLfloat mMaxLod; + GLenum mComparisonMode; + GLenum mComparisonFunc; +}; + +} + +#endif // LIBGLESV2_SAMPLER_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/Shader.cpp b/chromium/third_party/angle/src/libGLESv2/Shader.cpp index f6a2f03dfc4..7d0d781093e 100644 --- a/chromium/third_party/angle/src/libGLESv2/Shader.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Shader.cpp @@ -12,7 +12,7 @@ #include "libGLESv2/Shader.h" #include "GLSLANG/ShaderLang.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/Constants.h" #include "libGLESv2/ResourceManager.h" @@ -25,22 +25,16 @@ void *Shader::mVertexCompiler = NULL; Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle) : mHandle(handle), mRenderer(renderer), mResourceManager(manager) { - mSource = NULL; - mHlsl = NULL; - mInfoLog = NULL; - uncompile(); initializeCompiler(); mRefCount = 0; mDeleteStatus = false; + mShaderVersion = 100; } Shader::~Shader() { - delete[] mSource; - delete[] mHlsl; - delete[] mInfoLog; } GLuint Shader::getHandle() const @@ -48,69 +42,31 @@ GLuint Shader::getHandle() const return mHandle; } -void Shader::setSource(GLsizei count, const char **string, const GLint *length) +void Shader::setSource(GLsizei count, const char *const *string, const GLint *length) { - delete[] mSource; - int totalLength = 0; - - for (int i = 0; i < count; i++) - { - if (length && length[i] >= 0) - { - totalLength += length[i]; - } - else - { - totalLength += (int)strlen(string[i]); - } - } - - mSource = new char[totalLength + 1]; - char *code = mSource; + std::ostringstream stream; for (int i = 0; i < count; i++) { - int stringLength; - - if (length && length[i] >= 0) - { - stringLength = length[i]; - } - else - { - stringLength = (int)strlen(string[i]); - } - - strncpy(code, string[i], stringLength); - code += stringLength; + stream << string[i]; } - mSource[totalLength] = '\0'; + mSource = stream.str(); } int Shader::getInfoLogLength() const { - if (!mInfoLog) - { - return 0; - } - else - { - return strlen(mInfoLog) + 1; - } + return mInfoLog.empty() ? 0 : (mInfoLog.length() + 1); } -void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) +void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const { int index = 0; if (bufSize > 0) { - if (mInfoLog) - { - index = std::min(bufSize - 1, (int)strlen(mInfoLog)); - memcpy(infoLog, mInfoLog, index); - } + index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length())); + memcpy(infoLog, mInfoLog.c_str(), index); infoLog[index] = '\0'; } @@ -123,39 +79,22 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) int Shader::getSourceLength() const { - if (!mSource) - { - return 0; - } - else - { - return strlen(mSource) + 1; - } + return mSource.empty() ? 0 : (mSource.length() + 1); } int Shader::getTranslatedSourceLength() const { - if (!mHlsl) - { - return 0; - } - else - { - return strlen(mHlsl) + 1; - } + return mHlsl.empty() ? 0 : (mHlsl.length() + 1); } -void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer) +void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const { int index = 0; if (bufSize > 0) { - if (source) - { - index = std::min(bufSize - 1, (int)strlen(source)); - memcpy(buffer, source, index); - } + index = std::min(bufSize - 1, static_cast<GLsizei>(source.length())); + memcpy(buffer, source.c_str(), index); buffer[index] = '\0'; } @@ -166,27 +105,37 @@ void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char } } -void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) +void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const { getSourceImpl(mSource, bufSize, length, buffer); } -void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) +void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const { getSourceImpl(mHlsl, bufSize, length, buffer); } -const sh::ActiveUniforms &Shader::getUniforms() +const std::vector<Uniform> &Shader::getUniforms() const { return mActiveUniforms; } -bool Shader::isCompiled() +const std::vector<InterfaceBlock> &Shader::getInterfaceBlocks() const { - return mHlsl != NULL; + return mActiveInterfaceBlocks; } -const char *Shader::getHLSL() +std::vector<PackedVarying> &Shader::getVaryings() +{ + return mVaryings; +} + +bool Shader::isCompiled() const +{ + return !mHlsl.empty(); +} + +const std::string &Shader::getHLSL() const { return mHlsl; } @@ -245,9 +194,15 @@ void Shader::initializeCompiler() resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets(); resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport(); resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1; + resources.EXT_shader_texture_lod = 1; // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported. resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output + // GLSL ES 3.0 constants + resources.MaxVertexOutputVectors = mRenderer->getMaxVaryingVectors(); + resources.MaxFragmentInputVectors = mRenderer->getMaxVaryingVectors(); + resources.MinProgramTexelOffset = -8; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE + resources.MaxProgramTexelOffset = 7; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); @@ -266,57 +221,37 @@ void Shader::releaseCompiler() ShFinalize(); } -void Shader::parseVaryings() +void Shader::parseVaryings(void *compiler) { - if (mHlsl) + if (!mHlsl.empty()) { - const char *input = strstr(mHlsl, "// Varyings") + 12; + std::vector<Varying> *activeVaryings; + ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&activeVaryings)); - while(true) + for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++) { - char varyingType[256]; - char varyingName[256]; - - int matches = sscanf(input, "static %255s %255s", varyingType, varyingName); - - if (matches != 2) - { - break; - } - - char *array = strstr(varyingName, "["); - int size = 1; - - if (array) - { - size = atoi(array + 1); - *array = '\0'; - } - - mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL)); - - input = strstr(input, ";") + 2; + mVaryings.push_back(PackedVarying((*activeVaryings)[varyingIndex])); } - mUsesMultipleRenderTargets = strstr(mHlsl, "GL_USES_MRT") != NULL; - mUsesFragColor = strstr(mHlsl, "GL_USES_FRAG_COLOR") != NULL; - mUsesFragData = strstr(mHlsl, "GL_USES_FRAG_DATA") != NULL; - mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL; - mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL; - mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL; - mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL; - mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL; - mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL; - mUsesDiscardRewriting = strstr(mHlsl, "ANGLE_USES_DISCARD_REWRITING") != NULL; + mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos; + mUsesFragColor = mHlsl.find("GL_USES_FRAG_COLOR") != std::string::npos; + mUsesFragData = mHlsl.find("GL_USES_FRAG_DATA") != std::string::npos; + mUsesFragCoord = mHlsl.find("GL_USES_FRAG_COORD") != std::string::npos; + mUsesFrontFacing = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos; + mUsesPointSize = mHlsl.find("GL_USES_POINT_SIZE") != std::string::npos; + mUsesPointCoord = mHlsl.find("GL_USES_POINT_COORD") != std::string::npos; + mUsesDepthRange = mHlsl.find("GL_USES_DEPTH_RANGE") != std::string::npos; + mUsesFragDepth = mHlsl.find("GL_USES_FRAG_DEPTH") != std::string::npos; + mUsesDiscardRewriting = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; + mUsesNestedBreak = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; } } void Shader::resetVaryingsRegisterAssignment() { - for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++) + for (unsigned int varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++) { - var->reg = -1; - var->col = -1; + mVaryings[varyingIndex].resetRegisterAssignment(); } } @@ -324,10 +259,8 @@ void Shader::resetVaryingsRegisterAssignment() void Shader::uncompile() { // set by compileToHLSL - delete[] mHlsl; - mHlsl = NULL; - delete[] mInfoLog; - mInfoLog = NULL; + mHlsl.clear(); + mInfoLog.clear(); // set by parseVaryings mVaryings.clear(); @@ -341,20 +274,16 @@ void Shader::uncompile() mUsesPointCoord = false; mUsesDepthRange = false; mUsesFragDepth = false; + mShaderVersion = 100; mUsesDiscardRewriting = false; + mUsesNestedBreak = false; mActiveUniforms.clear(); + mActiveInterfaceBlocks.clear(); } void Shader::compileToHLSL(void *compiler) { - // ensure we don't pass a NULL source to the compiler - const char *source = "\0"; - if (mSource) - { - source = mSource; - } - // ensure the compiler is loaded initializeCompiler(); @@ -363,164 +292,189 @@ void Shader::compileToHLSL(void *compiler) if (perfActive()) { sourcePath = getTempPath(); - writeFile(sourcePath.c_str(), source, strlen(source)); + writeFile(sourcePath.c_str(), mSource.c_str(), mSource.length()); compileOptions |= SH_LINE_DIRECTIVES; } int result; if (sourcePath.empty()) { - result = ShCompile(compiler, &source, 1, compileOptions); + const char* sourceStrings[] = + { + mSource.c_str(), + }; + + result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); } else { - const char* sourceStrings[2] = + const char* sourceStrings[] = { sourcePath.c_str(), - source + mSource.c_str(), }; - result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH); + result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } - if (result) + size_t shaderVersion = 100; + ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion); + + mShaderVersion = static_cast<int>(shaderVersion); + + if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3) + { + mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts"; + TRACE("\n%s", mInfoLog.c_str()); + } + else if (result) { size_t objCodeLen = 0; ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); - mHlsl = new char[objCodeLen]; - ShGetObjectCode(compiler, mHlsl); + + char* outputHLSL = new char[objCodeLen]; + ShGetObjectCode(compiler, outputHLSL); + +#ifdef _DEBUG + std::ostringstream hlslStream; + hlslStream << "// GLSL\n"; + hlslStream << "//\n"; + + size_t curPos = 0; + while (curPos != std::string::npos) + { + size_t nextLine = mSource.find("\n", curPos); + size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); + + hlslStream << "// " << mSource.substr(curPos, len); + + curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); + } + hlslStream << "\n\n"; + hlslStream << outputHLSL; + mHlsl = hlslStream.str(); +#else + mHlsl = outputHLSL; +#endif + + delete[] outputHLSL; void *activeUniforms; ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms); - mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms; + mActiveUniforms = *(std::vector<Uniform>*)activeUniforms; + + void *activeInterfaceBlocks; + ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks); + mActiveInterfaceBlocks = *(std::vector<InterfaceBlock>*)activeInterfaceBlocks; } else { size_t infoLogLen = 0; ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); - mInfoLog = new char[infoLogLen]; - ShGetInfoLog(compiler, mInfoLog); - TRACE("\n%s", mInfoLog); + char* infoLog = new char[infoLogLen]; + ShGetInfoLog(compiler, infoLog); + mInfoLog = infoLog; + + TRACE("\n%s", mInfoLog.c_str()); } } -GLenum Shader::parseType(const std::string &type) +rx::D3DWorkaroundType Shader::getD3DWorkarounds() const { - if (type == "float") - { - return GL_FLOAT; - } - else if (type == "float2") - { - return GL_FLOAT_VEC2; - } - else if (type == "float3") - { - return GL_FLOAT_VEC3; - } - else if (type == "float4") - { - return GL_FLOAT_VEC4; - } - else if (type == "float2x2") + if (mUsesDiscardRewriting) { - return GL_FLOAT_MAT2; + // ANGLE issue 486: + // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization + return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION; } - else if (type == "float3x3") - { - return GL_FLOAT_MAT3; - } - else if (type == "float4x4") + + if (mUsesNestedBreak) { - return GL_FLOAT_MAT4; + // ANGLE issue 603: + // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization + // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence + return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION; } - else UNREACHABLE(); - return GL_NONE; + return rx::ANGLE_D3D_WORKAROUND_NONE; } +// [OpenGL ES SL 3.00.4] Section 11 p. 120 +// Vertex Outs/Fragment Ins packing priorities +static const GLenum varyingPriorityList[] = +{ + // 1. Arrays of mat4 and mat4 + GL_FLOAT_MAT4, + + // Non-square matrices of type matCxR consume the same space as a square + // matrix of type matN where N is the greater of C and R + GL_FLOAT_MAT3x4, + GL_FLOAT_MAT4x3, + GL_FLOAT_MAT2x4, + GL_FLOAT_MAT4x2, + + // 2. Arrays of mat2 and mat2 (since they occupy full rows) + GL_FLOAT_MAT2, + + // 3. Arrays of vec4 and vec4 + GL_FLOAT_VEC4, + GL_INT_VEC4, + GL_UNSIGNED_INT_VEC4, + + // 4. Arrays of mat3 and mat3 + GL_FLOAT_MAT3, + GL_FLOAT_MAT2x3, + GL_FLOAT_MAT3x2, + + // 5. Arrays of vec3 and vec3 + GL_FLOAT_VEC3, + GL_INT_VEC3, + GL_UNSIGNED_INT_VEC3, + + // 6. Arrays of vec2 and vec2 + GL_FLOAT_VEC2, + GL_INT_VEC2, + GL_UNSIGNED_INT_VEC2, + + // 7. Arrays of float and float + GL_FLOAT, + GL_INT, + GL_UNSIGNED_INT, +}; + // true if varying x has a higher priority in packing than y -bool Shader::compareVarying(const Varying &x, const Varying &y) +bool Shader::compareVarying(const PackedVarying &x, const PackedVarying &y) { - if(x.type == y.type) + if (x.type == y.type) { - return x.size > y.size; + return x.arraySize > y.arraySize; } - switch (x.type) + // Special case for handling structs: we sort these to the end of the list + if (x.type == GL_STRUCT_ANGLEX) { - case GL_FLOAT_MAT4: return true; - case GL_FLOAT_MAT2: - switch(y.type) - { - case GL_FLOAT_MAT4: return false; - case GL_FLOAT_MAT2: return true; - case GL_FLOAT_VEC4: return true; - case GL_FLOAT_MAT3: return true; - case GL_FLOAT_VEC3: return true; - case GL_FLOAT_VEC2: return true; - case GL_FLOAT: return true; - default: UNREACHABLE(); - } - break; - case GL_FLOAT_VEC4: - switch(y.type) - { - case GL_FLOAT_MAT4: return false; - case GL_FLOAT_MAT2: return false; - case GL_FLOAT_VEC4: return true; - case GL_FLOAT_MAT3: return true; - case GL_FLOAT_VEC3: return true; - case GL_FLOAT_VEC2: return true; - case GL_FLOAT: return true; - default: UNREACHABLE(); - } - break; - case GL_FLOAT_MAT3: - switch(y.type) - { - case GL_FLOAT_MAT4: return false; - case GL_FLOAT_MAT2: return false; - case GL_FLOAT_VEC4: return false; - case GL_FLOAT_MAT3: return true; - case GL_FLOAT_VEC3: return true; - case GL_FLOAT_VEC2: return true; - case GL_FLOAT: return true; - default: UNREACHABLE(); - } - break; - case GL_FLOAT_VEC3: - switch(y.type) - { - case GL_FLOAT_MAT4: return false; - case GL_FLOAT_MAT2: return false; - case GL_FLOAT_VEC4: return false; - case GL_FLOAT_MAT3: return false; - case GL_FLOAT_VEC3: return true; - case GL_FLOAT_VEC2: return true; - case GL_FLOAT: return true; - default: UNREACHABLE(); - } - break; - case GL_FLOAT_VEC2: - switch(y.type) - { - case GL_FLOAT_MAT4: return false; - case GL_FLOAT_MAT2: return false; - case GL_FLOAT_VEC4: return false; - case GL_FLOAT_MAT3: return false; - case GL_FLOAT_VEC3: return false; - case GL_FLOAT_VEC2: return true; - case GL_FLOAT: return true; - default: UNREACHABLE(); - } - break; - case GL_FLOAT: return false; - default: UNREACHABLE(); + return false; + } + + unsigned int xPriority = GL_INVALID_INDEX; + unsigned int yPriority = GL_INVALID_INDEX; + + for (unsigned int priorityIndex = 0; priorityIndex < ArraySize(varyingPriorityList); priorityIndex++) + { + if (varyingPriorityList[priorityIndex] == x.type) xPriority = priorityIndex; + if (varyingPriorityList[priorityIndex] == y.type) yPriority = priorityIndex; + if (xPriority != GL_INVALID_INDEX && yPriority != GL_INVALID_INDEX) break; } - return false; + ASSERT(xPriority != GL_INVALID_INDEX && yPriority != GL_INVALID_INDEX); + + return xPriority <= yPriority; +} + +int Shader::getShaderVersion() const +{ + return mShaderVersion; } VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle) @@ -542,7 +496,7 @@ void VertexShader::uncompile() Shader::uncompile(); // set by ParseAttributes - mAttributes.clear(); + mActiveAttributes.clear(); } void VertexShader::compile() @@ -551,7 +505,7 @@ void VertexShader::compile() compileToHLSL(mVertexCompiler); parseAttributes(); - parseVaryings(); + parseVaryings(mVertexCompiler); } int VertexShader::getSemanticIndex(const std::string &attributeName) @@ -559,14 +513,16 @@ int VertexShader::getSemanticIndex(const std::string &attributeName) if (!attributeName.empty()) { int semanticIndex = 0; - for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++) + for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++) { - if (attribute->name == attributeName) + const ShaderVariable &attribute = mActiveAttributes[attributeIndex]; + + if (attribute.name == attributeName) { return semanticIndex; } - semanticIndex += VariableRowCount(attribute->type); + semanticIndex += AttributeRegisterCount(attribute.type); } } @@ -575,27 +531,12 @@ int VertexShader::getSemanticIndex(const std::string &attributeName) void VertexShader::parseAttributes() { - const char *hlsl = getHLSL(); - if (hlsl) + const std::string &hlsl = getHLSL(); + if (!hlsl.empty()) { - const char *input = strstr(hlsl, "// Attributes") + 14; - - while(true) - { - char attributeType[256]; - char attributeName[256]; - - int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName); - - if (matches != 2) - { - break; - } - - mAttributes.push_back(Attribute(parseType(attributeType), attributeName)); - - input = strstr(input, ";") + 2; - } + void *activeAttributes; + ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes); + mActiveAttributes = *(std::vector<Attribute>*)activeAttributes; } } @@ -618,7 +559,45 @@ void FragmentShader::compile() uncompile(); compileToHLSL(mFragmentCompiler); - parseVaryings(); - mVaryings.sort(compareVarying); + parseVaryings(mFragmentCompiler); + std::sort(mVaryings.begin(), mVaryings.end(), compareVarying); + + const std::string &hlsl = getHLSL(); + if (!hlsl.empty()) + { + void *activeOutputVariables; + ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables); + mActiveOutputVariables = *(std::vector<Attribute>*)activeOutputVariables; + } } + +void FragmentShader::uncompile() +{ + Shader::uncompile(); + + mActiveOutputVariables.clear(); +} + +const std::vector<Attribute> &FragmentShader::getOutputVariables() const +{ + return mActiveOutputVariables; +} + +ShShaderOutput Shader::getCompilerOutputType(GLenum shader) +{ + void *compiler = NULL; + + switch (shader) + { + case GL_VERTEX_SHADER: compiler = mVertexCompiler; break; + case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break; + default: UNREACHABLE(); return SH_HLSL9_OUTPUT; + } + + size_t outputType = 0; + ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType); + + return static_cast<ShShaderOutput>(outputType); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/Shader.h b/chromium/third_party/angle/src/libGLESv2/Shader.h index 848d4c99a71..a4189499406 100644 --- a/chromium/third_party/angle/src/libGLESv2/Shader.h +++ b/chromium/third_party/angle/src/libGLESv2/Shader.h @@ -12,14 +12,16 @@ #ifndef LIBGLESV2_SHADER_H_ #define LIBGLESV2_SHADER_H_ -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include <string> #include <list> #include <vector> -#include "compiler/Uniform.h" +#include "common/shadervars.h" #include "common/angleutils.h" +#include "libGLESv2/angletypes.h" +#include "GLSLANG/ShaderLang.h" namespace rx { @@ -30,27 +32,26 @@ namespace gl { class ResourceManager; -struct Varying +struct PackedVarying : public Varying { - Varying(GLenum type, const std::string &name, int size, bool array) - : type(type), name(name), size(size), array(array), reg(-1), col(-1) - { - } + unsigned int registerIndex; // Assigned during link - GLenum type; - std::string name; - int size; // Number of 'type' elements - bool array; + PackedVarying(const Varying &varying) + : Varying(varying), + registerIndex(GL_INVALID_INDEX) + {} - int reg; // First varying register, assigned during link - int col; // First register element, assigned during link -}; + bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; } -typedef std::list<Varying> VaryingList; + void resetRegisterAssignment() + { + registerIndex = GL_INVALID_INDEX; + } +}; class Shader { - friend class ProgramBinary; + friend class DynamicHLSL; public: Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle); @@ -61,42 +62,49 @@ class Shader GLuint getHandle() const; void deleteSource(); - void setSource(GLsizei count, const char **string, const GLint *length); + void setSource(GLsizei count, const char *const *string, const GLint *length); int getInfoLogLength() const; - void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); + void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; int getSourceLength() const; - void getSource(GLsizei bufSize, GLsizei *length, char *buffer); + void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; int getTranslatedSourceLength() const; - void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer); - const sh::ActiveUniforms &getUniforms(); + void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; + const std::vector<Uniform> &getUniforms() const; + const std::vector<InterfaceBlock> &getInterfaceBlocks() const; + std::vector<PackedVarying> &getVaryings(); virtual void compile() = 0; virtual void uncompile(); - bool isCompiled(); - const char *getHLSL(); + bool isCompiled() const; + const std::string &getHLSL() const; void addRef(); void release(); unsigned int getRefCount() const; bool isFlaggedForDeletion() const; void flagForDeletion(); + int getShaderVersion() const; + void resetVaryingsRegisterAssignment(); static void releaseCompiler(); + static ShShaderOutput getCompilerOutputType(GLenum shader); + + bool usesDepthRange() const { return mUsesDepthRange; } + bool usesPointSize() const { return mUsesPointSize; } + rx::D3DWorkaroundType getD3DWorkarounds() const; protected: - void parseVaryings(); - void resetVaryingsRegisterAssignment(); + void parseVaryings(void *compiler); void compileToHLSL(void *compiler); - void getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer); + void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const; - static GLenum parseType(const std::string &type); - static bool compareVarying(const Varying &x, const Varying &y); + static bool compareVarying(const PackedVarying &x, const PackedVarying &y); const rx::Renderer *const mRenderer; - VaryingList mVaryings; + std::vector<PackedVarying> mVaryings; bool mUsesMultipleRenderTargets; bool mUsesFragColor; @@ -107,7 +115,9 @@ class Shader bool mUsesPointCoord; bool mUsesDepthRange; bool mUsesFragDepth; + int mShaderVersion; bool mUsesDiscardRewriting; + bool mUsesNestedBreak; static void *mFragmentCompiler; static void *mVertexCompiler; @@ -121,33 +131,18 @@ class Shader unsigned int mRefCount; // Number of program objects this shader is attached to bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use - char *mSource; - char *mHlsl; - char *mInfoLog; - sh::ActiveUniforms mActiveUniforms; + std::string mSource; + std::string mHlsl; + std::string mInfoLog; + std::vector<Uniform> mActiveUniforms; + std::vector<InterfaceBlock> mActiveInterfaceBlocks; ResourceManager *mResourceManager; }; -struct Attribute -{ - Attribute() : type(GL_NONE), name("") - { - } - - Attribute(GLenum type, const std::string &name) : type(type), name(name) - { - } - - GLenum type; - std::string name; -}; - -typedef std::vector<Attribute> AttributeArray; - class VertexShader : public Shader { - friend class ProgramBinary; + friend class DynamicHLSL; public: VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle); @@ -159,12 +154,14 @@ class VertexShader : public Shader virtual void uncompile(); int getSemanticIndex(const std::string &attributeName); + const std::vector<Attribute> &activeAttributes() const { return mActiveAttributes; } + private: DISALLOW_COPY_AND_ASSIGN(VertexShader); void parseAttributes(); - AttributeArray mAttributes; + std::vector<Attribute> mActiveAttributes; }; class FragmentShader : public Shader @@ -176,9 +173,13 @@ class FragmentShader : public Shader virtual GLenum getType(); virtual void compile(); + virtual void uncompile(); + const std::vector<Attribute> &getOutputVariables() const; private: DISALLOW_COPY_AND_ASSIGN(FragmentShader); + + std::vector<Attribute> mActiveOutputVariables; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/Texture.cpp b/chromium/third_party/angle/src/libGLESv2/Texture.cpp index cee9c57dacf..baa5bc68a96 100644 --- a/chromium/third_party/angle/src/libGLESv2/Texture.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Texture.cpp @@ -12,19 +12,44 @@ #include "libGLESv2/Texture.h" #include "libGLESv2/main.h" -#include "libGLESv2/mathutil.h" -#include "libGLESv2/utilities.h" -#include "libGLESv2/renderer/Blit.h" +#include "common/mathutil.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/renderer/Image.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/TextureStorage.h" #include "libEGL/Surface.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/renderer/BufferStorage.h" +#include "libGLESv2/renderer/RenderTarget.h" namespace gl { -Texture::Texture(rx::Renderer *renderer, GLuint id) : RefCountObject(id) +bool IsMipmapFiltered(const SamplerState &samplerState) +{ + switch (samplerState.minFilter) + { + case GL_NEAREST: + case GL_LINEAR: + return false; + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + return true; + default: UNREACHABLE(); + return false; + } +} + +bool IsRenderTargetUsage(GLenum usage) +{ + return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); +} + +Texture::Texture(rx::Renderer *renderer, GLuint id, GLenum target) : RefCountObject(id) { mRenderer = renderer; @@ -32,107 +57,129 @@ Texture::Texture(rx::Renderer *renderer, GLuint id) : RefCountObject(id) mSamplerState.magFilter = GL_LINEAR; mSamplerState.wrapS = GL_REPEAT; mSamplerState.wrapT = GL_REPEAT; + mSamplerState.wrapR = GL_REPEAT; mSamplerState.maxAnisotropy = 1.0f; - mSamplerState.lodOffset = 0; + mSamplerState.baseLevel = 0; + mSamplerState.maxLevel = 1000; + mSamplerState.minLod = -1000.0f; + mSamplerState.maxLod = 1000.0f; + mSamplerState.compareMode = GL_NONE; + mSamplerState.compareFunc = GL_LEQUAL; + mSamplerState.swizzleRed = GL_RED; + mSamplerState.swizzleGreen = GL_GREEN; + mSamplerState.swizzleBlue = GL_BLUE; + mSamplerState.swizzleAlpha = GL_ALPHA; mUsage = GL_NONE; - + mDirtyImages = true; mImmutable = false; + + mTarget = target; } Texture::~Texture() { } -// Returns true on successful filter state update (valid enum parameter) -bool Texture::setMinFilter(GLenum filter) +GLenum Texture::getTarget() const { - switch (filter) - { - case GL_NEAREST: - case GL_LINEAR: - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - mSamplerState.minFilter = filter; - return true; - default: - return false; - } + return mTarget; } -// Returns true on successful filter state update (valid enum parameter) -bool Texture::setMagFilter(GLenum filter) +void Texture::addProxyRef(const FramebufferAttachment *proxy) { - switch (filter) - { - case GL_NEAREST: - case GL_LINEAR: - mSamplerState.magFilter = filter; - return true; - default: - return false; - } + mRenderbufferProxies.addRef(proxy); } -// Returns true on successful wrap state update (valid enum parameter) -bool Texture::setWrapS(GLenum wrap) +void Texture::releaseProxy(const FramebufferAttachment *proxy) { - switch (wrap) - { - case GL_REPEAT: - case GL_CLAMP_TO_EDGE: - case GL_MIRRORED_REPEAT: - mSamplerState.wrapS = wrap; - return true; - default: - return false; - } + mRenderbufferProxies.release(proxy); } -// Returns true on successful wrap state update (valid enum parameter) -bool Texture::setWrapT(GLenum wrap) +void Texture::setMinFilter(GLenum filter) { - switch (wrap) - { - case GL_REPEAT: - case GL_CLAMP_TO_EDGE: - case GL_MIRRORED_REPEAT: - mSamplerState.wrapT = wrap; - return true; - default: - return false; - } + mSamplerState.minFilter = filter; } -// Returns true on successful max anisotropy update (valid anisotropy value) -bool Texture::setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy) +void Texture::setMagFilter(GLenum filter) { - textureMaxAnisotropy = std::min(textureMaxAnisotropy, contextMaxAnisotropy); - if (textureMaxAnisotropy < 1.0f) - { - return false; - } + mSamplerState.magFilter = filter; +} - mSamplerState.maxAnisotropy = textureMaxAnisotropy; +void Texture::setWrapS(GLenum wrap) +{ + mSamplerState.wrapS = wrap; +} - return true; +void Texture::setWrapT(GLenum wrap) +{ + mSamplerState.wrapT = wrap; } -// Returns true on successful usage state update (valid enum parameter) -bool Texture::setUsage(GLenum usage) +void Texture::setWrapR(GLenum wrap) { - switch (usage) - { - case GL_NONE: - case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: - mUsage = usage; - return true; - default: - return false; - } + mSamplerState.wrapR = wrap; +} + +void Texture::setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy) +{ + mSamplerState.maxAnisotropy = std::min(textureMaxAnisotropy, contextMaxAnisotropy); +} + +void Texture::setCompareMode(GLenum mode) +{ + mSamplerState.compareMode = mode; +} + +void Texture::setCompareFunc(GLenum func) +{ + mSamplerState.compareFunc = func; +} + +void Texture::setSwizzleRed(GLenum swizzle) +{ + mSamplerState.swizzleRed = swizzle; +} + +void Texture::setSwizzleGreen(GLenum swizzle) +{ + mSamplerState.swizzleGreen = swizzle; +} + +void Texture::setSwizzleBlue(GLenum swizzle) +{ + mSamplerState.swizzleBlue = swizzle; +} + +void Texture::setSwizzleAlpha(GLenum swizzle) +{ + mSamplerState.swizzleAlpha = swizzle; +} + +void Texture::setBaseLevel(GLint baseLevel) +{ + mSamplerState.baseLevel = baseLevel; +} + +void Texture::setMaxLevel(GLint maxLevel) +{ + mSamplerState.maxLevel = maxLevel; +} + +void Texture::setMinLod(GLfloat minLod) +{ + mSamplerState.minLod = minLod; +} + +void Texture::setMaxLod(GLfloat maxLod) +{ + mSamplerState.maxLod = maxLod; +} + +void Texture::setUsage(GLenum usage) +{ + mUsage = usage; } GLenum Texture::getMinFilter() const @@ -155,21 +202,72 @@ GLenum Texture::getWrapT() const return mSamplerState.wrapT; } +GLenum Texture::getWrapR() const +{ + return mSamplerState.wrapR; +} + float Texture::getMaxAnisotropy() const { return mSamplerState.maxAnisotropy; } -int Texture::getLodOffset() +GLenum Texture::getSwizzleRed() const +{ + return mSamplerState.swizzleRed; +} + +GLenum Texture::getSwizzleGreen() const +{ + return mSamplerState.swizzleGreen; +} + +GLenum Texture::getSwizzleBlue() const +{ + return mSamplerState.swizzleBlue; +} + +GLenum Texture::getSwizzleAlpha() const { - rx::TextureStorageInterface *texture = getStorage(false); - return texture ? texture->getLodOffset() : 0; + return mSamplerState.swizzleAlpha; +} + +GLint Texture::getBaseLevel() const +{ + return mSamplerState.baseLevel; +} + +GLint Texture::getMaxLevel() const +{ + return mSamplerState.maxLevel; +} + +GLfloat Texture::getMinLod() const +{ + return mSamplerState.minLod; +} + +GLfloat Texture::getMaxLod() const +{ + return mSamplerState.maxLod; +} + +bool Texture::isSwizzled() const +{ + return mSamplerState.swizzleRed != GL_RED || + mSamplerState.swizzleGreen != GL_GREEN || + mSamplerState.swizzleBlue != GL_BLUE || + mSamplerState.swizzleAlpha != GL_ALPHA; } void Texture::getSamplerState(SamplerState *sampler) { *sampler = mSamplerState; - sampler->lodOffset = getLodOffset(); + + // Offset the effective base level by the texture storage's top level + rx::TextureStorageInterface *texture = getNativeTexture(); + int topLevel = texture ? texture->getTopLevel() : 0; + sampler->baseLevel = topLevel + mSamplerState.baseLevel; } GLenum Texture::getUsage() const @@ -177,57 +275,121 @@ GLenum Texture::getUsage() const return mUsage; } -bool Texture::isMipmapFiltered() const +GLint Texture::getBaseLevelWidth() const { - switch (mSamplerState.minFilter) + const rx::Image *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getWidth() : 0); +} + +GLint Texture::getBaseLevelHeight() const +{ + const rx::Image *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getHeight() : 0); +} + +GLint Texture::getBaseLevelDepth() const +{ + const rx::Image *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getDepth() : 0); +} + +// Note: "base level image" is loosely defined to be any image from the base level, +// where in the base of 2D array textures and cube maps there are several. Don't use +// the base level image for anything except querying texture format and size. +GLenum Texture::getBaseLevelInternalFormat() const +{ + const rx::Image *baseImage = getBaseLevelImage(); + return (baseImage ? baseImage->getInternalFormat() : GL_NONE); +} + +void Texture::setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image) +{ + // No-op + if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) { - case GL_NEAREST: - case GL_LINEAR: - return false; - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - return true; - default: UNREACHABLE(); - return false; + return; + } + + // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. + // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. + const void *pixelData = pixels; + + if (unpack.pixelBuffer.id() != 0) + { + // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported + Buffer *pixelBuffer = unpack.pixelBuffer.get(); + ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels); + const void *bufferData = pixelBuffer->getStorage()->getData(); + pixelData = static_cast<const unsigned char *>(bufferData) + offset; + } + + if (pixelData != NULL) + { + image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData); + mDirtyImages = true; } } -void Texture::setImage(GLint unpackAlignment, const void *pixels, rx::Image *image) +bool Texture::isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat) { - if (pixels != NULL) + return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat); +} + +bool Texture::fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea, + GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget) +{ + if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0) { - image->loadData(0, 0, image->getWidth(), image->getHeight(), unpackAlignment, pixels); - mDirtyImages = true; + return true; } + + // In order to perform the fast copy through the shader, we must have the right format, and be able + // to create a render target. + ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat)); + + unsigned int offset = reinterpret_cast<unsigned int>(pixels); + + return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea); } void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image) { if (pixels != NULL) { - image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), pixels); + image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels); mDirtyImages = true; } } -bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, rx::Image *image) +bool Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image) { - if (pixels != NULL) + const void *pixelData = pixels; + + // CPU readback & copy where direct GPU copy is not supported + if (unpack.pixelBuffer.id() != 0) { - image->loadData(xoffset, yoffset, width, height, unpackAlignment, pixels); + Buffer *pixelBuffer = unpack.pixelBuffer.get(); + unsigned int offset = reinterpret_cast<unsigned int>(pixels); + const void *bufferData = pixelBuffer->getStorage()->getData(); + pixelData = static_cast<const unsigned char *>(bufferData) + offset; + } + + if (pixelData != NULL) + { + image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData); mDirtyImages = true; } return true; } -bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image) +bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image) { if (pixels != NULL) { - image->loadCompressedData(xoffset, yoffset, width, height, pixels); + image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels); mDirtyImages = true; } @@ -237,11 +399,12 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL rx::TextureStorageInterface *Texture::getNativeTexture() { // ensure the underlying texture is created + initializeStorage(false); - rx::TextureStorageInterface *storage = getStorage(false); + rx::TextureStorageInterface *storage = getBaseLevelStorage(); if (storage) { - updateTexture(); + updateStorage(); } return storage; @@ -259,26 +422,26 @@ void Texture::resetDirty() unsigned int Texture::getTextureSerial() { - rx::TextureStorageInterface *texture = getStorage(false); + rx::TextureStorageInterface *texture = getNativeTexture(); return texture ? texture->getTextureSerial() : 0; } -unsigned int Texture::getRenderTargetSerial(GLenum target) +bool Texture::isImmutable() const { - rx::TextureStorageInterface *texture = getStorage(true); - return texture ? texture->getRenderTargetSerial(target) : 0; + return mImmutable; } -bool Texture::isImmutable() const +int Texture::immutableLevelCount() { - return mImmutable; + return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0); } -GLint Texture::creationLevels(GLsizei width, GLsizei height) const +GLint Texture::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const { - if ((isPow2(width) && isPow2(height)) || mRenderer->getNonPower2TextureSupport()) + if ((isPow2(width) && isPow2(height) && isPow2(depth)) || mRenderer->getNonPower2TextureSupport()) { - return 0; // Maximum number of levels + // Maximum number of levels + return log2(std::max(std::max(width, height), depth)) + 1; } else { @@ -287,17 +450,15 @@ GLint Texture::creationLevels(GLsizei width, GLsizei height) const } } -GLint Texture::creationLevels(GLsizei size) const +int Texture::mipLevels() const { - return creationLevels(size, size); + return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1; } -Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id) +Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D) { mTexStorage = NULL; mSurface = NULL; - mColorbufferProxy = NULL; - mProxyRefs = 0; for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { @@ -307,8 +468,6 @@ Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id) Texture2D::~Texture2D() { - mColorbufferProxy = NULL; - delete mTexStorage; mTexStorage = NULL; @@ -324,28 +483,6 @@ Texture2D::~Texture2D() } } -// We need to maintain a count of references to renderbuffers acting as -// proxies for this texture, so that we do not attempt to use a pointer -// to a renderbuffer proxy which has been deleted. -void Texture2D::addProxyRef(const Renderbuffer *proxy) -{ - mProxyRefs++; -} - -void Texture2D::releaseProxy(const Renderbuffer *proxy) -{ - if (mProxyRefs > 0) - mProxyRefs--; - - if (mProxyRefs == 0) - mColorbufferProxy = NULL; -} - -GLenum Texture2D::getTarget() const -{ - return GL_TEXTURE_2D; -} - GLsizei Texture2D::getWidth(GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -375,24 +512,24 @@ GLenum Texture2D::getActualFormat(GLint level) const if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) return mImageArray[level]->getActualFormat(); else - return D3DFMT_UNKNOWN; + return GL_NONE; } -void Texture2D::redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height) +void Texture2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height) { releaseTexImage(); // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, mImageArray[0]->getWidth() >> level); - const int storageHeight = std::max(1, mImageArray[0]->getHeight() >> level); - const int storageFormat = mImageArray[0]->getInternalFormat(); + const int storageWidth = std::max(1, getBaseLevelWidth() >> level); + const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); - mImageArray[level]->redefine(mRenderer, internalformat, width, height, false); + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, width, height, 1, false); if (mTexStorage) { - const int storageLevels = mTexStorage->levelCount(); - + const int storageLevels = mTexStorage->getLevelCount(); + if ((level >= storageLevels && storageLevels != 0) || width != storageWidth || height != storageHeight || @@ -410,21 +547,44 @@ void Texture2D::redefineImage(GLint level, GLint internalformat, GLsizei width, } } -void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - GLint internalformat = ConvertSizedInternalFormat(format, type); - redefineImage(level, internalformat, width, height); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat + : GetSizedInternalFormat(format, type, clientVersion); + redefineImage(level, sizedInternalFormat, width, height); + + bool fastUnpacked = false; - Texture::setImage(unpackAlignment, pixels, mImageArray[level]); + // Attempt a fast gpu copy of the pixel data to the surface + if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level)) + { + // Will try to create RT storage if it does not exist + rx::RenderTarget *destRenderTarget = getRenderTarget(level); + Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1); + + if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) + { + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; + } + } + + if (!fastUnpacked) + { + Texture::setImage(unpack, type, pixels, mImageArray[level]); + } } void Texture2D::bindTexImage(egl::Surface *surface) { releaseTexImage(); - GLint internalformat = surface->getFormat(); + GLenum internalformat = surface->getFormat(); - mImageArray[0]->redefine(mRenderer, internalformat, surface->getWidth(), surface->getHeight(), true); + mImageArray[0]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, surface->getWidth(), surface->getHeight(), 1, true); delete mTexStorage; mTexStorage = new rx::TextureStorageInterface2D(mRenderer, surface->getSwapChain()); @@ -449,7 +609,7 @@ void Texture2D::releaseTexImage() for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mImageArray[i]->redefine(mRenderer, GL_NONE, 0, 0, true); + mImageArray[i]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true); } } } @@ -464,19 +624,35 @@ void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - if (level < levelCount()) + if (isValidLevel(level)) { rx::Image *image = mImageArray[level]; - if (image->updateSurface(mTexStorage, level, xoffset, yoffset, width, height)) + if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, width, height)) { image->markClean(); } } } -void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, mImageArray[level])) + bool fastUnpacked = false; + + if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level)) + { + rx::RenderTarget *renderTarget = getRenderTarget(level); + Box destArea(xoffset, yoffset, 0, width, height, 1); + + if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget)) + { + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; + } + } + + if (!fastUnpacked && Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level])) { commitRect(level, xoffset, yoffset, width, height); } @@ -484,7 +660,7 @@ void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei widt void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) { - if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, mImageArray[level])) + if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level])) { commitRect(level, xoffset, yoffset, width, height); } @@ -492,24 +668,22 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - GLint internalformat = ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE); - redefineImage(level, internalformat, width, height); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format + : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion); + redefineImage(level, sizedInternalFormat, width, height); if (!mImageArray[level]->isRenderableFormat()) { - mImageArray[level]->copy(0, 0, x, y, width, height, source); + mImageArray[level]->copy(0, 0, 0, x, y, width, height, source); mDirtyImages = true; } else { - if (!mTexStorage || !mTexStorage->isRenderTarget()) - { - convertToRenderTarget(); - } - + ensureRenderTarget(); mImageArray[level]->markClean(); - if (width != 0 && height != 0 && level < levelCount()) + if (width != 0 && height != 0 && isValidLevel(level)) { gl::Rectangle sourceRect; sourceRect.x = x; @@ -522,37 +696,35 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei } } -void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - if (xoffset + width > mImageArray[level]->getWidth() || yoffset + height > mImageArray[level]->getHeight()) - { - return gl::error(GL_INVALID_VALUE); - } + // can only make our texture storage to a render target if level 0 is defined (with a width & height) and + // the current level we're copying to is defined (with appropriate format, width & height) + bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); - if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !isSamplerComplete())) + if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) { - mImageArray[level]->copy(xoffset, yoffset, x, y, width, height, source); + mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source); mDirtyImages = true; } else { - if (!mTexStorage || !mTexStorage->isRenderTarget()) - { - convertToRenderTarget(); - } + ensureRenderTarget(); - updateTexture(); - - if (level < levelCount()) + if (isValidLevel(level)) { + updateStorageLevel(level); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + gl::Rectangle sourceRect; sourceRect.x = x; sourceRect.width = width; sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, - gl::ExtractFormat(mImageArray[0]->getInternalFormat()), + mRenderer->copyImage(source, sourceRect, + gl::GetFormat(getBaseLevelInternalFormat(), clientVersion), xoffset, yoffset, mTexStorage, level); } } @@ -560,52 +732,54 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - delete mTexStorage; - mTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, mUsage, false, width, height); - mImmutable = true; - for (int level = 0; level < levels; level++) { - mImageArray[level]->redefine(mRenderer, internalformat, width, height, true); - width = std::max(1, width >> 1); - height = std::max(1, height >> 1); + GLsizei levelWidth = std::max(1, width >> level); + GLsizei levelHeight = std::max(1, height >> level); + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, levelWidth, levelHeight, 1, true); } for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - mImageArray[level]->redefine(mRenderer, GL_NONE, 0, 0, true); + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true); } - if (mTexStorage->isManaged()) - { - int levels = levelCount(); + mImmutable = true; + + setCompleteTexStorage(new rx::TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels)); +} + +void Texture2D::setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage) +{ + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; - for (int level = 0; level < levels; level++) + if (mTexStorage && mTexStorage->isManaged()) + { + for (int level = 0; level < mTexStorage->getLevelCount(); level++) { mImageArray[level]->setManagedSurface(mTexStorage, level); } } + + mDirtyImages = true; } // Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85. -bool Texture2D::isSamplerComplete() const +bool Texture2D::isSamplerComplete(const SamplerState &samplerState) const { - GLsizei width = mImageArray[0]->getWidth(); - GLsizei height = mImageArray[0]->getHeight(); + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); if (width <= 0 || height <= 0) { return false; } - bool mipmapping = isMipmapFiltered(); - bool filtering, renderable; - - if ((IsFloat32Format(getInternalFormat(0)) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) || - (IsFloat16Format(getInternalFormat(0)) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable))) + if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer)) { - if (mSamplerState.magFilter != GL_NEAREST || - (mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) + if (samplerState.magFilter != GL_NEAREST || + (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) { return false; } @@ -615,14 +789,14 @@ bool Texture2D::isSamplerComplete() const if (!npotSupport) { - if ((mSamplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(width)) || - (mSamplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(height))) + if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(width)) || + (samplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(height))) { return false; } } - if (mipmapping) + if (IsMipmapFiltered(samplerState)) { if (!npotSupport) { @@ -638,43 +812,82 @@ bool Texture2D::isSamplerComplete() const } } + // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if: + // The internalformat specified for the texture arrays is a sized internal depth or + // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_- + // MODE is NONE, and either the magnification filter is not NEAREST or the mini- + // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST. + if (gl::GetDepthBits(getInternalFormat(0), mRenderer->getCurrentClientVersion()) > 0 && + mRenderer->getCurrentClientVersion() > 2) + { + if (mSamplerState.compareMode == GL_NONE) + { + if ((mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) || + mSamplerState.magFilter != GL_NEAREST) + { + return false; + } + } + } + return true; } // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. bool Texture2D::isMipmapComplete() const { + int levelCount = mipLevels(); + + for (int level = 0; level < levelCount; level++) + { + if (!isLevelComplete(level)) + { + return false; + } + } + + return true; +} + +bool Texture2D::isLevelComplete(int level) const +{ if (isImmutable()) { return true; } - GLsizei width = mImageArray[0]->getWidth(); - GLsizei height = mImageArray[0]->getHeight(); + const rx::Image *baseImage = getBaseLevelImage(); + + GLsizei width = baseImage->getWidth(); + GLsizei height = baseImage->getHeight(); if (width <= 0 || height <= 0) { return false; } - int q = log2(std::max(width, height)); + // The base image level is complete if the width and height are positive + if (level == 0) + { + return true; + } + + ASSERT(level >= 1 && level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + rx::Image *image = mImageArray[level]; - for (int level = 1; level <= q; level++) + if (image->getInternalFormat() != baseImage->getInternalFormat()) { - if (mImageArray[level]->getInternalFormat() != mImageArray[0]->getInternalFormat()) - { - return false; - } + return false; + } - if (mImageArray[level]->getWidth() != std::max(1, width >> level)) - { - return false; - } + if (image->getWidth() != std::max(1, width >> level)) + { + return false; + } - if (mImageArray[level]->getHeight() != std::max(1, height >> level)) - { - return false; - } + if (image->getHeight() != std::max(1, height >> level)) + { + return false; } return true; @@ -682,211 +895,203 @@ bool Texture2D::isMipmapComplete() const bool Texture2D::isCompressed(GLint level) const { - return IsCompressed(getInternalFormat(level)); + return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion()); } bool Texture2D::isDepth(GLint level) const { - return IsDepthTexture(getInternalFormat(level)); + return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0; } // Constructs a native texture resource from the texture images -void Texture2D::createTexture() +void Texture2D::initializeStorage(bool renderTarget) { - GLsizei width = mImageArray[0]->getWidth(); - GLsizei height = mImageArray[0]->getHeight(); - - if (!(width > 0 && height > 0)) - return; // do not attempt to create native textures for nonexistant data - - GLint levels = creationLevels(width, height); - GLenum internalformat = mImageArray[0]->getInternalFormat(); - - delete mTexStorage; - mTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, mUsage, false, width, height); - - if (mTexStorage->isManaged()) + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) { - int levels = levelCount(); + return; + } - for (int level = 0; level < levels; level++) - { - mImageArray[level]->setManagedSurface(mTexStorage, level); - } + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(0)) + { + return; } - mDirtyImages = true; + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + + setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + ASSERT(mTexStorage); + + // flush image data to the storage + updateStorage(); } -void Texture2D::updateTexture() +rx::TextureStorageInterface2D *Texture2D::createCompleteStorage(bool renderTarget) const { - bool mipmapping = (isMipmapFiltered() && isMipmapComplete()); + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); - int levels = (mipmapping ? levelCount() : 1); + ASSERT(width > 0 && height > 0); - for (int level = 0; level < levels; level++) - { - rx::Image *image = mImageArray[level]; + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); - if (image->isDirty()) + return new rx::TextureStorageInterface2D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, levels); +} + +void Texture2D::updateStorage() +{ + ASSERT(mTexStorage != NULL); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (mImageArray[level]->isDirty() && isLevelComplete(level)) { - commitRect(level, 0, 0, mImageArray[level]->getWidth(), mImageArray[level]->getHeight()); + updateStorageLevel(level); } } } -void Texture2D::convertToRenderTarget() +void Texture2D::updateStorageLevel(int level) { - rx::TextureStorageInterface2D *newTexStorage = NULL; + ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + ASSERT(isLevelComplete(level)); - if (mImageArray[0]->getWidth() != 0 && mImageArray[0]->getHeight() != 0) + if (mImageArray[level]->isDirty()) { - GLsizei width = mImageArray[0]->getWidth(); - GLsizei height = mImageArray[0]->getHeight(); - GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(width, height); - GLenum internalformat = mImageArray[0]->getInternalFormat(); + commitRect(level, 0, 0, getWidth(level), getHeight(level)); + } +} - newTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true, width, height); +bool Texture2D::ensureRenderTarget() +{ + initializeStorage(true); - if (mTexStorage != NULL) + if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0) + { + ASSERT(mTexStorage); + if (!mTexStorage->isRenderTarget()) { - if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage)) - { - delete newTexStorage; - return gl::error(GL_OUT_OF_MEMORY); + rx::TextureStorageInterface2D *newRenderTargetStorage = createCompleteStorage(true); + + if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + { + delete newRenderTargetStorage; + return gl::error(GL_OUT_OF_MEMORY, false); } + + setCompleteTexStorage(newRenderTargetStorage); } } - delete mTexStorage; - mTexStorage = newTexStorage; - - mDirtyImages = true; + return (mTexStorage && mTexStorage->isRenderTarget()); } void Texture2D::generateMipmaps() { - if (!mRenderer->getNonPower2TextureSupport()) - { - if (!isPow2(mImageArray[0]->getWidth()) || !isPow2(mImageArray[0]->getHeight())) - { - return gl::error(GL_INVALID_OPERATION); - } - } - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - unsigned int q = log2(std::max(mImageArray[0]->getWidth(), mImageArray[0]->getHeight())); - for (unsigned int i = 1; i <= q; i++) + int levelCount = mipLevels(); + for (int level = 1; level < levelCount; level++) { - redefineImage(i, mImageArray[0]->getInternalFormat(), - std::max(mImageArray[0]->getWidth() >> i, 1), - std::max(mImageArray[0]->getHeight() >> i, 1)); + redefineImage(level, getBaseLevelInternalFormat(), + std::max(getBaseLevelWidth() >> level, 1), + std::max(getBaseLevelHeight() >> level, 1)); } if (mTexStorage && mTexStorage->isRenderTarget()) { - for (unsigned int i = 1; i <= q; i++) + for (int level = 1; level < levelCount; level++) { - mTexStorage->generateMipmap(i); + mTexStorage->generateMipmap(level); - mImageArray[i]->markClean(); + mImageArray[level]->markClean(); } } else { - for (unsigned int i = 1; i <= q; i++) + for (int level = 1; level < levelCount; level++) { - mRenderer->generateMipmap(mImageArray[i], mImageArray[i - 1]); + mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]); } } } -Renderbuffer *Texture2D::getRenderbuffer(GLenum target) +const rx::Image *Texture2D::getBaseLevelImage() const { - if (target != GL_TEXTURE_2D) - { - return gl::error(GL_INVALID_OPERATION, (Renderbuffer *)NULL); - } + return mImageArray[0]; +} - if (mColorbufferProxy == NULL) +rx::TextureStorageInterface *Texture2D::getBaseLevelStorage() +{ + return mTexStorage; +} + +FramebufferAttachment *Texture2D::getAttachment(GLint level) +{ + FramebufferAttachment *attachment = mRenderbufferProxies.get(level, 0); + if (!attachment) { - mColorbufferProxy = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2D(this, target)); + attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DAttachment(this, level)); + mRenderbufferProxies.add(level, 0, attachment); } - return mColorbufferProxy; + return attachment; } -rx::RenderTarget *Texture2D::getRenderTarget(GLenum target) +unsigned int Texture2D::getRenderTargetSerial(GLint level) { - ASSERT(target == GL_TEXTURE_2D); + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0); +} +rx::RenderTarget *Texture2D::getRenderTarget(GLint level) +{ // ensure the underlying texture is created - if (getStorage(true) == NULL) + if (!ensureRenderTarget()) { return NULL; } - updateTexture(); - + updateStorageLevel(level); + // ensure this is NOT a depth texture - if (isDepth(0)) + if (isDepth(level)) { return NULL; } - return mTexStorage->getRenderTarget(); + return mTexStorage->getRenderTarget(level); } -rx::RenderTarget *Texture2D::getDepthStencil(GLenum target) +rx::RenderTarget *Texture2D::getDepthSencil(GLint level) { - ASSERT(target == GL_TEXTURE_2D); - // ensure the underlying texture is created - if (getStorage(true) == NULL) + if (!ensureRenderTarget()) { return NULL; } - updateTexture(); + updateStorageLevel(level); // ensure this is actually a depth texture - if (!isDepth(0)) + if (!isDepth(level)) { return NULL; } - return mTexStorage->getRenderTarget(); -} -int Texture2D::levelCount() -{ - return mTexStorage ? mTexStorage->levelCount() : 0; + return mTexStorage->getRenderTarget(level); } -rx::TextureStorageInterface *Texture2D::getStorage(bool renderTarget) +bool Texture2D::isValidLevel(int level) const { - if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) - { - if (renderTarget) - { - convertToRenderTarget(); - } - else - { - createTexture(); - } - } - - return mTexStorage; + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false); } -TextureCubeMap::TextureCubeMap(rx::Renderer *renderer, GLuint id) : Texture(renderer, id) +TextureCubeMap::TextureCubeMap(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_CUBE_MAP) { mTexStorage = NULL; for (int i = 0; i < 6; i++) { - mFaceProxies[i] = NULL; - mFaceProxyRefs[i] = 0; - for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j) { mImageArray[i][j] = renderer->createImage(); @@ -898,8 +1103,6 @@ TextureCubeMap::~TextureCubeMap() { for (int i = 0; i < 6; i++) { - mFaceProxies[i] = NULL; - for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j) { delete mImageArray[i][j]; @@ -910,44 +1113,10 @@ TextureCubeMap::~TextureCubeMap() mTexStorage = NULL; } -// We need to maintain a count of references to renderbuffers acting as -// proxies for this texture, so that the texture is not deleted while -// proxy references still exist. If the reference count drops to zero, -// we set our proxy pointer NULL, so that a new attempt at referencing -// will cause recreation. -void TextureCubeMap::addProxyRef(const Renderbuffer *proxy) -{ - for (int i = 0; i < 6; i++) - { - if (mFaceProxies[i] == proxy) - mFaceProxyRefs[i]++; - } -} - -void TextureCubeMap::releaseProxy(const Renderbuffer *proxy) -{ - for (int i = 0; i < 6; i++) - { - if (mFaceProxies[i] == proxy) - { - if (mFaceProxyRefs[i] > 0) - mFaceProxyRefs[i]--; - - if (mFaceProxyRefs[i] == 0) - mFaceProxies[i] = NULL; - } - } -} - -GLenum TextureCubeMap::getTarget() const -{ - return GL_TEXTURE_CUBE_MAP; -} - GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[faceIndex(target)][level]->getWidth(); + return mImageArray[targetToIndex(target)][level]->getWidth(); else return 0; } @@ -955,7 +1124,7 @@ GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[faceIndex(target)][level]->getHeight(); + return mImageArray[targetToIndex(target)][level]->getHeight(); else return 0; } @@ -963,7 +1132,7 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[faceIndex(target)][level]->getInternalFormat(); + return mImageArray[targetToIndex(target)][level]->getInternalFormat(); else return GL_NONE; } @@ -971,88 +1140,89 @@ GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[faceIndex(target)][level]->getActualFormat(); + return mImageArray[targetToIndex(target)][level]->getActualFormat(); else - return D3DFMT_UNKNOWN; + return GL_NONE; } -void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(0, level, width, height, format, type, unpackAlignment, pixels); + setImage(0, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(1, level, width, height, format, type, unpackAlignment, pixels); + setImage(1, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(2, level, width, height, format, type, unpackAlignment, pixels); + setImage(2, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(3, level, width, height, format, type, unpackAlignment, pixels); + setImage(3, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(4, level, width, height, format, type, unpackAlignment, pixels); + setImage(4, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - setImage(5, level, width, height, format, type, unpackAlignment, pixels); + setImage(5, level, width, height, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) { // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - redefineImage(faceIndex(face), level, format, width, height); + int faceIndex = targetToIndex(target); + redefineImage(faceIndex, level, format, width, height); - Texture::setCompressedImage(imageSize, pixels, mImageArray[faceIndex(face)][level]); + Texture::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]); } -void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +void TextureCubeMap::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - if (level < levelCount()) + if (isValidFaceLevel(faceIndex, level)) { - rx::Image *image = mImageArray[face][level]; - if (image->updateSurface(mTexStorage, face, level, xoffset, yoffset, width, height)) + rx::Image *image = mImageArray[faceIndex][level]; + if (image->copyToStorage(mTexStorage, faceIndex, level, xoffset, yoffset, width, height)) image->markClean(); } } -void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, mImageArray[faceIndex(target)][level])) + int faceIndex = targetToIndex(target); + if (Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level])) { - commitRect(faceIndex(target), level, xoffset, yoffset, width, height); + commitRect(faceIndex, level, xoffset, yoffset, width, height); } } void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) { - if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, mImageArray[faceIndex(target)][level])) + int faceIndex = targetToIndex(target); + if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level])) { - commitRect(faceIndex(target), level, xoffset, yoffset, width, height); + commitRect(faceIndex, level, xoffset, yoffset, width, height); } } // Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86. -bool TextureCubeMap::isSamplerComplete() const +bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState) const { - int size = mImageArray[0][0]->getWidth(); + int size = getBaseLevelWidth(); - bool mipmapping = isMipmapFiltered(); - bool filtering, renderable; + bool mipmapping = IsMipmapFiltered(samplerState); - if ((gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) == GL_FLOAT && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) || - (gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable))) + if (!IsTextureFilteringSupported(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0), mRenderer)) { - if (mSamplerState.magFilter != GL_NEAREST || - (mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) + if (samplerState.magFilter != GL_NEAREST || + (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) { return false; } @@ -1060,7 +1230,7 @@ bool TextureCubeMap::isSamplerComplete() const if (!isPow2(size) && !mRenderer->getNonPower2TextureSupport()) { - if (mSamplerState.wrapS != GL_CLAMP_TO_EDGE || mSamplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping) + if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping) { return false; } @@ -1087,16 +1257,22 @@ bool TextureCubeMap::isSamplerComplete() const // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. bool TextureCubeMap::isCubeComplete() const { - if (mImageArray[0][0]->getWidth() <= 0 || mImageArray[0][0]->getHeight() != mImageArray[0][0]->getWidth()) + int baseWidth = getBaseLevelWidth(); + int baseHeight = getBaseLevelHeight(); + GLenum baseFormat = getBaseLevelInternalFormat(); + + if (baseWidth <= 0 || baseWidth != baseHeight) { return false; } - for (unsigned int face = 1; face < 6; face++) + for (int faceIndex = 1; faceIndex < 6; faceIndex++) { - if (mImageArray[face][0]->getWidth() != mImageArray[0][0]->getWidth() || - mImageArray[face][0]->getWidth() != mImageArray[0][0]->getHeight() || - mImageArray[face][0]->getInternalFormat() != mImageArray[0][0]->getInternalFormat()) + const rx::Image &faceBaseImage = *mImageArray[faceIndex][0]; + + if (faceBaseImage.getWidth() != baseWidth || + faceBaseImage.getHeight() != baseHeight || + faceBaseImage.getInternalFormat() != baseFormat ) { return false; } @@ -1117,20 +1293,13 @@ bool TextureCubeMap::isMipmapCubeComplete() const return false; } - GLsizei size = mImageArray[0][0]->getWidth(); - - int q = log2(size); + int levelCount = mipLevels(); for (int face = 0; face < 6; face++) { - for (int level = 1; level <= q; level++) + for (int level = 1; level < levelCount; level++) { - if (mImageArray[face][level]->getInternalFormat() != mImageArray[0][0]->getInternalFormat()) - { - return false; - } - - if (mImageArray[face][level]->getWidth() != std::max(1, size >> level)) + if (!isFaceLevelComplete(face, level)) { return false; } @@ -1140,34 +1309,103 @@ bool TextureCubeMap::isMipmapCubeComplete() const return true; } +bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const +{ + ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); + + if (isImmutable()) + { + return true; + } + + int baseSize = getBaseLevelWidth(); + + if (baseSize <= 0) + { + return false; + } + + // "isCubeComplete" checks for base level completeness and we must call that + // to determine if any face at level 0 is complete. We omit that check here + // to avoid re-checking cube-completeness for every face at level 0. + if (level == 0) + { + return true; + } + + // Check that non-zero levels are consistent with the base level. + const rx::Image *faceLevelImage = mImageArray[faceIndex][level]; + + if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat()) + { + return false; + } + + if (faceLevelImage->getWidth() != std::max(1, baseSize >> level)) + { + return false; + } + + return true; +} + bool TextureCubeMap::isCompressed(GLenum target, GLint level) const { - return IsCompressed(getInternalFormat(target, level)); + return IsFormatCompressed(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()); +} + +bool TextureCubeMap::isDepth(GLenum target, GLint level) const +{ + return GetDepthBits(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()) > 0; +} + +void TextureCubeMap::initializeStorage(bool renderTarget) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return; + } + + // do not attempt to create storage for nonexistant data + if (!isFaceLevelComplete(0, 0)) + { + return; + } + + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + + setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + ASSERT(mTexStorage); + + // flush image data to the storage + updateStorage(); } -// Constructs a native texture resource from the texture images, or returns an existing one -void TextureCubeMap::createTexture() +rx::TextureStorageInterfaceCube *TextureCubeMap::createCompleteStorage(bool renderTarget) const { - GLsizei size = mImageArray[0][0]->getWidth(); + GLsizei size = getBaseLevelWidth(); - if (!(size > 0)) - return; // do not attempt to create native textures for nonexistant data + ASSERT(size > 0); - GLint levels = creationLevels(size); - GLenum internalformat = mImageArray[0][0]->getInternalFormat(); + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1)); - delete mTexStorage; - mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, mUsage, false, size); + return new rx::TextureStorageInterfaceCube(mRenderer, getBaseLevelInternalFormat(), renderTarget, size, levels); +} - if (mTexStorage->isManaged()) - { - int levels = levelCount(); +void TextureCubeMap::setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage) +{ + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; - for (int face = 0; face < 6; face++) + if (mTexStorage && mTexStorage->isManaged()) + { + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - for (int level = 0; level < levels; level++) + for (int level = 0; level < mTexStorage->getLevelCount(); level++) { - mImageArray[face][level]->setManagedSurface(mTexStorage, face, level); + mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level); } } } @@ -1175,63 +1413,69 @@ void TextureCubeMap::createTexture() mDirtyImages = true; } -void TextureCubeMap::updateTexture() +void TextureCubeMap::updateStorage() { - bool mipmapping = isMipmapFiltered() && isMipmapCubeComplete(); - + ASSERT(mTexStorage != NULL); + GLint storageLevels = mTexStorage->getLevelCount(); for (int face = 0; face < 6; face++) { - int levels = (mipmapping ? levelCount() : 1); - - for (int level = 0; level < levels; level++) + for (int level = 0; level < storageLevels; level++) { - rx::Image *image = mImageArray[face][level]; - - if (image->isDirty()) + if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level)) { - commitRect(face, level, 0, 0, image->getWidth(), image->getHeight()); + updateStorageFaceLevel(face, level); } } } } -void TextureCubeMap::convertToRenderTarget() +void TextureCubeMap::updateStorageFaceLevel(int faceIndex, int level) { - rx::TextureStorageInterfaceCube *newTexStorage = NULL; + ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); + rx::Image *image = mImageArray[faceIndex][level]; - if (mImageArray[0][0]->getWidth() != 0) + if (image->isDirty()) { - GLsizei size = mImageArray[0][0]->getWidth(); - GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(size); - GLenum internalformat = mImageArray[0][0]->getInternalFormat(); + commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight()); + } +} - newTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true, size); +bool TextureCubeMap::ensureRenderTarget() +{ + initializeStorage(true); - if (mTexStorage != NULL) + if (getBaseLevelWidth() > 0) + { + ASSERT(mTexStorage); + if (!mTexStorage->isRenderTarget()) { - if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage)) + rx::TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true); + + if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) { - delete newTexStorage; - return gl::error(GL_OUT_OF_MEMORY); + delete newRenderTargetStorage; + return gl::error(GL_OUT_OF_MEMORY, false); } + + setCompleteTexStorage(newRenderTargetStorage); } } - delete mTexStorage; - mTexStorage = newTexStorage; - - mDirtyImages = true; + return (mTexStorage && mTexStorage->isRenderTarget()); } -void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - GLint internalformat = ConvertSizedInternalFormat(format, type); - redefineImage(faceIndex, level, internalformat, width, height); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat + : GetSizedInternalFormat(format, type, clientVersion); - Texture::setImage(unpackAlignment, pixels, mImageArray[faceIndex][level]); + redefineImage(faceIndex, level, sizedInternalFormat, width, height); + + Texture::setImage(unpack, type, pixels, mImageArray[faceIndex][level]); } -unsigned int TextureCubeMap::faceIndex(GLenum face) +int TextureCubeMap::targetToIndex(GLenum target) { META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1); META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2); @@ -1239,32 +1483,32 @@ unsigned int TextureCubeMap::faceIndex(GLenum face) META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4); META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5); - return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X; + return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X; } -void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat, GLsizei width, GLsizei height) +void TextureCubeMap::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height) { // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, mImageArray[0][0]->getWidth() >> level); - const int storageHeight = std::max(1, mImageArray[0][0]->getHeight() >> level); - const int storageFormat = mImageArray[0][0]->getInternalFormat(); + const int storageWidth = std::max(1, getBaseLevelWidth() >> level); + const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); - mImageArray[face][level]->redefine(mRenderer, internalformat, width, height, false); + mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, width, height, 1, false); if (mTexStorage) { - const int storageLevels = mTexStorage->levelCount(); - + const int storageLevels = mTexStorage->getLevelCount(); + if ((level >= storageLevels && storageLevels != 0) || width != storageWidth || height != storageHeight || internalformat != storageFormat) // Discard mismatched storage { - for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - for (int f = 0; f < 6; f++) + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - mImageArray[f][i]->markDirty(); + mImageArray[faceIndex][level]->markDirty(); } } @@ -1278,27 +1522,25 @@ void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat, void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - unsigned int faceindex = faceIndex(target); - GLint internalformat = gl::ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE); - redefineImage(faceindex, level, internalformat, width, height); + int faceIndex = targetToIndex(target); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format + : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion); + redefineImage(faceIndex, level, sizedInternalFormat, width, height); - if (!mImageArray[faceindex][level]->isRenderableFormat()) + if (!mImageArray[faceIndex][level]->isRenderableFormat()) { - mImageArray[faceindex][level]->copy(0, 0, x, y, width, height, source); + mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source); mDirtyImages = true; } else { - if (!mTexStorage || !mTexStorage->isRenderTarget()) - { - convertToRenderTarget(); - } - - mImageArray[faceindex][level]->markClean(); + ensureRenderTarget(); + mImageArray[faceIndex][level]->markClean(); ASSERT(width == height); - if (width > 0 && level < levelCount()) + if (width > 0 && isValidFaceLevel(faceIndex, level)) { gl::Rectangle sourceRect; sourceRect.x = x; @@ -1311,40 +1553,37 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint } } -void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - GLsizei size = mImageArray[faceIndex(target)][level]->getWidth(); + int faceIndex = targetToIndex(target); - if (xoffset + width > size || yoffset + height > size) - { - return gl::error(GL_INVALID_VALUE); - } - - unsigned int faceindex = faceIndex(target); + // We can only make our texture storage to a render target if the level we're copying *to* is complete + // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot + // rely on the "getBaseLevel*" methods reliably otherwise. + bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete(); - if (!mImageArray[faceindex][level]->isRenderableFormat() || (!mTexStorage && !isSamplerComplete())) + if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) { - mImageArray[faceindex][level]->copy(0, 0, x, y, width, height, source); + mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source); mDirtyImages = true; } else { - if (!mTexStorage || !mTexStorage->isRenderTarget()) - { - convertToRenderTarget(); - } + ensureRenderTarget(); - updateTexture(); - - if (level < levelCount()) + if (isValidFaceLevel(faceIndex, level)) { + updateStorageFaceLevel(faceIndex, level); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + gl::Rectangle sourceRect; sourceRect.x = x; sourceRect.width = width; sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, gl::ExtractFormat(mImageArray[0][0]->getInternalFormat()), + mRenderer->copyImage(source, sourceRect, gl::GetFormat(getBaseLevelInternalFormat(), clientVersion), xoffset, yoffset, mTexStorage, target, level); } } @@ -1352,144 +1591,1229 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) { - delete mTexStorage; - mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, mUsage, false, size); - mImmutable = true; - for (int level = 0; level < levels; level++) { GLsizei mipSize = std::max(1, size >> level); - for (int face = 0; face < 6; face++) + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - mImageArray[face][level]->redefine(mRenderer, internalformat, mipSize, mipSize, true); + mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true); } } for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - for (int face = 0; face < 6; face++) + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - mImageArray[face][level]->redefine(mRenderer, GL_NONE, 0, 0, true); + mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, GL_NONE, 0, 0, 0, true); } } - if (mTexStorage->isManaged()) + mImmutable = true; + + setCompleteTexStorage(new rx::TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), size, levels)); +} + +void TextureCubeMap::generateMipmaps() +{ + // Purge array levels 1 through q and reset them to represent the generated mipmap levels. + int levelCount = mipLevels(); + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - int levels = levelCount(); + for (int level = 1; level < levelCount; level++) + { + int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1)); + redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize); + } + } - for (int face = 0; face < 6; face++) + if (mTexStorage && mTexStorage->isRenderTarget()) + { + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - for (int level = 0; level < levels; level++) + for (int level = 1; level < levelCount; level++) { - mImageArray[face][level]->setManagedSurface(mTexStorage, face, level); + mTexStorage->generateMipmap(faceIndex, level); + + mImageArray[faceIndex][level]->markClean(); + } + } + } + else + { + for (int faceIndex = 0; faceIndex < 6; faceIndex++) + { + for (int level = 1; level < levelCount; level++) + { + mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]); } } } } -void TextureCubeMap::generateMipmaps() +const rx::Image *TextureCubeMap::getBaseLevelImage() const { - if (!isCubeComplete()) + // Note: if we are not cube-complete, there is no single base level image that can describe all + // cube faces, so this method is only well-defined for a cube-complete base level. + return mImageArray[0][0]; +} + +rx::TextureStorageInterface *TextureCubeMap::getBaseLevelStorage() +{ + return mTexStorage; +} + +FramebufferAttachment *TextureCubeMap::getAttachment(GLenum target, GLint level) +{ + ASSERT(!IsCubemapTextureTarget(target)); + int faceIndex = targetToIndex(target); + + FramebufferAttachment *attachment = mRenderbufferProxies.get(level, faceIndex); + if (!attachment) + { + attachment = new FramebufferAttachment(mRenderer, id(), new TextureCubeMapAttachment(this, target, level)); + mRenderbufferProxies.add(level, faceIndex, attachment); + } + + return attachment; +} + +unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level) +{ + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0); +} + +rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level) +{ + ASSERT(IsCubemapTextureTarget(target)); + + // ensure the underlying texture is created + if (!ensureRenderTarget()) { - return gl::error(GL_INVALID_OPERATION); + return NULL; } - if (!mRenderer->getNonPower2TextureSupport()) + updateStorageFaceLevel(targetToIndex(target), level); + + // ensure this is NOT a depth texture + if (isDepth(target, level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(target, level); +} + +rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level) +{ + ASSERT(IsCubemapTextureTarget(target)); + + // ensure the underlying texture is created + if (!ensureRenderTarget()) + { + return NULL; + } + + updateStorageFaceLevel(targetToIndex(target), level); + + // ensure this is a depth texture + if (!isDepth(target, level)) { - if (!isPow2(mImageArray[0][0]->getWidth())) + return NULL; + } + + return mTexStorage->getRenderTarget(target, level); +} + +bool TextureCubeMap::isValidFaceLevel(int faceIndex, int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +Texture3D::Texture3D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_3D) +{ + mTexStorage = NULL; + + for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) + { + mImageArray[i] = renderer->createImage(); + } +} + +Texture3D::~Texture3D() +{ + delete mTexStorage; + mTexStorage = NULL; + + for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) + { + delete mImageArray[i]; + } +} + +GLsizei Texture3D::getWidth(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getWidth() : 0; +} + +GLsizei Texture3D::getHeight(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getHeight() : 0; +} + +GLsizei Texture3D::getDepth(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getDepth() : 0; +} + +GLenum Texture3D::getInternalFormat(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getInternalFormat() : GL_NONE; +} + +GLenum Texture3D::getActualFormat(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getActualFormat() : GL_NONE; +} + +bool Texture3D::isCompressed(GLint level) const +{ + return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion()); +} + +bool Texture3D::isDepth(GLint level) const +{ + return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0; +} + +void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat + : GetSizedInternalFormat(format, type, clientVersion); + redefineImage(level, sizedInternalFormat, width, height, depth); + + bool fastUnpacked = false; + + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer + if (isFastUnpackable(unpack, sizedInternalFormat)) + { + // Will try to create RT storage if it does not exist + rx::RenderTarget *destRenderTarget = getRenderTarget(level); + Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); + + if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) { - return gl::error(GL_INVALID_OPERATION); + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } } - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - unsigned int q = log2(mImageArray[0][0]->getWidth()); - for (unsigned int f = 0; f < 6; f++) + if (!fastUnpacked) { - for (unsigned int i = 1; i <= q; i++) + Texture::setImage(unpack, type, pixels, mImageArray[level]); + } +} + +void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +{ + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly + redefineImage(level, format, width, height, depth); + + Texture::setCompressedImage(imageSize, pixels, mImageArray[level]); +} + +void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +{ + bool fastUnpacked = false; + + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer + if (isFastUnpackable(unpack, getInternalFormat(level))) + { + rx::RenderTarget *destRenderTarget = getRenderTarget(level); + Box destArea(xoffset, yoffset, zoffset, width, height, depth); + + if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget)) { - redefineImage(f, i, mImageArray[f][0]->getInternalFormat(), - std::max(mImageArray[f][0]->getWidth() >> i, 1), - std::max(mImageArray[f][0]->getWidth() >> i, 1)); + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } } + if (!fastUnpacked && Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level])) + { + commitRect(level, xoffset, yoffset, zoffset, width, height, depth); + } +} + +void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +{ + if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level])) + { + commitRect(level, xoffset, yoffset, zoffset, width, height, depth); + } +} + +void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + for (int level = 0; level < levels; level++) + { + GLsizei levelWidth = std::max(1, width >> level); + GLsizei levelHeight = std::max(1, height >> level); + GLsizei levelDepth = std::max(1, depth >> level); + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, levelWidth, levelHeight, levelDepth, true); + } + + for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true); + } + + mImmutable = true; + + setCompleteTexStorage(new rx::TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels)); +} + +void Texture3D::generateMipmaps() +{ + // Purge array levels 1 through q and reset them to represent the generated mipmap levels. + int levelCount = mipLevels(); + for (int level = 1; level < levelCount; level++) + { + redefineImage(level, getBaseLevelInternalFormat(), + std::max(getBaseLevelWidth() >> level, 1), + std::max(getBaseLevelHeight() >> level, 1), + std::max(getBaseLevelDepth() >> level, 1)); + } + if (mTexStorage && mTexStorage->isRenderTarget()) { - for (unsigned int f = 0; f < 6; f++) + for (int level = 1; level < levelCount; level++) + { + mTexStorage->generateMipmap(level); + + mImageArray[level]->markClean(); + } + } + else + { + for (int level = 1; level < levelCount; level++) + { + mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]); + } + } +} + +const rx::Image *Texture3D::getBaseLevelImage() const +{ + return mImageArray[0]; +} + +rx::TextureStorageInterface *Texture3D::getBaseLevelStorage() +{ + return mTexStorage; +} + +void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +{ + // can only make our texture storage to a render target if level 0 is defined (with a width & height) and + // the current level we're copying to is defined (with appropriate format, width & height) + bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); + + if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + { + mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source); + mDirtyImages = true; + } + else + { + ensureRenderTarget(); + + if (isValidLevel(level)) + { + updateStorageLevel(level); + + gl::Rectangle sourceRect; + sourceRect.x = x; + sourceRect.width = width; + sourceRect.y = y; + sourceRect.height = height; + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mRenderer->copyImage(source, sourceRect, + gl::GetFormat(getBaseLevelInternalFormat(), clientVersion), + xoffset, yoffset, zoffset, mTexStorage, level); + } + } +} + +bool Texture3D::isSamplerComplete(const SamplerState &samplerState) const +{ + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei depth = getBaseLevelDepth(); + + if (width <= 0 || height <= 0 || depth <= 0) + { + return false; + } + + if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer)) + { + if (samplerState.magFilter != GL_NEAREST || + (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) + { + return false; + } + } + + if (IsMipmapFiltered(samplerState) && !isMipmapComplete()) + { + return false; + } + + return true; +} + +bool Texture3D::isMipmapComplete() const +{ + int levelCount = mipLevels(); + + for (int level = 0; level < levelCount; level++) + { + if (!isLevelComplete(level)) + { + return false; + } + } + + return true; +} + +bool Texture3D::isLevelComplete(int level) const +{ + ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + + if (isImmutable()) + { + return true; + } + + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei depth = getBaseLevelDepth(); + + if (width <= 0 || height <= 0 || depth <= 0) + { + return false; + } + + if (level == 0) + { + return true; + } + + rx::Image *levelImage = mImageArray[level]; + + if (levelImage->getInternalFormat() != getBaseLevelInternalFormat()) + { + return false; + } + + if (levelImage->getWidth() != std::max(1, width >> level)) + { + return false; + } + + if (levelImage->getHeight() != std::max(1, height >> level)) + { + return false; + } + + if (levelImage->getDepth() != std::max(1, depth >> level)) + { + return false; + } + + return true; +} + +FramebufferAttachment *Texture3D::getAttachment(GLint level, GLint layer) +{ + FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer); + if (!attachment) + { + attachment = new FramebufferAttachment(mRenderer, id(), new Texture3DAttachment(this, level, layer)); + mRenderbufferProxies.add(level, 0, attachment); + } + + return attachment; +} + +unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer) +{ + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0); +} + +bool Texture3D::isValidLevel(int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +void Texture3D::initializeStorage(bool renderTarget) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return; + } + + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(0)) + { + return; + } + + bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + + setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + ASSERT(mTexStorage); + + // flush image data to the storage + updateStorage(); +} + +rx::TextureStorageInterface3D *Texture3D::createCompleteStorage(bool renderTarget) const +{ + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei depth = getBaseLevelDepth(); + + ASSERT(width > 0 && height > 0 && depth > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth)); + + return new rx::TextureStorageInterface3D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels); +} + +void Texture3D::setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage) +{ + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; + mDirtyImages = true; + + // We do not support managed 3D storage, as that is D3D9/ES2-only + ASSERT(!mTexStorage->isManaged()); +} + +void Texture3D::updateStorage() +{ + ASSERT(mTexStorage != NULL); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (mImageArray[level]->isDirty() && isLevelComplete(level)) + { + updateStorageLevel(level); + } + } +} + +void Texture3D::updateStorageLevel(int level) +{ + ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + ASSERT(isLevelComplete(level)); + + if (mImageArray[level]->isDirty()) + { + commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); + } +} + +bool Texture3D::ensureRenderTarget() +{ + initializeStorage(true); + + if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0) + { + ASSERT(mTexStorage); + if (!mTexStorage->isRenderTarget()) + { + rx::TextureStorageInterface3D *newRenderTargetStorage = createCompleteStorage(true); + + if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + { + delete newRenderTargetStorage; + return gl::error(GL_OUT_OF_MEMORY, false); + } + + setCompleteTexStorage(newRenderTargetStorage); + } + } + + return (mTexStorage && mTexStorage->isRenderTarget()); +} + +rx::RenderTarget *Texture3D::getRenderTarget(GLint level) +{ + // ensure the underlying texture is created + if (!ensureRenderTarget()) + { + return NULL; + } + + updateStorageLevel(level); + + // ensure this is NOT a depth texture + if (isDepth(level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(level); +} + +rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer) +{ + // ensure the underlying texture is created + if (!ensureRenderTarget()) + { + return NULL; + } + + updateStorage(); + + // ensure this is NOT a depth texture + if (isDepth(level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(level, layer); +} + +rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer) +{ + // ensure the underlying texture is created + if (!ensureRenderTarget()) + { + return NULL; + } + + updateStorageLevel(level); + + // ensure this is a depth texture + if (!isDepth(level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(level, layer); +} + +void Texture3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getBaseLevelWidth() >> level); + const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const int storageDepth = std::max(1, getBaseLevelDepth() >> level); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, width, height, depth, false); + + if (mTexStorage) + { + const int storageLevels = mTexStorage->getLevelCount(); + + if ((level >= storageLevels && storageLevels != 0) || + width != storageWidth || + height != storageHeight || + depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage + { + for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mImageArray[i]->markDirty(); + } + + delete mTexStorage; + mTexStorage = NULL; + mDirtyImages = true; + } + } +} + +void Texture3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +{ + if (isValidLevel(level)) + { + rx::Image *image = mImageArray[level]; + if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth)) + { + image->markClean(); + } + } +} + +Texture2DArray::Texture2DArray(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D_ARRAY) +{ + mTexStorage = NULL; + + for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) + { + mLayerCounts[level] = 0; + mImageArray[level] = NULL; + } +} + +Texture2DArray::~Texture2DArray() +{ + delete mTexStorage; + mTexStorage = NULL; + + deleteImages(); +} + +void Texture2DArray::deleteImages() +{ + for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) + { + for (int layer = 0; layer < mLayerCounts[level]; ++layer) + { + delete mImageArray[level][layer]; + } + delete[] mImageArray[level]; + mImageArray[level] = NULL; + mLayerCounts[level] = 0; + } +} + +GLsizei Texture2DArray::getWidth(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getWidth() : 0; +} + +GLsizei Texture2DArray::getHeight(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0; +} + +GLsizei Texture2DArray::getLayers(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mLayerCounts[level] : 0; +} + +GLenum Texture2DArray::getInternalFormat(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE; +} + +GLenum Texture2DArray::getActualFormat(GLint level) const +{ + return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getActualFormat() : GL_NONE; +} + +bool Texture2DArray::isCompressed(GLint level) const +{ + return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion()); +} + +bool Texture2DArray::isDepth(GLint level) const +{ + return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0; +} + +void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat + : GetSizedInternalFormat(format, type, clientVersion); + redefineImage(level, sizedInternalFormat, width, height, depth); + + GLsizei inputDepthPitch = gl::GetDepthPitch(sizedInternalFormat, type, clientVersion, width, height, unpack.alignment); + + for (int i = 0; i < depth; i++) + { + const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL; + Texture::setImage(unpack, type, layerPixels, mImageArray[level][i]); + } +} + +void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +{ + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly + redefineImage(level, format, width, height, depth); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1); + + for (int i = 0; i < depth; i++) + { + const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL; + Texture::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]); + } +} + +void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +{ + GLenum internalformat = getInternalFormat(level); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputDepthPitch = gl::GetDepthPitch(internalformat, type, clientVersion, width, height, unpack.alignment); + + for (int i = 0; i < depth; i++) + { + int layer = zoffset + i; + const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL; + + if (Texture::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer])) { - for (unsigned int i = 1; i <= q; i++) + commitRect(level, xoffset, yoffset, layer, width, height); + } + } +} + +void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1); + + for (int i = 0; i < depth; i++) + { + int layer = zoffset + i; + const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL; + + if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer])) + { + commitRect(level, xoffset, yoffset, layer, width, height); + } + } +} + +void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + deleteImages(); + + for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + GLsizei levelWidth = std::max(1, width >> level); + GLsizei levelHeight = std::max(1, height >> level); + + mLayerCounts[level] = (level < levels ? depth : 0); + + if (mLayerCounts[level] > 0) + { + // Create new images for this level + mImageArray[level] = new rx::Image*[mLayerCounts[level]]; + + for (int layer = 0; layer < mLayerCounts[level]; layer++) { - mTexStorage->generateMipmap(f, i); + mImageArray[level][layer] = mRenderer->createImage(); + mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, levelWidth, + levelHeight, 1, true); + } + } + } + + mImmutable = true; + setCompleteTexStorage(new rx::TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels)); +} + +void Texture2DArray::generateMipmaps() +{ + int baseWidth = getBaseLevelWidth(); + int baseHeight = getBaseLevelHeight(); + int baseDepth = getBaseLevelDepth(); + GLenum baseFormat = getBaseLevelInternalFormat(); + + // Purge array levels 1 through q and reset them to represent the generated mipmap levels. + int levelCount = mipLevels(); + for (int level = 1; level < levelCount; level++) + { + redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth); + } + + if (mTexStorage && mTexStorage->isRenderTarget()) + { + for (int level = 1; level < levelCount; level++) + { + mTexStorage->generateMipmap(level); - mImageArray[f][i]->markClean(); + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + mImageArray[level][layer]->markClean(); } } } else { - for (unsigned int f = 0; f < 6; f++) + for (int level = 1; level < levelCount; level++) { - for (unsigned int i = 1; i <= q; i++) + for (int layer = 0; layer < mLayerCounts[level]; layer++) { - mRenderer->generateMipmap(mImageArray[f][i], mImageArray[f][i - 1]); + mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]); } } } } -Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target) +const rx::Image *Texture2DArray::getBaseLevelImage() const +{ + return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL); +} + +rx::TextureStorageInterface *Texture2DArray::getBaseLevelStorage() +{ + return mTexStorage; +} + +void Texture2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +{ + // can only make our texture storage to a render target if level 0 is defined (with a width & height) and + // the current level we're copying to is defined (with appropriate format, width & height) + bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); + + if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + { + mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source); + mDirtyImages = true; + } + else + { + ensureRenderTarget(); + + if (isValidLevel(level)) + { + updateStorageLevel(level); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + gl::Rectangle sourceRect; + sourceRect.x = x; + sourceRect.width = width; + sourceRect.y = y; + sourceRect.height = height; + + mRenderer->copyImage(source, sourceRect, gl::GetFormat(getInternalFormat(0), clientVersion), + xoffset, yoffset, zoffset, mTexStorage, level); + } + } +} + +bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState) const { - if (!IsCubemapTextureTarget(target)) + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei depth = getLayers(0); + + if (width <= 0 || height <= 0 || depth <= 0) { - return gl::error(GL_INVALID_OPERATION, (Renderbuffer *)NULL); + return false; } - unsigned int face = faceIndex(target); + if (!IsTextureFilteringSupported(getBaseLevelInternalFormat(), mRenderer)) + { + if (samplerState.magFilter != GL_NEAREST || + (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) + { + return false; + } + } - if (mFaceProxies[face] == NULL) + if (IsMipmapFiltered(samplerState) && !isMipmapComplete()) { - mFaceProxies[face] = new Renderbuffer(mRenderer, id(), new RenderbufferTextureCubeMap(this, target)); + return false; } - return mFaceProxies[face]; + return true; } -rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target) +bool Texture2DArray::isMipmapComplete() const { - ASSERT(IsCubemapTextureTarget(target)); + int levelCount = mipLevels(); + + for (int level = 1; level < levelCount; level++) + { + if (!isLevelComplete(level)) + { + return false; + } + } + + return true; +} + +bool Texture2DArray::isLevelComplete(int level) const +{ + ASSERT(level >= 0 && level < (int)ArraySize(mImageArray)); + + if (isImmutable()) + { + return true; + } + + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei layers = getLayers(0); + if (width <= 0 || height <= 0 || layers <= 0) + { + return false; + } + + if (level == 0) + { + return true; + } + + if (getInternalFormat(level) != getInternalFormat(0)) + { + return false; + } + + if (getWidth(level) != std::max(1, width >> level)) + { + return false; + } + + if (getHeight(level) != std::max(1, height >> level)) + { + return false; + } + + if (getLayers(level) != layers) + { + return false; + } + + return true; +} + +FramebufferAttachment *Texture2DArray::getAttachment(GLint level, GLint layer) +{ + FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer); + if (!attachment) + { + attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DArrayAttachment(this, level, layer)); + mRenderbufferProxies.add(level, 0, attachment); + } + + return attachment; +} + +unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer) +{ + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0); +} + +bool Texture2DArray::isValidLevel(int level) const +{ + return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); +} + +void Texture2DArray::initializeStorage(bool renderTarget) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return; + } + + // do not attempt to create storage for nonexistant data + if (!isLevelComplete(0)) + { + return; + } + + bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + + setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + ASSERT(mTexStorage); + + // flush image data to the storage + updateStorage(); +} + +rx::TextureStorageInterface2DArray *Texture2DArray::createCompleteStorage(bool renderTarget) const +{ + GLsizei width = getBaseLevelWidth(); + GLsizei height = getBaseLevelHeight(); + GLsizei depth = getLayers(0); + + ASSERT(width > 0 && height > 0 && depth > 0); + + // use existing storage level count, when previously specified by TexStorage*D + GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); + + return new rx::TextureStorageInterface2DArray(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels); +} + +void Texture2DArray::setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage) +{ + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; + mDirtyImages = true; + + // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only + ASSERT(!mTexStorage->isManaged()); +} + +void Texture2DArray::updateStorage() +{ + ASSERT(mTexStorage != NULL); + GLint storageLevels = mTexStorage->getLevelCount(); + for (int level = 0; level < storageLevels; level++) + { + if (isLevelComplete(level)) + { + updateStorageLevel(level); + } + } +} + +void Texture2DArray::updateStorageLevel(int level) +{ + ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts)); + ASSERT(isLevelComplete(level)); + + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL); + if (mImageArray[level][layer]->isDirty()) + { + commitRect(level, 0, 0, layer, getWidth(level), getHeight(level)); + } + } +} + +bool Texture2DArray::ensureRenderTarget() +{ + initializeStorage(true); + + if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0) + { + ASSERT(mTexStorage); + if (!mTexStorage->isRenderTarget()) + { + rx::TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true); + + if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + { + delete newRenderTargetStorage; + return gl::error(GL_OUT_OF_MEMORY, false); + } + + setCompleteTexStorage(newRenderTargetStorage); + } + } + + return (mTexStorage && mTexStorage->isRenderTarget()); +} + +rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer) +{ // ensure the underlying texture is created - if (getStorage(true) == NULL) + if (!ensureRenderTarget()) { return NULL; } - updateTexture(); - - return mTexStorage->getRenderTarget(target); + updateStorageLevel(level); + + // ensure this is NOT a depth texture + if (isDepth(level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(level, layer); } -int TextureCubeMap::levelCount() +rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer) { - return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0; + // ensure the underlying texture is created + if (!ensureRenderTarget()) + { + return NULL; + } + + updateStorageLevel(level); + + // ensure this is a depth texture + if (!isDepth(level)) + { + return NULL; + } + + return mTexStorage->getRenderTarget(level, layer); } -rx::TextureStorageInterface *TextureCubeMap::getStorage(bool renderTarget) +void Texture2DArray::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) + // If there currently is a corresponding storage texture image, it has these parameters + const int storageWidth = std::max(1, getBaseLevelWidth() >> level); + const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const int storageDepth = getLayers(0); + const GLenum storageFormat = getBaseLevelInternalFormat(); + + for (int layer = 0; layer < mLayerCounts[level]; layer++) { - if (renderTarget) + delete mImageArray[level][layer]; + } + delete[] mImageArray[level]; + mImageArray[level] = NULL; + mLayerCounts[level] = depth; + + if (depth > 0) + { + mImageArray[level] = new rx::Image*[depth](); + + for (int layer = 0; layer < mLayerCounts[level]; layer++) { - convertToRenderTarget(); + mImageArray[level][layer] = mRenderer->createImage(); + mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, width, height, 1, false); } - else + } + + if (mTexStorage) + { + const int storageLevels = mTexStorage->getLevelCount(); + + if ((level >= storageLevels && storageLevels != 0) || + width != storageWidth || + height != storageHeight || + depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage { - createTexture(); + for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (int layer = 0; layer < mLayerCounts[level]; layer++) + { + mImageArray[level][layer]->markDirty(); + } + } + + delete mTexStorage; + mTexStorage = NULL; + mDirtyImages = true; } } +} - return mTexStorage; +void Texture2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height) +{ + if (isValidLevel(level) && layerTarget < getLayers(level)) + { + rx::Image *image = mImageArray[level][layerTarget]; + if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, layerTarget, width, height)) + { + image->markClean(); + } + } } } diff --git a/chromium/third_party/angle/src/libGLESv2/Texture.h b/chromium/third_party/angle/src/libGLESv2/Texture.h index 4f5fab28d01..84ca289877b 100644 --- a/chromium/third_party/angle/src/libGLESv2/Texture.h +++ b/chromium/third_party/angle/src/libGLESv2/Texture.h @@ -13,12 +13,13 @@ #include <vector> -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include "common/debug.h" #include "common/RefCountObject.h" #include "libGLESv2/angletypes.h" +#include "libGLESv2/RenderbufferProxySet.h" namespace egl { @@ -31,6 +32,8 @@ class Renderer; class TextureStorageInterface; class TextureStorageInterface2D; class TextureStorageInterfaceCube; +class TextureStorageInterface3D; +class TextureStorageInterface2DArray; class RenderTarget; class Image; } @@ -38,81 +41,110 @@ class Image; namespace gl { class Framebuffer; -class Renderbuffer; +class FramebufferAttachment; enum { // These are the maximums the implementation can support // The actual GL caps are limited by the device caps // and should be queried from the Context - IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384, + IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384, + IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048, + IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048, IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE }; +bool IsMipmapFiltered(const SamplerState &samplerState); + class Texture : public RefCountObject { public: - Texture(rx::Renderer *renderer, GLuint id); + Texture(rx::Renderer *renderer, GLuint id, GLenum target); virtual ~Texture(); - virtual void addProxyRef(const Renderbuffer *proxy) = 0; - virtual void releaseProxy(const Renderbuffer *proxy) = 0; - - virtual GLenum getTarget() const = 0; - - bool setMinFilter(GLenum filter); - bool setMagFilter(GLenum filter); - bool setWrapS(GLenum wrap); - bool setWrapT(GLenum wrap); - bool setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy); - bool setUsage(GLenum usage); + void addProxyRef(const FramebufferAttachment *proxy); + void releaseProxy(const FramebufferAttachment *proxy); + + GLenum getTarget() const; + + void setMinFilter(GLenum filter); + void setMagFilter(GLenum filter); + void setWrapS(GLenum wrap); + void setWrapT(GLenum wrap); + void setWrapR(GLenum wrap); + void setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy); + void setCompareMode(GLenum mode); + void setCompareFunc(GLenum func); + void setSwizzleRed(GLenum swizzle); + void setSwizzleGreen(GLenum swizzle); + void setSwizzleBlue(GLenum swizzle); + void setSwizzleAlpha(GLenum swizzle); + void setBaseLevel(GLint baseLevel); + void setMaxLevel(GLint maxLevel); + void setMinLod(GLfloat minLod); + void setMaxLod(GLfloat maxLod); + void setUsage(GLenum usage); GLenum getMinFilter() const; GLenum getMagFilter() const; GLenum getWrapS() const; GLenum getWrapT() const; + GLenum getWrapR() const; float getMaxAnisotropy() const; - int getLodOffset(); + GLenum getSwizzleRed() const; + GLenum getSwizzleGreen() const; + GLenum getSwizzleBlue() const; + GLenum getSwizzleAlpha() const; + GLint getBaseLevel() const; + GLint getMaxLevel() const; + GLfloat getMinLod() const; + GLfloat getMaxLod() const; + bool isSwizzled() const; void getSamplerState(SamplerState *sampler); GLenum getUsage() const; - bool isMipmapFiltered() const; - virtual bool isSamplerComplete() const = 0; + GLint getBaseLevelWidth() const; + GLint getBaseLevelHeight() const; + GLint getBaseLevelDepth() const; + GLenum getBaseLevelInternalFormat() const; + + virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0; rx::TextureStorageInterface *getNativeTexture(); - virtual Renderbuffer *getRenderbuffer(GLenum target) = 0; virtual void generateMipmaps() = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; bool hasDirtyParameters() const; bool hasDirtyImages() const; void resetDirty(); unsigned int getTextureSerial(); - unsigned int getRenderTargetSerial(GLenum target); bool isImmutable() const; + int immutableLevelCount(); static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. protected: - void setImage(GLint unpackAlignment, const void *pixels, rx::Image *image); - bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, rx::Image *image); + void setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image); + bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image); void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image); - bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image); - - GLint creationLevels(GLsizei width, GLsizei height) const; - GLint creationLevels(GLsizei size) const; + bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image); + bool isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat); + bool fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea, + GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget); - virtual void createTexture() = 0; - virtual void updateTexture() = 0; - virtual void convertToRenderTarget() = 0; - virtual rx::RenderTarget *getRenderTarget(GLenum target) = 0; + GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; + int mipLevels() const; - virtual int levelCount() = 0; + virtual void initializeStorage(bool renderTarget) = 0; + virtual void updateStorage() = 0; + virtual bool ensureRenderTarget() = 0; rx::Renderer *mRenderer; @@ -123,10 +155,20 @@ class Texture : public RefCountObject bool mImmutable; + GLenum mTarget; + + // A specific internal reference count is kept for colorbuffer proxy references, + // because, as the renderbuffer acting as proxy will maintain a binding pointer + // back to this texture, there would be a circular reference if we used a binding + // pointer here. This reference count will cause the pointer to be set to NULL if + // the count drops to zero, but will not cause deletion of the FramebufferAttachment. + RenderbufferProxySet mRenderbufferProxies; + private: DISALLOW_COPY_AND_ASSIGN(Texture); - virtual rx::TextureStorageInterface *getStorage(bool renderTarget) = 0; + virtual rx::TextureStorageInterface *getBaseLevelStorage() = 0; + virtual const rx::Image *getBaseLevelImage() const = 0; }; class Texture2D : public Texture @@ -136,11 +178,6 @@ class Texture2D : public Texture ~Texture2D(); - void addProxyRef(const Renderbuffer *proxy); - void releaseProxy(const Renderbuffer *proxy); - - virtual GLenum getTarget() const; - GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; GLenum getInternalFormat(GLint level) const; @@ -148,53 +185,52 @@ class Texture2D : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); - virtual bool isSamplerComplete() const; + virtual bool isSamplerComplete(const SamplerState &samplerState) const; virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual Renderbuffer *getRenderbuffer(GLenum target); + FramebufferAttachment *getAttachment(GLint level); + unsigned int getRenderTargetSerial(GLint level); protected: - friend class RenderbufferTexture2D; - virtual rx::RenderTarget *getRenderTarget(GLenum target); - virtual rx::RenderTarget *getDepthStencil(GLenum target); - virtual int levelCount(); + friend class Texture2DAttachment; + rx::RenderTarget *getRenderTarget(GLint level); + rx::RenderTarget *getDepthSencil(GLint level); private: DISALLOW_COPY_AND_ASSIGN(Texture2D); - virtual void createTexture(); - virtual void updateTexture(); - virtual void convertToRenderTarget(); - virtual rx::TextureStorageInterface *getStorage(bool renderTarget); + virtual void initializeStorage(bool renderTarget); + rx::TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage); + + virtual void updateStorage(); + virtual bool ensureRenderTarget(); + virtual rx::TextureStorageInterface *getBaseLevelStorage(); + virtual const rx::Image *getBaseLevelImage() const; bool isMipmapComplete() const; + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + void updateStorageLevel(int level); - void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height); + void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; rx::TextureStorageInterface2D *mTexStorage; egl::Surface *mSurface; - - // A specific internal reference count is kept for colorbuffer proxy references, - // because, as the renderbuffer acting as proxy will maintain a binding pointer - // back to this texture, there would be a circular reference if we used a binding - // pointer here. This reference count will cause the pointer to be set to NULL if - // the count drops to zero, but will not cause deletion of the Renderbuffer. - Renderbuffer *mColorbufferProxy; - unsigned int mProxyRefs; }; class TextureCubeMap : public Texture @@ -204,72 +240,196 @@ class TextureCubeMap : public Texture ~TextureCubeMap(); - void addProxyRef(const Renderbuffer *proxy); - void releaseProxy(const Renderbuffer *proxy); - - virtual GLenum getTarget() const; - GLsizei getWidth(GLenum target, GLint level) const; GLsizei getHeight(GLenum target, GLint level) const; GLenum getInternalFormat(GLenum target, GLint level) const; GLenum getActualFormat(GLenum target, GLint level) const; bool isCompressed(GLenum target, GLint level) const; + bool isDepth(GLenum target, GLint level) const; - void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); + void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); void storage(GLsizei levels, GLenum internalformat, GLsizei size); - virtual bool isSamplerComplete() const; + virtual bool isSamplerComplete(const SamplerState &samplerState) const; + bool isCubeComplete() const; virtual void generateMipmaps(); - virtual Renderbuffer *getRenderbuffer(GLenum target); + FramebufferAttachment *getAttachment(GLenum target, GLint level); + unsigned int getRenderTargetSerial(GLenum target, GLint level); - static unsigned int faceIndex(GLenum face); + static int targetToIndex(GLenum target); protected: - friend class RenderbufferTextureCubeMap; - virtual rx::RenderTarget *getRenderTarget(GLenum target); - virtual int levelCount(); + friend class TextureCubeMapAttachment; + rx::RenderTarget *getRenderTarget(GLenum target, GLint level); + rx::RenderTarget *getDepthStencil(GLenum target, GLint level); private: DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); - virtual void createTexture(); - virtual void updateTexture(); - virtual void convertToRenderTarget(); - virtual rx::TextureStorageInterface *getStorage(bool renderTarget); + virtual void initializeStorage(bool renderTarget); + rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage); + + virtual void updateStorage(); + virtual bool ensureRenderTarget(); + virtual rx::TextureStorageInterface *getBaseLevelStorage(); + virtual const rx::Image *getBaseLevelImage() const; - bool isCubeComplete() const; bool isMipmapCubeComplete() const; + bool isValidFaceLevel(int faceIndex, int level) const; + bool isFaceLevelComplete(int faceIndex, int level) const; + void updateStorageFaceLevel(int faceIndex, int level); - void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height); + void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height); rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; rx::TextureStorageInterfaceCube *mTexStorage; +}; - // A specific internal reference count is kept for colorbuffer proxy references, - // because, as the renderbuffer acting as proxy will maintain a binding pointer - // back to this texture, there would be a circular reference if we used a binding - // pointer here. This reference count will cause the pointer to be set to NULL if - // the count drops to zero, but will not cause deletion of the Renderbuffer. - Renderbuffer *mFaceProxies[6]; - unsigned int *mFaceProxyRefs[6]; +class Texture3D : public Texture +{ + public: + Texture3D(rx::Renderer *renderer, GLuint id); + + ~Texture3D(); + + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLsizei getDepth(GLint level) const; + GLenum getInternalFormat(GLint level) const; + GLenum getActualFormat(GLint level) const; + bool isCompressed(GLint level) const; + bool isDepth(GLint level) const; + + void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + + virtual void generateMipmaps(); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + + virtual bool isSamplerComplete(const SamplerState &samplerState) const; + virtual bool isMipmapComplete() const; + + FramebufferAttachment *getAttachment(GLint level, GLint layer); + unsigned int getRenderTargetSerial(GLint level, GLint layer); + + protected: + friend class Texture3DAttachment; + rx::RenderTarget *getRenderTarget(GLint level); + rx::RenderTarget *getRenderTarget(GLint level, GLint layer); + rx::RenderTarget *getDepthStencil(GLint level, GLint layer); + + private: + DISALLOW_COPY_AND_ASSIGN(Texture3D); + + virtual void initializeStorage(bool renderTarget); + rx::TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage); + + virtual void updateStorage(); + virtual bool ensureRenderTarget(); + + virtual rx::TextureStorageInterface *getBaseLevelStorage(); + virtual const rx::Image *getBaseLevelImage() const; + + void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + void updateStorageLevel(int level); + + rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + rx::TextureStorageInterface3D *mTexStorage; +}; + +class Texture2DArray : public Texture +{ + public: + Texture2DArray(rx::Renderer *renderer, GLuint id); + + ~Texture2DArray(); + + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLsizei getLayers(GLint level) const; + GLenum getInternalFormat(GLint level) const; + GLenum getActualFormat(GLint level) const; + bool isCompressed(GLint level) const; + bool isDepth(GLint level) const; + + void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + + virtual void generateMipmaps(); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + + virtual bool isSamplerComplete(const SamplerState &samplerState) const; + virtual bool isMipmapComplete() const; + + FramebufferAttachment *getAttachment(GLint level, GLint layer); + unsigned int getRenderTargetSerial(GLint level, GLint layer); + + protected: + friend class Texture2DArrayAttachment; + rx::RenderTarget *getRenderTarget(GLint level, GLint layer); + rx::RenderTarget *getDepthStencil(GLint level, GLint layer); + + private: + DISALLOW_COPY_AND_ASSIGN(Texture2DArray); + + virtual void initializeStorage(bool renderTarget); + rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage); + + virtual void updateStorage(); + virtual bool ensureRenderTarget(); + + virtual rx::TextureStorageInterface *getBaseLevelStorage(); + virtual const rx::Image *getBaseLevelImage() const; + + void deleteImages(); + void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height); + + bool isValidLevel(int level) const; + bool isLevelComplete(int level) const; + void updateStorageLevel(int level); + + // Storing images as an array of single depth textures since D3D11 treats each array level of a + // Texture2D object as a separate subresource. Each layer would have to be looped over + // to update all the texture layers since they cannot all be updated at once and it makes the most + // sense for the Image class to not have to worry about layer subresource as well as mip subresources. + GLsizei mLayerCounts[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + rx::Image **mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + rx::TextureStorageInterface2DArray *mTexStorage; }; + } #endif // LIBGLESV2_TEXTURE_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/TransformFeedback.cpp b/chromium/third_party/angle/src/libGLESv2/TransformFeedback.cpp new file mode 100644 index 00000000000..79ce08405d1 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/TransformFeedback.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2014 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 "libGLESv2/TransformFeedback.h" + +namespace gl +{ + +TransformFeedback::TransformFeedback(GLuint id) + : RefCountObject(id), + mStarted(GL_FALSE), + mPrimitiveMode(GL_NONE), + mPaused(GL_FALSE) +{ +} + +TransformFeedback::~TransformFeedback() +{ +} + +void TransformFeedback::start(GLenum primitiveMode) +{ + mStarted = GL_TRUE; + mPrimitiveMode = primitiveMode; + mPaused = GL_FALSE; +} + +void TransformFeedback::stop() +{ + mStarted = GL_FALSE; + mPrimitiveMode = GL_NONE; + mPaused = GL_FALSE; +} + +GLboolean TransformFeedback::isStarted() const +{ + return mStarted; +} + +GLenum TransformFeedback::getDrawMode() const +{ + return mPrimitiveMode; +} + +void TransformFeedback::pause() +{ + mPaused = GL_TRUE; +} + +void TransformFeedback::resume() +{ + mPaused = GL_FALSE; +} + +GLboolean TransformFeedback::isPaused() const +{ + return mPaused; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/TransformFeedback.h b/chromium/third_party/angle/src/libGLESv2/TransformFeedback.h new file mode 100644 index 00000000000..183873c82ff --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/TransformFeedback.h @@ -0,0 +1,45 @@ +// +// Copyright (c) 2014 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 LIBGLESV2_TRANSFORM_FEEDBACK_H_ +#define LIBGLESV2_TRANSFORM_FEEDBACK_H_ + +#include "common/angleutils.h" +#include "common/RefCountObject.h" + +#include <GLES3/gl3.h> +#include <GLES2/gl2.h> + +namespace gl +{ + +class TransformFeedback : public RefCountObject +{ + public: + explicit TransformFeedback(GLuint id); + virtual ~TransformFeedback(); + + void start(GLenum primitiveMode); + void stop(); + GLboolean isStarted() const; + + GLenum getDrawMode() const; + + void pause(); + void resume(); + GLboolean isPaused() const; + + private: + DISALLOW_COPY_AND_ASSIGN(TransformFeedback); + + GLboolean mStarted; + GLenum mPrimitiveMode; + GLboolean mPaused; +}; + +} + +#endif // LIBGLESV2_TRANSFORM_FEEDBACK_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/Uniform.cpp b/chromium/third_party/angle/src/libGLESv2/Uniform.cpp index 5424e271b5c..a5ab7cb517d 100644 --- a/chromium/third_party/angle/src/libGLESv2/Uniform.cpp +++ b/chromium/third_party/angle/src/libGLESv2/Uniform.cpp @@ -7,37 +7,100 @@ #include "libGLESv2/Uniform.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" namespace gl { -Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) - : type(type), precision(precision), name(name), arraySize(arraySize) +LinkedUniform::LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, + const int blockIndex, const BlockMemberInfo &blockInfo) + : type(type), + precision(precision), + name(name), + arraySize(arraySize), + blockIndex(blockIndex), + blockInfo(blockInfo), + data(NULL), + dirty(true), + psRegisterIndex(GL_INVALID_INDEX), + vsRegisterIndex(GL_INVALID_INDEX), + registerCount(0), + registerElement(0) { - int bytes = gl::UniformInternalSize(type) * elementCount(); - data = new unsigned char[bytes]; - memset(data, 0, bytes); - dirty = true; - - psRegisterIndex = -1; - vsRegisterIndex = -1; - registerCount = VariableRowCount(type) * elementCount(); + // We use data storage for default block uniforms to cache values that are sent to D3D during rendering + // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only) + if (isInDefaultBlock()) + { + size_t bytes = dataSize(); + data = new unsigned char[bytes]; + memset(data, 0, bytes); + registerCount = VariableRowCount(type) * elementCount(); + } } -Uniform::~Uniform() +LinkedUniform::~LinkedUniform() { delete[] data; } -bool Uniform::isArray() const +bool LinkedUniform::isArray() const { return arraySize > 0; } -unsigned int Uniform::elementCount() const +unsigned int LinkedUniform::elementCount() const { return arraySize > 0 ? arraySize : 1; } +bool LinkedUniform::isReferencedByVertexShader() const +{ + return vsRegisterIndex != GL_INVALID_INDEX; +} + +bool LinkedUniform::isReferencedByFragmentShader() const +{ + return psRegisterIndex != GL_INVALID_INDEX; +} + +bool LinkedUniform::isInDefaultBlock() const +{ + return blockIndex == -1; +} + +size_t LinkedUniform::dataSize() const +{ + ASSERT(type != GL_STRUCT_ANGLEX); + return UniformInternalSize(type) * elementCount(); +} + +bool LinkedUniform::isSampler() const +{ + return IsSampler(type); +} + +UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize) + : name(name), + elementIndex(elementIndex), + dataSize(dataSize), + psRegisterIndex(GL_INVALID_INDEX), + vsRegisterIndex(GL_INVALID_INDEX) +{ +} + +bool UniformBlock::isArrayElement() const +{ + return elementIndex != GL_INVALID_INDEX; +} + +bool UniformBlock::isReferencedByVertexShader() const +{ + return vsRegisterIndex != GL_INVALID_INDEX; +} + +bool UniformBlock::isReferencedByFragmentShader() const +{ + return psRegisterIndex != GL_INVALID_INDEX; +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/Uniform.h b/chromium/third_party/angle/src/libGLESv2/Uniform.h index 8ab0fbe2341..221ba48f949 100644 --- a/chromium/third_party/angle/src/libGLESv2/Uniform.h +++ b/chromium/third_party/angle/src/libGLESv2/Uniform.h @@ -10,38 +10,69 @@ #include <string> #include <vector> -#define GL_APICALL +#include <GLES3/gl3.h> #include <GLES2/gl2.h> #include "common/debug.h" +#include "angletypes.h" +#include "common/shadervars.h" namespace gl { // Helper struct representing a single shader uniform -struct Uniform +struct LinkedUniform { - Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize); + LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const BlockMemberInfo &blockInfo); - ~Uniform(); + ~LinkedUniform(); bool isArray() const; unsigned int elementCount() const; + bool isReferencedByVertexShader() const; + bool isReferencedByFragmentShader() const; + bool isInDefaultBlock() const; + size_t dataSize() const; + bool isSampler() const; const GLenum type; const GLenum precision; const std::string name; const unsigned int arraySize; + const int blockIndex; + const BlockMemberInfo blockInfo; unsigned char *data; bool dirty; - int psRegisterIndex; - int vsRegisterIndex; + unsigned int psRegisterIndex; + unsigned int vsRegisterIndex; unsigned int registerCount; + + // Register "elements" are used for uniform structs in ES3, to appropriately identify single uniforms + // inside aggregate types, which are packed according C-like structure rules. + unsigned int registerElement; }; -typedef std::vector<Uniform*> UniformArray; +// Helper struct representing a single shader uniform block +struct UniformBlock +{ + // use GL_INVALID_INDEX for non-array elements + UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize); + + bool isArrayElement() const; + bool isReferencedByVertexShader() const; + bool isReferencedByFragmentShader() const; + + const std::string name; + const unsigned int elementIndex; + const unsigned int dataSize; + + std::vector<unsigned int> memberUniformIndexes; + + unsigned int psRegisterIndex; + unsigned int vsRegisterIndex; +}; } diff --git a/chromium/third_party/angle/src/libGLESv2/VertexArray.cpp b/chromium/third_party/angle/src/libGLESv2/VertexArray.cpp new file mode 100644 index 00000000000..bd2df391695 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/VertexArray.cpp @@ -0,0 +1,71 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// +// Implementation of the state class for mananging GLES 3 Vertex Array Objects. +// + +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/Buffer.h" + +namespace gl +{ + +VertexArray::VertexArray(rx::Renderer *renderer, GLuint id) + : RefCountObject(id) +{ +} + +VertexArray::~VertexArray() +{ + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + mVertexAttributes[i].mBoundBuffer.set(NULL); + } + mElementArrayBuffer.set(NULL); +} + +void VertexArray::detachBuffer(GLuint bufferName) +{ + for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) + { + if (mVertexAttributes[attribute].mBoundBuffer.id() == bufferName) + { + mVertexAttributes[attribute].mBoundBuffer.set(NULL); + } + } + + if (mElementArrayBuffer.id() == bufferName) + { + mElementArrayBuffer.set(NULL); + } +} + +const VertexAttribute& VertexArray::getVertexAttribute(unsigned int attributeIndex) const +{ + ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS); + return mVertexAttributes[attributeIndex]; +} + +void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor) +{ + ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + mVertexAttributes[index].mDivisor = divisor; +} + +void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState) +{ + ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS); + mVertexAttributes[attributeIndex].mArrayEnabled = enabledState; +} + +void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, + bool normalized, bool pureInteger, GLsizei stride, const void *pointer) +{ + ASSERT(attributeIndex < gl::MAX_VERTEX_ATTRIBS); + mVertexAttributes[attributeIndex].setState(boundBuffer, size, type, normalized, pureInteger, stride, pointer); +} + +}
\ No newline at end of file diff --git a/chromium/third_party/angle/src/libGLESv2/VertexArray.h b/chromium/third_party/angle/src/libGLESv2/VertexArray.h new file mode 100644 index 00000000000..ecfe7ad8f91 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/VertexArray.h @@ -0,0 +1,54 @@ +// +// Copyright (c) 2013 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. +// +// This class contains prototypes for representing GLES 3 Vertex Array Objects: +// +// The buffer objects that are to be used by the vertex stage of the GL are collected +// together to form a vertex array object. All state related to the definition of data used +// by the vertex processor is encapsulated in a vertex array object. +// + +#ifndef LIBGLESV2_VERTEXARRAY_H_ +#define LIBGLESV2_VERTEXARRAY_H_ + +#include "common/RefCountObject.h" +#include "libGLESv2/constants.h" +#include "libGLESv2/VertexAttribute.h" + +namespace rx +{ +class Renderer; +} + +namespace gl +{ +class Buffer; + +class VertexArray : public RefCountObject +{ + public: + VertexArray(rx::Renderer *renderer, GLuint id); + ~VertexArray(); + + const VertexAttribute& getVertexAttribute(unsigned int attributeIndex) const; + void detachBuffer(GLuint bufferName); + void setVertexAttribDivisor(GLuint index, GLuint divisor); + void enableAttribute(unsigned int attributeIndex, bool enabledState); + void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, + bool normalized, bool pureInteger, GLsizei stride, const void *pointer); + + const VertexAttribute* getVertexAttributes() const { return mVertexAttributes; } + Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); } + void setElementArrayBuffer(Buffer *elementArrayBuffer) { mElementArrayBuffer.set(elementArrayBuffer); } + GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); } + + private: + VertexAttribute mVertexAttributes[MAX_VERTEX_ATTRIBS]; + BindingPointer<Buffer> mElementArrayBuffer; +}; + +} + +#endif // LIBGLESV2_VERTEXARRAY_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/VertexAttribute.h b/chromium/third_party/angle/src/libGLESv2/VertexAttribute.h new file mode 100644 index 00000000000..e9364d66e83 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/VertexAttribute.h @@ -0,0 +1,156 @@ +// +// Copyright (c) 2013 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. +// +// Helper structure describing a single vertex attribute +// + +#ifndef LIBGLESV2_VERTEXATTRIBUTE_H_ +#define LIBGLESV2_VERTEXATTRIBUTE_H_ + +#include "libGLESv2/Buffer.h" + +namespace gl +{ + +class VertexAttribute +{ + public: + VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mPureInteger(false), + mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0) + { + } + + int typeSize() const + { + switch (mType) + { + case GL_BYTE: return mSize * sizeof(GLbyte); + case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte); + case GL_SHORT: return mSize * sizeof(GLshort); + case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort); + case GL_INT: return mSize * sizeof(GLint); + case GL_UNSIGNED_INT: return mSize * sizeof(GLuint); + case GL_INT_2_10_10_10_REV: return 4; + case GL_UNSIGNED_INT_2_10_10_10_REV: return 4; + case GL_FIXED: return mSize * sizeof(GLfixed); + case GL_HALF_FLOAT: return mSize * sizeof(GLhalf); + case GL_FLOAT: return mSize * sizeof(GLfloat); + default: UNREACHABLE(); return mSize * sizeof(GLfloat); + } + } + + GLsizei stride() const + { + return (mArrayEnabled ? (mStride ? mStride : typeSize()) : 16); + } + + void setState(gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, + bool pureInteger, GLsizei stride, const void *pointer) + { + mBoundBuffer.set(boundBuffer); + mSize = size; + mType = type; + mNormalized = normalized; + mPureInteger = pureInteger; + mStride = stride; + mPointer = pointer; + } + + template <typename T> + T querySingleParameter(GLenum pname) const + { + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + return static_cast<T>(mArrayEnabled ? GL_TRUE : GL_FALSE); + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + return static_cast<T>(mSize); + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + return static_cast<T>(mStride); + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + return static_cast<T>(mType); + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + return static_cast<T>(mNormalized ? GL_TRUE : GL_FALSE); + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return static_cast<T>(mBoundBuffer.id()); + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + return static_cast<T>(mDivisor); + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + return static_cast<T>(mPureInteger ? GL_TRUE : GL_FALSE); + default: + UNREACHABLE(); + return static_cast<T>(0); + } + } + + // From glVertexAttribPointer + GLenum mType; + GLint mSize; + bool mNormalized; + bool mPureInteger; + GLsizei mStride; // 0 means natural stride + + union + { + const void *mPointer; + intptr_t mOffset; + }; + + BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called. + bool mArrayEnabled; // From glEnable/DisableVertexAttribArray + unsigned int mDivisor; +}; + +struct VertexAttribCurrentValueData +{ + union + { + GLfloat FloatValues[4]; + GLint IntValues[4]; + GLuint UnsignedIntValues[4]; + }; + GLenum Type; + + void setFloatValues(const GLfloat floatValues[4]) + { + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + FloatValues[valueIndex] = floatValues[valueIndex]; + } + Type = GL_FLOAT; + } + + void setIntValues(const GLint intValues[4]) + { + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + IntValues[valueIndex] = intValues[valueIndex]; + } + Type = GL_INT; + } + + void setUnsignedIntValues(const GLuint unsignedIntValues[4]) + { + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex]; + } + Type = GL_UNSIGNED_INT; + } + + bool operator==(const VertexAttribCurrentValueData &other) + { + return (Type == other.Type && memcmp(FloatValues, other.FloatValues, sizeof(float) * 4) == 0); + } + + bool operator!=(const VertexAttribCurrentValueData &other) + { + return !(*this == other); + } +}; + +} + +#endif // LIBGLESV2_VERTEXATTRIBUTE_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/angletypes.cpp b/chromium/third_party/angle/src/libGLESv2/angletypes.cpp new file mode 100644 index 00000000000..acb3da8999d --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/angletypes.cpp @@ -0,0 +1,177 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2 + +#include "libGLESv2/angletypes.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/VertexAttribute.h" + +namespace gl +{ + +bool SamplerState::swizzleRequired() const +{ + return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || + swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA; +} + +static void MinMax(int a, int b, int *minimum, int *maximum) +{ + if (a < b) + { + *minimum = a; + *maximum = b; + } + else + { + *minimum = b; + *maximum = a; + } +} + +bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection) +{ + int minSourceX, maxSourceX, minSourceY, maxSourceY; + MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX); + MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY); + + int minClipX, maxClipX, minClipY, maxClipY; + MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX); + MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY); + + if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY || maxSourceY <= minClipY) + { + if (intersection) + { + intersection->x = minSourceX; + intersection->y = maxSourceY; + intersection->width = maxSourceX - minSourceX; + intersection->height = maxSourceY - minSourceY; + } + + return false; + } + else + { + if (intersection) + { + intersection->x = std::max(minSourceX, minClipX); + intersection->y = std::max(minSourceY, minClipY); + intersection->width = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX); + intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY); + } + + return true; + } +} + +VertexFormat::VertexFormat() + : mType(GL_NONE), + mNormalized(GL_FALSE), + mComponents(0), + mPureInteger(false) +{} + +VertexFormat::VertexFormat(GLenum type, GLboolean normalized, GLuint components, bool pureInteger) + : mType(type), + mNormalized(normalized), + mComponents(components), + mPureInteger(pureInteger) +{ + // Float data can not be normalized, so ignore the user setting + if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) + { + mNormalized = GL_FALSE; + } +} + +VertexFormat::VertexFormat(const VertexAttribute &attribute) + : mType(attribute.mType), + mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE), + mComponents(attribute.mSize), + mPureInteger(attribute.mPureInteger) +{ + // Ensure we aren't initializing a vertex format which should be using + // the current-value type + ASSERT(attribute.mArrayEnabled); + + // Float data can not be normalized, so ignore the user setting + if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) + { + mNormalized = GL_FALSE; + } +} + +VertexFormat::VertexFormat(const VertexAttribute &attribute, GLenum currentValueType) + : mType(attribute.mType), + mNormalized(attribute.mNormalized ? GL_TRUE : GL_FALSE), + mComponents(attribute.mSize), + mPureInteger(attribute.mPureInteger) +{ + if (!attribute.mArrayEnabled) + { + mType = currentValueType; + mNormalized = GL_FALSE; + mComponents = 4; + mPureInteger = (currentValueType != GL_FLOAT); + } + + // Float data can not be normalized, so ignore the user setting + if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) + { + mNormalized = GL_FALSE; + } +} + +void VertexFormat::GetInputLayout(VertexFormat *inputLayout, + ProgramBinary *programBinary, + const VertexAttribute *attributes, + const gl::VertexAttribCurrentValueData *currentValues) +{ + for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + int semanticIndex = programBinary->getSemanticIndex(attributeIndex); + + if (semanticIndex != -1) + { + inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type); + } + } +} + +bool VertexFormat::operator==(const VertexFormat &other) const +{ + return (mType == other.mType && + mComponents == other.mComponents && + mNormalized == other.mNormalized && + mPureInteger == other.mPureInteger ); +} + +bool VertexFormat::operator!=(const VertexFormat &other) const +{ + return !(*this == other); +} + +bool VertexFormat::operator<(const VertexFormat& other) const +{ + if (mType != other.mType) + { + return mType < other.mType; + } + if (mNormalized != other.mNormalized) + { + return mNormalized < other.mNormalized; + } + if (mComponents != other.mComponents) + { + return mComponents < other.mComponents; + } + return mPureInteger < other.mPureInteger; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/angletypes.h b/chromium/third_party/angle/src/libGLESv2/angletypes.h index b2f0cad2659..0e91279d241 100644 --- a/chromium/third_party/angle/src/libGLESv2/angletypes.h +++ b/chromium/third_party/angle/src/libGLESv2/angletypes.h @@ -9,13 +9,22 @@ #ifndef LIBGLESV2_ANGLETYPES_H_ #define LIBGLESV2_ANGLETYPES_H_ +#include "libGLESv2/constants.h" +#include "common/RefCountObject.h" + namespace gl { +class Buffer; +class ProgramBinary; +class VertexAttribute; +struct VertexAttribCurrentValueData; enum TextureType { TEXTURE_2D, TEXTURE_CUBE, + TEXTURE_3D, + TEXTURE_2D_ARRAY, TEXTURE_TYPE_COUNT, TEXTURE_UNKNOWN @@ -27,20 +36,56 @@ enum SamplerType SAMPLER_VERTEX }; +template <typename T> struct Color { - float red; - float green; - float blue; - float alpha; + T red; + T green; + T blue; + T alpha; + + Color() : red(0), green(0), blue(0), alpha(0) { } + Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) { } }; +typedef Color<float> ColorF; +typedef Color<int> ColorI; +typedef Color<unsigned int> ColorUI; + struct Rectangle { int x; int y; int width; int height; + + Rectangle() : x(0), y(0), width(0), height(0) { } + Rectangle(int x_in, int y_in, int width_in, int height_in) : x(x_in), y(y_in), width(width_in), height(height_in) { } +}; + +bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection); + +struct Box +{ + int x; + int y; + int z; + int width; + int height; + int depth; + + Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { } + Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { } +}; + +struct Extents +{ + int width; + int height; + int depth; + + Extents() : width(0), height(0), depth(0) { } + Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) { } }; struct RasterizerState @@ -55,6 +100,8 @@ struct RasterizerState bool pointDrawMode; bool multiSample; + + bool rasterizerDiscard; }; struct BlendState @@ -104,24 +151,119 @@ struct SamplerState GLenum magFilter; GLenum wrapS; GLenum wrapT; + GLenum wrapR; float maxAnisotropy; - int lodOffset; + + GLint baseLevel; + GLint maxLevel; + GLfloat minLod; + GLfloat maxLod; + + GLenum compareMode; + GLenum compareFunc; + + GLenum swizzleRed; + GLenum swizzleGreen; + GLenum swizzleBlue; + GLenum swizzleAlpha; + + bool swizzleRequired() const; }; struct ClearParameters { - GLbitfield mask; - - Color colorClearValue; + bool clearColor[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; + ColorF colorFClearValue; + ColorI colorIClearValue; + ColorUI colorUIClearValue; + GLenum colorClearType; bool colorMaskRed; bool colorMaskGreen; bool colorMaskBlue; bool colorMaskAlpha; + bool clearDepth; float depthClearValue; + bool clearStencil; GLint stencilClearValue; GLuint stencilWriteMask; + + bool scissorEnabled; + Rectangle scissor; +}; + +struct PixelUnpackState +{ + BindingPointer<Buffer> pixelBuffer; + GLint alignment; + + PixelUnpackState() + : alignment(4) + {} + + explicit PixelUnpackState(GLint alignmentIn) + : alignment(alignmentIn) + {} +}; + +struct PixelPackState +{ + BindingPointer<Buffer> pixelBuffer; + GLint alignment; + bool reverseRowOrder; + + PixelPackState() + : alignment(4), + reverseRowOrder(false) + {} + + explicit PixelPackState(GLint alignmentIn, bool reverseRowOrderIn) + : alignment(alignmentIn), + reverseRowOrder(reverseRowOrderIn) + {} +}; + +struct VertexFormat +{ + GLenum mType; + GLboolean mNormalized; + GLuint mComponents; + bool mPureInteger; + + VertexFormat(); + VertexFormat(GLenum type, GLboolean normalized, GLuint components, bool pureInteger); + explicit VertexFormat(const VertexAttribute &attribute); + VertexFormat(const VertexAttribute &attribute, GLenum currentValueType); + + static void GetInputLayout(VertexFormat *inputLayout, + ProgramBinary *programBinary, + const VertexAttribute *attributes, + const gl::VertexAttribCurrentValueData *currentValues); + + bool operator==(const VertexFormat &other) const; + bool operator!=(const VertexFormat &other) const; + bool operator<(const VertexFormat& other) const; +}; + +} + +namespace rx +{ + +enum VertexConversionType +{ + VERTEX_CONVERT_NONE = 0, + VERTEX_CONVERT_CPU = 1, + VERTEX_CONVERT_GPU = 2, + VERTEX_CONVERT_BOTH = 3 +}; + +enum D3DWorkaroundType +{ + ANGLE_D3D_WORKAROUND_NONE, + ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION, + ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION }; } diff --git a/chromium/third_party/angle/src/libGLESv2/Constants.h b/chromium/third_party/angle/src/libGLESv2/constants.h index 9f24d66a7dc..0c1c0ef1375 100644 --- a/chromium/third_party/angle/src/libGLESv2/Constants.h +++ b/chromium/third_party/angle/src/libGLESv2/constants.h @@ -22,7 +22,15 @@ enum IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS, IMPLEMENTATION_MAX_VARYING_VECTORS = 32, - IMPLEMENTATION_MAX_DRAW_BUFFERS = 8 + IMPLEMENTATION_MAX_DRAW_BUFFERS = 8, + IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers + + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS + + IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS, + + IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4, }; const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f; diff --git a/chromium/third_party/angle/src/libGLESv2/formatutils.cpp b/chromium/third_party/angle/src/libGLESv2/formatutils.cpp new file mode 100644 index 00000000000..3aac25efadd --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/formatutils.cpp @@ -0,0 +1,1812 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// formatutils.cpp: Queries for GL image formats. + +#include "common/mathutil.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/imageformats.h" +#include "libGLESv2/renderer/copyimage.h" + +namespace gl +{ + +// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation +// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid +// format and type combinations. + +struct FormatTypeInfo +{ + GLenum mInternalFormat; + ColorWriteFunction mColorWriteFunction; + + FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc) + : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc) + { } +}; + +typedef std::pair<GLenum, GLenum> FormatTypePair; +typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair; +typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap; + +// A helper function to insert data into the format map with fewer characters. +static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc) +{ + map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc))); +} + +FormatMap BuildES2FormatMap() +{ + FormatMap map; + + using namespace rx; + + // | Format | Type | Internal format | Color write function | + InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT, WriteColor<A8, GLfloat> ); + InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT, WriteColor<A32F, GLfloat> ); + InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> ); + + InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT, WriteColor<L8, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT, WriteColor<L32F, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> ); + + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT, WriteColor<L8A8, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8_EXT, WriteColor<R8, GLfloat> ); + InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F_EXT, WriteColor<R32F, GLfloat> ); + InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F_EXT, WriteColor<R16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8_EXT, WriteColor<R8G8, GLfloat> ); + InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F_EXT, WriteColor<R32G32F, GLfloat> ); + InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F_EXT, WriteColor<R16G16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8_OES, WriteColor<R8G8B8, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, WriteColor<R5G6B5, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F_EXT, WriteColor<R32G32B32F, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F_EXT, WriteColor<R16G16B16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8_OES, WriteColor<R8G8B8A8, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, WriteColor<R4G4B4A4, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, WriteColor<R5G5B5A1, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F_EXT, WriteColor<R32G32B32A32F, GLfloat>); + InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F_EXT, WriteColor<R16G16B16A16F, GLfloat>); + + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT, WriteColor<B8G8R8A8, GLfloat> ); + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> ); + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> ); + + InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, NULL ); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL ); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL ); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL ); + + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, NULL ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES, NULL ); + + InsertFormatMapping(&map, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, GL_DEPTH24_STENCIL8_OES, NULL ); + + return map; +} + +FormatMap BuildES3FormatMap() +{ + FormatMap map; + + using namespace rx; + + // | Format | Type | Internal format | Color write function | + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8, WriteColor<R8G8B8A8, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM, WriteColor<R8G8B8A8S, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, WriteColor<R4G4B4A4, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, WriteColor<R5G5B5A1, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2, WriteColor<R10G10B10A2, GLfloat> ); + InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F, WriteColor<R32G32B32A32F, GLfloat>); + InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, WriteColor<R16G16B16A16F, GLfloat>); + + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI, WriteColor<R8G8B8A8, GLuint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I, WriteColor<R8G8B8A8S, GLint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI, WriteColor<R16G16B16A16, GLuint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I, WriteColor<R16G16B16A16S, GLint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI, WriteColor<R32G32B32A32, GLuint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I, WriteColor<R32G32B32A32S, GLint> ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI, WriteColor<R10G10B10A2, GLuint> ); + + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8, WriteColor<R8G8B8, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM, WriteColor<R8G8B8S, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, WriteColor<R5G6B5, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F, WriteColor<R11G11B10F, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5, WriteColor<R9G9B9E5, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F, WriteColor<R32G32B32F, GLfloat> ); + InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F, WriteColor<R16G16B16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI, WriteColor<R8G8B8, GLuint> ); + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I, WriteColor<R8G8B8S, GLint> ); + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI, WriteColor<R16G16B16, GLuint> ); + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I, WriteColor<R16G16B16S, GLint> ); + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI, WriteColor<R32G32B32, GLuint> ); + InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I, WriteColor<R32G32B32S, GLint> ); + + InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8, WriteColor<R8G8, GLfloat> ); + InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM, WriteColor<R8G8S, GLfloat> ); + InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F, WriteColor<R32G32F, GLfloat> ); + InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F, WriteColor<R16G16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI, WriteColor<R8G8, GLuint> ); + InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I, WriteColor<R8G8S, GLint> ); + InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI, WriteColor<R16G16, GLuint> ); + InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I, WriteColor<R16G16S, GLint> ); + InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI, WriteColor<R32G32, GLuint> ); + InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I, WriteColor<R32G32S, GLint> ); + + InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8, WriteColor<R8, GLfloat> ); + InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM, WriteColor<R8S, GLfloat> ); + InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F, WriteColor<R32F, GLfloat> ); + InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F, WriteColor<R16F, GLfloat> ); + + InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI, WriteColor<R8, GLuint> ); + InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I, WriteColor<R8S, GLint> ); + InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI, WriteColor<R16, GLuint> ); + InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I, WriteColor<R16S, GLint> ); + InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI, WriteColor<R32, GLuint> ); + InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I, WriteColor<R32S, GLint> ); + + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT, WriteColor<L8A8, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT, WriteColor<L8, GLfloat> ); + InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT, WriteColor<A8, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT, WriteColor<L32F, GLfloat> ); + InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT, WriteColor<A32F, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> ); + InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> ); + InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> ); + + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT, WriteColor<B8G8R8A8, GLfloat> ); + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> ); + InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> ); + + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, NULL ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24, NULL ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F, NULL ); + + InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, NULL ); + InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, NULL ); + + return map; +} + +static const FormatMap &GetFormatMap(GLuint clientVersion) +{ + if (clientVersion == 2) + { + static const FormatMap formats = BuildES2FormatMap(); + return formats; + } + else if (clientVersion == 3) + { + static const FormatMap formats = BuildES3FormatMap(); + return formats; + } + else + { + UNREACHABLE(); + static FormatMap emptyMap; + return emptyMap; + } +} + +struct FormatInfo +{ + GLenum mInternalformat; + GLenum mFormat; + GLenum mType; + + FormatInfo(GLenum internalformat, GLenum format, GLenum type) + : mInternalformat(internalformat), mFormat(format), mType(type) { } + + bool operator<(const FormatInfo& other) const + { + return memcmp(this, &other, sizeof(FormatInfo)) < 0; + } +}; + +// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable. +typedef std::set<FormatInfo> ES3FormatSet; + +ES3FormatSet BuildES3FormatSet() +{ + ES3FormatSet set; + + // Format combinations from ES 3.0.1 spec, table 3.2 + + // | Internal format | Format | Type | + // | | | | + set.insert(FormatInfo(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE )); + set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 )); + set.insert(FormatInfo(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV )); + set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV )); + set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 )); + set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_RGBA32F, GL_RGBA, GL_FLOAT )); + set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_FLOAT )); + set.insert(FormatInfo(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE )); + set.insert(FormatInfo(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT )); + set.insert(FormatInfo(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT )); + set.insert(FormatInfo(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT )); + set.insert(FormatInfo(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV )); + set.insert(FormatInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGB8_SNORM, GL_RGB, GL_BYTE )); + set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 )); + set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV )); + set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV )); + set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_RGB32F, GL_RGB, GL_FLOAT )); + set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_FLOAT )); + set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT )); + set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_FLOAT )); + set.insert(FormatInfo(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGB8I, GL_RGB_INTEGER, GL_BYTE )); + set.insert(FormatInfo(GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT )); + set.insert(FormatInfo(GL_RGB16I, GL_RGB_INTEGER, GL_SHORT )); + set.insert(FormatInfo(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_RGB32I, GL_RGB_INTEGER, GL_INT )); + set.insert(FormatInfo(GL_RG8, GL_RG, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RG8_SNORM, GL_RG, GL_BYTE )); + set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_RG32F, GL_RG, GL_FLOAT )); + set.insert(FormatInfo(GL_RG16F, GL_RG, GL_FLOAT )); + set.insert(FormatInfo(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RG8I, GL_RG_INTEGER, GL_BYTE )); + set.insert(FormatInfo(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT )); + set.insert(FormatInfo(GL_RG16I, GL_RG_INTEGER, GL_SHORT )); + set.insert(FormatInfo(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_RG32I, GL_RG_INTEGER, GL_INT )); + set.insert(FormatInfo(GL_R8, GL_RED, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_R8_SNORM, GL_RED, GL_BYTE )); + set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_R32F, GL_RED, GL_FLOAT )); + set.insert(FormatInfo(GL_R16F, GL_RED, GL_FLOAT )); + set.insert(FormatInfo(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_R8I, GL_RED_INTEGER, GL_BYTE )); + set.insert(FormatInfo(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT )); + set.insert(FormatInfo(GL_R16I, GL_RED_INTEGER, GL_SHORT )); + set.insert(FormatInfo(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_R32I, GL_RED_INTEGER, GL_INT )); + + // Unsized formats + set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 )); + set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 )); + set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 )); + set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE )); + + // Depth stencil formats + set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT )); + set.insert(FormatInfo(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT )); + set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT )); + set.insert(FormatInfo(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 )); + set.insert(FormatInfo(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV)); + + // From GL_OES_texture_float + set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT )); + set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_FLOAT )); + + // From GL_OES_texture_half_float + set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT )); + + // From GL_EXT_texture_format_BGRA8888 + set.insert(FormatInfo(GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE )); + + // From GL_EXT_texture_storage + // | Internal format | Format | Type | + // | | | | + set.insert(FormatInfo(GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT )); + set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT )); + set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT )); + + // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888 + set.insert(FormatInfo(GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT)); + set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE )); + set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)); + set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE )); + + // From GL_ANGLE_depth_texture + set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES )); + + // Compressed formats + // From ES 3.0.1 spec, table 3.16 + // | Internal format | Format | Type | + // | | | | + set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE)); + + + // From GL_EXT_texture_compression_dxt1 + set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE)); + set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE)); + + // From GL_ANGLE_texture_compression_dxt3 + set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE)); + + // From GL_ANGLE_texture_compression_dxt5 + set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE)); + + return set; +} + +static const ES3FormatSet &GetES3FormatSet() +{ + static const ES3FormatSet es3FormatSet = BuildES3FormatSet(); + return es3FormatSet; +} + +// Map of sizes of input types +struct TypeInfo +{ + GLuint mTypeBytes; + bool mSpecialInterpretation; + + TypeInfo() + : mTypeBytes(0), mSpecialInterpretation(false) { } + + TypeInfo(GLuint typeBytes, bool specialInterpretation) + : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { } + + bool operator<(const TypeInfo& other) const + { + return memcmp(this, &other, sizeof(TypeInfo)) < 0; + } +}; + +typedef std::pair<GLenum, TypeInfo> TypeInfoPair; +typedef std::map<GLenum, TypeInfo> TypeInfoMap; + +static TypeInfoMap BuildTypeInfoMap() +{ + TypeInfoMap map; + + map.insert(TypeInfoPair(GL_UNSIGNED_BYTE, TypeInfo( 1, false))); + map.insert(TypeInfoPair(GL_BYTE, TypeInfo( 1, false))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT, TypeInfo( 2, false))); + map.insert(TypeInfoPair(GL_SHORT, TypeInfo( 2, false))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT, TypeInfo( 4, false))); + map.insert(TypeInfoPair(GL_INT, TypeInfo( 4, false))); + map.insert(TypeInfoPair(GL_HALF_FLOAT, TypeInfo( 2, false))); + map.insert(TypeInfoPair(GL_HALF_FLOAT_OES, TypeInfo( 2, false))); + map.insert(TypeInfoPair(GL_FLOAT, TypeInfo( 4, false))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5, TypeInfo( 2, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4, TypeInfo( 2, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1, TypeInfo( 2, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV, TypeInfo( 4, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8, TypeInfo( 4, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV, TypeInfo( 4, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV, TypeInfo( 4, true ))); + map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES, TypeInfo( 4, true ))); + map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true ))); + + return map; +} + +static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo) +{ + static const TypeInfoMap infoMap = BuildTypeInfoMap(); + TypeInfoMap::const_iterator iter = infoMap.find(type); + if (iter != infoMap.end()) + { + if (outTypeInfo) + { + *outTypeInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +// Information about internal formats +typedef bool ((Context::*ContextSupportCheckMemberFunction)(void) const); +typedef bool (*ContextSupportCheckFunction)(const Context *context); + +typedef bool ((rx::Renderer::*RendererSupportCheckMemberFunction)(void) const); +typedef bool (*ContextRendererSupportCheckFunction)(const Context *context, const rx::Renderer *renderer); + +template <ContextSupportCheckMemberFunction func> +bool CheckSupport(const Context *context) +{ + return (context->*func)(); +} + +template <ContextSupportCheckMemberFunction contextFunc, RendererSupportCheckMemberFunction rendererFunc> +bool CheckSupport(const Context *context, const rx::Renderer *renderer) +{ + if (context) + { + return (context->*contextFunc)(); + } + else if (renderer) + { + return (renderer->*rendererFunc)(); + } + else + { + UNREACHABLE(); + return false; + } +} + +template <typename objectType> +bool AlwaysSupported(const objectType*) +{ + return true; +} + +template <typename objectTypeA, typename objectTypeB> +bool AlwaysSupported(const objectTypeA*, const objectTypeB*) +{ + return true; +} + +template <typename objectType> +bool NeverSupported(const objectType*) +{ + return false; +} + +template <typename objectTypeA, typename objectTypeB> +bool NeverSupported(const objectTypeA *, const objectTypeB *) +{ + return false; +} + +template <typename objectType> +bool UnimplementedSupport(const objectType*) +{ + UNIMPLEMENTED(); + return false; +} + +template <typename objectTypeA, typename objectTypeB> +bool UnimplementedSupport(const objectTypeA*, const objectTypeB*) +{ + UNIMPLEMENTED(); + return false; +} + +struct InternalFormatInfo +{ + GLuint mRedBits; + GLuint mGreenBits; + GLuint mBlueBits; + + GLuint mLuminanceBits; + + GLuint mAlphaBits; + GLuint mSharedBits; + + GLuint mDepthBits; + GLuint mStencilBits; + + GLuint mPixelBits; + + GLuint mComponentCount; + + GLuint mCompressedBlockWidth; + GLuint mCompressedBlockHeight; + + GLenum mFormat; + GLenum mType; + + GLenum mComponentType; + GLenum mColorEncoding; + + bool mIsCompressed; + + ContextRendererSupportCheckFunction mIsColorRenderable; + ContextRendererSupportCheckFunction mIsDepthRenderable; + ContextRendererSupportCheckFunction mIsStencilRenderable; + ContextRendererSupportCheckFunction mIsTextureFilterable; + + ContextSupportCheckFunction mSupportFunction; + + InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0), + mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE), + mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mIsColorRenderable(NeverSupported), + mIsDepthRenderable(NeverSupported), mIsStencilRenderable(NeverSupported), mIsTextureFilterable(NeverSupported), + mSupportFunction(NeverSupported) + { + } + + static InternalFormatInfo UnsizedFormat(GLenum format, ContextSupportCheckFunction supportFunction) + { + InternalFormatInfo formatInfo; + formatInfo.mFormat = format; + formatInfo.mSupportFunction = supportFunction; + + if (format == GL_RGB || format == GL_RGBA) + formatInfo.mIsColorRenderable = AlwaysSupported; + + return formatInfo; + } + + static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared, + GLenum format, GLenum type, GLenum componentType, bool srgb, + ContextRendererSupportCheckFunction colorRenderable, + ContextRendererSupportCheckFunction textureFilterable, + ContextSupportCheckFunction supportFunction) + { + InternalFormatInfo formatInfo; + formatInfo.mRedBits = red; + formatInfo.mGreenBits = green; + formatInfo.mBlueBits = blue; + formatInfo.mAlphaBits = alpha; + formatInfo.mSharedBits = shared; + formatInfo.mPixelBits = red + green + blue + alpha + shared; + formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); + formatInfo.mFormat = format; + formatInfo.mType = type; + formatInfo.mComponentType = componentType; + formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR); + formatInfo.mIsColorRenderable = colorRenderable; + formatInfo.mIsTextureFilterable = textureFilterable; + formatInfo.mSupportFunction = supportFunction; + return formatInfo; + } + + static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType, + ContextSupportCheckFunction supportFunction) + { + InternalFormatInfo formatInfo; + formatInfo.mLuminanceBits = luminance; + formatInfo.mAlphaBits = alpha; + formatInfo.mPixelBits = luminance + alpha; + formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); + formatInfo.mFormat = format; + formatInfo.mType = type; + formatInfo.mComponentType = componentType; + formatInfo.mColorEncoding = GL_LINEAR; + formatInfo.mIsTextureFilterable = AlwaysSupported; + formatInfo.mSupportFunction = supportFunction; + return formatInfo; + } + + static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format, + GLenum type, GLenum componentType, + ContextRendererSupportCheckFunction depthRenderable, + ContextRendererSupportCheckFunction stencilRenderable, + ContextSupportCheckFunction supportFunction) + { + InternalFormatInfo formatInfo; + formatInfo.mDepthBits = depthBits; + formatInfo.mStencilBits = stencilBits; + formatInfo.mPixelBits = depthBits + stencilBits + unusedBits; + formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0); + formatInfo.mFormat = format; + formatInfo.mType = type; + formatInfo.mComponentType = componentType; + formatInfo.mColorEncoding = GL_LINEAR; + formatInfo.mIsDepthRenderable = depthRenderable; + formatInfo.mIsStencilRenderable = stencilRenderable; + formatInfo.mIsTextureFilterable = AlwaysSupported; + formatInfo.mSupportFunction = supportFunction; + return formatInfo; + } + + static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize, + GLuint componentCount, GLenum format, GLenum type, bool srgb, + ContextSupportCheckFunction supportFunction) + { + InternalFormatInfo formatInfo; + formatInfo.mCompressedBlockWidth = compressedBlockWidth; + formatInfo.mCompressedBlockHeight = compressedBlockHeight; + formatInfo.mPixelBits = compressedBlockSize; + formatInfo.mComponentCount = componentCount; + formatInfo.mFormat = format; + formatInfo.mType = type; + formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED; + formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR); + formatInfo.mIsCompressed = true; + formatInfo.mIsTextureFilterable = AlwaysSupported; + formatInfo.mSupportFunction = supportFunction; + return formatInfo; + } +}; + +typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair; +typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap; + +static InternalFormatInfoMap BuildES3InternalFormatInfoMap() +{ + InternalFormatInfoMap map; + + // From ES 3.0.1 spec, table 3.12 + map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo())); + + // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Color | Texture | Supported | + // | | | | | | | | | | | | renderable | filterable | | + map.insert(InternalFormatInfoPair(GL_R8, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R8_SNORM, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG8, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB10_A2, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_SRGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, InternalFormatInfo::RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB9_E5, InternalFormatInfo::RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, NeverSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R8I, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R8UI, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R16I, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R16UI, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R32I, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R32UI, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG8I, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG8UI, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG16I, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG16UI, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG32I, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG32UI, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, NeverSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, AlwaysSupported, NeverSupported, AlwaysSupported ))); + + map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported ))); + + // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float + // | Internal format | | D |S | Format | Type | Comp | SRGB | Color renderable | Texture filterable | Supported | + // | | | | | | | type | | | | | + map.insert(InternalFormatInfoPair(GL_R16F, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG16F, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_R32F, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RG32F, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGB32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_RGBA32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported ))); + + // Depth stencil formats + // | Internal format | | D |S | X | Format | Type | Component type | Depth | Stencil | Supported | + // | | | | | | | | | renderable | renderable | | + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, InternalFormatInfo::DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, AlwaysSupported, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, NeverSupported, AlwaysSupported, AlwaysSupported))); + + // Luminance alpha formats + // | Internal format | | L | A | Format | Type | Component type | Supported | + map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, AlwaysSupported))); + + // Unsized formats + // | Internal format | | Format | Supported | + map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RED, InternalFormatInfo::UnsizedFormat(GL_RED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RG, InternalFormatInfo::UnsizedFormat(GL_RG, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RED_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RG_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, AlwaysSupported))); + + // Compressed formats, From ES 3.0.1 spec, table 3.16 + // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, UnimplementedSupport))); + + // From GL_EXT_texture_compression_dxt1 + // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, AlwaysSupported))); + + // From GL_ANGLE_texture_compression_dxt3 + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported))); + + // From GL_ANGLE_texture_compression_dxt5 + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported))); + + return map; +} + +static InternalFormatInfoMap BuildES2InternalFormatInfoMap() +{ + InternalFormatInfoMap map; + + // From ES 2.0.25 table 4.5 + map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo())); + + // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Color | Texture | Supported | + // | | | | | | | | | | | | renderable | filterable | | + map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + + // Extension formats + map.insert(InternalFormatInfoPair(GL_R8_EXT, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>))); + map.insert(InternalFormatInfoPair(GL_RG8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>))); + map.insert(InternalFormatInfoPair(GL_RGB8_OES, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGBA8_OES, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, AlwaysSupported))); + + // Floating point formats have to query the renderer for support + // | Internal format | | R | G | B | A |S | Format | Type | Comp | SRGB | Color renderable | Texture filterable | Supported | + // | | | | | | | | | | type | | | | | + map.insert(InternalFormatInfoPair(GL_R16F_EXT, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT_OES, GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures> ))); + map.insert(InternalFormatInfoPair(GL_R32F_EXT, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures> ))); + map.insert(InternalFormatInfoPair(GL_RG16F_EXT, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT_OES, GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures> ))); + map.insert(InternalFormatInfoPair(GL_RG32F_EXT, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures> ))); + map.insert(InternalFormatInfoPair(GL_RGB16F_EXT, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT_OES, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>))); + map.insert(InternalFormatInfoPair(GL_RGB32F_EXT, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>))); + map.insert(InternalFormatInfoPair(GL_RGBA16F_EXT, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES, GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>))); + map.insert(InternalFormatInfoPair(GL_RGBA32F_EXT, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>))); + + // Depth and stencil formats + // | Internal format | | D |S |X | Format | Type | Internal format | Depth | Stencil | Supported | + // | | | | | | | | type | renderable | renderable | | + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES,InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported, CheckSupport<&Context::supportsDepthTextures>))); + map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8_OES, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, CheckSupport<&Context::supportsDepthTextures>))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, NeverSupported, AlwaysSupported, AlwaysSupported))); + + // Unsized formats + // | Internal format | | Format | Supported | + map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RED_EXT, InternalFormatInfo::UnsizedFormat(GL_RED_EXT, CheckSupport<&Context::supportsRGTextures>))); + map.insert(InternalFormatInfoPair(GL_RG_EXT, InternalFormatInfo::UnsizedFormat(GL_RG_EXT, CheckSupport<&Context::supportsRGTextures>))); + map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, AlwaysSupported))); + + // Luminance alpha formats from GL_EXT_texture_storage + // | Internal format | | L | A | Format | Type | Component type | Supported | + map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, AlwaysSupported))); + + // From GL_EXT_texture_compression_dxt1 + // | Internal format | |W |H | BS |CC|Format | Type | SRGB | Supported | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>))); + + // From GL_ANGLE_texture_compression_dxt3 + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT3Textures>))); + + // From GL_ANGLE_texture_compression_dxt5 + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT5Textures>))); + + return map; +} + +static bool GetInternalFormatInfo(GLenum internalFormat, GLuint clientVersion, InternalFormatInfo *outFormatInfo) +{ + const InternalFormatInfoMap* map = NULL; + + if (clientVersion == 2) + { + static const InternalFormatInfoMap formatMap = BuildES2InternalFormatInfoMap(); + map = &formatMap; + } + else if (clientVersion == 3) + { + static const InternalFormatInfoMap formatMap = BuildES3InternalFormatInfoMap(); + map = &formatMap; + } + else + { + UNREACHABLE(); + } + + InternalFormatInfoMap::const_iterator iter = map->find(internalFormat); + if (iter != map->end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +typedef std::set<GLenum> FormatSet; + +static FormatSet BuildES2ValidFormatSet() +{ + static const FormatMap &formatMap = GetFormatMap(2); + + FormatSet set; + + for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++) + { + const FormatTypePair& formatPair = i->first; + set.insert(formatPair.first); + } + + return set; +} + +static FormatSet BuildES3ValidFormatSet() +{ + static const ES3FormatSet &formatSet = GetES3FormatSet(); + + FormatSet set; + + for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++) + { + const FormatInfo& formatInfo = *i; + set.insert(formatInfo.mFormat); + } + + return set; +} + +typedef std::set<GLenum> TypeSet; + +static TypeSet BuildES2ValidTypeSet() +{ + static const FormatMap &formatMap = GetFormatMap(2); + + TypeSet set; + + for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++) + { + const FormatTypePair& formatPair = i->first; + set.insert(formatPair.second); + } + + return set; +} + +static TypeSet BuildES3ValidTypeSet() +{ + static const ES3FormatSet &formatSet = GetES3FormatSet(); + + TypeSet set; + + for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++) + { + const FormatInfo& formatInfo = *i; + set.insert(formatInfo.mType); + } + + return set; +} + +struct EffectiveInternalFormatInfo +{ + GLenum mEffectiveFormat; + GLenum mDestFormat; + GLuint mMinRedBits; + GLuint mMaxRedBits; + GLuint mMinGreenBits; + GLuint mMaxGreenBits; + GLuint mMinBlueBits; + GLuint mMaxBlueBits; + GLuint mMinAlphaBits; + GLuint mMaxAlphaBits; + + EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits, + GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits, + GLuint minAlphaBits, GLuint maxAlphaBits) + : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits), + mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits), + mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits), + mMaxAlphaBits(maxAlphaBits) {}; +}; + +typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList; + +static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList() +{ + EffectiveInternalFormatList list; + + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and + // linear source buffer component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | N/A | R | G | B | A | + list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8)); + list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0)); + list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0)); + list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1)); + list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2)); + + return list; +} + + +static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList() +{ + EffectiveInternalFormatList list; + + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and + // linear source buffer component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | Dest Format | R | G | B | A | + list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8)); + list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX)); + list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX)); + list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4)); + list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1)); + list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8)); + + return list; +} + +static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat, + GLuint clientVersion, GLenum *outEffectiveFormat) +{ + const EffectiveInternalFormatList *list = NULL; + GLenum targetFormat = GL_NONE; + + if (gl::IsSizedInternalFormat(destFormat.mFormat, clientVersion)) + { + static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList(); + list = &sizedList; + } + else + { + static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList(); + list = &unsizedList; + targetFormat = destFormat.mFormat; + } + + for (size_t curFormat = 0; curFormat < list->size(); ++curFormat) + { + const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat); + if ((formatInfo.mDestFormat == targetFormat) && + (formatInfo.mMinRedBits <= srcFormat.mRedBits && formatInfo.mMaxRedBits >= srcFormat.mRedBits) && + (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) && + (formatInfo.mMinBlueBits <= srcFormat.mBlueBits && formatInfo.mMaxBlueBits >= srcFormat.mBlueBits) && + (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits)) + { + *outEffectiveFormat = formatInfo.mEffectiveFormat; + return true; + } + } + + return false; +} + +struct CopyConversion +{ + GLenum mTextureFormat; + GLenum mFramebufferFormat; + + CopyConversion(GLenum textureFormat, GLenum framebufferFormat) + : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { } + + bool operator<(const CopyConversion& other) const + { + return memcmp(this, &other, sizeof(CopyConversion)) < 0; + } +}; + +typedef std::set<CopyConversion> CopyConversionSet; + +static CopyConversionSet BuildValidES3CopyTexImageCombinations() +{ + CopyConversionSet set; + + // From ES 3.0.1 spec, table 3.15 + set.insert(CopyConversion(GL_ALPHA, GL_RGBA)); + set.insert(CopyConversion(GL_LUMINANCE, GL_RED)); + set.insert(CopyConversion(GL_LUMINANCE, GL_RG)); + set.insert(CopyConversion(GL_LUMINANCE, GL_RGB)); + set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA)); + set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA)); + set.insert(CopyConversion(GL_RED, GL_RED)); + set.insert(CopyConversion(GL_RED, GL_RG)); + set.insert(CopyConversion(GL_RED, GL_RGB)); + set.insert(CopyConversion(GL_RED, GL_RGBA)); + set.insert(CopyConversion(GL_RG, GL_RG)); + set.insert(CopyConversion(GL_RG, GL_RGB)); + set.insert(CopyConversion(GL_RG, GL_RGBA)); + set.insert(CopyConversion(GL_RGB, GL_RGB)); + set.insert(CopyConversion(GL_RGB, GL_RGBA)); + set.insert(CopyConversion(GL_RGBA, GL_RGBA)); + + // Necessary for ANGLE back-buffers + set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_RED, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_RG, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT)); + + set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER)); + set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER)); + set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER)); + set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER)); + set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER)); + set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER)); + set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER)); + set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER)); + set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER)); + set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER)); + + return set; +} + +bool IsValidInternalFormat(GLenum internalFormat, const Context *context) +{ + if (!context) + { + return false; + } + + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo)) + { + ASSERT(internalFormatInfo.mSupportFunction != NULL); + return internalFormatInfo.mSupportFunction(context); + } + else + { + return false; + } +} + +bool IsValidFormat(GLenum format, GLuint clientVersion) +{ + if (clientVersion == 2) + { + static const FormatSet formatSet = BuildES2ValidFormatSet(); + return formatSet.find(format) != formatSet.end(); + } + else if (clientVersion == 3) + { + static const FormatSet formatSet = BuildES3ValidFormatSet(); + return formatSet.find(format) != formatSet.end(); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsValidType(GLenum type, GLuint clientVersion) +{ + if (clientVersion == 2) + { + static const TypeSet typeSet = BuildES2ValidTypeSet(); + return typeSet.find(type) != typeSet.end(); + } + else if (clientVersion == 3) + { + static const TypeSet typeSet = BuildES3ValidTypeSet(); + return typeSet.find(type) != typeSet.end(); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion) +{ + if (clientVersion == 2) + { + static const FormatMap &formats = GetFormatMap(clientVersion); + FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type)); + + return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat)); + } + else if (clientVersion == 3) + { + static const ES3FormatSet &formats = GetES3FormatSet(); + return formats.find(FormatInfo(internalFormat, format, type)) != formats.end(); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion) +{ + InternalFormatInfo textureInternalFormatInfo; + InternalFormatInfo framebufferInternalFormatInfo; + if (GetInternalFormatInfo(textureInternalFormat, clientVersion, &textureInternalFormatInfo) && + GetInternalFormatInfo(frameBufferInternalFormat, clientVersion, &framebufferInternalFormatInfo)) + { + if (clientVersion == 2) + { + UNIMPLEMENTED(); + return false; + } + else if (clientVersion == 3) + { + static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations(); + const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat, + framebufferInternalFormatInfo.mFormat); + if (conversionSet.find(conversion) != conversionSet.end()) + { + // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats + // must both be signed, unsigned, or fixed point and both source and destinations + // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed + // conversion between fixed and floating point. + + if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)) + { + return false; + } + + if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) || + ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT))) + { + return false; + } + + if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) && + !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType)) + { + return false; + } + + // GLES specification 3.0.3, sec 3.8.5, pg 139-140: + // The effective internal format of the source buffer is determined with the following rules applied in order: + // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the + // effective internal format is the source buffer's sized internal format. + // * If the source buffer is a texture that was created with an unsized base internal format, then the + // effective internal format is the source image array's effective internal format, as specified by table + // 3.12, which is determined from the <format> and <type> that were used when the source image array was + // specified by TexImage*. + // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where + // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent + // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the + // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING + // is SRGB. + InternalFormatInfo sourceEffectiveFormat; + if (readBufferHandle != 0) + { + // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer + if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat, clientVersion)) + { + sourceEffectiveFormat = framebufferInternalFormatInfo; + } + else + { + // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format + // texture. We can use the same table we use when creating textures to get its effective sized format. + GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat, + framebufferInternalFormatInfo.mType, clientVersion); + gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat); + } + } + else + { + // The effective internal format must be derived from the source framebuffer's channel sizes. + // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17) + if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR) + { + GLenum effectiveFormat; + if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, clientVersion, &effectiveFormat)) + { + gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat); + } + else + { + return false; + } + } + else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB) + { + // SRGB buffers can only be copied to sized format destinations according to table 3.18 + if (gl::IsSizedInternalFormat(textureInternalFormat, clientVersion) && + (framebufferInternalFormatInfo.mRedBits >= 1 && framebufferInternalFormatInfo.mRedBits <= 8) && + (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) && + (framebufferInternalFormatInfo.mBlueBits >= 1 && framebufferInternalFormatInfo.mBlueBits <= 8) && + (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8)) + { + gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, clientVersion, &sourceEffectiveFormat); + } + else + { + return false; + } + } + else + { + UNREACHABLE(); + } + } + + if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat, clientVersion)) + { + // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized, + // component sizes of the source and destination formats must exactly match + if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits || + textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits || + textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits || + textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits) + { + return false; + } + } + + + return true; // A conversion function exists, and no rule in the specification has precluded conversion + // between these formats. + } + + return false; + } + else + { + UNREACHABLE(); + return false; + } + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mPixelBits > 0; + } + else + { + UNREACHABLE(); + return false; + } +} + +GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion) +{ + const FormatMap &formats = GetFormatMap(clientVersion); + FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type)); + return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE; +} + +GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mPixelBits / 8; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mAlphaBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mRedBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mGreenBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mBlueBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mLuminanceBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mDepthBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mStencilBits; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetTypeBytes(GLenum type) +{ + TypeInfo typeInfo; + if (GetTypeInfo(type, &typeInfo)) + { + return typeInfo.mTypeBytes; + } + else + { + UNREACHABLE(); + return 0; + } +} + +bool IsSpecialInterpretationType(GLenum type) +{ + TypeInfo typeInfo; + if (GetTypeInfo(type, &typeInfo)) + { + return typeInfo.mSpecialInterpretation; + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsFloatOrFixedComponentType(GLenum type) +{ + if (type == GL_UNSIGNED_NORMALIZED || + type == GL_SIGNED_NORMALIZED || + type == GL_FLOAT) + { + return true; + } + else + { + return false; + } +} + +GLenum GetFormat(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mFormat; + } + else + { + UNREACHABLE(); + return GL_NONE; + } +} + +GLenum GetType(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mType; + } + else + { + UNREACHABLE(); + return GL_NONE; + } +} + +GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mComponentType; + } + else + { + UNREACHABLE(); + return GL_NONE; + } +} + +GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mComponentCount; + } + else + { + UNREACHABLE(); + return false; + } +} + +GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mColorEncoding; + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer) +{ + InternalFormatInfo internalFormatInfo; + if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsColorRenderable(NULL, renderer); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsColorRenderingSupported(GLenum internalFormat, const Context *context) +{ + InternalFormatInfo internalFormatInfo; + if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsColorRenderable(context, NULL); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer) +{ + InternalFormatInfo internalFormatInfo; + if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsTextureFilterable(NULL, renderer); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context) +{ + InternalFormatInfo internalFormatInfo; + if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsTextureFilterable(context, NULL); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer) +{ + InternalFormatInfo internalFormatInfo; + if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsDepthRenderable(NULL, renderer); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context) +{ + InternalFormatInfo internalFormatInfo; + if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsDepthRenderable(context, NULL); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer) +{ + InternalFormatInfo internalFormatInfo; + if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsStencilRenderable(NULL, renderer); + } + else + { + UNREACHABLE(); + return false; + } +} + +bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context) +{ + InternalFormatInfo internalFormatInfo; + if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo)) + { + return internalFormatInfo.mIsStencilRenderable(context, NULL); + } + else + { + UNREACHABLE(); + return false; + } +} + +GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment) +{ + ASSERT(alignment > 0 && isPow2(alignment)); + return rx::roundUp(GetBlockSize(internalFormat, type, clientVersion, width, 1), static_cast<GLuint>(alignment)); +} + +GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment) +{ + return GetRowPitch(internalFormat, type, clientVersion, width, alignment) * height; +} + +GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + if (internalFormatInfo.mIsCompressed) + { + GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth; + GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight; + + return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; + } + else + { + TypeInfo typeInfo; + if (GetTypeInfo(type, &typeInfo)) + { + if (typeInfo.mSpecialInterpretation) + { + return typeInfo.mTypeBytes * width * height; + } + else + { + return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height; + } + } + else + { + UNREACHABLE(); + return 0; + } + } + } + else + { + UNREACHABLE(); + return 0; + } +} + +bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mIsCompressed; + } + else + { + UNREACHABLE(); + return false; + } +} + +GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mCompressedBlockWidth; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion) +{ + InternalFormatInfo internalFormatInfo; + if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo)) + { + return internalFormatInfo.mCompressedBlockHeight; + } + else + { + UNREACHABLE(); + return 0; + } +} + +ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion) +{ + static const FormatMap &formats = GetFormatMap(clientVersion); + FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type)); + return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/formatutils.h b/chromium/third_party/angle/src/libGLESv2/formatutils.h new file mode 100644 index 00000000000..004c8eda83b --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/formatutils.h @@ -0,0 +1,98 @@ +// +// Copyright (c) 2013 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. +// + +// formatutils.h: Queries for GL image formats. + +#ifndef LIBGLESV2_FORMATUTILS_H_ +#define LIBGLESV2_FORMATUTILS_H_ + +#include <GLES3/gl3.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include "libGLESv2/angletypes.h" + +typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned char *destData, int destRowPitch, int destDepthPitch); + +typedef void (*LoadImageFunction)(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +typedef void (*InitializeTextureDataFunction)(int width, int height, int depth, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +typedef void (*ColorReadFunction)(const void *source, void *dest); +typedef void (*ColorWriteFunction)(const void *source, void *dest); +typedef void (*ColorCopyFunction)(const void *source, void *dest); + +typedef void (*VertexCopyFunction)(const void *input, size_t stride, size_t count, void *output); + +namespace rx +{ + +class Renderer; + +} + +namespace gl +{ + +class Context; + +bool IsValidInternalFormat(GLenum internalFormat, const Context *context); +bool IsValidFormat(GLenum format, GLuint clientVersion); +bool IsValidType(GLenum type, GLuint clientVersion); + +bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion); +bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion); + +bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion); +GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion); + +GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion); +GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion); +GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion); + +GLuint GetTypeBytes(GLenum type); +bool IsSpecialInterpretationType(GLenum type); +bool IsFloatOrFixedComponentType(GLenum type); + +GLenum GetFormat(GLenum internalFormat, GLuint clientVersion); +GLenum GetType(GLenum internalFormat, GLuint clientVersion); + +GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion); +GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion); +GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion); + +bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer); +bool IsColorRenderingSupported(GLenum internalFormat, const Context *context); +bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer); +bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context); +bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer); +bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context); +bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer); +bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context); + +GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment); +GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment); +GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height); + +bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion); +GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion); +GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion); + +ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion); + +} + +#endif LIBGLESV2_FORMATUTILS_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp b/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp index 1e7cf9d0cfa..bf3cd0fdaf3 100644 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp +++ b/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -10,7 +10,8 @@ #include "common/version.h" #include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Fence.h" #include "libGLESv2/Framebuffer.h" @@ -20,242 +21,19 @@ #include "libGLESv2/Texture.h" #include "libGLESv2/Query.h" #include "libGLESv2/Context.h" +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/TransformFeedback.h" -bool validImageSize(GLint level, GLsizei width, GLsizei height) -{ - if (level < 0 || width < 0 || height < 0) - { - return false; - } - - if (gl::getContext() && gl::getContext()->supportsNonPower2Texture()) - { - return true; - } - - if (level == 0) - { - return true; - } - - if (gl::isPow2(width) && gl::isPow2(height)) - { - return true; - } - - return false; -} - -// Verify that format/type are one of the combinations from table 3.4. -bool checkTextureFormatType(GLenum format, GLenum type) -{ - // validate <format> by itself (used as secondary key below) - switch (format) - { - case GL_RGBA: - case GL_BGRA_EXT: - case GL_RGB: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL_OES: - break; - default: - return gl::error(GL_INVALID_ENUM, false); - } - - // invalid <type> -> sets INVALID_ENUM - // invalid <format>+<type> combination -> sets INVALID_OPERATION - switch (type) - { - case GL_UNSIGNED_BYTE: - switch (format) - { - case GL_RGBA: - case GL_BGRA_EXT: - case GL_RGB: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - switch (format) - { - case GL_RGBA: - case GL_RGB: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - switch (format) - { - case GL_RGBA: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - case GL_UNSIGNED_SHORT_5_6_5: - switch (format) - { - case GL_RGB: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - switch (format) - { - case GL_DEPTH_COMPONENT: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - case GL_UNSIGNED_INT_24_8_OES: - switch (format) - { - case GL_DEPTH_STENCIL_OES: - return true; - default: - return gl::error(GL_INVALID_OPERATION, false); - } - - default: - return gl::error(GL_INVALID_ENUM, false); - } -} - -bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, - GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type, - gl::Texture2D *texture) -{ - if (!texture) - { - return gl::error(GL_INVALID_OPERATION, false); - } - - if (compressed != texture->isCompressed(level)) - { - return gl::error(GL_INVALID_OPERATION, false); - } - - if (format != GL_NONE) - { - GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); - if (internalformat != texture->getInternalFormat(level)) - { - return gl::error(GL_INVALID_OPERATION, false); - } - } - - if (compressed) - { - if ((width % 4 != 0 && width != texture->getWidth(0)) || - (height % 4 != 0 && height != texture->getHeight(0))) - { - return gl::error(GL_INVALID_OPERATION, false); - } - } - - if (xoffset + width > texture->getWidth(level) || - yoffset + height > texture->getHeight(level)) - { - return gl::error(GL_INVALID_VALUE, false); - } - - return true; -} - -bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, - GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type, - gl::TextureCubeMap *texture) -{ - if (!texture) - { - return gl::error(GL_INVALID_OPERATION, false); - } - - if (compressed != texture->isCompressed(target, level)) - { - return gl::error(GL_INVALID_OPERATION, false); - } - - if (format != GL_NONE) - { - GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); - if (internalformat != texture->getInternalFormat(target, level)) - { - return gl::error(GL_INVALID_OPERATION, false); - } - } - - if (compressed) - { - if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || - (height % 4 != 0 && height != texture->getHeight(target, 0))) - { - return gl::error(GL_INVALID_OPERATION, false); - } - } - - if (xoffset + width > texture->getWidth(target, level) || - yoffset + height > texture->getHeight(target, level)) - { - return gl::error(GL_INVALID_VALUE, false); - } - - return true; -} - -// check for combinations of format and type that are valid for ReadPixels -bool validReadFormatType(GLenum format, GLenum type) -{ - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - default: - return false; - } - return true; -} +#include "libGLESv2/validationES.h" +#include "libGLESv2/validationES2.h" +#include "libGLESv2/validationES3.h" +#include "libGLESv2/queryconversions.h" extern "C" { +// OpenGL ES 2.0 functions + void __stdcall glActiveTexture(GLenum texture) { EVENT("(GLenum texture = 0x%X)", texture); @@ -274,7 +52,7 @@ void __stdcall glActiveTexture(GLenum texture) context->setActiveSampler(texture - GL_TEXTURE0); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -323,7 +101,7 @@ void __stdcall glAttachShader(GLuint program, GLuint shader) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -335,28 +113,19 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id) try { - switch (target) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - - if (id == 0) - { - return gl::error(GL_INVALID_OPERATION); - } - gl::Context *context = gl::getNonLostContext(); if (context) { + if (!ValidateBeginQuery(context, target, id)) + { + return; + } + context->beginQuery(target, id); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -399,7 +168,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* programObject->bindAttributeLocation(index, name); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -415,6 +184,11 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer) if (context) { + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } + switch (target) { case GL_ARRAY_BUFFER: @@ -423,12 +197,30 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer) case GL_ELEMENT_ARRAY_BUFFER: context->bindElementArrayBuffer(buffer); return; + case GL_COPY_READ_BUFFER: + context->bindCopyReadBuffer(buffer); + return; + case GL_COPY_WRITE_BUFFER: + context->bindCopyWriteBuffer(buffer); + return; + case GL_PIXEL_PACK_BUFFER: + context->bindPixelPackBuffer(buffer); + return; + case GL_PIXEL_UNPACK_BUFFER: + context->bindPixelUnpackBuffer(buffer); + return; + case GL_UNIFORM_BUFFER: + context->bindGenericUniformBuffer(buffer); + return; + case GL_TRANSFORM_FEEDBACK_BUFFER: + context->bindGenericTransformFeedbackBuffer(buffer); + return; default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -440,7 +232,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) try { - if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) + if (!gl::ValidFramebufferTarget(target)) { return gl::error(GL_INVALID_ENUM); } @@ -460,7 +252,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -484,7 +276,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) context->bindRenderbuffer(renderbuffer); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -515,12 +307,26 @@ void __stdcall glBindTexture(GLenum target, GLuint texture) case GL_TEXTURE_CUBE_MAP: context->bindTextureCubeMap(texture); return; + case GL_TEXTURE_3D: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + context->bindTexture3D(texture); + return; + case GL_TEXTURE_2D_ARRAY: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + context->bindTexture2DArray(texture); + return; default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -540,7 +346,7 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha)); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -557,12 +363,17 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) try { + gl::Context *context = gl::getNonLostContext(); + switch (modeRGB) { case GL_FUNC_ADD: case GL_FUNC_SUBTRACT: case GL_FUNC_REVERSE_SUBTRACT: + case GL_MIN: + case GL_MAX: break; + default: return gl::error(GL_INVALID_ENUM); } @@ -572,19 +383,20 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) case GL_FUNC_ADD: case GL_FUNC_SUBTRACT: case GL_FUNC_REVERSE_SUBTRACT: + case GL_MIN: + case GL_MAX: break; + default: return gl::error(GL_INVALID_ENUM); } - gl::Context *context = gl::getNonLostContext(); - if (context) { context->setBlendEquation(modeRGB, modeAlpha); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -602,6 +414,8 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha try { + gl::Context *context = gl::getNonLostContext(); + switch (srcRGB) { case GL_ZERO: @@ -641,6 +455,14 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: break; + + case GL_SRC_ALPHA_SATURATE: + if (!context || context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + break; + default: return gl::error(GL_INVALID_ENUM); } @@ -684,6 +506,14 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: break; + + case GL_SRC_ALPHA_SATURATE: + if (!context || context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + break; + default: return gl::error(GL_INVALID_ENUM); } @@ -700,14 +530,12 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha return gl::error(GL_INVALID_OPERATION); } - gl::Context *context = gl::getNonLostContext(); - if (context) { context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -725,34 +553,40 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, return gl::error(GL_INVALID_VALUE); } + gl::Context *context = gl::getNonLostContext(); + switch (usage) { case GL_STREAM_DRAW: case GL_STATIC_DRAW: case GL_DYNAMIC_DRAW: break; + + case GL_STREAM_READ: + case GL_STREAM_COPY: + case GL_STATIC_READ: + case GL_STATIC_COPY: + case GL_DYNAMIC_READ: + case GL_DYNAMIC_COPY: + if (context && context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + break; + default: return gl::error(GL_INVALID_ENUM); } - gl::Context *context = gl::getNonLostContext(); - if (context) { - gl::Buffer *buffer; - - switch (target) + if (!gl::ValidBufferTarget(context, target)) { - case GL_ARRAY_BUFFER: - buffer = context->getArrayBuffer(); - break; - case GL_ELEMENT_ARRAY_BUFFER: - buffer = context->getElementArrayBuffer(); - break; - default: return gl::error(GL_INVALID_ENUM); } + gl::Buffer *buffer = context->getTargetBuffer(target); + if (!buffer) { return gl::error(GL_INVALID_OPERATION); @@ -761,7 +595,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, buffer->bufferData(data, size, usage); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -788,26 +622,30 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, if (context) { - gl::Buffer *buffer; - - switch (target) + if (!gl::ValidBufferTarget(context, target)) { - case GL_ARRAY_BUFFER: - buffer = context->getArrayBuffer(); - break; - case GL_ELEMENT_ARRAY_BUFFER: - buffer = context->getElementArrayBuffer(); - break; - default: return gl::error(GL_INVALID_ENUM); } + gl::Buffer *buffer = context->getTargetBuffer(target); + if (!buffer) { return gl::error(GL_INVALID_OPERATION); } - if ((size_t)size + offset > buffer->size()) + if (buffer->mapped()) + { + return gl::error(GL_INVALID_OPERATION); + } + + // Check for possible overflow of size + offset + if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset)) + { + return gl::error(GL_OUT_OF_MEMORY); + } + + if (size + offset > buffer->size()) { return gl::error(GL_INVALID_VALUE); } @@ -815,7 +653,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, buffer->bufferSubData(data, size, offset); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -827,7 +665,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) try { - if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) + if (!gl::ValidFramebufferTarget(target)) { return gl::error(GL_INVALID_ENUM, 0); } @@ -836,20 +674,12 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) if (context) { - gl::Framebuffer *framebuffer = NULL; - if (target == GL_READ_FRAMEBUFFER_ANGLE) - { - framebuffer = context->getReadFramebuffer(); - } - else - { - framebuffer = context->getDrawFramebuffer(); - } - + gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); + ASSERT(framebuffer); return framebuffer->completeness(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, 0); } @@ -859,7 +689,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) void __stdcall glClear(GLbitfield mask) { - EVENT("(GLbitfield mask = %X)", mask); + EVENT("(GLbitfield mask = 0x%X)", mask); try { @@ -867,10 +697,22 @@ void __stdcall glClear(GLbitfield mask) if (context) { + gl::Framebuffer *framebufferObject = context->getDrawFramebuffer(); + + if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); + } + + if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) + { + return gl::error(GL_INVALID_VALUE); + } + context->clear(mask); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -890,7 +732,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp context->setClearColor(red, green, blue, alpha); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -909,7 +751,7 @@ void __stdcall glClearDepthf(GLclampf depth) context->setClearDepth(depth); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -928,7 +770,7 @@ void __stdcall glClearStencil(GLint s) context->setClearStencil(s); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -936,7 +778,7 @@ void __stdcall glClearStencil(GLint s) void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", + EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", red, green, blue, alpha); try @@ -948,7 +790,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -981,7 +823,7 @@ void __stdcall glCompileShader(GLuint shader) shaderObject->compile(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -996,42 +838,25 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna try { - if (!validImageSize(level, width, height) || border != 0 || imageSize < 0) - { - return gl::error(GL_INVALID_VALUE); - } - - switch (internalformat) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - - if (border != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (width != 1 && width != 2 && width % 4 != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (height != 1 && height != 2 && height % 4 != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + if (context->getClientVersion() < 3 && + !ValidateES2TexImageParameters(context, target, level, internalformat, true, false, + 0, 0, width, height, border, GL_NONE, GL_NONE, data)) + { + return; + } + + if (context->getClientVersion() >= 3 && + !ValidateES3TexImageParameters(context, target, level, internalformat, true, false, + 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data)) + { + return; + } + + if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) { return gl::error(GL_INVALID_VALUE); } @@ -1039,108 +864,30 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna switch (target) { case GL_TEXTURE_2D: - if (width > (context->getMaximumTextureDimension() >> level) || - height > (context->getMaximumTextureDimension() >> level)) { - return gl::error(GL_INVALID_VALUE); + gl::Texture2D *texture = context->getTexture2D(); + texture->setCompressedImage(level, internalformat, width, height, imageSize, data); } break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - if (width != height) - { - return gl::error(GL_INVALID_VALUE); - } - - if (width > (context->getMaximumCubeTextureDimension() >> level) || - height > (context->getMaximumCubeTextureDimension() >> level)) { - return gl::error(GL_INVALID_VALUE); + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); } break; + default: return gl::error(GL_INVALID_ENUM); } - - switch (internalformat) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (!context->supportsDXT1Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (!context->supportsDXT3Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (!context->supportsDXT5Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - default: UNREACHABLE(); - } - - if (imageSize != gl::ComputeCompressedSize(width, height, internalformat)) - { - return gl::error(GL_INVALID_VALUE); - } - - if (target == GL_TEXTURE_2D) - { - gl::Texture2D *texture = context->getTexture2D(); - - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } - - texture->setCompressedImage(level, internalformat, width, height, imageSize, data); - } - else - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (target) - { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); - break; - default: UNREACHABLE(); - } - } } - } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1156,98 +903,56 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs try { - if (!gl::IsInternalTextureTarget(target)) - { - return gl::error(GL_INVALID_ENUM); - } - - if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) - { - return gl::error(GL_INVALID_VALUE); - } - - switch (format) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - - if (width == 0 || height == 0 || data == NULL) - { - return; - } - gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + if (context->getClientVersion() < 3 && + !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, + xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data)) { - return gl::error(GL_INVALID_VALUE); - } - - switch (format) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (!context->supportsDXT1Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (!context->supportsDXT3Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (!context->supportsDXT5Textures()) - { - return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed - } - break; - default: UNREACHABLE(); + return; } - if (imageSize != gl::ComputeCompressedSize(width, height, format)) + if (context->getClientVersion() >= 3 && + !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, + xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data)) { - return gl::error(GL_INVALID_VALUE); + return; } - if (xoffset % 4 != 0 || yoffset % 4 != 0) + if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) { - return gl::error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction - // does not exist unless DXT textures are supported. + return gl::error(GL_INVALID_VALUE); } - if (target == GL_TEXTURE_2D) + switch (target) { - gl::Texture2D *texture = context->getTexture2D(); - if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture)) + case GL_TEXTURE_2D: { + gl::Texture2D *texture = context->getTexture2D(); texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); } - } - else if (gl::IsCubemapTextureTarget(target)) - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture)) + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); } - } - else - { - UNREACHABLE(); + break; + + default: + return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1261,189 +966,53 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma try { - if (!validImageSize(level, width, height)) - { - return gl::error(GL_INVALID_VALUE); - } - - if (border != 0) - { - return gl::error(GL_INVALID_VALUE); - } - gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + if (context->getClientVersion() < 3 && + !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, + 0, 0, x, y, width, height, border)) { - return gl::error(GL_INVALID_VALUE); + return; } + if (context->getClientVersion() >= 3 && + !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false, + 0, 0, 0, x, y, width, height, border)) + { + return; + } + + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + switch (target) { case GL_TEXTURE_2D: - if (width > (context->getMaximumTextureDimension() >> level) || - height > (context->getMaximumTextureDimension() >> level)) { - return gl::error(GL_INVALID_VALUE); + gl::Texture2D *texture = context->getTexture2D(); + texture->copyImage(level, internalformat, x, y, width, height, framebuffer); } break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - if (width != height) - { - return gl::error(GL_INVALID_VALUE); - } - - if (width > (context->getMaximumCubeTextureDimension() >> level) || - height > (context->getMaximumCubeTextureDimension() >> level)) { - return gl::error(GL_INVALID_VALUE); + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); } break; - default: - return gl::error(GL_INVALID_ENUM); - } - - gl::Framebuffer *framebuffer = context->getReadFramebuffer(); - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) - { - return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); - } - - if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) - { - return gl::error(GL_INVALID_OPERATION); - } - - gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); - GLenum colorbufferFormat = source->getInternalFormat(); - - // [OpenGL ES 2.0.24] table 3.9 - switch (internalformat) - { - case GL_ALPHA: - if (colorbufferFormat != GL_ALPHA8_EXT && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - case GL_LUMINANCE: - case GL_RGB: - if (colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - if (colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (context->supportsDXT1Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (context->supportsDXT3Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (context->supportsDXT5Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH_STENCIL_OES: - case GL_DEPTH24_STENCIL8_OES: - if (context->supportsDepthTextures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - default: + default: return gl::error(GL_INVALID_ENUM); } - - if (target == GL_TEXTURE_2D) - { - gl::Texture2D *texture = context->getTexture2D(); - - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } - - texture->copyImage(level, internalformat, x, y, width, height, framebuffer); - } - else if (gl::IsCubemapTextureTarget(target)) - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } - - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } - - texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); - } - else UNREACHABLE(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1457,125 +1026,54 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL try { - if (!gl::IsInternalTextureTarget(target)) - { - return gl::error(GL_INVALID_ENUM); - } - - if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) - { - return gl::error(GL_INVALID_VALUE); - } - - if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) - { - return gl::error(GL_INVALID_VALUE); - } - - if (width == 0 || height == 0) - { - return; - } - gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) - { - return gl::error(GL_INVALID_VALUE); - } - - gl::Framebuffer *framebuffer = context->getReadFramebuffer(); - - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (context->getClientVersion() < 3 && + !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, + xoffset, yoffset, x, y, width, height, 0)) { - return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); - } - - if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) - { - return gl::error(GL_INVALID_OPERATION); + return; } - gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); - GLenum colorbufferFormat = source->getInternalFormat(); - gl::Texture *texture = NULL; - GLenum textureFormat = GL_RGBA; - - if (target == GL_TEXTURE_2D) + if (context->getClientVersion() >= 3 && + !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, + xoffset, yoffset, 0, x, y, width, height, 0)) { - gl::Texture2D *tex2d = context->getTexture2D(); - - if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d)) - { - return; // error already registered by validateSubImageParams - } - textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level)); - texture = tex2d; + return; } - else if (gl::IsCubemapTextureTarget(target)) - { - gl::TextureCubeMap *texcube = context->getTextureCubeMap(); - if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube)) - { - return; // error already registered by validateSubImageParams - } - textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level)); - texture = texcube; - } - else UNREACHABLE(); + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); - // [OpenGL ES 2.0.24] table 3.9 - switch (textureFormat) + switch (target) { - case GL_ALPHA: - if (colorbufferFormat != GL_ALPHA8_EXT && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - case GL_LUMINANCE: - case GL_RGB: - if (colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES) + case GL_TEXTURE_2D: { - return gl::error(GL_INVALID_OPERATION); + gl::Texture2D *texture = context->getTexture2D(); + texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); } break; - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - if (colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES) + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { - return gl::error(GL_INVALID_OPERATION); + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); } break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return gl::error(GL_INVALID_OPERATION); - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL_OES: - return gl::error(GL_INVALID_OPERATION); + default: - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_ENUM); } - - texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1594,7 +1092,7 @@ GLuint __stdcall glCreateProgram(void) return context->createProgram(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, 0); } @@ -1622,7 +1120,7 @@ GLuint __stdcall glCreateShader(GLenum type) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, 0); } @@ -1654,7 +1152,7 @@ void __stdcall glCullFace(GLenum mode) return gl::error(GL_INVALID_ENUM); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1681,7 +1179,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1704,11 +1202,11 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) { for (int i = 0; i < n; i++) { - context->deleteFence(fences[i]); + context->deleteFenceNV(fences[i]); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1738,7 +1236,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1774,7 +1272,7 @@ void __stdcall glDeleteProgram(GLuint program) context->deleteProgram(program); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1801,7 +1299,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1828,7 +1326,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1864,7 +1362,7 @@ void __stdcall glDeleteShader(GLuint shader) context->deleteShader(shader); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1894,7 +1392,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1928,7 +1426,7 @@ void __stdcall glDepthFunc(GLenum func) context->setDepthFunc(func); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1936,7 +1434,7 @@ void __stdcall glDepthFunc(GLenum func) void __stdcall glDepthMask(GLboolean flag) { - EVENT("(GLboolean flag = %d)", flag); + EVENT("(GLboolean flag = %u)", flag); try { @@ -1947,7 +1445,7 @@ void __stdcall glDepthMask(GLboolean flag) context->setDepthMask(flag != GL_FALSE); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -1966,7 +1464,7 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) context->setDepthRange(zNear, zFar); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2019,7 +1517,7 @@ void __stdcall glDetachShader(GLuint program, GLuint shader) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2035,23 +1533,15 @@ void __stdcall glDisable(GLenum cap) if (context) { - switch (cap) + if (!ValidCap(context, cap)) { - case GL_CULL_FACE: context->setCullFace(false); break; - case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break; - case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break; - case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break; - case GL_SCISSOR_TEST: context->setScissorTest(false); break; - case GL_STENCIL_TEST: context->setStencilTest(false); break; - case GL_DEPTH_TEST: context->setDepthTest(false); break; - case GL_BLEND: context->setBlend(false); break; - case GL_DITHER: context->setDither(false); break; - default: return gl::error(GL_INVALID_ENUM); } + + context->setCap(cap, false); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2075,7 +1565,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index) context->setEnableVertexAttribArray(index, false); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2094,12 +1584,28 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) gl::Context *context = gl::getNonLostContext(); + // Check for mapped buffers + if (context->hasMappedBuffer(GL_ARRAY_BUFFER)) + { + return gl::error(GL_INVALID_OPERATION); + } + if (context) { + gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() && + curTransformFeedback->getDrawMode() != mode) + { + // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode + // that does not match the current transform feedback object's draw mode (if transform feedback + // is active), (3.0.2, section 2.14, pg 86) + return gl::error(GL_INVALID_OPERATION); + } + context->drawArrays(mode, first, count, 0); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2120,13 +1626,29 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun { gl::Context *context = gl::getNonLostContext(); + // Check for mapped buffers + if (context->hasMappedBuffer(GL_ARRAY_BUFFER)) + { + return gl::error(GL_INVALID_OPERATION); + } + if (context) { + gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() && + curTransformFeedback->getDrawMode() != mode) + { + // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode + // that does not match the current transform feedback object's draw mode (if transform feedback + // is active), (3.0.2, section 2.14, pg 86) + return gl::error(GL_INVALID_OPERATION); + } + context->drawArrays(mode, first, count, primcount); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2156,17 +1678,31 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv case GL_UNSIGNED_INT: if (!context->supports32bitIndices()) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_ENUM); } break; default: return gl::error(GL_INVALID_ENUM); } - + + gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) + { + // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced + // while transform feedback is active, (3.0.2, section 2.14, pg 86) + return gl::error(GL_INVALID_OPERATION); + } + + // Check for mapped buffers + if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) + { + return gl::error(GL_INVALID_OPERATION); + } + context->drawElements(mode, count, type, indices, 0); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2198,18 +1734,32 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t case GL_UNSIGNED_INT: if (!context->supports32bitIndices()) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_ENUM); } break; default: return gl::error(GL_INVALID_ENUM); } - + + gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) + { + // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced + // while transform feedback is active, (3.0.2, section 2.14, pg 86) + return gl::error(GL_INVALID_OPERATION); + } + + // Check for mapped buffers + if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) + { + return gl::error(GL_INVALID_OPERATION); + } + context->drawElements(mode, count, type, indices, primcount); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2225,23 +1775,15 @@ void __stdcall glEnable(GLenum cap) if (context) { - switch (cap) + if (!ValidCap(context, cap)) { - case GL_CULL_FACE: context->setCullFace(true); break; - case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break; - case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break; - case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break; - case GL_SCISSOR_TEST: context->setScissorTest(true); break; - case GL_STENCIL_TEST: context->setStencilTest(true); break; - case GL_DEPTH_TEST: context->setDepthTest(true); break; - case GL_BLEND: context->setBlend(true); break; - case GL_DITHER: context->setDither(true); break; - default: return gl::error(GL_INVALID_ENUM); } + + context->setCap(cap, true); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2265,7 +1807,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index) context->setEnableVertexAttribArray(index, true); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2277,23 +1819,19 @@ void __stdcall glEndQueryEXT(GLenum target) try { - switch (target) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - gl::Context *context = gl::getNonLostContext(); if (context) { + if (!ValidateEndQuery(context, target)) + { + return; + } + context->endQuery(target); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2309,17 +1847,22 @@ void __stdcall glFinishFenceNV(GLuint fence) if (context) { - gl::Fence* fenceObject = context->getFence(fence); + gl::FenceNV *fenceObject = context->getFenceNV(fence); if (fenceObject == NULL) { return gl::error(GL_INVALID_OPERATION); } + if (fenceObject->isFence() != GL_TRUE) + { + return gl::error(GL_INVALID_OPERATION); + } + fenceObject->finishFence(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2338,7 +1881,7 @@ void __stdcall glFinish(void) context->sync(true); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2357,7 +1900,7 @@ void __stdcall glFlush(void) context->sync(false); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2370,8 +1913,7 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu try { - if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) - || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) + if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) { return gl::error(GL_INVALID_ENUM); } @@ -2380,52 +1922,40 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu if (context) { - gl::Framebuffer *framebuffer = NULL; - GLuint framebufferHandle = 0; - if (target == GL_READ_FRAMEBUFFER_ANGLE) - { - framebuffer = context->getReadFramebuffer(); - framebufferHandle = context->getReadFramebufferHandle(); - } - else + if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer)) { - framebuffer = context->getDrawFramebuffer(); - framebufferHandle = context->getDrawFramebufferHandle(); + return; } - if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) - { - return gl::error(GL_INVALID_OPERATION); - } + gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); + ASSERT(framebuffer); if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - - if (colorAttachment >= context->getMaximumRenderTargets()) - { - return gl::error(GL_INVALID_VALUE); - } - - framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer); + unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0); } else { switch (attachment) { case GL_DEPTH_ATTACHMENT: - framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer); + framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); break; case GL_STENCIL_ATTACHMENT: - framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer); + framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); + break; + case GL_DEPTH_STENCIL_ATTACHMENT: + framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); break; default: - return gl::error(GL_INVALID_ENUM); + UNREACHABLE(); + break; } } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2438,134 +1968,45 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t try { - if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) - { - return gl::error(GL_INVALID_ENUM); - } - gl::Context *context = gl::getNonLostContext(); - if (context) { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (context->getClientVersion() < 3 && + !ValidateES2FramebufferTextureParameters(context, target, attachment, textarget, texture, level)) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - - if (colorAttachment >= context->getMaximumRenderTargets()) - { - return gl::error(GL_INVALID_VALUE); - } + return; } - else + + if (context->getClientVersion() >= 3 && + !ValidateES3FramebufferTextureParameters(context, target, attachment, textarget, texture, level, 0, false)) { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; - default: - return gl::error(GL_INVALID_ENUM); - } + return; } if (texture == 0) { textarget = GL_NONE; } - else - { - gl::Texture *tex = context->getTexture(texture); - - if (tex == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (textarget) - { - case GL_TEXTURE_2D: - { - if (tex->getTarget() != GL_TEXTURE_2D) - { - return gl::error(GL_INVALID_OPERATION); - } - gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); - if (tex2d->isCompressed(0)) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - } - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - { - if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) - { - return gl::error(GL_INVALID_OPERATION); - } - gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); - if (texcube->isCompressed(textarget, level)) - { - return gl::error(GL_INVALID_OPERATION); - } - break; - } - - default: - return gl::error(GL_INVALID_ENUM); - } - - if (level != 0) - { - return gl::error(GL_INVALID_VALUE); - } - } - gl::Framebuffer *framebuffer = NULL; - GLuint framebufferHandle = 0; - if (target == GL_READ_FRAMEBUFFER_ANGLE) - { - framebuffer = context->getReadFramebuffer(); - framebufferHandle = context->getReadFramebufferHandle(); - } - else - { - framebuffer = context->getDrawFramebuffer(); - framebufferHandle = context->getDrawFramebufferHandle(); - } - - if (framebufferHandle == 0 || !framebuffer) - { - return gl::error(GL_INVALID_OPERATION); - } + gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) { const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - - if (colorAttachment >= context->getMaximumRenderTargets()) - { - return gl::error(GL_INVALID_VALUE); - } - - framebuffer->setColorbuffer(colorAttachment, textarget, texture); + framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0); } else { switch (attachment) { - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break; + case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break; + case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break; + case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break; } } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2594,7 +2035,7 @@ void __stdcall glFrontFace(GLenum mode) return gl::error(GL_INVALID_ENUM); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2621,7 +2062,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2637,44 +2078,55 @@ void __stdcall glGenerateMipmap(GLenum target) if (context) { - switch (target) + if (!ValidTextureTarget(context, target)) { - case GL_TEXTURE_2D: - { - gl::Texture2D *tex2d = context->getTexture2D(); + return gl::error(GL_INVALID_ENUM); + } - if (tex2d->isCompressed(0)) - { - return gl::error(GL_INVALID_OPERATION); - } - if (tex2d->isDepth(0)) - { - return gl::error(GL_INVALID_OPERATION); - } + gl::Texture *texture = context->getTargetTexture(target); - tex2d->generateMipmaps(); - break; - } + if (texture == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } - case GL_TEXTURE_CUBE_MAP: - { - gl::TextureCubeMap *texcube = context->getTextureCubeMap(); + GLenum internalFormat = texture->getBaseLevelInternalFormat(); - if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) - { - return gl::error(GL_INVALID_OPERATION); - } + // Internally, all texture formats are sized so checking if the format + // is color renderable and filterable will not fail. - texcube->generateMipmaps(); - break; - } + bool validRenderable = (gl::IsColorRenderingSupported(internalFormat, context) || + gl::IsSizedInternalFormat(internalFormat, context->getClientVersion())); - default: - return gl::error(GL_INVALID_ENUM); + if (gl::IsDepthRenderingSupported(internalFormat, context) || + gl::IsFormatCompressed(internalFormat, context->getClientVersion()) || + !gl::IsTextureFilteringSupported(internalFormat, context) || + !validRenderable) + { + return gl::error(GL_INVALID_OPERATION); } + + // Non-power of 2 ES2 check + if (!context->supportsNonPower2Texture() && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight()))) + { + ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP)); + return gl::error(GL_INVALID_OPERATION); + } + + // Cube completeness check + if (target == GL_TEXTURE_CUBE_MAP) + { + gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture); + if (!textureCube->isCubeComplete()) + { + return gl::error(GL_INVALID_OPERATION); + } + } + + texture->generateMipmaps(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2697,11 +2149,11 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) { for (int i = 0; i < n; i++) { - fences[i] = context->createFence(); + fences[i] = context->createFenceNV(); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2728,7 +2180,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2740,22 +2192,22 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) try { - if (n < 0) - { - return gl::error(GL_INVALID_VALUE); - } - gl::Context *context = gl::getNonLostContext(); if (context) { - for (int i = 0; i < n; i++) + if (n < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (GLsizei i = 0; i < n; i++) { ids[i] = context->createQuery(); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2782,7 +2234,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2790,7 +2242,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) void __stdcall glGenTextures(GLsizei n, GLuint* textures) { - EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); + EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); try { @@ -2809,7 +2261,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2854,7 +2306,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, programObject->getActiveAttribute(index, bufsize, length, size, type, name); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2899,7 +2351,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, programObject->getActiveUniform(index, bufsize, length, size, type, name); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2938,7 +2390,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c return programObject->getAttachedShaders(maxcount, count, shaders); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -2978,7 +2430,7 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) return programBinary->getAttributeLocation(name); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, -1); } @@ -2996,54 +2448,24 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) if (context) { - if (!(context->getBooleanv(pname, params))) + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) - return gl::error(GL_INVALID_ENUM); - - if (numParams == 0) - return; // it is known that the pname is valid, but there are no parameters to return - - if (nativeType == GL_FLOAT) - { - GLfloat *floatParams = NULL; - floatParams = new GLfloat[numParams]; - - context->getFloatv(pname, floatParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - if (floatParams[i] == 0.0f) - params[i] = GL_FALSE; - else - params[i] = GL_TRUE; - } - - delete [] floatParams; - } - else if (nativeType == GL_INT) - { - GLint *intParams = NULL; - intParams = new GLint[numParams]; - - context->getIntegerv(pname, intParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - if (intParams[i] == 0) - params[i] = GL_FALSE; - else - params[i] = GL_TRUE; - } + return; + } - delete [] intParams; - } + if (nativeType == GL_BOOL) + { + context->getBooleanv(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3059,19 +2481,18 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params if (context) { - gl::Buffer *buffer; + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } - switch (target) + if (!gl::ValidBufferParameter(context, pname)) { - case GL_ARRAY_BUFFER: - buffer = context->getArrayBuffer(); - break; - case GL_ELEMENT_ARRAY_BUFFER: - buffer = context->getElementArrayBuffer(); - break; - default: return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_ENUM); } + gl::Buffer *buffer = context->getTargetBuffer(target); + if (!buffer) { // A null buffer means that "0" is bound to the requested buffer target @@ -3081,16 +2502,28 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params switch (pname) { case GL_BUFFER_USAGE: - *params = buffer->usage(); + *params = static_cast<GLint>(buffer->usage()); break; case GL_BUFFER_SIZE: - *params = buffer->size(); + *params = gl::clampCast<GLint>(buffer->size()); break; - default: return gl::error(GL_INVALID_ENUM); + case GL_BUFFER_ACCESS_FLAGS: + *params = buffer->accessFlags(); + break; + case GL_BUFFER_MAPPED: + *params = static_cast<GLint>(buffer->mapped()); + break; + case GL_BUFFER_MAP_OFFSET: + *params = gl::clampCast<GLint>(buffer->mapOffset()); + break; + case GL_BUFFER_MAP_LENGTH: + *params = gl::clampCast<GLint>(buffer->mapLength()); + break; + default: UNREACHABLE(); break; } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3121,17 +2554,31 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) if (context) { - gl::Fence *fenceObject = context->getFence(fence); + gl::FenceNV *fenceObject = context->getFenceNV(fence); if (fenceObject == NULL) { return gl::error(GL_INVALID_OPERATION); } - fenceObject->getFenceiv(pname, params); + if (fenceObject->isFence() != GL_TRUE) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (pname) + { + case GL_FENCE_STATUS_NV: + case GL_FENCE_CONDITION_NV: + break; + + default: return gl::error(GL_INVALID_ENUM); + } + + params[0] = fenceObject->getFencei(pname); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3147,51 +2594,24 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params) if (context) { - if (!(context->getFloatv(pname, params))) + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) - return gl::error(GL_INVALID_ENUM); - - if (numParams == 0) - return; // it is known that the pname is valid, but that there are no parameters to return. - - if (nativeType == GL_BOOL) - { - GLboolean *boolParams = NULL; - boolParams = new GLboolean[numParams]; - - context->getBooleanv(pname, boolParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - if (boolParams[i] == GL_FALSE) - params[i] = 0.0f; - else - params[i] = 1.0f; - } - - delete [] boolParams; - } - else if (nativeType == GL_INT) - { - GLint *intParams = NULL; - intParams = new GLint[numParams]; - - context->getIntegerv(pname, intParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - params[i] = (GLfloat)intParams[i]; - } + return; + } - delete [] intParams; - } + if (nativeType == GL_FLOAT) + { + context->getFloatv(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3208,68 +2628,162 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac if (context) { - if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) + if (!gl::ValidFramebufferTarget(target)) { return gl::error(GL_INVALID_ENUM); } - gl::Framebuffer *framebuffer = NULL; - if (target == GL_READ_FRAMEBUFFER_ANGLE) + switch (pname) { - if(context->getReadFramebufferHandle() == 0) + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + break; + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (context->getClientVersion() >= 3) { - return gl::error(GL_INVALID_OPERATION); + break; } - - framebuffer = context->getReadFramebuffer(); + default: + return gl::error(GL_INVALID_ENUM); } - else + + // Determine if the attachment is a valid enum + switch (attachment) { - if (context->getDrawFramebufferHandle() == 0) + case GL_BACK: + case GL_FRONT: + case GL_DEPTH: + case GL_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (context->getClientVersion() < 3) { - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_ENUM); } + break; - framebuffer = context->getDrawFramebuffer(); + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + default: + if (attachment < GL_COLOR_ATTACHMENT0_EXT || + (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_ENUM); + } + break; } + GLuint framebufferHandle = context->getTargetFramebufferHandle(target); + ASSERT(framebufferHandle != GL_INVALID_INDEX); + gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle); + GLenum attachmentType; GLuint attachmentHandle; + GLuint attachmentLevel; + GLuint attachmentLayer; + gl::FramebufferAttachment *attachmentObject; - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (framebufferHandle == 0) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - - if (colorAttachment >= context->getMaximumRenderTargets()) + if (context->getClientVersion() < 3) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_OPERATION); } - attachmentType = framebuffer->getColorbufferType(colorAttachment); - attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment); - } - else - { switch (attachment) { - case GL_DEPTH_ATTACHMENT: + case GL_BACK: + attachmentType = framebuffer->getColorbufferType(0); + attachmentHandle = framebuffer->getColorbufferHandle(0); + attachmentLevel = framebuffer->getColorbufferMipLevel(0); + attachmentLayer = framebuffer->getColorbufferLayer(0); + attachmentObject = framebuffer->getColorbuffer(0); + break; + case GL_DEPTH: attachmentType = framebuffer->getDepthbufferType(); attachmentHandle = framebuffer->getDepthbufferHandle(); + attachmentLevel = framebuffer->getDepthbufferMipLevel(); + attachmentLayer = framebuffer->getDepthbufferLayer(); + attachmentObject = framebuffer->getDepthbuffer(); break; - case GL_STENCIL_ATTACHMENT: + case GL_STENCIL: attachmentType = framebuffer->getStencilbufferType(); attachmentHandle = framebuffer->getStencilbufferHandle(); + attachmentLevel = framebuffer->getStencilbufferMipLevel(); + attachmentLayer = framebuffer->getStencilbufferLayer(); + attachmentObject = framebuffer->getStencilbuffer(); break; - default: return gl::error(GL_INVALID_ENUM); + default: + return gl::error(GL_INVALID_OPERATION); + } + } + else + { + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + attachmentType = framebuffer->getColorbufferType(colorAttachment); + attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment); + attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment); + attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment); + attachmentObject = framebuffer->getColorbuffer(colorAttachment); + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + attachmentType = framebuffer->getDepthbufferType(); + attachmentHandle = framebuffer->getDepthbufferHandle(); + attachmentLevel = framebuffer->getDepthbufferMipLevel(); + attachmentLayer = framebuffer->getDepthbufferLayer(); + attachmentObject = framebuffer->getDepthbuffer(); + break; + case GL_STENCIL_ATTACHMENT: + attachmentType = framebuffer->getStencilbufferType(); + attachmentHandle = framebuffer->getStencilbufferHandle(); + attachmentLevel = framebuffer->getStencilbufferMipLevel(); + attachmentLayer = framebuffer->getStencilbufferLayer(); + attachmentObject = framebuffer->getStencilbuffer(); + break; + case GL_DEPTH_STENCIL_ATTACHMENT: + if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle()) + { + return gl::error(GL_INVALID_OPERATION); + } + attachmentType = framebuffer->getDepthStencilbufferType(); + attachmentHandle = framebuffer->getDepthStencilbufferHandle(); + attachmentLevel = framebuffer->getDepthStencilbufferMipLevel(); + attachmentLayer = framebuffer->getDepthStencilbufferLayer(); + attachmentObject = framebuffer->getDepthStencilBuffer(); + break; + default: + return gl::error(GL_INVALID_OPERATION); + } } } GLenum attachmentObjectType; // Type category - if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER) + if (framebufferHandle == 0) + { + attachmentObjectType = GL_FRAMEBUFFER_DEFAULT; + } + else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER) { attachmentObjectType = attachmentType; } - else if (gl::IsInternalTextureTarget(attachmentType)) + else if (gl::IsInternalTextureTarget(attachmentType, context->getClientVersion())) { attachmentObjectType = GL_TEXTURE; } @@ -3279,54 +2793,128 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac return; } - switch (pname) + if (attachmentObjectType == GL_NONE) { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - *params = attachmentObjectType; - break; - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE) - { - *params = attachmentHandle; - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: - if (attachmentObjectType == GL_TEXTURE) - { - *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - if (attachmentObjectType == GL_TEXTURE) + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) { - if (gl::IsCubemapTextureTarget(attachmentType)) + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = attachmentObjectType; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = 0; + break; + + default: + if (context->getClientVersion() < 3) { - *params = attachmentType; + return gl::error(GL_INVALID_ENUM); } else { - *params = 0; + gl::error(GL_INVALID_OPERATION); } } - else + } + else + { + ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE || + attachmentObjectType == GL_FRAMEBUFFER_DEFAULT); + ASSERT(attachmentObject != NULL); + + switch (pname) { - return gl::error(GL_INVALID_ENUM); + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = attachmentObjectType; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE) + { + return gl::error(GL_INVALID_ENUM); + } + *params = attachmentHandle; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + if (attachmentObjectType != GL_TEXTURE) + { + return gl::error(GL_INVALID_ENUM); + } + *params = attachmentLevel; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + if (attachmentObjectType != GL_TEXTURE) + { + return gl::error(GL_INVALID_ENUM); + } + *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + *params = attachmentObject->getRedSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + *params = attachmentObject->getGreenSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + *params = attachmentObject->getBlueSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + *params = attachmentObject->getAlphaSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + *params = attachmentObject->getDepthSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + *params = attachmentObject->getStencilSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + if (attachment == GL_DEPTH_STENCIL) + { + gl::error(GL_INVALID_OPERATION); + } + *params = attachmentObject->getComponentType(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + *params = attachmentObject->getColorEncoding(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (attachmentObjectType != GL_TEXTURE) + { + return gl::error(GL_INVALID_ENUM); + } + *params = attachmentLayer; + break; + + default: + UNREACHABLE(); + break; } - break; - default: - return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3347,7 +2935,7 @@ GLenum __stdcall glGetGraphicsResetStatusEXT(void) return GL_NO_ERROR; } - catch(std::bad_alloc&) + catch (...) { return GL_OUT_OF_MEMORY; } @@ -3363,56 +2951,25 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params) if (context) { - if (!(context->getIntegerv(pname, params))) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) - return gl::error(GL_INVALID_ENUM); - - if (numParams == 0) - return; // it is known that pname is valid, but there are no parameters to return - - if (nativeType == GL_BOOL) - { - GLboolean *boolParams = NULL; - boolParams = new GLboolean[numParams]; - - context->getBooleanv(pname, boolParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - if (boolParams[i] == GL_FALSE) - params[i] = 0; - else - params[i] = 1; - } + GLenum nativeType; + unsigned int numParams = 0; - delete [] boolParams; - } - else if (nativeType == GL_FLOAT) - { - GLfloat *floatParams = NULL; - floatParams = new GLfloat[numParams]; - - context->getFloatv(pname, floatParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) - { - params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f); - } - else - params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); - } + if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) + { + return; + } - delete [] floatParams; - } + if (nativeType == GL_INT) + { + context->getIntegerv(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3435,6 +2992,19 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) return gl::error(GL_INVALID_VALUE); } + if (context->getClientVersion() < 3) + { + switch (pname) + { + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + case GL_TRANSFORM_FEEDBACK_VARYINGS: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + return gl::error(GL_INVALID_ENUM); + } + } + switch (pname) { case GL_DELETE_STATUS: @@ -3467,12 +3037,27 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) case GL_PROGRAM_BINARY_LENGTH_OES: *params = programObject->getProgramBinaryLength(); return; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = programObject->getActiveUniformBlockCount(); + return; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = programObject->getActiveUniformBlockMaxLength(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + *params = programObject->getTransformFeedbackBufferMode(); + break; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = programObject->getTransformFeedbackVaryingCount(); + break; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = programObject->getTransformFeedbackVaryingMaxLength(); + break; default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3504,7 +3089,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len programObject->getInfoLog(bufsize, length, infolog); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3516,22 +3101,27 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) try { - switch (pname) - { - case GL_CURRENT_QUERY_EXT: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - gl::Context *context = gl::getNonLostContext(); if (context) { - params[0] = context->getActiveQuery(target); + if (!ValidQueryType(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } + + switch (pname) + { + case GL_CURRENT_QUERY_EXT: + params[0] = context->getActiveQueryId(target); + break; + + default: + return gl::error(GL_INVALID_ENUM); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3543,14 +3133,6 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) try { - switch (pname) - { - case GL_QUERY_RESULT_EXT: - case GL_QUERY_RESULT_AVAILABLE_EXT: - break; - default: - return gl::error(GL_INVALID_ENUM); - } gl::Context *context = gl::getNonLostContext(); if (context) @@ -3562,7 +3144,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) return gl::error(GL_INVALID_OPERATION); } - if (context->getActiveQuery(queryObject->getType()) == id) + if (context->getActiveQueryId(queryObject->getType()) == id) { return gl::error(GL_INVALID_OPERATION); } @@ -3576,11 +3158,11 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) params[0] = queryObject->isResultAvailable(); break; default: - ASSERT(false); + return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3606,23 +3188,23 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* return gl::error(GL_INVALID_OPERATION); } - gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle()); + gl::FramebufferAttachment *attachment = context->getRenderbuffer(context->getRenderbufferHandle()); switch (pname) { - case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; - case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; - case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; - case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; - case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; - case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; - case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; - case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; + case GL_RENDERBUFFER_WIDTH: *params = attachment->getWidth(); break; + case GL_RENDERBUFFER_HEIGHT: *params = attachment->getHeight(); break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = attachment->getInternalFormat(); break; + case GL_RENDERBUFFER_RED_SIZE: *params = attachment->getRedSize(); break; + case GL_RENDERBUFFER_GREEN_SIZE: *params = attachment->getGreenSize(); break; + case GL_RENDERBUFFER_BLUE_SIZE: *params = attachment->getBlueSize(); break; + case GL_RENDERBUFFER_ALPHA_SIZE: *params = attachment->getAlphaSize(); break; + case GL_RENDERBUFFER_DEPTH_SIZE: *params = attachment->getDepthSize(); break; + case GL_RENDERBUFFER_STENCIL_SIZE: *params = attachment->getStencilSize(); break; case GL_RENDERBUFFER_SAMPLES_ANGLE: if (context->getMaxSupportedSamples() != 0) { - *params = renderbuffer->getSamples(); + *params = attachment->getSamples(); } else { @@ -3634,7 +3216,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3682,7 +3264,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3714,7 +3296,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt shaderObject->getInfoLog(bufsize, length, infolog); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3759,7 +3341,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp return gl::error(GL_INVALID_ENUM); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3791,7 +3373,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length shaderObject->getSource(bufsize, length, source); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3823,7 +3405,7 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, shaderObject->getTranslatedSource(bufsize, length, source); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3844,16 +3426,30 @@ const GLubyte* __stdcall glGetString(GLenum name) case GL_RENDERER: return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); case GL_VERSION: - return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")"; + if (context->getClientVersion() == 2) + { + return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"; + } + else + { + return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")"; + } case GL_SHADING_LANGUAGE_VERSION: - return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")"; + if (context->getClientVersion() == 2) + { + return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"; + } + else + { + return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")"; + } case GL_EXTENSIONS: - return (GLubyte*)((context != NULL) ? context->getExtensionString() : ""); + return (GLubyte*)((context != NULL) ? context->getCombinedExtensionsString() : ""); default: return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL); } @@ -3869,17 +3465,10 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) if (context) { - gl::Texture *texture; + gl::Texture *texture = context->getTargetTexture(target); - switch (target) + if (!texture) { - case GL_TEXTURE_2D: - texture = context->getTexture2D(); - break; - case GL_TEXTURE_CUBE_MAP: - texture = context->getTextureCubeMap(); - break; - default: return gl::error(GL_INVALID_ENUM); } @@ -3897,9 +3486,24 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) case GL_TEXTURE_WRAP_T: *params = (GLfloat)texture->getWrapT(); break; - case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: + case GL_TEXTURE_WRAP_R: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getWrapR(); + break; + case GL_TEXTURE_IMMUTABLE_FORMAT: + // Exposed to ES2.0 through EXT_texture_storage, no client version validation. *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->immutableLevelCount(); + break; case GL_TEXTURE_USAGE_ANGLE: *params = (GLfloat)texture->getUsage(); break; @@ -3910,12 +3514,68 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) } *params = (GLfloat)texture->getMaxAnisotropy(); break; + case GL_TEXTURE_SWIZZLE_R: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getSwizzleRed(); + break; + case GL_TEXTURE_SWIZZLE_G: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getSwizzleGreen(); + break; + case GL_TEXTURE_SWIZZLE_B: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getSwizzleBlue(); + break; + case GL_TEXTURE_SWIZZLE_A: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getSwizzleAlpha(); + break; + case GL_TEXTURE_BASE_LEVEL: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getBaseLevel(); + break; + case GL_TEXTURE_MAX_LEVEL: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLfloat)texture->getMaxLevel(); + break; + case GL_TEXTURE_MIN_LOD: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getMinLod(); + break; + case GL_TEXTURE_MAX_LOD: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getMaxLod(); + break; default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -3931,17 +3591,10 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) if (context) { - gl::Texture *texture; + gl::Texture *texture = context->getTargetTexture(target); - switch (target) + if (!texture) { - case GL_TEXTURE_2D: - texture = context->getTexture2D(); - break; - case GL_TEXTURE_CUBE_MAP: - texture = context->getTextureCubeMap(); - break; - default: return gl::error(GL_INVALID_ENUM); } @@ -3959,9 +3612,24 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) case GL_TEXTURE_WRAP_T: *params = texture->getWrapT(); break; - case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: + case GL_TEXTURE_WRAP_R: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getWrapR(); + break; + case GL_TEXTURE_IMMUTABLE_FORMAT: + // Exposed to ES2.0 through EXT_texture_storage, no client version validation. *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->immutableLevelCount(); + break; case GL_TEXTURE_USAGE_ANGLE: *params = texture->getUsage(); break; @@ -3972,12 +3640,68 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) } *params = (GLint)texture->getMaxAnisotropy(); break; + case GL_TEXTURE_SWIZZLE_R: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getSwizzleRed(); + break; + case GL_TEXTURE_SWIZZLE_G: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getSwizzleGreen(); + break; + case GL_TEXTURE_SWIZZLE_B: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getSwizzleBlue(); + break; + case GL_TEXTURE_SWIZZLE_A: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getSwizzleAlpha(); + break; + case GL_TEXTURE_BASE_LEVEL: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getBaseLevel(); + break; + case GL_TEXTURE_MAX_LEVEL: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = texture->getMaxLevel(); + break; + case GL_TEXTURE_MIN_LOD: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLint)texture->getMinLod(); + break; + case GL_TEXTURE_MAX_LOD: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + *params = (GLint)texture->getMaxLod(); + break; default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4023,7 +3747,7 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4063,7 +3787,7 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4109,7 +3833,7 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4149,7 +3873,7 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4193,7 +3917,7 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) return programBinary->getUniformLocation(name); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, -1); } @@ -4218,40 +3942,26 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) const gl::VertexAttribute &attribState = context->getVertexAttribState(index); - switch (pname) + if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: - *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); - break; - case GL_VERTEX_ATTRIB_ARRAY_SIZE: - *params = (GLfloat)attribState.mSize; - break; - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: - *params = (GLfloat)attribState.mStride; - break; - case GL_VERTEX_ATTRIB_ARRAY_TYPE: - *params = (GLfloat)attribState.mType; - break; - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: - *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE); - break; - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: - *params = (GLfloat)attribState.mBoundBuffer.id(); - break; - case GL_CURRENT_VERTEX_ATTRIB: + return; + } + + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); for (int i = 0; i < 4; ++i) { - params[i] = attribState.mCurrentValue[i]; + params[i] = currentValueData.FloatValues[i]; } - break; - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: - *params = (GLfloat)attribState.mDivisor; - break; - default: return gl::error(GL_INVALID_ENUM); + } + else + { + *params = attribState.querySingleParameter<GLfloat>(pname); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4274,41 +3984,27 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) const gl::VertexAttribute &attribState = context->getVertexAttribState(index); - switch (pname) + if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: - *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); - break; - case GL_VERTEX_ATTRIB_ARRAY_SIZE: - *params = attribState.mSize; - break; - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: - *params = attribState.mStride; - break; - case GL_VERTEX_ATTRIB_ARRAY_TYPE: - *params = attribState.mType; - break; - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: - *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE); - break; - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: - *params = attribState.mBoundBuffer.id(); - break; - case GL_CURRENT_VERTEX_ATTRIB: + return; + } + + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); for (int i = 0; i < 4; ++i) { - float currentValue = attribState.mCurrentValue[i]; - params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f)); + float currentValue = currentValueData.FloatValues[i]; + params[i] = gl::iround<GLint>(currentValue); } - break; - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: - *params = (GLint)attribState.mDivisor; - break; - default: return gl::error(GL_INVALID_ENUM); + } + else + { + *params = attribState.querySingleParameter<GLint>(pname); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4337,7 +4033,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index)); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4372,7 +4068,7 @@ void __stdcall glHint(GLenum target, GLenum mode) return gl::error(GL_INVALID_ENUM); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4396,7 +4092,7 @@ GLboolean __stdcall glIsBuffer(GLuint buffer) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4414,23 +4110,15 @@ GLboolean __stdcall glIsEnabled(GLenum cap) if (context) { - switch (cap) + if (!ValidCap(context, cap)) { - case GL_CULL_FACE: return context->isCullFaceEnabled(); - case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); - case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); - case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); - case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); - case GL_STENCIL_TEST: return context->isStencilTestEnabled(); - case GL_DEPTH_TEST: return context->isDepthTestEnabled(); - case GL_BLEND: return context->isBlendEnabled(); - case GL_DITHER: return context->isDitherEnabled(); - default: return gl::error(GL_INVALID_ENUM, false); } + + return context->getCap(cap); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, false); } @@ -4448,7 +4136,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence) if (context) { - gl::Fence *fenceObject = context->getFence(fence); + gl::FenceNV *fenceObject = context->getFenceNV(fence); if (fenceObject == NULL) { @@ -4458,7 +4146,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence) return fenceObject->isFence(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4484,7 +4172,7 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4510,7 +4198,7 @@ GLboolean __stdcall glIsProgram(GLuint program) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4524,24 +4212,14 @@ GLboolean __stdcall glIsQueryEXT(GLuint id) try { - if (id == 0) - { - return GL_FALSE; - } - gl::Context *context = gl::getNonLostContext(); if (context) { - gl::Query *queryObject = context->getQuery(id, false, GL_NONE); - - if (queryObject) - { - return GL_TRUE; - } + return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4559,7 +4237,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) if (context && renderbuffer) { - gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); + gl::FramebufferAttachment *renderbufferObject = context->getRenderbuffer(renderbuffer); if (renderbufferObject) { @@ -4567,7 +4245,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4593,7 +4271,7 @@ GLboolean __stdcall glIsShader(GLuint shader) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4619,7 +4297,7 @@ GLboolean __stdcall glIsTexture(GLuint texture) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); } @@ -4645,7 +4323,7 @@ void __stdcall glLineWidth(GLfloat width) context->setLineWidth(width); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4678,7 +4356,7 @@ void __stdcall glLinkProgram(GLuint program) context->linkProgram(program); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4718,12 +4396,27 @@ void __stdcall glPixelStorei(GLenum pname, GLint param) context->setPackReverseRowOrder(param != 0); break; + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + UNIMPLEMENTED(); + break; + default: return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4742,7 +4435,7 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) context->setPolygonOffsetParams(factor, units); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4767,23 +4460,16 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, if (context) { - GLenum currentFormat, currentType; - - // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, - // and attempting to read back if that's the case is an error. The error will be registered - // by getCurrentReadFormat. - if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) - return; - - if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) + if (!gl::ValidateReadPixelsParameters(context, x, y, width, height, + format, type, &bufSize, data)) { - return gl::error(GL_INVALID_OPERATION); + return; } context->readPixels(x, y, width, height, format, type, &bufSize, data); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4807,23 +4493,16 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, if (context) { - GLenum currentFormat, currentType; - - // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, - // and attempting to read back if that's the case is an error. The error will be registered - // by getCurrentReadFormat. - if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) - return; - - if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) + if (!gl::ValidateReadPixelsParameters(context, x, y, width, height, + format, type, NULL, pixels)) { - return gl::error(GL_INVALID_OPERATION); + return; } context->readPixels(x, y, width, height, format, type, NULL, pixels); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4837,7 +4516,7 @@ void __stdcall glReleaseShaderCompiler(void) { gl::Shader::releaseCompiler(); } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4850,59 +4529,20 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp try { - switch (target) - { - case GL_RENDERBUFFER: - break; - default: - return gl::error(GL_INVALID_ENUM); - } - - if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat)) - { - return gl::error(GL_INVALID_ENUM); - } - - if (width < 0 || height < 0 || samples < 0) - { - return gl::error(GL_INVALID_VALUE); - } - gl::Context *context = gl::getNonLostContext(); if (context) { - if (width > context->getMaximumRenderbufferDimension() || - height > context->getMaximumRenderbufferDimension() || - samples > context->getMaxSupportedSamples()) - { - return gl::error(GL_INVALID_VALUE); - } - - GLuint handle = context->getRenderbufferHandle(); - if (handle == 0) + if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat, + width, height, true)) { - return gl::error(GL_INVALID_OPERATION); + return; } - switch (internalformat) - { - case GL_DEPTH_COMPONENT16: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB565: - case GL_RGB8_OES: - case GL_RGBA8_OES: - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: - context->setRenderbufferStorage(width, height, internalformat, samples); - break; - default: - return gl::error(GL_INVALID_ENUM); - } + context->setRenderbufferStorage(width, height, internalformat, samples); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4915,7 +4555,7 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) { - EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert); + EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert); try { @@ -4926,7 +4566,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4947,7 +4587,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) if (context) { - gl::Fence *fenceObject = context->getFence(fence); + gl::FenceNV *fenceObject = context->getFenceNV(fence); if (fenceObject == NULL) { @@ -4957,7 +4597,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) fenceObject->setFence(condition); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4981,7 +4621,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) context->setScissorParams(x, y, width, height); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -4998,13 +4638,13 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor // No binary shader formats are supported. return gl::error(GL_INVALID_ENUM); } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) +void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", shader, count, string, length); @@ -5037,7 +4677,7 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** strin shaderObject->setSource(count, string, length); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -5094,7 +4734,7 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -5136,7 +4776,7 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -5224,7 +4864,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -5240,17 +4880,22 @@ GLboolean __stdcall glTestFenceNV(GLuint fence) if (context) { - gl::Fence *fenceObject = context->getFence(fence); + gl::FenceNV *fenceObject = context->getFenceNV(fence); if (fenceObject == NULL) { return gl::error(GL_INVALID_OPERATION, GL_TRUE); } + if (fenceObject->isFence() != GL_TRUE) + { + return gl::error(GL_INVALID_OPERATION, GL_TRUE); + } + return fenceObject->testFence(); } } - catch(std::bad_alloc&) + catch (...) { gl::error(GL_OUT_OF_MEMORY); } @@ -5262,294 +4907,477 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " - "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", + "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", target, level, internalformat, width, height, border, format, type, pixels); try { - if (!validImageSize(level, width, height)) - { - return gl::error(GL_INVALID_VALUE); - } + gl::Context *context = gl::getNonLostContext(); - if (internalformat != GLint(format)) + if (context) { - return gl::error(GL_INVALID_OPERATION); - } + if (context->getClientVersion() < 3 && + !ValidateES2TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, width, height, border, format, type, pixels)) + { + return; + } - // validate <type> by itself (used as secondary key below) - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_24_8_OES: - case GL_HALF_FLOAT_OES: - case GL_FLOAT: - break; - default: - return gl::error(GL_INVALID_ENUM); + if (context->getClientVersion() >= 3 && + !ValidateES3TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, 0, width, height, 1, border, format, type, pixels)) + { + return; + } + + switch (target) + { + case GL_TEXTURE_2D: + { + gl::Texture2D *texture = context->getTexture2D(); + texture->setImage(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImagePosX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImageNegX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImagePosY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImageNegY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImagePosZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->setImageNegZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); + } + break; + default: UNREACHABLE(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - // validate <format> + <type> combinations - // - invalid <format> -> sets INVALID_ENUM - // - invalid <format>+<type> combination -> sets INVALID_OPERATION - switch (format) +void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - switch (type) + if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param))) { - case GL_UNSIGNED_BYTE: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - return gl::error(GL_INVALID_OPERATION); + return; } - break; - case GL_RGB: - switch (type) + + gl::Texture *texture = context->getTargetTexture(target); + + if (!texture) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_ENUM); } - break; - case GL_RGBA: - switch (type) + + switch (pname) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - return gl::error(GL_INVALID_OPERATION); + case GL_TEXTURE_WRAP_S: texture->setWrapS(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_WRAP_T: texture->setWrapT(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_WRAP_R: texture->setWrapR(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(param, context->getTextureMaxAnisotropy()); break; + case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(gl::uiround<GLenum>(param)); break; + case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(gl::iround<GLint>(param)); break; + case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(gl::iround<GLint>(param)); break; + case GL_TEXTURE_MIN_LOD: texture->setMinLod(param); break; + case GL_TEXTURE_MAX_LOD: texture->setMaxLod(param); break; + default: UNREACHABLE(); break; } - break; - case GL_BGRA_EXT: - switch (type) + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +{ + glTexParameterf(target, pname, (GLfloat)*params); +} + +void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateTexParamParameters(context, pname, param)) { - case GL_UNSIGNED_BYTE: - break; - default: - return gl::error(GL_INVALID_OPERATION); + return; } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - break; - case GL_DEPTH_COMPONENT: - switch (type) + + gl::Texture *texture = context->getTargetTexture(target); + + if (!texture) { - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - break; - default: - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_ENUM); } - break; - case GL_DEPTH_STENCIL_OES: - switch (type) + + switch (pname) { - case GL_UNSIGNED_INT_24_8_OES: - break; - default: - return gl::error(GL_INVALID_OPERATION); + case GL_TEXTURE_WRAP_S: texture->setWrapS((GLenum)param); break; + case GL_TEXTURE_WRAP_T: texture->setWrapT((GLenum)param); break; + case GL_TEXTURE_WRAP_R: texture->setWrapR((GLenum)param); break; + case GL_TEXTURE_MIN_FILTER: texture->setMinFilter((GLenum)param); break; + case GL_TEXTURE_MAG_FILTER: texture->setMagFilter((GLenum)param); break; + case GL_TEXTURE_USAGE_ANGLE: texture->setUsage((GLenum)param); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()); break; + case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode((GLenum)param); break; + case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc((GLenum)param); break; + case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed((GLenum)param); break; + case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen((GLenum)param); break; + case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue((GLenum)param); break; + case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha((GLenum)param); break; + case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(param); break; + case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(param); break; + case GL_TEXTURE_MIN_LOD: texture->setMinLod((GLfloat)param); break; + case GL_TEXTURE_MAX_LOD: texture->setMaxLod((GLfloat)param); break; + default: UNREACHABLE(); break; } - break; - default: - return gl::error(GL_INVALID_ENUM); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (border != 0) - { - return gl::error(GL_INVALID_VALUE); - } +void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +{ + glTexParameteri(target, pname, *params); +} +void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + target, levels, internalformat, width, height); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + if (context->getClientVersion() < 3 && + !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height)) { - return gl::error(GL_INVALID_VALUE); + return; + } + + if (context->getClientVersion() >= 3 && + !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) + { + return; } switch (target) { case GL_TEXTURE_2D: - if (width > (context->getMaximumTextureDimension() >> level) || - height > (context->getMaximumTextureDimension() >> level)) { - return gl::error(GL_INVALID_VALUE); + gl::Texture2D *texture2d = context->getTexture2D(); + texture2d->storage(levels, internalformat, width, height); } break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - if (width != height) - { - return gl::error(GL_INVALID_VALUE); - } - if (width > (context->getMaximumCubeTextureDimension() >> level) || - height > (context->getMaximumCubeTextureDimension() >> level)) + case GL_TEXTURE_CUBE_MAP: { - return gl::error(GL_INVALID_VALUE); + gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); + textureCube->storage(levels, internalformat, width); } break; + default: return gl::error(GL_INVALID_ENUM); } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - switch (format) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (context->supportsDXT1Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (context->supportsDXT3Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (context->supportsDXT5Textures()) - { - return gl::error(GL_INVALID_OPERATION); - } - else +void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid* pixels) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " + "const GLvoid* pixels = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, type, pixels); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3 && + !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, + xoffset, yoffset, width, height, 0, format, type, pixels)) + { + return; + } + + if (context->getClientVersion() >= 3 && + !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, + xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels)) + { + return; + } + + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + switch (target) + { + case GL_TEXTURE_2D: { - return gl::error(GL_INVALID_ENUM); + gl::Texture2D *texture = context->getTexture2D(); + texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels); } break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL_OES: - if (!context->supportsDepthTextures()) - { - return gl::error(GL_INVALID_VALUE); - } - if (target != GL_TEXTURE_2D) + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { - return gl::error(GL_INVALID_OPERATION); - } - // OES_depth_texture supports loading depth data and multiple levels, - // but ANGLE_depth_texture does not - if (pixels != NULL || level != 0) - { - return gl::error(GL_INVALID_OPERATION); + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels); } break; + default: - break; + UNREACHABLE(); } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (type == GL_FLOAT) +void __stdcall glUniform1f(GLint location, GLfloat x) +{ + glUniform1fv(location, 1, &x); +} + +void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_FLOAT, location, count)) { - if (!context->supportsFloat32Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + return; } - else if (type == GL_HALF_FLOAT_OES) + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform1fv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniform1i(GLint location, GLint x) +{ + glUniform1iv(location, 1, &x); +} + +void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_INT, location, count)) { - if (!context->supportsFloat16Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + return; } - if (target == GL_TEXTURE_2D) - { - gl::Texture2D *texture = context->getTexture2D(); + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform1iv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } +void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) +{ + GLfloat xy[2] = {x, y}; - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } + glUniform2fv(location, 1, xy); +} + +void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); - texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels); + if (context) + { + if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count)) + { + return; } - else + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform2fv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniform2i(GLint location, GLint x, GLint y) +{ + GLint xy[2] = {x, y}; + + glUniform2iv(location, 1, xy); +} + +void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_INT_VEC2, location, count)) { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); + return; + } - if (!texture) - { - return gl::error(GL_INVALID_OPERATION); - } + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform2iv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } +void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat xyz[3] = {x, y, z}; - switch (target) - { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); - break; - default: UNREACHABLE(); - } + glUniform3fv(location, 1, xyz); +} + +void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count)) + { + return; } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform3fv(location, count, v); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) +void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) { - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); + GLint xyz[3] = {x, y, z}; + + glUniform3iv(location, 1, xyz); +} + +void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); try { @@ -5557,81 +5385,115 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) if (context) { - gl::Texture *texture; + if (!ValidateUniform(context, GL_INT_VEC3, location, count)) + { + return; + } - switch (target) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform3iv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat xyzw[4] = {x, y, z, w}; + + glUniform4fv(location, 1, xyzw); +} + +void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count)) { - case GL_TEXTURE_2D: - texture = context->getTexture2D(); - break; - case GL_TEXTURE_CUBE_MAP: - texture = context->getTextureCubeMap(); - break; - default: - return gl::error(GL_INVALID_ENUM); + return; } - switch (pname) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform4fv(location, count, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +{ + GLint xyzw[4] = {x, y, z, w}; + + glUniform4iv(location, 1, xyzw); +} + +void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_INT_VEC4, location, count)) { - case GL_TEXTURE_WRAP_S: - if (!texture->setWrapS((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_WRAP_T: - if (!texture->setWrapT((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_MIN_FILTER: - if (!texture->setMinFilter((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_MAG_FILTER: - if (!texture->setMagFilter((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_USAGE_ANGLE: - if (!texture->setUsage((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->supportsTextureFilterAnisotropy()) - { - return gl::error(GL_INVALID_ENUM); - } - if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) - { - return gl::error(GL_INVALID_VALUE); - } - break; - default: - return gl::error(GL_INVALID_ENUM); + return; } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform4iv(location, count, v); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - glTexParameterf(target, pname, (GLfloat)*params); + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix2fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) +void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); try { @@ -5639,824 +5501,2937 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) if (context) { - gl::Texture *texture; + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose)) + { + return; + } - switch (target) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix3fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose)) { - case GL_TEXTURE_2D: - texture = context->getTexture2D(); - break; - case GL_TEXTURE_CUBE_MAP: - texture = context->getTextureCubeMap(); - break; - default: - return gl::error(GL_INVALID_ENUM); + return; } - switch (pname) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix4fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUseProgram(GLuint program) +{ + EVENT("(GLuint program = %d)", program); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Program *programObject = context->getProgram(program); + + if (!programObject && program != 0) { - case GL_TEXTURE_WRAP_S: - if (!texture->setWrapS((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_WRAP_T: - if (!texture->setWrapT((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_MIN_FILTER: - if (!texture->setMinFilter((GLenum)param)) - { - return gl::error(GL_INVALID_ENUM); - } - break; - case GL_TEXTURE_MAG_FILTER: - if (!texture->setMagFilter((GLenum)param)) + if (context->getShader(program)) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_OPERATION); } - break; - case GL_TEXTURE_USAGE_ANGLE: - if (!texture->setUsage((GLenum)param)) + else { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_VALUE); } - break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->supportsTextureFilterAnisotropy()) + } + + if (program != 0 && !programObject->isLinked()) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->useProgram(program); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glValidateProgram(GLuint program) +{ + EVENT("(GLuint program = %d)", program); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + if (context->getShader(program)) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_OPERATION); } - if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) + else { return gl::error(GL_INVALID_VALUE); } - break; - default: - return gl::error(GL_INVALID_ENUM); } + + programObject->validate(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) { - glTexParameteri(target, pname, *params); + EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + GLfloat vals[4] = { x, 0, 0, 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) { - EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", - target, levels, internalformat, width, height); + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); try { - if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) + if (index >= gl::MAX_VERTEX_ATTRIBS) { - return gl::error(GL_INVALID_ENUM); + return gl::error(GL_INVALID_VALUE); } - if (width < 1 || height < 1 || levels < 1) + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + GLfloat vals[4] = { values[0], 0, 0, 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +{ + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) { return gl::error(GL_INVALID_VALUE); } - if (target == GL_TEXTURE_CUBE_MAP && width != height) + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + GLfloat vals[4] = { x, y, 0, 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) +{ + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) { return gl::error(GL_INVALID_VALUE); } - if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_OPERATION); + GLfloat vals[4] = { values[0], values[1], 0, 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); } - GLenum format = gl::ExtractFormat(internalformat); - GLenum type = gl::ExtractType(internalformat); + gl::Context *context = gl::getNonLostContext(); - if (format == GL_NONE || type == GL_NONE) + if (context) { + GLfloat vals[4] = { x, y, z, 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) +{ + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + GLfloat vals[4] = { values[0], values[1], values[2], 1 }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + GLfloat vals[4] = { x, y, z, w }; + context->setVertexAttribf(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) +{ + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->setVertexAttribf(index, values); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) +{ + EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->setVertexAttribDivisor(index, divisor); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +{ + EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " + "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", + index, size, type, normalized, stride, ptr); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + if (size < 1 || size > 4) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + switch (type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_FIXED: + case GL_FLOAT: + break; + case GL_HALF_FLOAT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (context && context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM); + } + else + { + break; + } + default: return gl::error(GL_INVALID_ENUM); } + if (stride < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (context) + { + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && ptr != NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->setVertexAttribState(index, context->getArrayBuffer(), size, type, + normalized == GL_TRUE, false, stride, ptr); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); + + try + { + if (width < 0 || height < 0) + { + return gl::error(GL_INVALID_VALUE); + } + gl::Context *context = gl::getNonLostContext(); if (context) { - switch (target) + context->setViewportParams(x, y, width, height); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +// OpenGL ES 3.0 functions + +void __stdcall glReadBuffer(GLenum mode) +{ + EVENT("(GLenum mode = 0x%X)", mode); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { - case GL_TEXTURE_2D: - if (width > context->getMaximumTextureDimension() || - height > context->getMaximumTextureDimension()) + return gl::error(GL_INVALID_OPERATION); + } + + // glReadBuffer + UNIMPLEMENTED(); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) +{ + EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, " + "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glDrawRangeElements + UNIMPLEMENTED(); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " + "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, format, type, pixels); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, 0, width, height, depth, border, format, type, pixels)) + { + return; + } + + switch(target) + { + case GL_TEXTURE_3D: { - return gl::error(GL_INVALID_VALUE); + gl::Texture3D *texture = context->getTexture3D(); + texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels); } break; - case GL_TEXTURE_CUBE_MAP: - if (width > context->getMaximumCubeTextureDimension() || - height > context->getMaximumCubeTextureDimension()) + + case GL_TEXTURE_2D_ARRAY: { - return gl::error(GL_INVALID_VALUE); + gl::Texture2DArray *texture = context->getTexture2DArray(); + texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels); } break; + default: return gl::error(GL_INVALID_ENUM); } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - if (levels != 1 && !context->supportsNonPower2Texture()) + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { - if (!gl::isPow2(width) || !gl::isPow2(height)) - { - return gl::error(GL_INVALID_OPERATION); - } + return gl::error(GL_INVALID_OPERATION); + } + + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, + xoffset, yoffset, zoffset, width, height, depth, 0, + format, type, pixels)) + { + return; + } + + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0 || depth == 0) + { + return; } - switch (internalformat) + switch(target) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (!context->supportsDXT1Textures()) + case GL_TEXTURE_3D: { - return gl::error(GL_INVALID_ENUM); + gl::Texture3D *texture = context->getTexture3D(); + texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels); } break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (!context->supportsDXT3Textures()) + + case GL_TEXTURE_2D_ARRAY: { - return gl::error(GL_INVALID_ENUM); + gl::Texture2DArray *texture = context->getTexture2DArray(); + texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels); } break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (!context->supportsDXT5Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + + default: + return gl::error(GL_INVALID_ENUM); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", + target, level, xoffset, yoffset, zoffset, x, y, width, height); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset, + x, y, width, height, 0)) + { + return; + } + + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + gl::Texture *texture = NULL; + switch (target) + { + case GL_TEXTURE_3D: + texture = context->getTexture3D(); break; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - if (!context->supportsFloat32Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + + case GL_TEXTURE_2D_ARRAY: + texture = context->getTexture2DArray(); break; - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - if (!context->supportsFloat16Textures()) + + default: + return gl::error(GL_INVALID_ENUM); + } + + texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " + "const GLvoid* data = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, imageSize, data); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) + { + return gl::error(GL_INVALID_VALUE); + } + + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false, + 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data)) + { + return; + } + + switch(target) + { + case GL_TEXTURE_3D: { - return gl::error(GL_INVALID_ENUM); + gl::Texture3D *texture = context->getTexture3D(); + texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); } break; - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH24_STENCIL8_OES: - if (!context->supportsDepthTextures()) - { - return gl::error(GL_INVALID_ENUM); - } - if (target != GL_TEXTURE_2D) + + case GL_TEXTURE_2D_ARRAY: { - return gl::error(GL_INVALID_OPERATION); - } - // ANGLE_depth_texture only supports 1-level textures - if (levels != 1) - { - return gl::error(GL_INVALID_OPERATION); + gl::Texture2DArray *texture = context->getTexture2DArray(); + texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); } break; + default: - break; + return gl::error(GL_INVALID_ENUM); } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (target == GL_TEXTURE_2D) +void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " + "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { - gl::Texture2D *texture = context->getTexture2D(); + return gl::error(GL_INVALID_OPERATION); + } - if (!texture || texture->id() == 0) - { - return gl::error(GL_INVALID_OPERATION); - } + if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) + { + return gl::error(GL_INVALID_VALUE); + } - if (texture->isImmutable()) - { - return gl::error(GL_INVALID_OPERATION); - } + if (!data) + { + return gl::error(GL_INVALID_VALUE); + } - texture->storage(levels, internalformat, width, height); + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, + 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data)) + { + return; } - else if (target == GL_TEXTURE_CUBE_MAP) + + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); + return; + } - if (!texture || texture->id() == 0) + switch(target) + { + case GL_TEXTURE_3D: { - return gl::error(GL_INVALID_OPERATION); + gl::Texture3D *texture = context->getTexture3D(); + texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, data); } + break; - if (texture->isImmutable()) + case GL_TEXTURE_2D_ARRAY: { - return gl::error(GL_INVALID_OPERATION); + gl::Texture2DArray *texture = context->getTexture2DArray(); + texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, data); } + break; - texture->storage(levels, internalformat, width); + default: + return gl::error(GL_INVALID_ENUM); } - else UNREACHABLE(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid* pixels) +void __stdcall glGenQueries(GLsizei n, GLuint* ids) { - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " - "const GLvoid* pixels = 0x%0.8p)", - target, level, xoffset, yoffset, width, height, format, type, pixels); + EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); try { - if (!gl::IsInternalTextureTarget(target)) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_ENUM); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (n < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (GLsizei i = 0; i < n; i++) + { + ids[i] = context->createQuery(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) +{ + EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (n < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (GLsizei i = 0; i < n; i++) + { + context->deleteQuery(ids[i]); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) +GLboolean __stdcall glIsQuery(GLuint id) +{ + EVENT("(GLuint id = %u)", id); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; +} + +void __stdcall glBeginQuery(GLenum target, GLuint id) +{ + EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (!checkTextureFormatType(format, type)) + if (context) { - return; // error is set by helper function + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateBeginQuery(context, target, id)) + { + return; + } + context->beginQuery(target, id); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glEndQuery(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + if (context->getClientVersion() < 3) { - return gl::error(GL_INVALID_VALUE); + return gl::error(GL_INVALID_OPERATION); } - if (format == GL_FLOAT) + if (!ValidateEndQuery(context, target)) { - if (!context->supportsFloat32Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + return; } - else if (format == GL_HALF_FLOAT_OES) + + context->endQuery(target); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { - if (!context->supportsFloat16Textures()) - { - return gl::error(GL_INVALID_ENUM); - } + return gl::error(GL_INVALID_OPERATION); } - else if (gl::IsDepthTexture(format)) + + if (!ValidQueryType(context, target)) { - if (!context->supportsDepthTextures()) - { - return gl::error(GL_INVALID_ENUM); - } - if (target != GL_TEXTURE_2D) - { - return gl::error(GL_INVALID_OPERATION); - } - // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_ENUM); } - if (width == 0 || height == 0 || pixels == NULL) + switch (pname) { - return; + case GL_CURRENT_QUERY: + params[0] = static_cast<GLint>(context->getActiveQueryId(target)); + break; + + default: + return gl::error(GL_INVALID_ENUM); } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +{ + EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (target == GL_TEXTURE_2D) + if (context) + { + if (context->getClientVersion() < 3) { - gl::Texture2D *texture = context->getTexture2D(); - if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture)) - { - texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); - } + return gl::error(GL_INVALID_OPERATION); + } + + gl::Query *queryObject = context->getQuery(id, false, GL_NONE); + + if (!queryObject) + { + return gl::error(GL_INVALID_OPERATION); } - else if (gl::IsCubemapTextureTarget(target)) + + if (context->getActiveQueryId(queryObject->getType()) == id) { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture)) - { - texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); - } + return gl::error(GL_INVALID_OPERATION); } - else + + switch(pname) { - UNREACHABLE(); + case GL_QUERY_RESULT: + params[0] = queryObject->getResult(); + break; + case GL_QUERY_RESULT_AVAILABLE: + params[0] = queryObject->isResultAvailable(); + break; + default: + return gl::error(GL_INVALID_ENUM); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform1f(GLint location, GLfloat x) +GLboolean __stdcall glUnmapBuffer(GLenum target) { - glUniform1fv(location, 1, &x); + EVENT("(GLenum target = 0x%X)", target); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + return glUnmapBufferOES(target); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; } -void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + glGetBufferPointervOES(target, pname, params); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (location == -1) +void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) +{ + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + glDrawBuffersEXT(n, bufs); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose)) { - return gl::error(GL_INVALID_OPERATION); + return; } - if (!programBinary->setUniform1fv(location, count, v)) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix2x3fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose)) { - return gl::error(GL_INVALID_OPERATION); + return; } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix3x2fv(location, count, transpose, value); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform1i(GLint location, GLint x) +void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - glUniform1iv(location, 1, &x); + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix2x4fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) +void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix4x2fv(location, count, transpose, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); - if (location == -1) + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniformMatrix3x4fv(location, count, transpose, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", + location, count, transpose, value); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { + if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose)) + { + return; + } + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + programBinary->setUniformMatrix4x3fv(location, count, transpose, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, " + "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)", + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + try + { + gl::Context *context = gl::getNonLostContext(); + if (context) + { + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform1iv(location, count, v)) + if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter, + false)) + { + return; + } + + context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + target, samples, internalformat, width, height); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } + + if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat, + width, height, false)) + { + return; + } + + context->setRenderbufferStorage(width, height, internalformat, samples); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) +void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - GLfloat xy[2] = {x, y}; + EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)", + target, attachment, texture, level, layer); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateES3FramebufferTextureParameters(context, target, attachment, GL_NONE, texture, level, layer, true)) + { + return; + } + + gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); + ASSERT(framebuffer); - glUniform2fv(location, 1, (GLfloat*)&xy); + gl::Texture *textureObject = context->getTexture(texture); + GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE; + + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer); + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break; + case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break; + case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break; + } + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", + target, offset, length, access); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + return glMapBufferRangeEXT(target, offset, length, access); } - - if (location == -1) + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); + } + + return NULL; +} + +void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + glFlushMappedBufferRangeEXT(target, offset, length); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glBindVertexArray(GLuint array) +{ + EVENT("(GLuint array = %u)", array); + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform2fv(location, count, v)) + gl::VertexArray *vao = context->getVertexArray(array); + + if (!vao) { + // The default VAO should always exist + ASSERT(array != 0); return gl::error(GL_INVALID_OPERATION); } + + context->bindVertexArray(array); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform2i(GLint location, GLint x, GLint y) +void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) { - GLint xy[4] = {x, y}; + EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); + + try + { + gl::Context *context = gl::getNonLostContext(); - glUniform2iv(location, 1, (GLint*)&xy); + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (n < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + if (arrays[arrayIndex] != 0) + { + context->deleteVertexArray(arrays[arrayIndex]); + } + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) +void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (n < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + arrays[arrayIndex] = context->createVertexArray(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +GLboolean __stdcall glIsVertexArray(GLuint array) +{ + EVENT("(GLuint array = %u)", array); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (location == -1) + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + if (array == 0) + { + return GL_FALSE; + } + + gl::VertexArray *vao = context->getVertexArray(array); + + return (vao != NULL ? GL_TRUE : GL_FALSE); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + return GL_FALSE; +} + +void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", + target, index, data); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform2iv(location, count, v)) + switch (target) { - return gl::error(GL_INVALID_OPERATION); + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= context->getMaxTransformFeedbackBufferBindings()) + return gl::error(GL_INVALID_VALUE); + break; + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_BINDING: + if (index >= context->getMaximumCombinedUniformBufferBindings()) + return gl::error(GL_INVALID_VALUE); + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + if (!(context->getIndexedIntegerv(target, index, data))) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) + return gl::error(GL_INVALID_ENUM); + + if (numParams == 0) + return; // it is known that pname is valid, but there are no parameters to return + + if (nativeType == GL_INT_64_ANGLEX) + { + GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min()); + GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max()); + GLint64 *int64Params = new GLint64[numParams]; + + context->getIndexedInteger64v(target, index, int64Params); + + for (unsigned int i = 0; i < numParams; ++i) + { + GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue); + data[i] = static_cast<GLint>(clampedValue); + } + + delete [] int64Params; + } + else + { + UNREACHABLE(); + } } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +void __stdcall glBeginTransformFeedback(GLenum primitiveMode) { - GLfloat xyz[3] = {x, y, z}; + EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (primitiveMode) + { + case GL_TRIANGLES: + case GL_LINES: + case GL_POINTS: + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); + ASSERT(transformFeedback != NULL); - glUniform3fv(location, 1, (GLfloat*)&xyz); + if (transformFeedback->isStarted()) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (transformFeedback->isPaused()) + { + transformFeedback->resume(); + } + else + { + transformFeedback->start(primitiveMode); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +void __stdcall glEndTransformFeedback(void) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(void)"); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); + ASSERT(transformFeedback != NULL); + + if (!transformFeedback->isStarted()) + { + return gl::error(GL_INVALID_OPERATION); + } + + transformFeedback->stop(); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)", + target, index, buffer, offset, size); - if (location == -1) + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER: + if (index >= context->getMaxTransformFeedbackBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + break; + + case GL_UNIFORM_BUFFER: + if (index >= context->getMaximumCombinedUniformBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + break; + + default: + return gl::error(GL_INVALID_ENUM); + } + + if (buffer != 0 && size <= 0) + { + return gl::error(GL_INVALID_VALUE); + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER: + + // size and offset must be a multiple of 4 + if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0)) + { + return gl::error(GL_INVALID_VALUE); + } + + context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size); + context->bindGenericTransformFeedbackBuffer(buffer); + break; + + case GL_UNIFORM_BUFFER: + + // it is an error to bind an offset not a multiple of the alignment + if (buffer != 0 && (offset % context->getUniformBufferOffsetAlignment()) != 0) + { + return gl::error(GL_INVALID_VALUE); + } + + context->bindIndexedUniformBuffer(buffer, index, offset, size); + context->bindGenericUniformBuffer(buffer); + break; + + default: + UNREACHABLE(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", + target, index, buffer); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform3fv(location, count, v)) + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER: + if (index >= context->getMaxTransformFeedbackBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + break; + + case GL_UNIFORM_BUFFER: + if (index >= context->getMaximumCombinedUniformBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + break; + + default: + return gl::error(GL_INVALID_ENUM); + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER: + context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0); + context->bindGenericTransformFeedbackBuffer(buffer); + break; + + case GL_UNIFORM_BUFFER: + context->bindIndexedUniformBuffer(buffer, index, 0, 0); + context->bindGenericUniformBuffer(buffer); + break; + + default: + UNREACHABLE(); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) +{ + EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)", + program, count, varyings, bufferMode); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } + + if (count < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + switch (bufferMode) + { + case GL_INTERLEAVED_ATTRIBS: + break; + case GL_SEPARATE_ATTRIBS: + if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + if (!gl::ValidProgram(context, program)) + { + return; + } + + gl::Program *programObject = context->getProgram(program); + ASSERT(programObject); + + programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) +void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) { - GLint xyz[3] = {x, y, z}; + EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, " + "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", + program, index, bufSize, length, size, type, name); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (bufSize < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + if (!gl::ValidProgram(context, program)) + { + return; + } + + gl::Program *programObject = context->getProgram(program); + ASSERT(programObject); + + if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount())) + { + return gl::error(GL_INVALID_VALUE); + } - glUniform3iv(location, 1, (GLint*)&xyz); + programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) +void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)", + index, size, type, stride, pointer); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + } + + if (index >= gl::MAX_VERTEX_ATTRIBS) { return gl::error(GL_INVALID_VALUE); } - if (location == -1) + if (size < 1 || size > 4) { - return; + return gl::error(GL_INVALID_VALUE); + } + + switch (type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + break; + default: + return gl::error(GL_INVALID_ENUM); } + if (stride < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (context) + { + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && pointer != NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, true, + stride, pointer); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", + index, pname, params); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform3iv(location, count, v)) + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + const gl::VertexAttribute &attribState = context->getVertexAttribState(index); + + if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) + { + return; + } + + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); + for (int i = 0; i < 4; ++i) + { + params[i] = currentValueData.IntValues[i]; + } + } + else + { + *params = attribState.querySingleParameter<GLint>(pname); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)", + index, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } + + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + const gl::VertexAttribute &attribState = context->getVertexAttribState(index); + + if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) + { + return; + } + + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); + for (int i = 0; i < 4; ++i) + { + params[i] = currentValueData.UnsignedIntValues[i]; + } + } + else + { + *params = attribState.querySingleParameter<GLuint>(pname); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) { - GLfloat xyzw[4] = {x, y, z, w}; + EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", + index, x, y, z, w); + + try + { + gl::Context *context = gl::getNonLostContext(); - glUniform4fv(location, 1, (GLfloat*)&xyzw); + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + GLint vals[4] = { x, y, z, w }; + context->setVertexAttribi(index, vals); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } } -void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", + index, x, y, z, w); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + GLuint vals[4] = { x, y, z, w }; + context->setVertexAttribu(index, vals); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) +{ + EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v); - if (location == -1) + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + context->setVertexAttribi(index, v); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) +{ + EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return gl::error(GL_INVALID_VALUE); + } + + context->setVertexAttribu(index, v); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)", + program, location, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (program == 0) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject || !programObject->isLinked()) + { + return gl::error(GL_INVALID_OPERATION); + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); if (!programBinary) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniform4fv(location, count, v)) + if (!programBinary->getUniformuiv(location, NULL, params)) { return gl::error(GL_INVALID_OPERATION); } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) { - GLint xyzw[4] = {x, y, z, w}; + EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", + program, name); - glUniform4iv(location, 1, (GLint*)&xyzw); + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, -1); + } + + if (program == 0) + { + return gl::error(GL_INVALID_VALUE, -1); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject || !programObject->isLinked()) + { + return gl::error(GL_INVALID_OPERATION, -1); + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) + { + return gl::error(GL_INVALID_OPERATION, -1); + } + + return programBinary->getFragDataLocation(name); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, 0); + } + + return 0; } -void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) +void __stdcall glUniform1ui(GLint location, GLuint v0) { - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + glUniform1uiv(location, 1, &v0); +} + +void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1) +{ + const GLuint xy[] = { v0, v1 }; + glUniform2uiv(location, 1, xy); +} + +void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + const GLuint xyz[] = { v0, v1, v2 }; + glUniform3uiv(location, 1, xyz); +} + +void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + const GLuint xyzw[] = { v0, v1, v2, v3 }; + glUniform4uiv(location, 1, xyzw); +} + +void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", + location, count, value); try { - if (count < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform1uiv(location, count, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (location == -1) +void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", + location, count, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count)) + { + return; + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform2uiv(location, count, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)", + location, count, value); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count)) { - return gl::error(GL_INVALID_OPERATION); + return; } - if (!programBinary->setUniform4iv(location, count, v)) + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform3uiv(location, count, value); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", + location, count, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count)) { - return gl::error(GL_INVALID_OPERATION); + return; } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + programBinary->setUniform4uiv(location, count, value); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)", + buffer, drawbuffer, value); try { - if (count < 0 || transpose != GL_FALSE) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) + { + return gl::error(GL_INVALID_VALUE); + } + break; + case GL_STENCIL: + if (drawbuffer != 0) + { + return gl::error(GL_INVALID_VALUE); + } + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + context->clearBufferiv(buffer, drawbuffer, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)", + buffer, drawbuffer, value); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (location == -1) + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) + { + return gl::error(GL_INVALID_VALUE); + } + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + context->clearBufferuiv(buffer, drawbuffer, value); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)", + buffer, drawbuffer, value); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniformMatrix2fv(location, count, value)) + switch (buffer) { - return gl::error(GL_INVALID_OPERATION); + case GL_COLOR: + if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) + { + return gl::error(GL_INVALID_VALUE); + } + break; + case GL_DEPTH: + if (drawbuffer != 0) + { + return gl::error(GL_INVALID_VALUE); + } + break; + default: + return gl::error(GL_INVALID_ENUM); } + + context->clearBufferfv(buffer, drawbuffer, value); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)", + buffer, drawbuffer, depth, stencil); try { - if (count < 0 || transpose != GL_FALSE) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (buffer) + { + case GL_DEPTH_STENCIL: + if (drawbuffer != 0) + { + return gl::error(GL_INVALID_VALUE); + } + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + context->clearBufferfi(buffer, drawbuffer, depth, stencil); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (location == -1) +const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) +{ + EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL)); + } + + if (name != GL_EXTENSIONS) + { + return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL)); + } + + if (index >= context->getNumExtensions()) + { + return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL)); + } + + return reinterpret_cast<const GLubyte*>(context->getExtensionString(index)); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLubyte*>(NULL)); + } + + return NULL; +} +void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +{ + EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)", + readTarget, writeTarget, readOffset, writeOffset, size); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); - if (!programBinary) + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget)) + { + return gl::error(GL_INVALID_ENUM); + } + + gl::Buffer *readBuffer = context->getTargetBuffer(readTarget); + gl::Buffer *writeBuffer = context->getTargetBuffer(writeTarget); + + if (!readBuffer || !writeBuffer) { return gl::error(GL_INVALID_OPERATION); } - if (!programBinary->setUniformMatrix3fv(location, count, value)) + if (readBuffer->mapped() || writeBuffer->mapped()) { return gl::error(GL_INVALID_OPERATION); } + + if (readOffset < 0 || writeOffset < 0 || size < 0 || + static_cast<unsigned int>(readOffset + size) > readBuffer->size() || + static_cast<unsigned int>(writeOffset + size) > writeBuffer->size()) + { + return gl::error(GL_INVALID_VALUE); + } + + if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size) + { + return gl::error(GL_INVALID_VALUE); + } + + // TODO: Verify that readBuffer and writeBuffer are not currently mapped (GL_INVALID_OPERATION) + + // if size is zero, the copy is a successful no-op + if (size > 0) + { + writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) { - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); + EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)", + program, uniformCount, uniformNames, uniformIndices); try { - if (count < 0 || transpose != GL_FALSE) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (uniformCount < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + if (context->getShader(program)) + { + return gl::error(GL_INVALID_OPERATION); + } + else + { + return gl::error(GL_INVALID_VALUE); + } + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programObject->isLinked() || !programBinary) + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = GL_INVALID_INDEX; + } + } + else + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]); + } + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (location == -1) +void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) +{ + EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", + program, uniformCount, uniformIndices, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return; + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (uniformCount < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + if (context->getShader(program)) + { + return gl::error(GL_INVALID_OPERATION); + } + else + { + return gl::error(GL_INVALID_VALUE); + } + } + + switch (pname) + { + case GL_UNIFORM_TYPE: + case GL_UNIFORM_SIZE: + case GL_UNIFORM_NAME_LENGTH: + case GL_UNIFORM_BLOCK_INDEX: + case GL_UNIFORM_OFFSET: + case GL_UNIFORM_ARRAY_STRIDE: + case GL_UNIFORM_MATRIX_STRIDE: + case GL_UNIFORM_IS_ROW_MAJOR: + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + if (!programBinary && uniformCount > 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + + if (index >= (GLuint)programBinary->getActiveUniformCount()) + { + return gl::error(GL_INVALID_VALUE); + } + } + + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + params[uniformId] = programBinary->getActiveUniformi(index, pname); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) +{ + EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + if (context->getShader(program)) + { + return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX); + } + else + { + return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX); + } + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); if (!programBinary) { - return gl::error(GL_INVALID_OPERATION); + return GL_INVALID_INDEX; } - if (!programBinary->setUniformMatrix4fv(location, count, value)) + return programBinary->getUniformBlockIndex(uniformBlockName); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, 0); + } + + return 0; +} + +void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +{ + EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", + program, uniformBlockIndex, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) { return gl::error(GL_INVALID_OPERATION); } + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + if (context->getShader(program)) + { + return gl::error(GL_INVALID_OPERATION); + } + else + { + return gl::error(GL_INVALID_VALUE); + } + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) + { + return gl::error(GL_INVALID_VALUE); + } + + switch (pname) + { + case GL_UNIFORM_BLOCK_BINDING: + *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex)); + break; + + case GL_UNIFORM_BLOCK_DATA_SIZE: + case GL_UNIFORM_BLOCK_NAME_LENGTH: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params); + break; + + default: + return gl::error(GL_INVALID_ENUM); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glUseProgram(GLuint program) +void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) { - EVENT("(GLuint program = %d)", program); + EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)", + program, uniformBlockIndex, bufSize, length, uniformBlockName); try { @@ -6464,9 +8439,14 @@ void __stdcall glUseProgram(GLuint program) if (context) { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + gl::Program *programObject = context->getProgram(program); - if (!programObject && program != 0) + if (!programObject) { if (context->getShader(program)) { @@ -6478,23 +8458,26 @@ void __stdcall glUseProgram(GLuint program) } } - if (program != 0 && !programObject->isLinked()) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) { - return gl::error(GL_INVALID_OPERATION); + return gl::error(GL_INVALID_VALUE); } - context->useProgram(program); + programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glValidateProgram(GLuint program) +void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - EVENT("(GLuint program = %d)", program); + EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", + program, uniformBlockIndex, uniformBlockBinding); try { @@ -6502,6 +8485,16 @@ void __stdcall glValidateProgram(GLuint program) if (context) { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings()) + { + return gl::error(GL_INVALID_VALUE); + } + gl::Program *programObject = context->getProgram(program); if (!programObject) @@ -6516,217 +8509,749 @@ void __stdcall glValidateProgram(GLuint program) } } - programObject->validate(); + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + // if never linked, there won't be any uniform blocks + if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) + { + return gl::error(GL_INVALID_VALUE); + } + + programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) +void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) { - EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", + mode, first, count, instanceCount); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glDrawArraysInstanced + UNIMPLEMENTED(); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) +{ + EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)", + mode, count, type, indices, instanceCount); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { x, 0, 0, 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glDrawElementsInstanced + UNIMPLEMENTED(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) +GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) { - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0)); + } + + if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) + { + return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0)); + } + + if (flags != 0) + { + return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0)); + } + + return context->createFenceSync(condition); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLsync>(NULL)); + } + + return NULL; +} +GLboolean __stdcall glIsSync(GLsync sync) +{ + EVENT("(GLsync sync = 0x%0.8p)", sync); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { values[0], 0, 0, 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + return (context->getFenceSync(sync) != NULL); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; +} + +void __stdcall glDeleteSync(GLsync sync) +{ + EVENT("(GLsync sync = 0x%0.8p)", sync); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync)) + { + return gl::error(GL_INVALID_VALUE); + } + + context->deleteFenceSync(sync); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); + EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", + sync, flags, timeout); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED); + } + + if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0) + { + return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED); + } + + gl::FenceSync *fenceSync = context->getFenceSync(sync); + + if (!fenceSync) + { + return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED); + } + + return fenceSync->clientWait(flags, timeout); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + return GL_FALSE; +} + +void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", + sync, flags, timeout); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { x, y, 0, 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (flags != 0) + { + return gl::error(GL_INVALID_VALUE); + } + + if (timeout != GL_TIMEOUT_IGNORED) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::FenceSync *fenceSync = context->getFenceSync(sync); + + if (!fenceSync) + { + return gl::error(GL_INVALID_VALUE); + } + + fenceSync->serverWait(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) +void __stdcall glGetInteger64v(GLenum pname, GLint64* params) { - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", + pname, params); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) + { + return; + } + + if (nativeType == GL_INT_64_ANGLEX) + { + context->getInteger64v(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +{ + EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)", + sync, pname, bufSize, length, values); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { values[0], values[1], 0, 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (bufSize < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + gl::FenceSync *fenceSync = context->getFenceSync(sync); + + if (!fenceSync) + { + return gl::error(GL_INVALID_VALUE); + } + + switch (pname) + { + case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break; + case GL_SYNC_STATUS: values[0] = static_cast<GLint>(fenceSync->getStatus()); break; + case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break; + case GL_SYNC_FLAGS: values[0] = 0; break; + + default: + return gl::error(GL_INVALID_ENUM); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) { - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)", + target, index, data); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= context->getMaxTransformFeedbackBufferBindings()) + return gl::error(GL_INVALID_VALUE); + break; + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_BINDING: + if (index >= context->getMaximumCombinedUniformBufferBindings()) + return gl::error(GL_INVALID_VALUE); + break; + default: + return gl::error(GL_INVALID_ENUM); + } + + if (!(context->getIndexedInteger64v(target, index, data))) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) + return gl::error(GL_INVALID_ENUM); + + if (numParams == 0) + return; // it is known that pname is valid, but there are no parameters to return + + if (nativeType == GL_INT) + { + GLint *intParams = new GLint[numParams]; + + context->getIndexedIntegerv(target, index, intParams); + + for (unsigned int i = 0; i < numParams; ++i) + { + data[i] = static_cast<GLint64>(intParams[i]); + } + + delete [] intParams; + } + else + { + UNREACHABLE(); + } + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", + target, pname, params); + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { x, y, z, 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } + + if (!gl::ValidBufferParameter(context, pname)) + { + return gl::error(GL_INVALID_ENUM); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (!buffer) + { + // A null buffer means that "0" is bound to the requested buffer target + return gl::error(GL_INVALID_OPERATION); + } + + switch (pname) + { + case GL_BUFFER_USAGE: + *params = static_cast<GLint64>(buffer->usage()); + break; + case GL_BUFFER_SIZE: + *params = buffer->size(); + break; + case GL_BUFFER_ACCESS_FLAGS: + *params = static_cast<GLint64>(buffer->accessFlags()); + break; + case GL_BUFFER_MAPPED: + *params = static_cast<GLint64>(buffer->mapped()); + break; + case GL_BUFFER_MAP_OFFSET: + *params = buffer->mapOffset(); + break; + case GL_BUFFER_MAP_LENGTH: + *params = buffer->mapLength(); + break; + default: UNREACHABLE(); break; + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) +void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) { - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (count < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (int i = 0; i < count; i++) + { + samplers[i] = context->createSampler(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) +{ + EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers); + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { values[0], values[1], values[2], 1 }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (count < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + for (int i = 0; i < count; i++) + { + context->deleteSampler(samplers[i]); + } } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GLboolean __stdcall glIsSampler(GLuint sampler) { - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); + EVENT("(GLuint sampler = %u)", sampler); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + return context->isSampler(sampler); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + return GL_FALSE; +} + +void __stdcall glBindSampler(GLuint unit, GLuint sampler) +{ + EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - GLfloat vals[4] = { x, y, z, w }; - context->setVertexAttrib(index, vals); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (sampler != 0 && !context->isSampler(sampler)) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (unit >= context->getMaximumCombinedTextureImageUnits()) + { + return gl::error(GL_INVALID_VALUE); + } + + context->bindSampler(unit, sampler); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) +void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidateSamplerObjectParameter(pname)) + { + return; + } + + if (!gl::ValidateTexParamParameters(context, pname, param)) + { + return; + } + + if (!context->isSampler(sampler)) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->samplerParameteri(sampler, pname, param); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} +void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) +{ + glSamplerParameteri(sampler, pname, *param); +} + +void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - context->setVertexAttrib(index, values); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidateSamplerObjectParameter(pname)) + { + return; + } + + if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param))) + { + return; + } + + if (!context->isSampler(sampler)) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->samplerParameterf(sampler, pname, param); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) +void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) { - EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); + glSamplerParameterf(sampler, pname, *param); +} + +void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidateSamplerObjectParameter(pname)) + { + return; + } + + if (!context->isSampler(sampler)) + { + return gl::error(GL_INVALID_OPERATION); + } + + *params = context->getSamplerParameteri(sampler, pname); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +{ + EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidateSamplerObjectParameter(pname)) + { + return; + } + + if (!context->isSampler(sampler)) + { + return gl::error(GL_INVALID_OPERATION); + } + + *params = context->getSamplerParameterf(sampler, pname); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) +{ + EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); try { @@ -6739,131 +9264,532 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) if (context) { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + context->setVertexAttribDivisor(index, divisor); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +void __stdcall glBindTransformFeedback(GLenum target, GLuint id) { - EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " - "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", - index, size, type, normalized, stride, ptr); + EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); try { - if (index >= gl::MAX_VERTEX_ATTRIBS) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK: + { + // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1) + gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) + { + return gl::error(GL_INVALID_OPERATION); + } + + // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1) + if (context->getTransformFeedback(id) == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + context->bindTransformFeedback(id); + } + break; + + default: + return gl::error(GL_INVALID_ENUM); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (size < 1 || size > 4) +void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) +{ + EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + for (int i = 0; i < n; i++) + { + context->deleteTransformFeedback(ids[i]); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - switch (type) +void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_FIXED: - case GL_FLOAT: - break; - default: - return gl::error(GL_INVALID_ENUM); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + for (int i = 0; i < n; i++) + { + ids[i] = context->createTransformFeedback(); + } } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if (stride < 0) +GLboolean __stdcall glIsTransformFeedback(GLuint id) +{ + EVENT("(GLuint id = %u)", id); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; +} +void __stdcall glPauseTransformFeedback(void) +{ + EVENT("(void)"); + + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); + ASSERT(transformFeedback != NULL); + + // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86) + if (!transformFeedback->isStarted() || transformFeedback->isPaused()) + { + return gl::error(GL_INVALID_OPERATION); + } + + transformFeedback->pause(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +void __stdcall glResumeTransformFeedback(void) { - EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); + EVENT("(void)"); try { - if (width < 0 || height < 0) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); + ASSERT(transformFeedback != NULL); + + // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86) + if (!transformFeedback->isStarted() || !transformFeedback->isPaused()) + { + return gl::error(GL_INVALID_OPERATION); + } + + transformFeedback->resume(); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) +{ + EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)", + program, bufSize, length, binaryFormat, binary); + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - context->setViewportParams(x, y, width, height); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glGetProgramBinary + UNIMPLEMENTED(); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } } -void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) +void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) { - EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " - "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " - "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", - srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); + EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", + program, binaryFormat, binary, length); try { - switch (filter) + gl::Context *context = gl::getNonLostContext(); + + if (context) { - case GL_NEAREST: - break; - default: - return gl::error(GL_INVALID_ENUM); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glProgramBinary + UNIMPLEMENTED(); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} - if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) +void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", + program, pname, value); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) { - return gl::error(GL_INVALID_VALUE); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + // glProgramParameteri + UNIMPLEMENTED(); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) +{ + EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)", + target, numAttachments, attachments); + + try + { + gl::Context *context = gl::getNonLostContext(); - if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) + if (context) { - ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation"); - return gl::error(GL_INVALID_OPERATION); + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) + { + return; + } + + int maxDimension = context->getMaximumRenderbufferDimension(); + context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension); } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, " + "GLint y = %d, GLsizei width = %d, GLsizei height = %d)", + target, numAttachments, attachments, x, y, width, height); + try + { gl::Context *context = gl::getNonLostContext(); if (context) { - if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle()) + if (context->getClientVersion() < 3) { - ERR("Blits with the same source and destination framebuffer are not supported by this implementation."); return gl::error(GL_INVALID_OPERATION); } - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask); + if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) + { + return; + } + + context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height); } } - catch(std::bad_alloc&) + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + target, levels, internalformat, width, height); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) + { + return; + } + + switch (target) + { + case GL_TEXTURE_2D: + { + gl::Texture2D *texture2d = context->getTexture2D(); + texture2d->storage(levels, internalformat, width, height); + } + break; + + case GL_TEXTURE_CUBE_MAP: + { + gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); + textureCube->storage(levels, internalformat, width); + } + break; + + default: + return gl::error(GL_INVALID_ENUM); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d)", + target, levels, internalformat, width, height, depth); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth)) + { + return; + } + + switch (target) + { + case GL_TEXTURE_3D: + { + gl::Texture3D *texture3d = context->getTexture3D(); + texture3d->storage(levels, internalformat, width, height, depth); + } + break; + + case GL_TEXTURE_2D_ARRAY: + { + gl::Texture2DArray *texture2darray = context->getTexture2DArray(); + texture2darray->storage(levels, internalformat, width, height, depth); + } + break; + + default: + UNREACHABLE(); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, " + "GLint* params = 0x%0.8p)", + target, internalformat, pname, bufSize, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::IsColorRenderingSupported(internalformat, context) && + !gl::IsDepthRenderingSupported(internalformat, context) && + !gl::IsStencilRenderingSupported(internalformat, context)) + { + return gl::error(GL_INVALID_ENUM); + } + + if (target != GL_RENDERBUFFER) + { + return gl::error(GL_INVALID_ENUM); + } + + if (bufSize < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + switch (pname) + { + case GL_NUM_SAMPLE_COUNTS: + if (bufSize != 0) + *params = context->getNumSampleCounts(internalformat); + break; + case GL_SAMPLES: + context->getSampleCounts(internalformat, bufSize, params); + break; + default: + return gl::error(GL_INVALID_ENUM); + } + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +// Extension functions + +void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " + "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " + "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", + srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter, + true)) + { + return; + } + + context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + } + } + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -6881,7 +9807,7 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat { UNIMPLEMENTED(); // FIXME } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -6921,7 +9847,7 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l *binaryFormat = GL_PROGRAM_BINARY_ANGLE; } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -6954,7 +9880,7 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, context->setProgramBinary(program, binary, length); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -7012,7 +9938,266 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) } } } - catch (std::bad_alloc&) + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!context->supportsPBOs()) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } + + if (pname != GL_BUFFER_MAP_POINTER) + { + return gl::error(GL_INVALID_ENUM); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (!buffer || !buffer->mapped()) + { + *params = NULL; + } + + *params = buffer->mapPointer(); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY); + } +} + +void * __stdcall glMapBufferOES(GLenum target, GLenum access) +{ + EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (buffer == NULL) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + if (access != GL_WRITE_ONLY_OES) + { + return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); + } + + if (buffer->mapped()) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + return buffer->mapRange(0, buffer->size(), GL_MAP_WRITE_BIT); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); + } + + return NULL; +} + +GLboolean __stdcall glUnmapBufferOES(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, GL_FALSE); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (buffer == NULL || !buffer->mapped()) + { + return gl::error(GL_INVALID_OPERATION, GL_FALSE); + } + + // TODO: detect if we had corruption. if so, throw an error and return false. + + buffer->unmap(); + + return GL_TRUE; + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; +} + +void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", + target, offset, length, access); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); + } + + if (offset < 0 || length < 0) + { + return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (buffer == NULL) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + // Check for buffer overflow + size_t offsetSize = static_cast<size_t>(offset); + size_t lengthSize = static_cast<size_t>(length); + + if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || + offsetSize + lengthSize > static_cast<size_t>(buffer->size())) + { + return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); + } + + // Check for invalid bits in the mask + GLbitfield allAccessBits = GL_MAP_READ_BIT | + GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_INVALIDATE_BUFFER_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_UNSYNCHRONIZED_BIT; + + if (access & ~(allAccessBits)) + { + return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); + } + + if (length == 0 || buffer->mapped()) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + // Check for invalid bit combinations + if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_INVALIDATE_BUFFER_BIT | + GL_MAP_UNSYNCHRONIZED_BIT; + + if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) + { + return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); + } + + return buffer->mapRange(offset, length, access); + } + } + catch (...) + { + return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); + } + + return NULL; +} + +void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) +{ + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (offset < 0 || length < 0) + { + return gl::error(GL_INVALID_VALUE); + } + + if (!gl::ValidBufferTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM); + } + + gl::Buffer *buffer = context->getTargetBuffer(target); + + if (buffer == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) + { + return gl::error(GL_INVALID_OPERATION); + } + + // Check for buffer overflow + size_t offsetSize = static_cast<size_t>(offset); + size_t lengthSize = static_cast<size_t>(length); + + if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || + offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength())) + { + return gl::error(GL_INVALID_VALUE); + } + + // We do not currently support a non-trivial implementation of FlushMappedBufferRange + } + } + catch (...) { return gl::error(GL_OUT_OF_MEMORY); } @@ -7056,7 +10241,12 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES}, - {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, }; + {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, + {"glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)glGetBufferPointervOES}, + {"glMapBufferOES", (__eglMustCastToProperFunctionPointerType)glMapBufferOES}, + {"glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)glUnmapBufferOES}, + {"glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glMapBufferRangeEXT}, + {"glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glFlushMappedBufferRangeEXT}, }; for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++) { @@ -7083,19 +10273,17 @@ bool __stdcall glBindTexImage(egl::Surface *surface) if (context) { gl::Texture2D *textureObject = context->getTexture2D(); + ASSERT(textureObject != NULL); if (textureObject->isImmutable()) { return false; } - if (textureObject) - { - textureObject->bindTexImage(surface); - } + textureObject->bindTexImage(surface); } } - catch(std::bad_alloc&) + catch (...) { return gl::error(GL_OUT_OF_MEMORY, false); } diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.def b/chromium/third_party/angle/src/libGLESv2/libGLESv2.def index b8320c8f256..88dceb3556b 100644 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.def +++ b/chromium/third_party/angle/src/libGLESv2/libGLESv2.def @@ -173,6 +173,117 @@ EXPORTS glProgramBinaryOES @175 glGetProgramBinaryOES @176 glDrawBuffersEXT @179 + glMapBufferOES @285 + glUnmapBufferOES @286 + glGetBufferPointervOES @287 + glMapBufferRangeEXT @288 + glFlushMappedBufferRangeEXT @289 + + ; GLES 3.0 Functions + glReadBuffer @180 + glDrawRangeElements @181 + glTexImage3D @182 + glTexSubImage3D @183 + glCopyTexSubImage3D @184 + glCompressedTexImage3D @185 + glCompressedTexSubImage3D @186 + glGenQueries @187 + glDeleteQueries @188 + glIsQuery @189 + glBeginQuery @190 + glEndQuery @191 + glGetQueryiv @192 + glGetQueryObjectuiv @193 + glUnmapBuffer @194 + glGetBufferPointerv @195 + glDrawBuffers @196 + glUniformMatrix2x3fv @197 + glUniformMatrix3x2fv @198 + glUniformMatrix2x4fv @199 + glUniformMatrix4x2fv @200 + glUniformMatrix3x4fv @201 + glUniformMatrix4x3fv @202 + glBlitFramebuffer @203 + glRenderbufferStorageMultisample @204 + glFramebufferTextureLayer @205 + glMapBufferRange @206 + glFlushMappedBufferRange @207 + glBindVertexArray @208 + glDeleteVertexArrays @209 + glGenVertexArrays @210 + glIsVertexArray @211 + glGetIntegeri_v @212 + glBeginTransformFeedback @213 + glEndTransformFeedback @214 + glBindBufferRange @215 + glBindBufferBase @216 + glTransformFeedbackVaryings @217 + glGetTransformFeedbackVarying @218 + glVertexAttribIPointer @219 + glGetVertexAttribIiv @220 + glGetVertexAttribIuiv @221 + glVertexAttribI4i @222 + glVertexAttribI4ui @223 + glVertexAttribI4iv @224 + glVertexAttribI4uiv @225 + glGetUniformuiv @226 + glGetFragDataLocation @227 + glUniform1ui @228 + glUniform2ui @229 + glUniform3ui @230 + glUniform4ui @231 + glUniform1uiv @232 + glUniform2uiv @233 + glUniform3uiv @234 + glUniform4uiv @235 + glClearBufferiv @236 + glClearBufferuiv @237 + glClearBufferfv @238 + glClearBufferfi @239 + glGetStringi @240 + glCopyBufferSubData @241 + glGetUniformIndices @242 + glGetActiveUniformsiv @243 + glGetUniformBlockIndex @244 + glGetActiveUniformBlockiv @245 + glGetActiveUniformBlockName @246 + glUniformBlockBinding @247 + glDrawArraysInstanced @248 + glDrawElementsInstanced @249 + glFenceSync @250 + glIsSync @251 + glDeleteSync @252 + glClientWaitSync @253 + glWaitSync @254 + glGetInteger64v @255 + glGetSynciv @256 + glGetInteger64i_v @257 + glGetBufferParameteri64v @258 + glGenSamplers @259 + glDeleteSamplers @260 + glIsSampler @261 + glBindSampler @262 + glSamplerParameteri @263 + glSamplerParameteriv @264 + glSamplerParameterf @265 + glSamplerParameterfv @266 + glGetSamplerParameteriv @267 + glGetSamplerParameterfv @268 + glVertexAttribDivisor @269 + glBindTransformFeedback @270 + glDeleteTransformFeedbacks @271 + glGenTransformFeedbacks @272 + glIsTransformFeedback @273 + glPauseTransformFeedback @274 + glResumeTransformFeedback @275 + glGetProgramBinary @276 + glProgramBinary @277 + glProgramParameteri @278 + glInvalidateFramebuffer @279 + glInvalidateSubFramebuffer @280 + glTexStorage2D @281 + glTexStorage3D @282 + glGetInternalformativ @283 ; EGL dependencies glCreateContext @144 NONAME @@ -185,4 +296,4 @@ EXPORTS glDestroyRenderer @178 NONAME ; Setting up TRACE macro callbacks - SetTraceFunctionPointers @180 + SetTraceFunctionPointers @284 diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.rc b/chromium/third_party/angle/src/libGLESv2/libGLESv2.rc index 0ad21e440e7..76cd05566ee 100644 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.rc +++ b/chromium/third_party/angle/src/libGLESv2/libGLESv2.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION - PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 + PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -71,13 +71,14 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library" - VALUE "FileVersion", VERSION_STRING + VALUE "FileVersion", ANGLE_VERSION_STRING VALUE "InternalName", "libGLESv2" VALUE "LegalCopyright", "Copyright (C) 2011 Google Inc." VALUE "OriginalFilename", "libGLESv2.dll" - VALUE "PrivateBuild", VERSION_STRING + VALUE "PrivateBuild", ANGLE_VERSION_STRING VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library" - VALUE "ProductVersion", VERSION_STRING + VALUE "ProductVersion", ANGLE_VERSION_STRING + VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE END END BLOCK "VarFileInfo" diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj b/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj deleted file mode 100644 index ecb04cffb8b..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj +++ /dev/null @@ -1,425 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{B5871A7A-968C-42E3-A33B-981E6F448E78}</ProjectGuid> - <RootNamespace>libGLESv2</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IncludePath)</IncludePath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(LibraryPath)</LibraryPath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IncludePath)</IncludePath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(LibraryPath)</LibraryPath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath)</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath)</IncludePath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath)</LibraryPath> - <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath)</LibraryPath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)/..; $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> - <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile> - <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> - <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> - </Link> - <PostBuildEvent> - <Command>%40echo on -mkdir "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" -%40echo off -</Command> - </PostBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)/..; $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>ANGLE_DISABLE_TRACE;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError>true</TreatWarningAsError> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> - <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile> - <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX86</TargetMachine> - </Link> - <PostBuildEvent> - <Command>%40echo on -mkdir "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" -%40echo off -</Command> - </PostBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>$(ProjectDir)/..; $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <TreatWarningAsError>true</TreatWarningAsError> - <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile> - <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> - <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX64</TargetMachine> - </Link> - <PostBuildEvent> - <Command>%40echo on -mkdir "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" -%40echo off -</Command> - </PostBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> - <AdditionalIncludeDirectories>$(ProjectDir)/..; $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <TreatWarningAsError>true</TreatWarningAsError> - <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile> - <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies> - <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> - <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <DataExecutionPrevention> - </DataExecutionPrevention> - <TargetMachine>MachineX64</TargetMachine> - </Link> - <PostBuildEvent> - <Command>%40echo on -mkdir "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" -copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" -%40echo off -</Command> - </PostBuildEvent> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\third_party\murmurhash\MurmurHash3.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> - </ClCompile> - <ClCompile Include="Buffer.cpp" /> - <ClCompile Include="Context.cpp" /> - <ClCompile Include="..\common\debug.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> - </ClCompile> - <ClCompile Include="..\common\event_tracer.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> - </ClCompile> - <ClCompile Include="Fence.cpp" /> - <ClCompile Include="Float16ToFloat32.cpp" /> - <ClCompile Include="Framebuffer.cpp" /> - <ClCompile Include="HandleAllocator.cpp" /> - <ClCompile Include="libGLESv2.cpp" /> - <ClCompile Include="main.cpp" /> - <ClCompile Include="precompiled.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="Program.cpp" /> - <ClCompile Include="ProgramBinary.cpp" /> - <ClCompile Include="Query.cpp" /> - <ClCompile Include="..\common\RefCountObject.cpp" /> - <ClCompile Include="Renderbuffer.cpp" /> - <ClCompile Include="renderer\Blit.cpp" /> - <ClCompile Include="renderer\Fence11.cpp" /> - <ClCompile Include="renderer\Fence9.cpp" /> - <ClCompile Include="renderer\BufferStorage.cpp" /> - <ClCompile Include="renderer\BufferStorage11.cpp" /> - <ClCompile Include="renderer\BufferStorage9.cpp" /> - <ClCompile Include="renderer\Image.cpp" /> - <ClCompile Include="renderer\Image9.cpp" /> - <ClCompile Include="renderer\IndexBuffer.cpp" /> - <ClCompile Include="renderer\IndexBuffer11.cpp" /> - <ClCompile Include="renderer\IndexBuffer9.cpp" /> - <ClCompile Include="renderer\IndexDataManager.cpp" /> - <ClCompile Include="renderer\ImageSSE2.cpp" /> - <ClCompile Include="renderer\Image11.cpp" /> - <ClCompile Include="renderer\IndexRangeCache.cpp" /> - <ClCompile Include="renderer\InputLayoutCache.cpp" /> - <ClCompile Include="renderer\Query11.cpp" /> - <ClCompile Include="renderer\Query9.cpp" /> - <ClCompile Include="renderer\Renderer.cpp" /> - <ClCompile Include="renderer\Renderer11.cpp" /> - <ClCompile Include="renderer\renderer11_utils.cpp" /> - <ClCompile Include="renderer\Renderer9.cpp" /> - <ClCompile Include="renderer\renderer9_utils.cpp" /> - <ClCompile Include="renderer\RenderTarget11.cpp" /> - <ClCompile Include="renderer\RenderTarget9.cpp" /> - <ClCompile Include="renderer\RenderStateCache.cpp" /> - <ClCompile Include="renderer\ShaderExecutable11.cpp" /> - <ClCompile Include="renderer\ShaderExecutable9.cpp" /> - <ClCompile Include="renderer\SwapChain11.cpp" /> - <ClCompile Include="renderer\SwapChain9.cpp" /> - <ClCompile Include="renderer\TextureStorage.cpp" /> - <ClCompile Include="renderer\TextureStorage11.cpp" /> - <ClCompile Include="renderer\TextureStorage9.cpp" /> - <ClCompile Include="renderer\VertexBuffer.cpp" /> - <ClCompile Include="renderer\VertexBuffer11.cpp" /> - <ClCompile Include="renderer\VertexBuffer9.cpp" /> - <ClCompile Include="renderer\VertexDataManager.cpp" /> - <ClCompile Include="renderer\VertexDeclarationCache.cpp" /> - <ClCompile Include="ResourceManager.cpp" /> - <ClCompile Include="Shader.cpp" /> - <ClCompile Include="Texture.cpp" /> - <ClCompile Include="Uniform.cpp" /> - <ClCompile Include="utilities.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\common\debug.h" /> - <ClInclude Include="..\common\event_tracer.h" /> - <ClInclude Include="..\common\system.h" /> - <ClInclude Include="..\third_party\murmurhash\MurmurHash3.h" /> - <ClInclude Include="..\third_party\trace_event\trace_event.h" /> - <ClInclude Include="angletypes.h" /> - <ClInclude Include="BinaryStream.h" /> - <ClInclude Include="Buffer.h" /> - <ClInclude Include="constants.h" /> - <ClInclude Include="Context.h" /> - <ClInclude Include="Fence.h" /> - <ClInclude Include="Framebuffer.h" /> - <ClInclude Include="..\..\include\GLES2\gl2.h" /> - <ClInclude Include="..\..\include\GLES2\gl2ext.h" /> - <ClInclude Include="..\..\include\GLES2\gl2platform.h" /> - <ClInclude Include="HandleAllocator.h" /> - <ClInclude Include="main.h" /> - <ClInclude Include="mathutil.h" /> - <ClInclude Include="precompiled.h" /> - <ClInclude Include="Program.h" /> - <ClInclude Include="ProgramBinary.h" /> - <ClInclude Include="Query.h" /> - <ClInclude Include="..\common\RefCountObject.h" /> - <ClInclude Include="Renderbuffer.h" /> - <ClInclude Include="renderer\Blit.h" /> - <ClInclude Include="renderer\Fence11.h" /> - <ClInclude Include="renderer\Fence9.h" /> - <ClInclude Include="renderer\FenceImpl.h" /> - <ClInclude Include="renderer\BufferStorage.h" /> - <ClInclude Include="renderer\BufferStorage11.h" /> - <ClInclude Include="renderer\BufferStorage9.h" /> - <ClInclude Include="renderer\generatemip.h" /> - <ClInclude Include="renderer\Image.h" /> - <ClInclude Include="renderer\Image11.h" /> - <ClInclude Include="renderer\Image9.h" /> - <ClInclude Include="renderer\IndexBuffer.h" /> - <ClInclude Include="renderer\IndexBuffer11.h" /> - <ClInclude Include="renderer\IndexBuffer9.h" /> - <ClInclude Include="renderer\IndexDataManager.h" /> - <ClInclude Include="renderer\IndexRangeCache.h" /> - <ClInclude Include="renderer\InputLayoutCache.h" /> - <ClInclude Include="renderer\Query11.h" /> - <ClInclude Include="renderer\QueryImpl.h" /> - <ClInclude Include="renderer\Query9.h" /> - <ClInclude Include="renderer\Renderer.h" /> - <ClInclude Include="renderer\Renderer11.h" /> - <ClInclude Include="renderer\renderer11_utils.h" /> - <ClInclude Include="renderer\Renderer9.h" /> - <ClInclude Include="renderer\renderer9_utils.h" /> - <ClInclude Include="renderer\RenderTarget.h" /> - <ClInclude Include="renderer\RenderTarget11.h" /> - <ClInclude Include="renderer\RenderTarget9.h" /> - <ClInclude Include="renderer\RenderStateCache.h" /> - <ClInclude Include="renderer\ShaderCache.h" /> - <ClInclude Include="renderer\ShaderExecutable.h" /> - <ClInclude Include="renderer\ShaderExecutable11.h" /> - <ClInclude Include="renderer\ShaderExecutable9.h" /> - <ClInclude Include="renderer\shaders\compiled\clear11vs.h" /> - <ClInclude Include="renderer\shaders\compiled\clearmultiple11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\clearsingle11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\componentmaskps.h" /> - <ClInclude Include="renderer\shaders\compiled\flipyvs.h" /> - <ClInclude Include="renderer\shaders\compiled\luminanceps.h" /> - <ClInclude Include="renderer\shaders\compiled\passthrough11vs.h" /> - <ClInclude Include="renderer\shaders\compiled\passthroughlum11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\passthroughlumalpha11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\passthroughps.h" /> - <ClInclude Include="renderer\shaders\compiled\passthroughrgb11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\passthroughrgba11ps.h" /> - <ClInclude Include="renderer\shaders\compiled\standardvs.h" /> - <ClInclude Include="renderer\SwapChain.h" /> - <ClInclude Include="renderer\SwapChain11.h" /> - <ClInclude Include="renderer\SwapChain9.h" /> - <ClInclude Include="renderer\TextureStorage.h" /> - <ClInclude Include="renderer\TextureStorage11.h" /> - <ClInclude Include="renderer\TextureStorage9.h" /> - <ClInclude Include="renderer\VertexBuffer.h" /> - <ClInclude Include="renderer\VertexBuffer11.h" /> - <ClInclude Include="renderer\VertexBuffer9.h" /> - <ClInclude Include="renderer\vertexconversion.h" /> - <ClInclude Include="renderer\VertexDataManager.h" /> - <ClInclude Include="renderer\VertexDeclarationCache.h" /> - <ClInclude Include="resource.h" /> - <ClInclude Include="ResourceManager.h" /> - <ClInclude Include="Shader.h" /> - <ClInclude Include="Texture.h" /> - <ClInclude Include="Uniform.h" /> - <ClInclude Include="utilities.h" /> - <ClInclude Include="..\common\version.h" /> - </ItemGroup> - <ItemGroup> - <None Include="libGLESv2.def" /> - <None Include="renderer\shaders\Blit.ps" /> - <None Include="renderer\shaders\Blit.vs" /> - <None Include="renderer\shaders\Clear11.hlsl" /> - <None Include="renderer\shaders\generate_shaders.bat" /> - <None Include="renderer\shaders\Passthrough11.hlsl" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="libGLESv2.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\compiler\preprocessor\preprocessor.vcxproj"> - <Project>{fbe32df3-0fb0-4f2f-a424-2c21bd7bc325}</Project> - </ProjectReference> - <ProjectReference Include="..\compiler\translator.vcxproj"> - <Project>{5b3a6db8-1e7e-40d7-92b9-da8aae619fad}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj.filters b/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj.filters deleted file mode 100644 index 131fd6f2aef..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.vcxproj.filters +++ /dev/null @@ -1,527 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Third Party"> - <UniqueIdentifier>{dc1dac40-3563-41be-9e2d-c2588d8670fb}</UniqueIdentifier> - </Filter> - <Filter Include="Third Party\MurmurHash"> - <UniqueIdentifier>{b0005d2f-9b4a-4659-a270-138811174f73}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Renderer"> - <UniqueIdentifier>{562e469d-1abb-44bc-b7fa-55eefbf75acc}</UniqueIdentifier> - </Filter> - <Filter Include="Shaders"> - <UniqueIdentifier>{6dc0306f-6396-4e80-9ef9-09b58aa53c4d}</UniqueIdentifier> - </Filter> - <Filter Include="Shaders\Compiled"> - <UniqueIdentifier>{6332705b-1999-4292-a38b-dd47329734aa}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Renderer"> - <UniqueIdentifier>{93a76964-77a3-4b20-a6f5-e14e762d4e14}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Renderer9"> - <UniqueIdentifier>{3877f35e-845c-4e95-b9a5-c7d8b9f307c5}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\Renderer11"> - <UniqueIdentifier>{2d70fd60-6dea-489f-ac09-16890d325669}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Renderer9"> - <UniqueIdentifier>{60e14f04-2cf2-4a07-b3ef-7c68a82ba2d9}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\Renderer11"> - <UniqueIdentifier>{72db61d3-e081-4b58-bc63-a04a8a70585f}</UniqueIdentifier> - </Filter> - <Filter Include="Third Party\trace_event"> - <UniqueIdentifier>{ebfc1614-8f0b-48c7-b6bd-295bf91ef85c}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="Buffer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Context.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\common\debug.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Fence.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Float16ToFloat32.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Framebuffer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="HandleAllocator.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="libGLESv2.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="main.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Program.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ProgramBinary.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Query.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\common\RefCountObject.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Renderbuffer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="ResourceManager.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Shader.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="Texture.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="utilities.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="renderer\Image.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\TextureStorage.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\Renderer.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="..\third_party\murmurhash\MurmurHash3.cpp"> - <Filter>Third Party\MurmurHash</Filter> - </ClCompile> - <ClCompile Include="renderer\IndexDataManager.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\VertexDataManager.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\Image.cpp"> - <Filter>Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\ImageSSE2.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\VertexBuffer.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\IndexBuffer.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="Uniform.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="renderer\BufferStorage.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="renderer\BufferStorage11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\Fence11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\Image11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\IndexBuffer11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\Query11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\Renderer11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\renderer11_utils.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\RenderTarget11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\ShaderExecutable11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\SwapChain11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\TextureStorage11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\VertexBuffer11.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\BufferStorage9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\Fence9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\Image9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\IndexBuffer9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\Query9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\Renderer9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\renderer9_utils.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\RenderTarget9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\ShaderExecutable9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\SwapChain9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\TextureStorage9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\VertexBuffer9.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\Blit.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="renderer\InputLayoutCache.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\RenderStateCache.cpp"> - <Filter>Source Files\Renderer11</Filter> - </ClCompile> - <ClCompile Include="renderer\VertexDeclarationCache.cpp"> - <Filter>Source Files\Renderer9</Filter> - </ClCompile> - <ClCompile Include="precompiled.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="renderer\IndexRangeCache.cpp"> - <Filter>Source Files\Renderer</Filter> - </ClCompile> - <ClCompile Include="..\common\event_tracer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="BinaryStream.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Buffer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Context.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Fence.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Framebuffer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\include\GLES2\gl2.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\include\GLES2\gl2ext.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\include\GLES2\gl2platform.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="HandleAllocator.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="main.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="mathutil.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Program.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ProgramBinary.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Query.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\common\RefCountObject.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Renderbuffer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="resource.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="ResourceManager.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Shader.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="Texture.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="utilities.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\common\version.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="angletypes.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\third_party\murmurhash\MurmurHash3.h"> - <Filter>Third Party\MurmurHash</Filter> - </ClInclude> - <ClInclude Include="Uniform.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthrough11vs.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthroughps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\standardvs.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\componentmaskps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\flipyvs.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\luminanceps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthroughrgba11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthroughrgb11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthroughlum11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\passthroughlumalpha11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\clear11vs.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\clearmultiple11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="renderer\shaders\compiled\clearsingle11ps.h"> - <Filter>Shaders\Compiled</Filter> - </ClInclude> - <ClInclude Include="..\common\system.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\common\debug.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="renderer\BufferStorage.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\FenceImpl.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\generatemip.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\Image.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\IndexBuffer.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\IndexDataManager.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\QueryImpl.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\Renderer.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\RenderTarget.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\ShaderExecutable.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\SwapChain.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\TextureStorage.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\VertexBuffer.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\vertexconversion.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\VertexDataManager.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="renderer\BufferStorage11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\IndexBuffer11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\Query11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\Renderer11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\RenderTarget11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\ShaderExecutable11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\SwapChain11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\TextureStorage11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\VertexBuffer11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\BufferStorage9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Fence9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Image9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\IndexBuffer9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Query9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Renderer9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\renderer9_utils.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\RenderTarget9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\ShaderExecutable9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\SwapChain9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\TextureStorage9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\VertexBuffer9.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Fence11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\Image11.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\renderer11_utils.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\Fence9.h"> - <Filter>Header Files\Renderer\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\Query11.h"> - <Filter>Header Files\Renderer\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\Blit.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\ShaderCache.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="renderer\InputLayoutCache.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\RenderStateCache.h"> - <Filter>Header Files\Renderer11</Filter> - </ClInclude> - <ClInclude Include="renderer\VertexDeclarationCache.h"> - <Filter>Header Files\Renderer9</Filter> - </ClInclude> - <ClInclude Include="constants.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="precompiled.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="renderer\IndexRangeCache.h"> - <Filter>Header Files\Renderer</Filter> - </ClInclude> - <ClInclude Include="..\common\event_tracer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\third_party\trace_event\trace_event.h"> - <Filter>Third Party\trace_event</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <None Include="renderer\shaders\Blit.ps"> - <Filter>Shaders</Filter> - </None> - <None Include="renderer\shaders\Blit.vs"> - <Filter>Shaders</Filter> - </None> - <None Include="renderer\shaders\generate_shaders.bat"> - <Filter>Shaders</Filter> - </None> - <None Include="renderer\shaders\Passthrough11.hlsl"> - <Filter>Shaders</Filter> - </None> - <None Include="renderer\shaders\Clear11.hlsl"> - <Filter>Shaders</Filter> - </None> - <None Include="libGLESv2.def" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="libGLESv2.rc" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/chromium/third_party/angle/src/libGLESv2/main.cpp b/chromium/third_party/angle/src/libGLESv2/main.cpp index 6d7a241340f..50e2593328d 100644 --- a/chromium/third_party/angle/src/libGLESv2/main.cpp +++ b/chromium/third_party/angle/src/libGLESv2/main.cpp @@ -13,6 +13,40 @@ static DWORD currentTLS = TLS_OUT_OF_INDEXES; +namespace gl +{ + +Current *AllocateCurrent() +{ + Current *current = (Current*)LocalAlloc(LPTR, sizeof(Current)); + + if (!current) + { + ERR("Could not allocate thread local storage."); + return NULL; + } + + ASSERT(currentTLS != TLS_OUT_OF_INDEXES); + TlsSetValue(currentTLS, current); + + current->context = NULL; + current->display = NULL; + + return current; +} + +void DeallocateCurrent() +{ + void *current = TlsGetValue(currentTLS); + + if (current) + { + LocalFree((HLOCAL)current); + } +} + +} + extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) @@ -29,36 +63,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved // Fall throught to initialize index case DLL_THREAD_ATTACH: { - gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current)); - - if (current) - { - TlsSetValue(currentTLS, current); - - current->context = NULL; - current->display = NULL; - } + gl::AllocateCurrent(); } break; case DLL_THREAD_DETACH: { - void *current = TlsGetValue(currentTLS); - - if (current) - { - LocalFree((HLOCAL)current); - } + gl::DeallocateCurrent(); } break; case DLL_PROCESS_DETACH: { - void *current = TlsGetValue(currentTLS); - - if (current) - { - LocalFree((HLOCAL)current); - } - + gl::DeallocateCurrent(); TlsFree(currentTLS); } break; @@ -71,10 +86,20 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved namespace gl { -void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) + +Current *GetCurrentData() { Current *current = (Current*)TlsGetValue(currentTLS); + // ANGLE issue 488: when the dll is loaded after thread initialization, + // thread local storage (current) might not exist yet. + return (current ? current : AllocateCurrent()); +} + +void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) +{ + Current *current = GetCurrentData(); + current->context = context; current->display = display; @@ -86,7 +111,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) Context *getContext() { - Current *current = (Current*)TlsGetValue(currentTLS); + Current *current = GetCurrentData(); return current->context; } @@ -112,7 +137,7 @@ Context *getNonLostContext() egl::Display *getDisplay() { - Current *current = (Current*)TlsGetValue(currentTLS); + Current *current = GetCurrentData(); return current->display; } diff --git a/chromium/third_party/angle/src/libGLESv2/main.h b/chromium/third_party/angle/src/libGLESv2/main.h index 196afaeab67..d17facf20dc 100644 --- a/chromium/third_party/angle/src/libGLESv2/main.h +++ b/chromium/third_party/angle/src/libGLESv2/main.h @@ -10,7 +10,6 @@ #define LIBGLESV2_MAIN_H_ #include "common/debug.h" -#include "common/system.h" namespace egl { @@ -54,7 +53,7 @@ class Renderer; extern "C" { // Exported functions for use by EGL -gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); +gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); void glDestroyContext(gl::Context *context); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); gl::Context *glGetCurrentContext(); diff --git a/chromium/third_party/angle/src/libGLESv2/mathutil.h b/chromium/third_party/angle/src/libGLESv2/mathutil.h deleted file mode 100644 index bb48b94eaf7..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/mathutil.h +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// mathutil.h: Math and bit manipulation functions. - -#ifndef LIBGLESV2_MATHUTIL_H_ -#define LIBGLESV2_MATHUTIL_H_ - -#include <intrin.h> - -#include "common/system.h" -#include "common/debug.h" - -namespace gl -{ -struct Vector4 -{ - Vector4() {} - Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} - - float x; - float y; - float z; - float w; -}; - -inline bool isPow2(int x) -{ - return (x & (x - 1)) == 0 && (x != 0); -} - -inline int log2(int x) -{ - int r = 0; - while ((x >> r) > 1) r++; - return r; -} - -inline unsigned int ceilPow2(unsigned int x) -{ - if (x != 0) x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x++; - - return x; -} - -template<typename T, typename MIN, typename MAX> -inline T clamp(T x, MIN min, MAX max) -{ - // Since NaNs fail all comparison tests, a NaN value will default to min - return x > min ? (x > max ? max : x) : min; -} - -inline float clamp01(float x) -{ - return clamp(x, 0.0f, 1.0f); -} - -template<const int n> -inline unsigned int unorm(float x) -{ - const unsigned int max = 0xFFFFFFFF >> (32 - n); - - if (x > 1) - { - return max; - } - else if (x < 0) - { - return 0; - } - else - { - return (unsigned int)(max * x + 0.5f); - } -} - -inline bool supportsSSE2() -{ - static bool checked = false; - static bool supports = false; - - if (checked) - { - return supports; - } - - int info[4]; - __cpuid(info, 0); - - if (info[0] >= 1) - { - __cpuid(info, 1); - - supports = (info[3] >> 26) & 1; - } - - checked = true; - - return supports; -} - -inline unsigned short float32ToFloat16(float fp32) -{ - unsigned int fp32i = (unsigned int&)fp32; - unsigned int sign = (fp32i & 0x80000000) >> 16; - unsigned int abs = fp32i & 0x7FFFFFFF; - - if(abs > 0x47FFEFFF) // Infinity - { - return sign | 0x7FFF; - } - else if(abs < 0x38800000) // Denormal - { - unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000; - int e = 113 - (abs >> 23); - - if(e < 24) - { - abs = mantissa >> e; - } - else - { - abs = 0; - } - - return sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13; - } - else - { - return sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13; - } -} - -float float16ToFloat32(unsigned short h); - -} - -namespace rx -{ - -struct Range -{ - Range() {} - Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); } - - int start; - int end; -}; - -} - -#endif // LIBGLESV2_MATHUTIL_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/precompiled.h b/chromium/third_party/angle/src/libGLESv2/precompiled.h index 58ad181874b..3bc66a1d41e 100644 --- a/chromium/third_party/angle/src/libGLESv2/precompiled.h +++ b/chromium/third_party/angle/src/libGLESv2/precompiled.h @@ -6,16 +6,18 @@ // precompiled.h: Precompiled header file for libGLESv2. -#define GL_APICALL +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> #include <GLES2/gl2.h> + #include <GLES2/gl2ext.h> -#define EGLAPI #include <EGL/egl.h> #include <assert.h> #include <cstddef> #include <float.h> +#include <stdint.h> #include <intrin.h> #include <math.h> #include <stdarg.h> @@ -32,11 +34,15 @@ #include <unordered_map> #include <vector> +#if defined(ANGLE_ENABLE_D3D9) #include <d3d9.h> +#include <d3dcompiler.h> +#endif // ANGLE_ENABLE_D3D9 + +#if defined(ANGLE_ENABLE_D3D11) +#include <d3d10_1.h> #include <d3d11.h> #include <dxgi.h> +#include <dxgi1_2.h> #include <d3dcompiler.h> - -#ifdef _MSC_VER -#include <hash_map> -#endif +#endif // ANGLE_ENABLE_D3D11 diff --git a/chromium/third_party/angle/src/libGLESv2/queryconversions.cpp b/chromium/third_party/angle/src/libGLESv2/queryconversions.cpp new file mode 100644 index 00000000000..67578efe3a2 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/queryconversions.cpp @@ -0,0 +1,148 @@ +#include "precompiled.h" +// +// Copyright (c) 2014 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. +// + +// queryconversions.cpp: Implementation of state query cast conversions + +#include "libGLESv2/Context.h" +#include "common/utilities.h" + +namespace gl +{ + +// Helper class for converting a GL type to a GLenum: +// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap. +// We restrict our use to CastStateValue, where it eliminates duplicate parameters. + +template <typename GLType> +struct CastStateValueEnum { static GLenum mEnumForType; }; + +template <> GLenum CastStateValueEnum<GLint>::mEnumForType = GL_INT; +template <> GLenum CastStateValueEnum<GLuint>::mEnumForType = GL_UNSIGNED_INT; +template <> GLenum CastStateValueEnum<GLboolean>::mEnumForType = GL_BOOL; +template <> GLenum CastStateValueEnum<GLint64>::mEnumForType = GL_INT_64_ANGLEX; +template <> GLenum CastStateValueEnum<GLfloat>::mEnumForType = GL_FLOAT; + +template <typename QueryT, typename NativeT> +QueryT CastStateValueToInt(GLenum pname, NativeT value) +{ + GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType; + GLenum nativeType = CastStateValueEnum<NativeT>::mEnumForType; + + if (nativeType == GL_FLOAT) + { + // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5 + if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) + { + return static_cast<QueryT>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) / 2.0f); + } + else + { + return gl::iround<QueryT>(value); + } + } + + // Clamp 64-bit int values when casting to int + if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT) + { + GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::min()); + GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<GLint>::max()); + GLint64 clampedValue = std::max(std::min(static_cast<GLint64>(value), maxIntValue), minIntValue); + return static_cast<QueryT>(clampedValue); + } + + return static_cast<QueryT>(value); +} + +template <typename QueryT, typename NativeT> +QueryT CastStateValue(GLenum pname, NativeT value) +{ + GLenum queryType = CastStateValueEnum<QueryT>::mEnumForType; + + switch (queryType) + { + case GL_INT: return CastStateValueToInt<QueryT, NativeT>(pname, value); + case GL_INT_64_ANGLEX: return CastStateValueToInt<QueryT, NativeT>(pname, value); + case GL_FLOAT: return static_cast<QueryT>(value); + case GL_BOOL: return (value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE); + default: UNREACHABLE(); return 0; + } +} + +template <typename QueryT> +void CastStateValues(Context *context, GLenum nativeType, GLenum pname, + unsigned int numParams, QueryT *outParams) +{ + if (nativeType == GL_INT) + { + GLint *intParams = NULL; + intParams = new GLint[numParams]; + + context->getIntegerv(pname, intParams); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastStateValue<QueryT>(pname, intParams[i]); + } + + delete [] intParams; + } + else if (nativeType == GL_BOOL) + { + GLboolean *boolParams = NULL; + boolParams = new GLboolean[numParams]; + + context->getBooleanv(pname, boolParams); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1)); + } + + delete [] boolParams; + } + else if (nativeType == GL_FLOAT) + { + GLfloat *floatParams = NULL; + floatParams = new GLfloat[numParams]; + + context->getFloatv(pname, floatParams); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastStateValue<QueryT>(pname, floatParams[i]); + } + + delete [] floatParams; + } + else if (nativeType == GL_INT_64_ANGLEX) + { + GLint64 *int64Params = NULL; + int64Params = new GLint64[numParams]; + + context->getInteger64v(pname, int64Params); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]); + } + + delete [] int64Params; + } + else UNREACHABLE(); +} + +// Explicit template instantiation (how we export template functions in different files) +// The calls below will make CastStateValues successfully link with the GL state query types +// The GL state query API types are: bool, int, uint, float, int64 + +template void CastStateValues<GLboolean>(Context *, GLenum, GLenum, unsigned int, GLboolean *); +template void CastStateValues<GLint>(Context *, GLenum, GLenum, unsigned int, GLint *); +template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, GLuint *); +template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *); +template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *); + +} diff --git a/chromium/third_party/angle/src/libGLESv2/queryconversions.h b/chromium/third_party/angle/src/libGLESv2/queryconversions.h new file mode 100644 index 00000000000..da7047f730e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/queryconversions.h @@ -0,0 +1,17 @@ +// +// Copyright (c) 2014 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. +// + +// queryconversions.h: Declaration of state query cast conversions + +namespace gl +{ + +// The GL state query API types are: bool, int, uint, float, int64 +template <typename QueryT> +void CastStateValues(Context *context, GLenum nativeType, GLenum pname, + unsigned int numParams, QueryT *outParams); + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.cpp index a49b7bab842..4d245f89daa 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.cpp @@ -33,8 +33,4 @@ void BufferStorage::updateSerial() mSerial = mNextSerial++; } -void BufferStorage::markBufferUsage() -{ -} - } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.h b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.h index ace1a11bae0..a5f95d1eb79 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2014 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. // @@ -22,13 +22,18 @@ class BufferStorage // The data returned is only guaranteed valid until next non-const method. virtual void *getData() = 0; - virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0; + virtual void setData(const void* data, size_t size, size_t offset) = 0; + virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset) = 0; virtual void clear() = 0; - virtual unsigned int getSize() const = 0; + virtual void markTransformFeedbackUsage() = 0; + virtual size_t getSize() const = 0; virtual bool supportsDirectBinding() const = 0; - virtual void markBufferUsage(); unsigned int getSerial() const; + virtual bool isMapped() const = 0; + virtual void *map(GLbitfield access) = 0; + virtual void unmap() = 0; + protected: void updateSerial(); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.cpp deleted file mode 100644 index 3647d8a8985..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// BufferStorage11.cpp Defines the BufferStorage11 class. - -#include "libGLESv2/renderer/BufferStorage11.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer11.h" - -namespace rx -{ - -BufferStorage11::BufferStorage11(Renderer11 *renderer) -{ - mRenderer = renderer; - - mStagingBuffer = NULL; - mStagingBufferSize = 0; - - mBuffer = NULL; - mBufferSize = 0; - - mSize = 0; - - mResolvedData = NULL; - mResolvedDataSize = 0; - mResolvedDataValid = false; - - mReadUsageCount = 0; - mWriteUsageCount = 0; -} - -BufferStorage11::~BufferStorage11() -{ - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - } - - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } - - if (mResolvedData) - { - free(mResolvedData); - mResolvedData = NULL; - } -} - -BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage) -{ - ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage)); - return static_cast<BufferStorage11*>(bufferStorage); -} - -void *BufferStorage11::getData() -{ - if (!mResolvedDataValid) - { - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - HRESULT result; - - if (!mStagingBuffer || mStagingBufferSize < mBufferSize) - { - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = mSize; - bufferDesc.Usage = D3D11_USAGE_STAGING; - bufferDesc.BindFlags = 0; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); - } - - mStagingBufferSize = bufferDesc.ByteWidth; - } - - if (!mResolvedData || mResolvedDataSize < mBufferSize) - { - free(mResolvedData); - mResolvedData = malloc(mSize); - mResolvedDataSize = mSize; - } - - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = mSize; - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(mStagingBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); - } - - memcpy(mResolvedData, mappedResource.pData, mSize); - - context->Unmap(mStagingBuffer, 0); - - mResolvedDataValid = true; - } - - mReadUsageCount = 0; - - return mResolvedData; -} - -void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset) -{ - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - HRESULT result; - - unsigned int requiredBufferSize = size + offset; - unsigned int requiredStagingSize = size; - bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset); - - if (!directInitialization) - { - if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize) - { - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = size; - bufferDesc.Usage = D3D11_USAGE_STAGING; - bufferDesc.BindFlags = 0; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - if (data) - { - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = data; - initialData.SysMemPitch = size; - initialData.SysMemSlicePitch = 0; - - result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer); - } - else - { - result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer); - } - - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - mStagingBufferSize = size; - } - else if (data) - { - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - memcpy(mappedResource.pData, data, size); - - context->Unmap(mStagingBuffer, 0); - } - } - - if (!mBuffer || mBufferSize < size + offset) - { - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = requiredBufferSize; - bufferDesc.Usage = D3D11_USAGE_DEFAULT; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER; - bufferDesc.CPUAccessFlags = 0; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - if (directInitialization) - { - // Since the data will fill the entire buffer (being larger than the initial size and having - // no offset), the buffer can be initialized with the data so no staging buffer is required - - // No longer need the old buffer - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - mBufferSize = 0; - } - - if (data) - { - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = data; - initialData.SysMemPitch = size; - initialData.SysMemSlicePitch = 0; - - result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer); - } - else - { - result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer); - } - - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - else if (mBuffer && offset > 0) - { - // If offset is greater than zero and the buffer is non-null, need to preserve the data from - // the old buffer up to offset - ID3D11Buffer *newBuffer = NULL; - - result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = std::min(offset, mBufferSize); - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox); - - mBuffer->Release(); - mBuffer = newBuffer; - } - else - { - // Simple case, nothing needs to be copied from the old buffer to the new one, just create - // a new buffer - - // No longer need the old buffer - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - mBufferSize = 0; - } - - // Create a new buffer for data storage - result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - updateSerial(); - mBufferSize = bufferDesc.ByteWidth; - } - - if (!directInitialization) - { - ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize); - - // Data is already put into the staging buffer, copy it over to the data buffer - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = size; - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox); - } - - mSize = std::max(mSize, offset + size); - - mWriteUsageCount = 0; - - mResolvedDataValid = false; -} - -void BufferStorage11::clear() -{ - mResolvedDataValid = false; - mSize = 0; -} - -unsigned int BufferStorage11::getSize() const -{ - return mSize; -} - -bool BufferStorage11::supportsDirectBinding() const -{ - return true; -} - -void BufferStorage11::markBufferUsage() -{ - mReadUsageCount++; - mWriteUsageCount++; - - static const unsigned int usageLimit = 5; - - if (mReadUsageCount > usageLimit && mResolvedData) - { - free(mResolvedData); - mResolvedData = NULL; - mResolvedDataSize = 0; - mResolvedDataValid = false; - } - - if (mReadUsageCount > usageLimit && mWriteUsageCount > usageLimit && mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } -} - -ID3D11Buffer *BufferStorage11::getBuffer() const -{ - return mBuffer; -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.h b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.h deleted file mode 100644 index b62348b0c93..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage11.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// BufferStorage11.h Defines the BufferStorage11 class. - -#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ -#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ - -#include "libGLESv2/renderer/BufferStorage.h" - -namespace rx -{ -class Renderer11; - -class BufferStorage11 : public BufferStorage -{ - public: - explicit BufferStorage11(Renderer11 *renderer); - virtual ~BufferStorage11(); - - static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage); - - virtual void *getData(); - virtual void setData(const void* data, unsigned int size, unsigned int offset); - virtual void clear(); - virtual unsigned int getSize() const; - virtual bool supportsDirectBinding() const; - virtual void markBufferUsage(); - - ID3D11Buffer *getBuffer() const; - - private: - Renderer11 *mRenderer; - - ID3D11Buffer *mStagingBuffer; - unsigned int mStagingBufferSize; - - ID3D11Buffer *mBuffer; - unsigned int mBufferSize; - - unsigned int mSize; - - void *mResolvedData; - unsigned int mResolvedDataSize; - bool mResolvedDataValid; - - unsigned int mReadUsageCount; - unsigned int mWriteUsageCount; -}; - -} - -#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage9.cpp deleted file mode 100644 index e69e7a8921e..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage9.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// BufferStorage9.cpp Defines the BufferStorage9 class. - -#include "libGLESv2/renderer/BufferStorage9.h" -#include "common/debug.h" - -namespace rx -{ - -BufferStorage9::BufferStorage9() -{ - mMemory = NULL; - mAllocatedSize = 0; - mSize = 0; -} - -BufferStorage9::~BufferStorage9() -{ - delete[] mMemory; -} - -BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage) -{ - ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage)); - return static_cast<BufferStorage9*>(bufferStorage); -} - -void *BufferStorage9::getData() -{ - return mMemory; -} - -void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset) -{ - if (!mMemory || offset + size > mAllocatedSize) - { - unsigned int newAllocatedSize = offset + size; - void *newMemory = new char[newAllocatedSize]; - - if (offset > 0 && mMemory && mAllocatedSize > 0) - { - memcpy(newMemory, mMemory, std::min(offset, mAllocatedSize)); - } - - delete[] mMemory; - mMemory = newMemory; - mAllocatedSize = newAllocatedSize; - } - - mSize = std::max(mSize, offset + size); - if (data) - { - memcpy(reinterpret_cast<char*>(mMemory) + offset, data, size); - } -} - -void BufferStorage9::clear() -{ - mSize = 0; -} - -unsigned int BufferStorage9::getSize() const -{ - return mSize; -} - -bool BufferStorage9::supportsDirectBinding() const -{ - return false; -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Fence11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Fence11.cpp deleted file mode 100644 index 9d11c9a0fc8..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Fence11.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. - -#include "libGLESv2/renderer/Fence11.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer11.h" - -namespace rx -{ - -Fence11::Fence11(rx::Renderer11 *renderer) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Fence11::~Fence11() -{ - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } -} - -GLboolean Fence11::isFence() -{ - // GL_NV_fence spec: - // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return mQuery != NULL; -} - -void Fence11::setFence(GLenum condition) -{ - if (!mQuery) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; - queryDesc.MiscFlags = 0; - - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mRenderer->getDeviceContext()->End(mQuery); - - setCondition(condition); - setStatus(GL_FALSE); -} - -GLboolean Fence11::testFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION, GL_TRUE); - } - - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0); - - if (mRenderer->isDeviceLost()) - { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - return getStatus(); -} - -void Fence11::finishFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - while (!testFence()) - { - Sleep(0); - } -} - -void Fence11::getFenceiv(GLenum pname, GLint *params) -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (getStatus()) - { - params[0] = GL_TRUE; - return; - } - - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); - - if (mRenderer->isDeviceLost()) - { - params[0] = GL_TRUE; - return gl::error(GL_OUT_OF_MEMORY); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - params[0] = getStatus(); - - break; - } - case GL_FENCE_CONDITION_NV: - params[0] = getCondition(); - break; - default: - return gl::error(GL_INVALID_ENUM); - break; - } -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Fence9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Fence9.cpp deleted file mode 100644 index 86064d7e52b..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Fence9.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Fence9.cpp: Defines the rx::Fence9 class. - -#include "libGLESv2/renderer/Fence9.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" - -namespace rx -{ - -Fence9::Fence9(rx::Renderer9 *renderer) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Fence9::~Fence9() -{ - if (mQuery) - { - mRenderer->freeEventQuery(mQuery); - mQuery = NULL; - } -} - -GLboolean Fence9::isFence() -{ - // GL_NV_fence spec: - // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return mQuery != NULL; -} - -void Fence9::setFence(GLenum condition) -{ - if (!mQuery) - { - mQuery = mRenderer->allocateEventQuery(); - if (!mQuery) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - HRESULT result = mQuery->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); - - setCondition(condition); - setStatus(GL_FALSE); -} - -GLboolean Fence9::testFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION, GL_TRUE); - } - - HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); - - if (d3d9::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - return getStatus(); -} - -void Fence9::finishFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - while (!testFence()) - { - Sleep(0); - } -} - -void Fence9::getFenceiv(GLenum pname, GLint *params) -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (getStatus()) - { - params[0] = GL_TRUE; - return; - } - - HRESULT result = mQuery->GetData(NULL, 0, 0); - - if (d3d9::isDeviceLostError(result)) - { - params[0] = GL_TRUE; - mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - params[0] = getStatus(); - - break; - } - case GL_FENCE_CONDITION_NV: - params[0] = getCondition(); - break; - default: - return gl::error(GL_INVALID_ENUM); - break; - } -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/FenceImpl.h b/chromium/third_party/angle/src/libGLESv2/renderer/FenceImpl.h index d7f2102a2e9..d54e6becd3e 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/FenceImpl.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/FenceImpl.h @@ -17,27 +17,16 @@ namespace rx class FenceImpl { public: - FenceImpl() : mStatus(GL_FALSE), mCondition(GL_NONE) { }; + FenceImpl() { }; virtual ~FenceImpl() { }; - virtual GLboolean isFence() = 0; - virtual void setFence(GLenum condition) = 0; - virtual GLboolean testFence() = 0; - virtual void finishFence() = 0; - virtual void getFenceiv(GLenum pname, GLint *params) = 0; - - protected: - void setStatus(GLboolean status) { mStatus = status; } - GLboolean getStatus() const { return mStatus; } - - void setCondition(GLuint condition) { mCondition = condition; } - GLuint getCondition() const { return mCondition; } + virtual bool isSet() const = 0; + virtual void set() = 0; + virtual bool test(bool flushCommandBuffer) = 0; + virtual bool hasError() const = 0; private: DISALLOW_COPY_AND_ASSIGN(FenceImpl); - - GLboolean mStatus; - GLenum mCondition; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Image.cpp index 57239ef74ff..5963534e03c 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/Image.cpp @@ -18,531 +18,12 @@ Image::Image() { mWidth = 0; mHeight = 0; + mDepth = 0; mInternalFormat = GL_NONE; mActualFormat = GL_NONE; -} - -void Image::loadAlphaDataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = 0; - dest[4 * x + 1] = 0; - dest[4 * x + 2] = 0; - dest[4 * x + 3] = source[x]; - } - } -} - -void Image::loadAlphaDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - memcpy(dest, source, width); - } -} - -void Image::loadAlphaFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = 0; - dest[4 * x + 1] = 0; - dest[4 * x + 2] = 0; - dest[4 * x + 3] = source[x]; - } - } -} - -void Image::loadAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned short *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = 0; - dest[4 * x + 1] = 0; - dest[4 * x + 2] = 0; - dest[4 * x + 3] = source[x]; - } - } -} - -void Image::loadLuminanceDataToNativeOrBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output, bool native) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - - if (!native) // BGRA8 destination format - { - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 0xFF; - } - } - else // L8 destination format - { - memcpy(dest, source, width); - } - } -} - -void Image::loadLuminanceFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 1.0f; - } - } -} - -void Image::loadLuminanceFloatDataToRGB(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[3 * x + 0] = source[x]; - dest[3 * x + 1] = source[x]; - dest[3 * x + 2] = source[x]; - } - } -} - -void Image::loadLuminanceHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned short *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1 - } - } -} - -void Image::loadLuminanceAlphaDataToNativeOrBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output, bool native) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - - if (!native) // BGRA8 destination format - { - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2*x+0]; - dest[4 * x + 1] = source[2*x+0]; - dest[4 * x + 2] = source[2*x+0]; - dest[4 * x + 3] = source[2*x+1]; - } - } - else - { - memcpy(dest, source, width * 2); - } - } -} - -void Image::loadLuminanceAlphaFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2*x+0]; - dest[4 * x + 1] = source[2*x+0]; - dest[4 * x + 2] = source[2*x+0]; - dest[4 * x + 3] = source[2*x+1]; - } - } -} - -void Image::loadLuminanceAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned short *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2*x+0]; - dest[4 * x + 1] = source[2*x+0]; - dest[4 * x + 2] = source[2*x+0]; - dest[4 * x + 3] = source[2*x+1]; - } - } -} - -void Image::loadRGBUByteDataToBGRX(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 2]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 0]; - dest[4 * x + 3] = 0xFF; - } - } -} - -void Image::loadRGBUByteDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 0]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 2]; - dest[4 * x + 3] = 0xFF; - } - } -} - -void Image::loadRGB565DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2); - dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9); - dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); - dest[4 * x + 3] = 0xFF; - } - } -} - -void Image::loadRGB565DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); - dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9); - dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2); - dest[4 * x + 3] = 0xFF; - } - } -} - -void Image::loadRGBFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 0]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 2]; - dest[4 * x + 3] = 1.0f; - } - } -} - -void Image::loadRGBFloatDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - memcpy(dest, source, width * 12); - } -} - -void Image::loadRGBHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned short *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); - for (int x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 0]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 2]; - dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1 - } - } -} - -void Image::loadRGBAUByteDataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned int *source = NULL; - unsigned int *dest = NULL; - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); - - for (int x = 0; x < width; x++) - { - unsigned int rgba = source[x]; - dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } -} - -void Image::loadRGBAUByteDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned int *source = NULL; - unsigned int *dest = NULL; - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); - - memcpy(dest, source, width * 4); - } -} - -void Image::loadRGBA4444DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); - dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); - dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); - dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); - } - } -} - -void Image::loadRGBA4444DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); - dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); - dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); - dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); - } - } -} - -void Image::loadRGBA5551DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); - dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); - dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); - dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0; - } - } -} - -void Image::loadRGBA5551DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned short *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + y * outputPitch; - for (int x = 0; x < width; x++) - { - unsigned short rgba = source[x]; - dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); - dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); - dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); - dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0; - } - } -} - -void Image::loadRGBAFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const float *source = NULL; - float *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); - memcpy(dest, source, width * 16); - } -} - -void Image::loadRGBAHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - memcpy(dest, source, width * 8); - } -} - -void Image::loadBGRADataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned char *dest = NULL; - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + y * outputPitch; - memcpy(dest, source, width*4); - } + mTarget = GL_NONE; + mRenderable = false; + mDirty = false; } } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image.h b/chromium/third_party/angle/src/libGLESv2/renderer/Image.h index 454e83e21e6..73e4e843d7d 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/Image.h @@ -23,6 +23,8 @@ namespace rx class Renderer; class TextureStorageInterface2D; class TextureStorageInterfaceCube; +class TextureStorageInterface3D; +class TextureStorageInterface2DArray; class Image { @@ -32,8 +34,11 @@ class Image GLsizei getWidth() const { return mWidth; } GLsizei getHeight() const { return mHeight; } + GLsizei getDepth() const { return mDepth; } GLenum getInternalFormat() const { return mInternalFormat; } GLenum getActualFormat() const { return mActualFormat; } + GLenum getTarget() const { return mTarget; } + bool isRenderableFormat() const { return mRenderable; } void markDirty() {mDirty = true;} void markClean() {mDirty = false;} @@ -41,84 +46,30 @@ class Image virtual void setManagedSurface(TextureStorageInterface2D *storage, int level) {}; virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) {}; - virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - - virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) = 0; - - virtual bool isRenderableFormat() const = 0; - - virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input) = 0; - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + virtual void setManagedSurface(TextureStorageInterface3D *storage, int level) {}; + virtual void setManagedSurface(TextureStorageInterface2DArray *storage, int layer, int level) {}; + virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; + virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; + virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0; + virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0; + + virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0; + + virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) = 0; + virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input) = 0; - virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - - static void loadAlphaDataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadAlphaDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadAlphaDataToBGRASSE2(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadAlphaFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadLuminanceDataToNativeOrBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output, bool native); - static void loadLuminanceFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadLuminanceFloatDataToRGB(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadLuminanceHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadLuminanceAlphaDataToNativeOrBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output, bool native); - static void loadLuminanceAlphaFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadLuminanceAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBUByteDataToBGRX(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBUByteDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGB565DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGB565DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBFloatDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBAUByteDataToBGRASSE2(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBAUByteDataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBAUByteDataToNative(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBA4444DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBA4444DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBA5551DataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBA5551DataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBAFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadRGBAHalfFloatDataToRGBA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); - static void loadBGRADataToBGRA(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output); + virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; protected: GLsizei mWidth; GLsizei mHeight; - GLint mInternalFormat; + GLsizei mDepth; + GLenum mInternalFormat; GLenum mActualFormat; + bool mRenderable; + GLenum mTarget; bool mDirty; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Image11.cpp deleted file mode 100644 index 09c8922d073..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image11.cpp +++ /dev/null @@ -1,457 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// Image11.h: Implements the rx::Image11 class, which acts as the interface to -// the actual underlying resources of a Texture - -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/Image11.h" -#include "libGLESv2/renderer/TextureStorage11.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" - -#include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/generatemip.h" - -namespace rx -{ - -Image11::Image11() -{ - mStagingTexture = NULL; - mRenderer = NULL; - mDXGIFormat = DXGI_FORMAT_UNKNOWN; -} - -Image11::~Image11() -{ - if (mStagingTexture) - { - mStagingTexture->Release(); - } -} - -Image11 *Image11::makeImage11(Image *img) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); - return static_cast<rx::Image11*>(img); -} - -void Image11::generateMipmap(Image11 *dest, Image11 *src) -{ - ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); - ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); - ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); - - D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped; - dest->map(D3D11_MAP_WRITE, &destMapped); - src->map(D3D11_MAP_READ, &srcMapped); - - const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData); - unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData); - - if (sourceData && destData) - { - switch (src->getDXGIFormat()) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - GenerateMip<R8G8B8A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_A8_UNORM: - GenerateMip<A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R8_UNORM: - GenerateMip<R8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - GenerateMip<A32B32G32R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32B32_FLOAT: - GenerateMip<R32G32B32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - GenerateMip<A16B16G16R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R8G8_UNORM: - GenerateMip<R8G8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16_FLOAT: - GenerateMip<R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16G16_FLOAT: - GenerateMip<R16G16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32_FLOAT: - GenerateMip<R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32_FLOAT: - GenerateMip<R32G32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - default: - UNREACHABLE(); - break; - } - - dest->unmap(); - src->unmap(); - } - - dest->markDirty(); -} - -bool Image11::isDirty() const -{ - return (mStagingTexture && mDirty); -} - -bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height); -} - -bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height); -} - -bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) -{ - if (mWidth != width || - mHeight != height || - mInternalFormat != internalformat || - forceRelease) - { - mRenderer = Renderer11::makeRenderer11(renderer); - - mWidth = width; - mHeight = height; - mInternalFormat = internalformat; - // compute the d3d format that will be used - mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat); - - if (mStagingTexture) - { - mStagingTexture->Release(); - mStagingTexture = NULL; - } - - return true; - } - - return false; -} - -bool Image11::isRenderableFormat() const -{ - return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat); -} - -DXGI_FORMAT Image11::getDXGIFormat() const -{ - // this should only happen if the image hasn't been redefined first - // which would be a bug by the caller - ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN); - - return mDXGIFormat; -} - -// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input -// into the target pixel rectangle. -void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input) -{ - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) - { - ERR("Could not map image for loading."); - return; - } - - GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); - size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8; - void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize)); - - switch (mInternalFormat) - { - case GL_ALPHA8_EXT: - loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE8_EXT: - loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); - break; - case GL_ALPHA32F_EXT: - loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE32F_EXT: - loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_ALPHA16F_EXT: - loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE16F_EXT: - loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE8_ALPHA8_EXT: - loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); - break; - case GL_LUMINANCE_ALPHA32F_EXT: - loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE_ALPHA16F_EXT: - loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB8_OES: - loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB565: - loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA8_OES: - loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA4: - loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB5_A1: - loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_BGRA8_EXT: - loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB32F_EXT: - loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB16F_EXT: - loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA32F_EXT: - loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA16F_EXT: - loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - default: UNREACHABLE(); - } - - unmap(); -} - -void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - const void *input) -{ - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); - - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) - { - ERR("Could not map image for loading."); - return; - } - - // Size computation assumes a 4x4 block compressed texture format - size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8; - void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize)); - - GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); - GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); - int rows = inputSize / inputPitch; - for (int i = 0; i < rows; ++i) - { - memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); - } - - unmap(); -} - -void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) -{ - gl::Renderbuffer *colorbuffer = source->getReadColorbuffer(); - - if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat) - { - // No conversion needed-- use copyback fastpath - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; - - if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) - { - D3D11_TEXTURE2D_DESC textureDesc; - colorBufferTexture->GetDesc(&textureDesc); - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); - if (FAILED(result)) - { - ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); - return; - } - - deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); - subresourceIndex = 0; - } - else - { - srcTex = colorBufferTexture; - srcTex->AddRef(); - } - - D3D11_BOX srcBox; - srcBox.left = x; - srcBox.right = x + width; - srcBox.top = y; - srcBox.bottom = y + height; - srcBox.front = 0; - srcBox.back = 1; - - deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox); - - srcTex->Release(); - colorBufferTexture->Release(); - } - } - else - { - // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - - // determine the offset coordinate into the destination buffer - GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset; - void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset; - - mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), - gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset); - - unmap(); - } -} - -ID3D11Texture2D *Image11::getStagingTexture() -{ - createStagingTexture(); - - return mStagingTexture; -} - -unsigned int Image11::getStagingSubresource() -{ - createStagingTexture(); - - return mStagingSubresource; -} - -void Image11::createStagingTexture() -{ - if (mStagingTexture) - { - return; - } - - ID3D11Texture2D *newTexture = NULL; - int lodOffset = 1; - const DXGI_FORMAT dxgiFormat = getDXGIFormat(); - ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures - - if (mWidth != 0 && mHeight != 0) - { - GLsizei width = mWidth; - GLsizei height = mHeight; - - // adjust size if needed for compressed textures - gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset); - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = lodOffset + 1; - desc.ArraySize = 1; - desc.Format = dxgiFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); - mDirty = false; -} - -HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) -{ - createStagingTexture(); - - HRESULT result = E_FAIL; - - if (mStagingTexture) - { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); - - // this can fail if the device is removed (from TDR) - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - } - else if (SUCCEEDED(result)) - { - mDirty = true; - } - } - - return result; -} - -void Image11::unmap() -{ - if (mStagingTexture) - { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - deviceContext->Unmap(mStagingTexture, mStagingSubresource); - } -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ImageSSE2.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/ImageSSE2.cpp deleted file mode 100644 index b2a90ca9611..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ImageSSE2.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// ImageSSE2.cpp: Implements SSE2-based functions of rx::Image class. It's -// in a separated file for GCC, which can enable SSE usage only per-file, -// not for code blocks that use SSE2 explicitly. - -#include "libGLESv2/Texture.h" -#include "libGLESv2/renderer/Image.h" - -namespace rx -{ - -void Image::loadRGBAUByteDataToBGRASSE2(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned int *source = NULL; - unsigned int *dest = NULL; - __m128i brMask = _mm_set1_epi32(0x00ff00ff); - - for (int y = 0; y < height; y++) - { - source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); - int x = 0; - - // Make output writes aligned - for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++) - { - unsigned int rgba = source[x]; - dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - - for (; x + 3 < width; x += 4) - { - __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x])); - // Mask out g and a, which don't change - __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); - // Mask out b and r - __m128i brComponents = _mm_and_si128(sourceData, brMask); - // Swap b and r - __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); - __m128i result = _mm_or_si128(gaComponents, brSwapped); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result); - } - - // Perform leftover writes - for (; x < width; x++) - { - unsigned int rgba = source[x]; - dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } -} - -void Image::loadAlphaDataToBGRASSE2(GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) -{ - const unsigned char *source = NULL; - unsigned int *dest = NULL; - __m128i zeroWide = _mm_setzero_si128(); - - for (int y = 0; y < height; y++) - { - source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); - - int x; - // Make output writes aligned - for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++) - { - dest[x] = static_cast<unsigned int>(source[x]) << 24; - } - - for (; x + 7 < width; x += 8) - { - __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x])); - // Interleave each byte to 16bit, make the lower byte to zero - sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); - // Interleave each 16bit to 32bit, make the lower 16bit to zero - __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); - __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); - - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi); - } - - // Handle the remainder - for (; x < width; x++) - { - dest[x] = static_cast<unsigned int>(source[x]) << 24; - } - } -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer.cpp index 37dbd3e1952..7fe2a3abe7c 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer.cpp @@ -194,4 +194,3 @@ IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() } } - diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexDataManager.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/IndexDataManager.cpp index 49bace81932..b8c7fa977c0 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexDataManager.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/IndexDataManager.cpp @@ -13,7 +13,7 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/IndexBuffer.h" namespace rx @@ -138,7 +138,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer default: UNREACHABLE(); alignedOffset = false; } - unsigned int typeSize = gl::ComputeTypeSize(type); + unsigned int typeSize = gl::GetTypeBytes(type); // check for integer overflows if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeSize) || @@ -167,7 +167,6 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer { indexBuffer = streamingBuffer; streamOffset = offset; - storage->markBufferUsage(); if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, &translated->maxIndex, NULL)) @@ -180,10 +179,11 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset) { indexBuffer = staticBuffer; + if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, &translated->maxIndex, &streamOffset)) { - streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType); + streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType); computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, translated->maxIndex, streamOffset); @@ -198,7 +198,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer if (staticBuffer->getBufferSize() == 0 && alignedOffset) { indexBuffer = staticBuffer; - convertCount = storage->getSize() / gl::ComputeTypeSize(type); + convertCount = storage->getSize() / gl::GetTypeBytes(type); } else { @@ -213,7 +213,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer return GL_INVALID_OPERATION; } - unsigned int indexTypeSize = gl::ComputeTypeSize(destinationIndexType); + unsigned int indexTypeSize = gl::GetTypeBytes(destinationIndexType); if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize) { ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize); @@ -246,7 +246,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer if (staticBuffer) { - streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType); + streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType); staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, translated->maxIndex, streamOffset); } @@ -255,12 +255,12 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer translated->storage = directStorage ? storage : NULL; translated->indexBuffer = indexBuffer->getIndexBuffer(); translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial(); - translated->startIndex = streamOffset / gl::ComputeTypeSize(destinationIndexType); + translated->startIndex = streamOffset / gl::GetTypeBytes(destinationIndexType); translated->startOffset = streamOffset; if (buffer) { - buffer->promoteStaticUsage(count * gl::ComputeTypeSize(type)); + buffer->promoteStaticUsage(count * gl::GetTypeBytes(type)); } return GL_NO_ERROR; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.cpp index 610a5efb9c4..14410d0245e 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -9,8 +9,8 @@ // ranges of indices. #include "libGLESv2/renderer/IndexRangeCache.h" +#include "libGLESv2/formatutils.h" #include "common/debug.h" -#include "libGLESv2/utilities.h" #include <tuple> namespace rx @@ -31,7 +31,7 @@ void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size) while (i != mIndexRangeCache.end()) { unsigned int rangeStart = i->second.streamOffset; - unsigned int rangeEnd = i->second.streamOffset + (gl::ComputeTypeSize(i->first.type) * i->first.count); + unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeBytes(i->first.type) * i->first.count); if (invalidateEnd < rangeStart || invalidateStart > rangeEnd) { diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.h b/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.h index 56834306f22..4318e2b7a43 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/IndexRangeCache.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_ #include "common/angleutils.h" +#include <map> namespace rx { diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Query11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Query11.cpp deleted file mode 100644 index 13210fc9291..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Query11.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. - -#include "libGLESv2/renderer/Query11.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Query11::~Query11() -{ - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } -} - -void Query11::begin() -{ - if (mQuery == NULL) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_OCCLUSION; - queryDesc.MiscFlags = 0; - - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mRenderer->getDeviceContext()->Begin(mQuery); -} - -void Query11::end() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - mRenderer->getDeviceContext()->End(mQuery); - - mStatus = GL_FALSE; - mResult = GL_FALSE; -} - -GLuint Query11::getResult() -{ - if (mQuery != NULL) - { - while (!testQuery()) - { - Sleep(0); - // explicitly check for device loss, some drivers seem to return S_FALSE - // if the device is lost - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } - } - } - - return mResult; -} - -GLboolean Query11::isResultAvailable() -{ - if (mQuery != NULL) - { - testQuery(); - } - - return mStatus; -} - -GLboolean Query11::testQuery() -{ - if (mQuery != NULL && mStatus != GL_TRUE) - { - UINT64 numPixels = 0; - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, &numPixels, sizeof(UINT64), 0); - if (result == S_OK) - { - mStatus = GL_TRUE; - - switch (getType()) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; - break; - default: - UNREACHABLE(); - } - } - else if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - return mStatus; - } - - return GL_TRUE; // prevent blocking when query is null -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/QueryImpl.h b/chromium/third_party/angle/src/libGLESv2/renderer/QueryImpl.h index a874047b0c2..a6750a204b7 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/QueryImpl.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/QueryImpl.h @@ -24,6 +24,7 @@ class QueryImpl virtual void end() = 0; virtual GLuint getResult() = 0; virtual GLboolean isResultAvailable() = 0; + virtual bool isStarted() const = 0; GLenum getType() const { return mType; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget.h b/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget.h index 80de39f4f76..44637ec7de9 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_RENDERTARGET_H_ #include "common/angleutils.h" +#include "libGLESv2/angletypes.h" namespace rx { @@ -21,6 +22,7 @@ class RenderTarget { mWidth = 0; mHeight = 0; + mDepth = 0; mInternalFormat = GL_NONE; mActualFormat = GL_NONE; mSamples = 0; @@ -28,21 +30,27 @@ class RenderTarget virtual ~RenderTarget() {}; - GLsizei getWidth() { return mWidth; } - GLsizei getHeight() { return mHeight; } - GLenum getInternalFormat() { return mInternalFormat; } - GLenum getActualFormat() { return mActualFormat; } - GLsizei getSamples() { return mSamples; } - + GLsizei getWidth() const { return mWidth; } + GLsizei getHeight() const { return mHeight; } + GLsizei getDepth() const { return mDepth; } + GLenum getInternalFormat() const { return mInternalFormat; } + GLenum getActualFormat() const { return mActualFormat; } + GLsizei getSamples() const { return mSamples; } + gl::Extents getExtents() const { return gl::Extents(mWidth, mHeight, mDepth); } + + virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) = 0; + struct Desc { GLsizei width; GLsizei height; + GLsizei depth; GLenum format; }; protected: GLsizei mWidth; GLsizei mHeight; + GLsizei mDepth; GLenum mInternalFormat; GLenum mActualFormat; GLsizei mSamples; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget9.cpp deleted file mode 100644 index a84c7090599..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget9.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9 -// pointers retained by renderbuffers. - -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/Renderer9.h" - -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) -{ - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = surface; - - if (mRenderTarget) - { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - mWidth = description.Width; - mHeight = description.Height; - - mInternalFormat = d3d9_gl::GetEquivalentFormat(description.Format); - mActualFormat = d3d9_gl::GetEquivalentFormat(description.Format); - mSamples = d3d9_gl::GetSamplesFromMultisampleType(description.MultiSampleType); - } -} - -RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples) -{ - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = NULL; - - D3DFORMAT requestedFormat = gl_d3d9::ConvertRenderbufferFormat(format); - int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); - - if (supportedSamples == -1) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } - - HRESULT result = D3DERR_INVALIDCALL; - - if (width > 0 && height > 0) - { - if (requestedFormat == D3DFMT_D24S8) - { - result = mRenderer->getDevice()->CreateDepthStencilSurface(width, height, requestedFormat, - gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - else - { - result = mRenderer->getDevice()->CreateRenderTarget(width, height, requestedFormat, - gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } - - ASSERT(SUCCEEDED(result)); - } - - mWidth = width; - mHeight = height; - mInternalFormat = format; - mSamples = supportedSamples; - mActualFormat = d3d9_gl::GetEquivalentFormat(requestedFormat); -} - -RenderTarget9::~RenderTarget9() -{ - if (mRenderTarget) - { - mRenderTarget->Release(); - } -} - -RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target)); - return static_cast<rx::RenderTarget9*>(target); -} - -IDirect3DSurface9 *RenderTarget9::getSurface() -{ - // Caller is responsible for releasing the returned surface reference. - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - - return mRenderTarget; -} - -}
\ No newline at end of file diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.cpp index e0b3abcf879..92594a4d566 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.cpp @@ -11,14 +11,21 @@ #include "libGLESv2/main.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" #include "third_party/trace_event/trace_event.h" +#include "libGLESv2/Shader.h" -#if !defined(ANGLE_ENABLE_D3D11) +#if defined (ANGLE_ENABLE_D3D9) +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#endif // ANGLE_ENABLE_D3D9 + +#if defined (ANGLE_ENABLE_D3D11) +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#endif // ANGLE_ENABLE_D3D11 + +#if !defined(ANGLE_DEFAULT_D3D11) // Enables use of the Direct3D 11 API for a default display, when available -#define ANGLE_ENABLE_D3D11 0 +#define ANGLE_DEFAULT_D3D11 0 #endif namespace rx @@ -26,145 +33,12 @@ namespace rx Renderer::Renderer(egl::Display *display) : mDisplay(display) { - mD3dCompilerModule = NULL; - mD3DCompileFunc = NULL; + mCurrentClientVersion = 2; } Renderer::~Renderer() { - if (mD3dCompilerModule) - { - FreeLibrary(mD3dCompilerModule); - mD3dCompilerModule = NULL; - } -} - -bool Renderer::initializeCompiler() -{ - TRACE_EVENT0("gpu", "initializeCompiler"); -#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) - // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. - static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; - - for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) - { - if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule)) - { - break; - } - } -#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES - - if (!mD3dCompilerModule) - { - // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. - mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL); - } - - if (!mD3dCompilerModule) - { - ERR("No D3D compiler module found - aborting!\n"); - return false; - } - - mD3DCompileFunc = reinterpret_cast<pCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile")); - ASSERT(mD3DCompileFunc); - - return mD3DCompileFunc != NULL; -} - -// Compiles HLSL code into executable binaries -ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags) -{ - if (!hlsl) - { - return NULL; - } - - HRESULT result = S_OK; - UINT flags = 0; - std::string sourceText; - if (gl::perfActive()) - { - flags |= D3DCOMPILE_DEBUG; - -#ifdef NDEBUG - flags |= optimizationFlags; -#else - flags |= D3DCOMPILE_SKIP_OPTIMIZATION; -#endif - - std::string sourcePath = getTempPath(); - sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); - } - else - { - flags |= optimizationFlags; - sourceText = hlsl; - } - - // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. - // Try the default flags first and if compilation fails, try some alternatives. - const static UINT extraFlags[] = - { - 0, - D3DCOMPILE_AVOID_FLOW_CONTROL, - D3DCOMPILE_PREFER_FLOW_CONTROL - }; - - const static char * const extraFlagNames[] = - { - "default", - "avoid flow control", - "prefer flow control" - }; - - int attempts = alternateFlags ? ArraySize(extraFlags) : 1; - pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); - for (int i = 0; i < attempts; ++i) - { - ID3DBlob *errorMessage = NULL; - ID3DBlob *binary = NULL; - - result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, - "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage); - if (errorMessage) - { - const char *message = (const char*)errorMessage->GetBufferPointer(); - - infoLog.appendSanitized(message); - TRACE("\n%s", hlsl); - TRACE("\n%s", message); - - errorMessage->Release(); - errorMessage = NULL; - } - - if (SUCCEEDED(result)) - { - return (ShaderBlob*)binary; - } - else - { - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL); - } - - infoLog.append("Warning: D3D shader compilation failed with "); - infoLog.append(extraFlagNames[i]); - infoLog.append(" flags."); - if (i + 1 < attempts) - { - infoLog.append(" Retrying with "); - infoLog.append(extraFlagNames[i + 1]); - infoLog.append(".\n"); - } - } - } - - return NULL; + gl::Shader::releaseCompiler(); } } @@ -174,45 +48,38 @@ extern "C" rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId) { - rx::Renderer *renderer = NULL; - EGLint status = EGL_BAD_ALLOC; - - if (ANGLE_ENABLE_D3D11 || +#if defined(ANGLE_ENABLE_D3D11) + if (ANGLE_DEFAULT_D3D11 || displayId == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) { - renderer = new rx::Renderer11(display, hDc); - - if (renderer) - { - status = renderer->initialize(); - } - - if (status == EGL_SUCCESS) + rx::Renderer11 *renderer = new rx::Renderer11(display, hDc); + if (renderer->initialize() == EGL_SUCCESS) { return renderer; } - else if (displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) + else { - return NULL; + // Failed to create a D3D11 renderer, try D3D9 + SafeDelete(renderer); } - - // Failed to create a D3D11 renderer, try creating a D3D9 renderer - delete renderer; - } - - bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); - renderer = new rx::Renderer9(display, hDc, softwareDevice); - - if (renderer) - { - status = renderer->initialize(); } +#endif - if (status == EGL_SUCCESS) +#if defined(ANGLE_ENABLE_D3D9) + if (displayId != EGL_D3D11_ONLY_DISPLAY_ANGLE) { - return renderer; + rx::Renderer9 *renderer = new rx::Renderer9(display, hDc); + if (renderer->initialize() == EGL_SUCCESS) + { + return renderer; + } + else + { + SafeDelete(renderer); + } } +#endif return NULL; } @@ -222,4 +89,4 @@ void glDestroyRenderer(rx::Renderer *renderer) delete renderer; } -}
\ No newline at end of file +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.h b/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.h index e1861f01eb1..b2a05d92d2c 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/Renderer.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -14,22 +14,11 @@ #include "libGLESv2/angletypes.h" #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) -#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang. +// It should only be used selectively to work around specific bugs. +#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1 #endif -const int versionWindowsVista = MAKEWORD(0x00, 0x06); -const int versionWindows7 = MAKEWORD(0x01, 0x06); - -// Return the version of the operating system in a format suitable for ordering -// comparison. -inline int getComparableOSVersion() -{ - DWORD version = GetVersion(); - int majorVersion = LOBYTE(LOWORD(version)); - int minorVersion = HIBYTE(LOWORD(version)); - return MAKEWORD(minorVersion, majorVersion); -} - namespace egl { class Display; @@ -39,31 +28,32 @@ namespace gl { class InfoLog; class ProgramBinary; +struct LinkedVarying; class VertexAttribute; class Buffer; class Texture; class Framebuffer; +struct VertexAttribCurrentValueData; } namespace rx { class TextureStorageInterface2D; class TextureStorageInterfaceCube; +class TextureStorageInterface3D; +class TextureStorageInterface2DArray; class VertexBuffer; class IndexBuffer; class QueryImpl; class FenceImpl; class BufferStorage; -class Blit; struct TranslatedIndexData; class ShaderExecutable; class SwapChain; class RenderTarget; class Image; class TextureStorage; - -typedef void * ShaderBlob; -typedef void (*pCompileFunc)(); +class UniformStorage; struct ConfigDesc { @@ -71,6 +61,7 @@ struct ConfigDesc GLenum depthStencilFormat; GLint multiSample; bool fastConfig; + bool es3Capable; }; struct dx_VertexConstants @@ -93,12 +84,6 @@ enum ShaderType SHADER_GEOMETRY }; -enum D3DWorkaroundType -{ - ANGLE_D3D_WORKAROUND_NONE, - ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER -}; - class Renderer { public: @@ -115,11 +100,14 @@ class Renderer virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; + virtual void generateSwizzle(gl::Texture *texture) = 0; virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; + virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; + virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0; - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) = 0; virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW) = 0; @@ -129,14 +117,17 @@ class Renderer bool ignoreViewport) = 0; virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; - virtual void applyShaders(gl::ProgramBinary *programBinary) = 0; - virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0; + virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]) = 0; + virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0; + virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) = 0; virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; + virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0; - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0; - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; + virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; + virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0; @@ -154,14 +145,20 @@ class Renderer virtual GUID getAdapterIdentifier() const = 0; virtual bool getBGRATextureSupport() const = 0; - virtual bool getDXT1TextureSupport() = 0; - virtual bool getDXT3TextureSupport() = 0; - virtual bool getDXT5TextureSupport() = 0; - virtual bool getEventQuerySupport() = 0; - virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable) = 0; - virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable) = 0; - virtual bool getLuminanceTextureSupport() = 0; - virtual bool getLuminanceAlphaTextureSupport() = 0; + virtual bool getDXT1TextureSupport() const = 0; + virtual bool getDXT3TextureSupport() const = 0; + virtual bool getDXT5TextureSupport() const = 0; + virtual bool getEventQuerySupport() const = 0; + virtual bool getFloat32TextureSupport() const = 0; + virtual bool getFloat32TextureFilteringSupport() const= 0; + virtual bool getFloat32TextureRenderingSupport() const= 0; + virtual bool getFloat16TextureSupport() const= 0; + virtual bool getFloat16TextureFilteringSupport() const= 0; + virtual bool getFloat16TextureRenderingSupport() const = 0; + virtual bool getRGB565TextureSupport() const = 0; + virtual bool getLuminanceTextureSupport() const = 0; + virtual bool getLuminanceAlphaTextureSupport() const = 0; + virtual bool getRGTextureSupport() const = 0; bool getVertexTextureSupport() const { return getMaxVertexTextureImageUnits() > 0; } virtual unsigned int getMaxVertexTextureImageUnits() const = 0; virtual unsigned int getMaxCombinedTextureImageUnits() const = 0; @@ -170,57 +167,86 @@ class Renderer virtual unsigned int getMaxVertexUniformVectors() const = 0; virtual unsigned int getMaxFragmentUniformVectors() const = 0; virtual unsigned int getMaxVaryingVectors() const = 0; + virtual unsigned int getMaxVertexShaderUniformBuffers() const = 0; + virtual unsigned int getMaxFragmentShaderUniformBuffers() const = 0; + virtual unsigned int getReservedVertexUniformBuffers() const = 0; + virtual unsigned int getReservedFragmentUniformBuffers() const = 0; + virtual unsigned int getMaxTransformFeedbackBuffers() const = 0; + virtual unsigned int getMaxTransformFeedbackSeparateComponents() const = 0; + virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const = 0; + virtual unsigned int getMaxUniformBufferSize() const = 0; virtual bool getNonPower2TextureSupport() const = 0; virtual bool getDepthTextureSupport() const = 0; virtual bool getOcclusionQuerySupport() const = 0; virtual bool getInstancingSupport() const = 0; virtual bool getTextureFilterAnisotropySupport() const = 0; + virtual bool getPBOSupport() const = 0; virtual float getTextureMaxAnisotropy() const = 0; virtual bool getShareHandleSupport() const = 0; virtual bool getDerivativeInstructionSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0; + virtual int getMaxRecommendedElementsIndices() const = 0; + virtual int getMaxRecommendedElementsVertices() const = 0; virtual int getMajorShaderModel() const = 0; virtual float getMaxPointSize() const = 0; virtual int getMaxViewportDimension() const = 0; virtual int getMaxTextureWidth() const = 0; virtual int getMaxTextureHeight() const = 0; + virtual int getMaxTextureDepth() const = 0; + virtual int getMaxTextureArrayLayers() const = 0; virtual bool get32BitIndexSupport() const = 0; virtual int getMinSwapInterval() const = 0; virtual int getMaxSwapInterval() const = 0; virtual GLsizei getMaxSupportedSamples() const = 0; + virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const = 0; + virtual GLsizei getNumSampleCounts(GLenum internalFormat) const = 0; + virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const = 0; virtual unsigned int getMaxRenderTargets() const = 0; // Pixel operations virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) = 0; virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) = 0; + virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) = 0; + virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) = 0; virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) = 0; virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) = 0; + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) = 0; + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) = 0; virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil) = 0; - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0; + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) = 0; + virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) = 0; // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0; - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) = 0; + virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0; // Shader operations - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type) = 0; - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) = 0; + virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers) = 0; + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround) = 0; + virtual UniformStorage *createUniformStorage(size_t storageSize) = 0; // Image operations virtual Image *createImage() = 0; virtual void generateMipmap(Image *dest, Image *source) = 0; virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0; - virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) = 0; - virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) = 0; + virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0; + virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0; + virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; + virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; // Buffer creation virtual VertexBuffer *createVertexBuffer() = 0; @@ -231,19 +257,27 @@ class Renderer virtual QueryImpl *createQuery(GLenum type) = 0; virtual FenceImpl *createFence() = 0; + // Current GLES client version + void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; } + int getCurrentClientVersion() const { return mCurrentClientVersion; } + + // Buffer-to-texture and Texture-to-buffer copies + virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; + virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; + virtual bool getLUID(LUID *adapterLuid) const = 0; + virtual GLenum getNativeTextureFormat(GLenum internalFormat) const = 0; + virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0; + virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0; protected: - bool initializeCompiler(); - ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags); - egl::Display *mDisplay; private: DISALLOW_COPY_AND_ASSIGN(Renderer); - HMODULE mD3dCompilerModule; - pCompileFunc mD3DCompileFunc; + int mCurrentClientVersion; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable.h b/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable.h index 293e340845e..5e229d7d5e8 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_ #include "common/angleutils.h" +#include "common/debug.h" namespace rx { @@ -46,6 +47,22 @@ class ShaderExecutable const size_t mLength; }; +class UniformStorage +{ + public: + UniformStorage(size_t initialSize) + : mSize(initialSize) + { + } + + virtual ~UniformStorage() {} + + size_t size() const { return mSize; } + + private: + size_t mSize; +}; + } #endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.cpp index 00b316f1cc5..650f368a1d8 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -15,6 +15,7 @@ #include "libGLESv2/Texture.h" #include "common/debug.h" +#include "common/mathutil.h" namespace rx { @@ -36,7 +37,6 @@ bool TextureStorageInterface::isRenderTarget() const return mInstance->isRenderTarget(); } - bool TextureStorageInterface::isManaged() const { return mInstance->isManaged(); @@ -52,36 +52,36 @@ unsigned int TextureStorageInterface::issueTextureSerial() return mCurrentTextureSerial++; } -int TextureStorageInterface::getLodOffset() const +int TextureStorageInterface::getTopLevel() const { - return mInstance->getLodOffset(); + return mInstance->getTopLevel(); } - -int TextureStorageInterface::levelCount() +int TextureStorageInterface::getLevelCount() const { - return mInstance->levelCount(); + return mInstance->getLevelCount(); } -TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain) - : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial()) +TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain) { + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(1); + mInstance = renderer->createTextureStorage2D(swapchain); } -TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) - : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial()) +TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) { - mInstance = renderer->createTextureStorage2D(levels, internalformat, usage, forceRenderable, width, height); + mInstance = renderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels); + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount())); } TextureStorageInterface2D::~TextureStorageInterface2D() { } -RenderTarget *TextureStorageInterface2D::getRenderTarget() const +RenderTarget *TextureStorageInterface2D::getRenderTarget(GLint level) const { - return mInstance->getRenderTarget(); + return mInstance->getRenderTarget(level); } void TextureStorageInterface2D::generateMipmap(int level) @@ -89,34 +89,92 @@ void TextureStorageInterface2D::generateMipmap(int level) mInstance->generateMipmap(level); } -unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLenum target) const +unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLint level) const { - return mRenderTargetSerial; + return mFirstRenderTargetSerial + level; } -TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) - : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials()) +TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) { - mInstance = renderer->createTextureStorageCube(levels, internalformat, usage, forceRenderable, size); + mInstance = renderer->createTextureStorageCube(internalformat, renderTarget, size, levels); + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * 6)); } TextureStorageInterfaceCube::~TextureStorageInterfaceCube() { } -RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget) const +RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget, GLint level) const +{ + return mInstance->getRenderTargetFace(faceTarget, level); +} + +void TextureStorageInterfaceCube::generateMipmap(int faceIndex, int level) +{ + mInstance->generateMipmap(faceIndex, level); +} + +unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target, GLint level) const +{ + return mFirstRenderTargetSerial + (level * 6) + gl::TextureCubeMap::targetToIndex(target); +} + +TextureStorageInterface3D::TextureStorageInterface3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels) +{ + + mInstance = renderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels); + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * depth)); +} + +TextureStorageInterface3D::~TextureStorageInterface3D() +{ +} + +void TextureStorageInterface3D::generateMipmap(int level) +{ + mInstance->generateMipmap(level); +} + +RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level) const +{ + return mInstance->getRenderTarget(level); +} + +RenderTarget *TextureStorageInterface3D::getRenderTarget(GLint level, GLint layer) const +{ + return mInstance->getRenderTargetLayer(level, layer); +} + +unsigned int TextureStorageInterface3D::getRenderTargetSerial(GLint level, GLint layer) const +{ + return mFirstRenderTargetSerial + static_cast<unsigned int>((layer * mInstance->getLevelCount()) + level); +} + +TextureStorageInterface2DArray::TextureStorageInterface2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels) +{ + mInstance = renderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels); + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * depth)); +} + +TextureStorageInterface2DArray::~TextureStorageInterface2DArray() { - return mInstance->getRenderTarget(faceTarget); } -void TextureStorageInterfaceCube::generateMipmap(int face, int level) +void TextureStorageInterface2DArray::generateMipmap(int level) { - mInstance->generateMipmap(face, level); + mInstance->generateMipmap(level); } -unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target) const +RenderTarget *TextureStorageInterface2DArray::getRenderTarget(GLint level, GLint layer) const { - return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target); + return mInstance->getRenderTargetLayer(level, layer); } -}
\ No newline at end of file +unsigned int TextureStorageInterface2DArray::getRenderTargetSerial(GLint level, GLint layer) const +{ + return mFirstRenderTargetSerial + static_cast<unsigned int>((layer * mInstance->getLevelCount()) + level); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.h b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.h index edddb75f3fc..0a212e16f27 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -18,7 +18,6 @@ namespace rx class Renderer; class SwapChain; class RenderTarget; -class Blit; class TextureStorage { @@ -26,13 +25,14 @@ class TextureStorage TextureStorage() {}; virtual ~TextureStorage() {}; - virtual int getLodOffset() const = 0; + virtual int getTopLevel() const = 0; virtual bool isRenderTarget() const = 0; virtual bool isManaged() const = 0; - virtual int levelCount() = 0; + virtual int getLevelCount() const = 0; - virtual RenderTarget *getRenderTarget() = 0; - virtual RenderTarget *getRenderTarget(GLenum faceTarget) = 0; + virtual RenderTarget *getRenderTarget(int level) = 0; + virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) = 0; + virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) = 0; virtual void generateMipmap(int level) = 0; virtual void generateMipmap(int face, int level) = 0; @@ -50,12 +50,11 @@ class TextureStorageInterface TextureStorage *getStorageInstance() { return mInstance; } unsigned int getTextureSerial() const; - virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; - virtual int getLodOffset() const; + virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; - virtual int levelCount(); + virtual int getLevelCount() const; protected: TextureStorage *mInstance; @@ -73,38 +72,74 @@ class TextureStorageInterface2D : public TextureStorageInterface { public: TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain); - TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorageInterface2D(); void generateMipmap(int level); - RenderTarget *getRenderTarget() const; + RenderTarget *getRenderTarget(GLint level) const; - virtual unsigned int getRenderTargetSerial(GLenum target) const; + unsigned int getRenderTargetSerial(GLint level) const; private: DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2D); - const unsigned int mRenderTargetSerial; + unsigned int mFirstRenderTargetSerial; }; class TextureStorageInterfaceCube : public TextureStorageInterface { public: - TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); virtual ~TextureStorageInterfaceCube(); - void generateMipmap(int face, int level); - RenderTarget *getRenderTarget(GLenum faceTarget) const; + void generateMipmap(int faceIndex, int level); + RenderTarget *getRenderTarget(GLenum faceTarget, GLint level) const; - virtual unsigned int getRenderTargetSerial(GLenum target) const; + virtual unsigned int getRenderTargetSerial(GLenum target, GLint level) const; private: DISALLOW_COPY_AND_ASSIGN(TextureStorageInterfaceCube); - const unsigned int mFirstRenderTargetSerial; + unsigned int mFirstRenderTargetSerial; +}; + +class TextureStorageInterface3D : public TextureStorageInterface +{ + public: + TextureStorageInterface3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual ~TextureStorageInterface3D(); + + void generateMipmap(int level); + RenderTarget *getRenderTarget(GLint level) const; + RenderTarget *getRenderTarget(GLint level, GLint layer) const; + + virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface3D); + + unsigned int mFirstRenderTargetSerial; +}; + +class TextureStorageInterface2DArray : public TextureStorageInterface +{ + public: + TextureStorageInterface2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual ~TextureStorageInterface2DArray(); + + void generateMipmap(int level); + RenderTarget *getRenderTarget(GLint level, GLint layer) const; + + virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2DArray); + + unsigned int mFirstRenderTargetSerial; }; } #endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_ - diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.cpp deleted file mode 100644 index 41515ed7696..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.cpp +++ /dev/null @@ -1,667 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived -// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. - -#include "libGLESv2/renderer/TextureStorage11.h" - -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/SwapChain11.h" -#include "libGLESv2/renderer/renderer11_utils.h" - -#include "libGLESv2/utilities.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) - : mBindFlags(bindFlags), - mLodOffset(0), - mMipLevels(0), - mTexture(NULL), - mTextureFormat(DXGI_FORMAT_UNKNOWN), - mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), - mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), - mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), - mSRV(NULL), - mTextureWidth(0), - mTextureHeight(0) -{ - mRenderer = Renderer11::makeRenderer11(renderer); -} - -TextureStorage11::~TextureStorage11() -{ -} - -TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage)); - return static_cast<TextureStorage11*>(storage); -} - -DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable) -{ - UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; - - if (d3d11::IsDepthStencilFormat(format)) - { - bindFlags |= D3D11_BIND_DEPTH_STENCIL; - } - else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) - { - bindFlags |= D3D11_BIND_RENDER_TARGET; - } - return bindFlags; -} - -bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format) -{ - switch(format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16G16_FLOAT: - return true; - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices - return false; - default: - UNREACHABLE(); - return false; - } -} - -UINT TextureStorage11::getBindFlags() const -{ - return mBindFlags; -} - -ID3D11Texture2D *TextureStorage11::getBaseTexture() const -{ - return mTexture; -} - -int TextureStorage11::getLodOffset() const -{ - return mLodOffset; -} - -bool TextureStorage11::isRenderTarget() const -{ - return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; -} - -bool TextureStorage11::isManaged() const -{ - return false; -} - -int TextureStorage11::levelCount() -{ - int levels = 0; - if (getBaseTexture()) - { - levels = mMipLevels - getLodOffset(); - } - return levels; -} - -UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex) -{ - UINT index = 0; - if (getBaseTexture()) - { - index = D3D11CalcSubresource(level, faceIndex, mMipLevels); - } - return index; -} - -bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource, - int level, int face, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height) -{ - if (srcTexture) - { - // Round up the width and height to the nearest multiple of dimension alignment - unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat); - width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment; - height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment; - - D3D11_BOX srcBox; - srcBox.left = xoffset; - srcBox.top = yoffset; - srcBox.right = xoffset + width; - srcBox.bottom = yoffset + height; - srcBox.front = 0; - srcBox.back = 1; - - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - ASSERT(getBaseTexture()); - context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face), - xoffset, yoffset, 0, srcTexture, sourceSubresource, &srcBox); - return true; - } - - return false; -} - -void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) -{ - if (source && dest) - { - ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); - - if (sourceSRV && destRTV) - { - gl::Rectangle sourceArea; - sourceArea.x = 0; - sourceArea.y = 0; - sourceArea.width = source->getWidth(); - sourceArea.height = source->getHeight(); - - gl::Rectangle destArea; - destArea.x = 0; - destArea.y = 0; - destArea.width = dest->getWidth(); - destArea.height = dest->getHeight(); - - mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(), - destRTV, destArea, dest->getWidth(), dest->getHeight(), - GL_RGBA); - } - } -} - -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) -{ - mTexture = swapchain->getOffscreenTexture(); - mSRV = swapchain->getRenderTargetShaderResource(); - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mRenderTarget[i] = NULL; - } - - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); - mMipLevels = texDesc.MipLevels; - mTextureFormat = texDesc.Format; - mTextureWidth = texDesc.Width; - mTextureHeight = texDesc.Height; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - mSRV->GetDesc(&srvDesc); - mShaderResourceFormat = srvDesc.Format; - - ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - offscreenRTV->GetDesc(&rtvDesc); - mRenderTargetFormat = rtvDesc.Format; - offscreenRTV->Release(); - - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; -} - -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) - : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable)) -{ - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mRenderTarget[i] = NULL; - } - - DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat); - if (d3d11::IsDepthStencilFormat(convertedFormat)) - { - mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); - mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); - mDepthStencilFormat = convertedFormat; - mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; - } - else - { - mTextureFormat = convertedFormat; - mShaderResourceFormat = convertedFormat; - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - mRenderTargetFormat = convertedFormat; - } - - // if the width or height is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (width > 0 && height > 0) - { - // adjust size if needed for compressed textures - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; // Compressed texture size constraints? - desc.Height = height; - desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - } - } -} - -TextureStorage11_2D::~TextureStorage11_2D() -{ - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mSRV) - { - mSRV->Release(); - mSRV = NULL; - } - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - delete mRenderTarget[i]; - mRenderTarget[i] = NULL; - } -} - -TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage)); - return static_cast<TextureStorage11_2D*>(storage); -} - -RenderTarget *TextureStorage11_2D::getRenderTarget(int level) -{ - if (level >= 0 && level < static_cast<int>(mMipLevels)) - { - if (!mRenderTarget[level]) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MostDetailedMip = level; - srvDesc.Texture2D.MipLevels = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = level; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = level; - dsvDesc.Flags = 0; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else - { - UNREACHABLE(); - } - } - - return mRenderTarget[level]; - } - else - { - return NULL; - } -} - -ID3D11ShaderResourceView *TextureStorage11_2D::getSRV() -{ - if (!mSRV) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); - srvDesc.Texture2D.MostDetailedMip = 0; - - HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - } - - return mSRV; -} - -void TextureStorage11_2D::generateMipmap(int level) -{ - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); - - generateMipmapLayer(source, dest); -} - -TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) - : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable)) -{ - for (unsigned int i = 0; i < 6; i++) - { - for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) - { - mRenderTarget[i][j] = NULL; - } - } - - DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat); - if (d3d11::IsDepthStencilFormat(convertedFormat)) - { - mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); - mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); - mDepthStencilFormat = convertedFormat; - mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; - } - else - { - mTextureFormat = convertedFormat; - mShaderResourceFormat = convertedFormat; - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - mRenderTargetFormat = convertedFormat; - } - - // if the size is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (size > 0) - { - // adjust size if needed for compressed textures - int height = size; - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = size; - desc.Height = size; - desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; - desc.ArraySize = 6; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - } - } -} - -TextureStorage11_Cube::~TextureStorage11_Cube() -{ - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mSRV) - { - mSRV->Release(); - mSRV = NULL; - } - - for (unsigned int i = 0; i < 6; i++) - { - for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) - { - delete mRenderTarget[i][j]; - mRenderTarget[i][j] = NULL; - } - } -} - -TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage)); - return static_cast<TextureStorage11_Cube*>(storage); -} - -RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level) -{ - unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget); - if (level >= 0 && level < static_cast<int>(mMipLevels)) - { - if (!mRenderTarget[faceIdx][level]) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube - srvDesc.Texture2DArray.MostDetailedMip = level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIdx; - srvDesc.Texture2DArray.ArraySize = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = level; - rtvDesc.Texture2DArray.FirstArraySlice = faceIdx; - rtvDesc.Texture2DArray.ArraySize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mRenderTargetFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Texture2DArray.MipSlice = level; - dsvDesc.Texture2DArray.FirstArraySlice = faceIdx; - dsvDesc.Texture2DArray.ArraySize = 1; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else - { - UNREACHABLE(); - } - } - - return mRenderTarget[faceIdx][level]; - } - else - { - return NULL; - } -} - -ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV() -{ - if (!mSRV) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); - srvDesc.TextureCube.MostDetailedMip = 0; - - HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL)); - } - ASSERT(SUCCEEDED(result)); - } - - return mSRV; -} - -void TextureStorage11_Cube::generateMipmap(int face, int level) -{ - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level)); - - generateMipmapLayer(source, dest); -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.h b/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.h deleted file mode 100644 index 3c5ded05b88..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage11.h +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived -// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. - -#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ -#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ - -#include "libGLESv2/Texture.h" -#include "libGLESv2/renderer/TextureStorage.h" - -namespace rx -{ -class RenderTarget; -class RenderTarget11; -class Renderer; -class Renderer11; -class SwapChain11; - -class TextureStorage11 : public TextureStorage -{ - public: - TextureStorage11(Renderer *renderer, UINT bindFlags); - virtual ~TextureStorage11(); - - static TextureStorage11 *makeTextureStorage11(TextureStorage *storage); - - static DWORD GetTextureBindFlags(DXGI_FORMAT d3dfmt, GLenum glusage, bool forceRenderable); - static bool IsTextureFormatRenderable(DXGI_FORMAT format); - - UINT getBindFlags() const; - - virtual ID3D11Texture2D *getBaseTexture() const; - virtual ID3D11ShaderResourceView *getSRV() = 0; - virtual RenderTarget *getRenderTarget() { return getRenderTarget(0); } - virtual RenderTarget *getRenderTarget(int level) { return NULL; } - virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return getRenderTarget(faceTarget, 0); } - virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level) { return NULL; } - - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; - - virtual int getLodOffset() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; - virtual int levelCount(); - UINT getSubresourceIndex(int level, int faceTarget); - - bool updateSubresourceLevel(ID3D11Texture2D *texture, unsigned int sourceSubresource, int level, - int faceTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - protected: - void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); - - Renderer11 *mRenderer; - int mLodOffset; - unsigned int mMipLevels; - - ID3D11Texture2D *mTexture; - DXGI_FORMAT mTextureFormat; - DXGI_FORMAT mShaderResourceFormat; - DXGI_FORMAT mRenderTargetFormat; - DXGI_FORMAT mDepthStencilFormat; - unsigned int mTextureWidth; - unsigned int mTextureHeight; - - ID3D11ShaderResourceView *mSRV; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11); - - const UINT mBindFlags; -}; - -class TextureStorage11_2D : public TextureStorage11 -{ - public: - TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); - TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual ~TextureStorage11_2D(); - - static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); - - virtual ID3D11ShaderResourceView *getSRV(); - virtual RenderTarget *getRenderTarget(int level); - - virtual void generateMipmap(int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); - - RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; -}; - -class TextureStorage11_Cube : public TextureStorage11 -{ - public: - TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); - virtual ~TextureStorage11_Cube(); - - static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); - - virtual ID3D11ShaderResourceView *getSRV(); - virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level); - - virtual void generateMipmap(int face, int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); - - RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; -}; - -} - -#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.cpp index a073d95033f..8adfb5bfa74 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.cpp @@ -10,7 +10,9 @@ #include "libGLESv2/renderer/VertexBuffer.h" #include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/Context.h" +#include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/renderer/BufferStorage.h" +#include "common/mathutil.h" namespace rx { @@ -87,8 +89,8 @@ bool VertexBufferInterface::discard() return mVertexBuffer->discard(); } -bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int *outStreamOffset) +bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) { unsigned int spaceRequired; if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired)) @@ -107,7 +109,7 @@ bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &att } mReservedSpace = 0; - if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition)) + if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition)) { return false; } @@ -119,33 +121,8 @@ bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &att mWritePosition += spaceRequired; - return true; -} - -bool VertexBufferInterface::storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset) -{ - if (mWritePosition + size < mWritePosition) - { - return false; - } - - if (!reserveSpace(mReservedSpace)) - { - return false; - } - mReservedSpace = 0; - - if (!mVertexBuffer->storeRawData(data, size, mWritePosition)) - { - return false; - } - - if (outStreamOffset) - { - *outStreamOffset = mWritePosition; - } - - mWritePosition += size; + // Align to 16-byte boundary + mWritePosition = rx::roundUp(mWritePosition, 16u); return true; } @@ -165,18 +142,10 @@ bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib } mReservedSpace += requiredSpace; - return true; -} -bool VertexBufferInterface::reserveRawDataSpace(unsigned int size) -{ - // Protect against integer overflow - if (mReservedSpace + size < mReservedSpace) - { - return false; - } + // Align to 16-byte boundary + mReservedSpace = rx::roundUp(mReservedSpace, 16u); - mReservedSpace += size; return true; } @@ -185,6 +154,39 @@ VertexBuffer* VertexBufferInterface::getVertexBuffer() const return mVertexBuffer; } +bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue) const +{ + gl::Buffer *buffer = attrib.mBoundBuffer.get(); + BufferStorage *storage = buffer ? buffer->getStorage() : NULL; + + if (!storage || !storage->supportsDirectBinding()) + { + return false; + } + + // Alignment restrictions: In D3D, vertex data must be aligned to + // the format stride, or to a 4-byte boundary, whichever is smaller. + // (Undocumented, and experimentally confirmed) + size_t alignment = 4; + bool requiresConversion = false; + + if (attrib.mType != GL_FLOAT) + { + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + + unsigned int outputElementSize; + getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); + alignment = std::min<size_t>(outputElementSize, 4); + + requiresConversion = (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0; + } + + bool isAligned = (static_cast<size_t>(attrib.stride()) % alignment == 0) && + (static_cast<size_t>(attrib.mOffset) % alignment == 0); + + return !requiresConversion && isAligned; +} StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true) { @@ -231,7 +233,8 @@ bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &att if (mCache[element].type == attribute.mType && mCache[element].size == attribute.mSize && mCache[element].stride == attribute.stride() && - mCache[element].normalized == attribute.mNormalized) + mCache[element].normalized == attribute.mNormalized && + mCache[element].pureInteger == attribute.mPureInteger) { if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride()) { @@ -266,14 +269,14 @@ bool StaticVertexBufferInterface::reserveSpace(unsigned int size) } } -bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int *outStreamOffset) +bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) { unsigned int streamOffset; - if (VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances, &streamOffset)) + if (VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset)) { int attributeOffset = attrib.mOffset % attrib.stride(); - VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, streamOffset }; + VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, streamOffset }; mCache.push_back(element); if (outStreamOffset) diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.h b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.h index cbafdd20f60..d4cdf9ee852 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer.h @@ -15,6 +15,7 @@ namespace gl { class VertexAttribute; +struct VertexAttribCurrentValueData; } namespace rx @@ -29,15 +30,11 @@ class VertexBuffer virtual bool initialize(unsigned int size, bool dynamicUsage) = 0; - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, - GLsizei instances, unsigned int offset) = 0; - virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset) = 0; - + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0; virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const = 0; - virtual bool requiresConversion(const gl::VertexAttribute &attrib) const = 0; - virtual unsigned int getBufferSize() const = 0; virtual bool setBufferSize(unsigned int size) = 0; virtual bool discard() = 0; @@ -61,15 +58,16 @@ class VertexBufferInterface virtual ~VertexBufferInterface(); bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); - bool reserveRawDataSpace(unsigned int size); unsigned int getBufferSize() const; unsigned int getSerial() const; - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int *outStreamOffset); - virtual bool storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset); + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); + + bool directStoragePossible(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue) const; VertexBuffer* getVertexBuffer() const; @@ -111,10 +109,10 @@ class StaticVertexBufferInterface : public VertexBufferInterface explicit StaticVertexBufferInterface(rx::Renderer *renderer); ~StaticVertexBufferInterface(); - bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int *outStreamOffset); + bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); - bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamOffset); + bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamFffset); protected: bool reserveSpace(unsigned int size); @@ -126,6 +124,7 @@ class StaticVertexBufferInterface : public VertexBufferInterface GLint size; GLsizei stride; bool normalized; + bool pureInteger; int attributeOffset; unsigned int streamOffset; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer11.cpp deleted file mode 100644 index 521da80c3d7..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer11.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. - -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage.h" - -#include "libGLESv2/Buffer.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/Context.h" - -namespace rx -{ - -VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) -{ - mBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; -} - -VertexBuffer11::~VertexBuffer11() -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } -} - -bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } - - updateSerial(); - - if (size > 0) - { - ID3D11Device* dxDevice = mRenderer->getDevice(); - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = size; - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return false; - } - } - - mBufferSize = size; - mDynamicUsage = dynamicUsage; - return true; -} - -VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); - return static_cast<VertexBuffer11*>(vetexBuffer); -} - -bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, - GLsizei instances, unsigned int offset) -{ - if (mBuffer) - { - gl::Buffer *buffer = attrib.mBoundBuffer.get(); - - int inputStride = attrib.stride(); - const VertexConverter &converter = getVertexConversion(attrib); - - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; - - const char *input = NULL; - if (buffer) - { - BufferStorage *storage = buffer->getStorage(); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); - } - else - { - input = static_cast<const char*>(attrib.mPointer); - } - - if (instances == 0 || attrib.mDivisor == 0) - { - input += inputStride * start; - } - - converter.conversionFunc(input, inputStride, count, output); - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset) -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - char* bufferData = static_cast<char*>(mappedResource.pData); - memcpy(bufferData + offset, data, size); - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const -{ - unsigned int elementSize = getVertexConversion(attrib).outputElementSize; - - unsigned int elementCount = 0; - if (instances == 0 || attrib.mDivisor == 0) - { - elementCount = count; - } - else - { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) - { - // Round up - elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; - } - else - { - elementCount = instances / attrib.mDivisor; - } - } - - if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return true; - } - else - { - return false; - } -} - -bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const -{ - return !getVertexConversion(attrib).identity; -} - -unsigned int VertexBuffer11::getBufferSize() const -{ - return mBufferSize; -} - -bool VertexBuffer11::setBufferSize(unsigned int size) -{ - if (size > mBufferSize) - { - return initialize(size, mDynamicUsage); - } - else - { - return true; - } -} - -bool VertexBuffer11::discard() -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const -{ - return getVertexConversion(attrib).outputElementSize; -} - -DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const -{ - return getVertexConversion(attrib).dxgiFormat; -} - -ID3D11Buffer *VertexBuffer11::getBuffer() const -{ - return mBuffer; -} - -template <typename T, unsigned int componentCount, bool widen, bool normalized> -static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output) -{ - unsigned int attribSize = sizeof(T) * componentCount; - - if (attribSize == stride && !widen) - { - memcpy(output, input, count * attribSize); - } - else - { - unsigned int outputStride = widen ? 4 : componentCount; - T defaultVal = normalized ? std::numeric_limits<T>::max() : T(1); - - for (unsigned int i = 0; i < count; i++) - { - const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride); - T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride; - - for (unsigned int j = 0; j < componentCount; j++) - { - offsetOutput[j] = offsetInput[j]; - } - - if (widen) - { - offsetOutput[3] = defaultVal; - } - } - } -} - -template <unsigned int componentCount> -static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output) -{ - static const float divisor = 1.0f / (1 << 16); - - for (unsigned int i = 0; i < count; i++) - { - const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i); - float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; - - for (unsigned int j = 0; j < componentCount; j++) - { - offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor; - } - } -} - -template <typename T, unsigned int componentCount, bool normalized> -static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output) -{ - typedef std::numeric_limits<T> NL; - - for (unsigned int i = 0; i < count; i++) - { - const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i); - float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; - - for (unsigned int j = 0; j < componentCount; j++) - { - if (normalized) - { - if (NL::is_signed) - { - const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1); - offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor; - } - else - { - offsetOutput[j] = static_cast<float>(offsetInput[j]) / NL::max(); - } - } - else - { - offsetOutput[j] = static_cast<float>(offsetInput[j]); - } - } - } -} - -const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = -{ - { // GL_BYTE - { // unnormalized - { ©ToFloatVertexData<GLbyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData<GLbyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData<GLbyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData<GLbyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData<GLbyte, 1, false, true>, true, DXGI_FORMAT_R8_SNORM, 1 }, - { ©VertexData<GLbyte, 2, false, true>, true, DXGI_FORMAT_R8G8_SNORM, 2 }, - { ©VertexData<GLbyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, - { ©VertexData<GLbyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, - }, - }, - { // GL_UNSIGNED_BYTE - { // unnormalized - { ©ToFloatVertexData<GLubyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData<GLubyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData<GLubyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData<GLubyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData<GLubyte, 1, false, true>, true, DXGI_FORMAT_R8_UNORM, 1 }, - { ©VertexData<GLubyte, 2, false, true>, true, DXGI_FORMAT_R8G8_UNORM, 2 }, - { ©VertexData<GLubyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, - { ©VertexData<GLubyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, - }, - }, - { // GL_SHORT - { // unnormalized - { ©ToFloatVertexData<GLshort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData<GLshort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData<GLshort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData<GLshort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData<GLshort, 1, false, true>, true, DXGI_FORMAT_R16_SNORM, 2 }, - { ©VertexData<GLshort, 2, false, true>, true, DXGI_FORMAT_R16G16_SNORM, 4 }, - { ©VertexData<GLshort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, - { ©VertexData<GLshort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, - }, - }, - { // GL_UNSIGNED_SHORT - { // unnormalized - { ©ToFloatVertexData<GLushort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData<GLushort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData<GLushort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData<GLushort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData<GLushort, 1, false, true>, true, DXGI_FORMAT_R16_UNORM, 2 }, - { ©VertexData<GLushort, 2, false, true>, true, DXGI_FORMAT_R16G16_UNORM, 4 }, - { ©VertexData<GLushort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, - { ©VertexData<GLushort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, - }, - }, - { // GL_FIXED - { // unnormalized - { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - }, - { // GL_FLOAT - { // unnormalized - { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©VertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©VertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©VertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - }, -}; - -const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute) -{ - unsigned int typeIndex = 0; - switch (attribute.mType) - { - case GL_BYTE: typeIndex = 0; break; - case GL_UNSIGNED_BYTE: typeIndex = 1; break; - case GL_SHORT: typeIndex = 2; break; - case GL_UNSIGNED_SHORT: typeIndex = 3; break; - case GL_FIXED: typeIndex = 4; break; - case GL_FLOAT: typeIndex = 5; break; - default: UNREACHABLE(); break; - } - - return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1]; -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.cpp deleted file mode 100644 index 5a792b97f25..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.cpp +++ /dev/null @@ -1,530 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. - -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/vertexconversion.h" -#include "libGLESv2/renderer/BufferStorage.h" -#include "libGLESv2/Context.h" -#include "libGLESv2/renderer/Renderer9.h" - -#include "libGLESv2/Buffer.h" - -namespace rx -{ - -bool VertexBuffer9::mTranslationsInitialized = false; -VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - -VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) -{ - mVertexBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; - - if (!mTranslationsInitialized) - { - initializeTranslations(renderer->getCapsDeclTypes()); - mTranslationsInitialized = true; - } -} - -VertexBuffer9::~VertexBuffer9() -{ - if (mVertexBuffer) - { - mVertexBuffer->Release(); - mVertexBuffer = NULL; - } -} - -bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) -{ - if (mVertexBuffer) - { - mVertexBuffer->Release(); - mVertexBuffer = NULL; - } - - updateSerial(); - - if (size > 0) - { - DWORD flags = D3DUSAGE_WRITEONLY; - if (dynamicUsage) - { - flags |= D3DUSAGE_DYNAMIC; - } - - HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); - - if (FAILED(result)) - { - ERR("Out of memory allocating a vertex buffer of size %lu.", size); - return false; - } - } - - mBufferSize = size; - mDynamicUsage = dynamicUsage; - return true; -} - -VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer)); - return static_cast<VertexBuffer9*>(vertexBuffer); -} - -bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, - GLsizei instances, unsigned int offset) -{ - if (mVertexBuffer) - { - gl::Buffer *buffer = attrib.mBoundBuffer.get(); - - int inputStride = attrib.stride(); - int elementSize = attrib.typeSize(); - const FormatConverter &converter = formatConverter(attrib); - - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - - void *mapPtr = NULL; - - unsigned int mapSize; - if (!spaceRequired(attrib, count, instances, &mapSize)) - { - return false; - } - - HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); - - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } - - const char *input = NULL; - if (buffer) - { - BufferStorage *storage = buffer->getStorage(); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); - } - else - { - input = static_cast<const char*>(attrib.mPointer); - } - - if (instances == 0 || attrib.mDivisor == 0) - { - input += inputStride * start; - } - - if (converter.identity && inputStride == elementSize) - { - memcpy(mapPtr, input, count * inputStride); - } - else - { - converter.convertArray(input, inputStride, count, mapPtr); - } - - mVertexBuffer->Unlock(); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset) -{ - if (mVertexBuffer) - { - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - - void *mapPtr = NULL; - HRESULT result = mVertexBuffer->Lock(offset, size, &mapPtr, lockFlags); - - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } - - memcpy(mapPtr, data, size); - - mVertexBuffer->Unlock(); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - return spaceRequired(attrib, count, instances, outSpaceRequired); -} - -bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const -{ - return !formatConverter(attrib).identity; -} - -unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const -{ - unsigned int spaceRequired; - return getSpaceRequired(attrib, 1, 0, &spaceRequired) ? spaceRequired : 0; -} - -D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const -{ - return formatConverter(attrib).d3dDeclType; -} - -unsigned int VertexBuffer9::getBufferSize() const -{ - return mBufferSize; -} - -bool VertexBuffer9::setBufferSize(unsigned int size) -{ - if (size > mBufferSize) - { - return initialize(size, mDynamicUsage); - } - else - { - return true; - } -} - -bool VertexBuffer9::discard() -{ - if (mVertexBuffer) - { - void *dummy; - HRESULT result; - - result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } - - result = mVertexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const -{ - return mVertexBuffer; -} - -// Mapping from OpenGL-ES vertex attrib type to D3D decl type: -// -// BYTE SHORT (Cast) -// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) -// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) -// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) -// SHORT SHORT (Identity) -// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) -// UNSIGNED_SHORT FLOAT (Cast) -// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) -// FIXED (not in WebGL) FLOAT (FixedToFloat) -// FLOAT FLOAT (Identity) - -// GLToCType maps from GL type (as GLenum) to the C typedef. -template <GLenum GLType> struct GLToCType { }; - -template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; }; -template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; }; -template <> struct GLToCType<GL_SHORT> { typedef GLshort type; }; -template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; }; -template <> struct GLToCType<GL_FIXED> { typedef GLuint type; }; -template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; }; - -// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) -enum D3DVertexType -{ - D3DVT_FLOAT, - D3DVT_SHORT, - D3DVT_SHORT_NORM, - D3DVT_UBYTE, - D3DVT_UBYTE_NORM, - D3DVT_USHORT_NORM -}; - -// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. -template <unsigned int D3DType> struct D3DToCType { }; - -template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; }; -template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; }; -template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; }; -template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; }; -template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; }; -template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; }; - -// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. -template <unsigned int type, int size> struct WidenRule { }; - -template <int size> struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size> { }; -template <int size> struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size> { }; -template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size> { }; -template <int size> struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size> { }; -template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size> { }; -template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size> { }; - -// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. -template <unsigned int d3dtype, int size> struct VertexTypeFlags { }; - -template <unsigned int _capflag, unsigned int _declflag> -struct VertexTypeFlagsHelper -{ - enum { capflag = _capflag }; - enum { declflag = _declflag }; -}; - -template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; -template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; -template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; -template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; -template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; -template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; -template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { }; -template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { }; -template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { }; -template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { }; -template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { }; -template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { }; - - -// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). -template <GLenum GLtype, bool normalized> struct VertexTypeMapping { }; - -template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred> -struct VertexTypeMappingBase -{ - enum { preferred = Preferred }; - enum { fallback = Fallback }; -}; - -template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast -template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize -template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast -template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize -template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity -template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize -template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast -template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize -template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat -template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity - - -// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). -// The conversion rules themselves are defined in vertexconversion.h. - -// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping). -template <GLenum fromType, bool normalized, unsigned int toType> -struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { }; - -// All conversions from normalized types to float use the Normalize operator. -template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { }; - -// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules. -template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; -template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; - -// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) -// whether it is normalized or not. -template <class T, bool normalized> struct DefaultVertexValuesStage2 { }; - -template <class T> struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T> { }; -template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { }; - -// Work out the default value rule for a D3D type (expressed as the C type) and -template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { }; -template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { }; - -// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion. -// The fallback conversion produces an output that all D3D9 devices must support. -template <class T> struct UsePreferred { enum { type = T::preferred }; }; -template <class T> struct UseFallback { enum { type = T::fallback }; }; - -// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion, -// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag -// and the D3DDECLTYPE member needed for the vertex declaration in declflag. -template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule> -struct Converter - : VertexDataConverter<typename GLToCType<fromType>::type, - WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>, - ConversionRule<fromType, - normalized, - PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>, - DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > > -{ -private: - enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type }; - enum { d3dsize = WidenRule<d3dtype, size>::finalWidth }; - -public: - enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag }; - enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; -}; - -// Initialize a TranslationInfo -#define TRANSLATION(type, norm, size, preferred) \ - { \ - Converter<type, norm, size, preferred>::identity, \ - Converter<type, norm, size, preferred>::finalSize, \ - Converter<type, norm, size, preferred>::convertArray, \ - static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \ - } - -#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ - { \ - Converter<type, norm, size, UsePreferred>::capflag, \ - TRANSLATION(type, norm, size, UsePreferred), \ - TRANSLATION(type, norm, size, UseFallback) \ - } - -#define TRANSLATIONS_FOR_TYPE(type) \ - { \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \ - } - -#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ - { \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - } - -const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] -{ - TRANSLATIONS_FOR_TYPE(GL_BYTE), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), - TRANSLATIONS_FOR_TYPE(GL_SHORT), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) -}; - -void VertexBuffer9::initializeTranslations(DWORD declTypes) -{ - for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) - { - for (unsigned int j = 0; j < 2; j++) - { - for (unsigned int k = 0; k < 4; k++) - { - if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; - } - else - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; - } - } - } - } -} - -unsigned int VertexBuffer9::typeIndex(GLenum type) -{ - switch (type) - { - case GL_BYTE: return 0; - case GL_UNSIGNED_BYTE: return 1; - case GL_SHORT: return 2; - case GL_UNSIGNED_SHORT: return 3; - case GL_FIXED: return 4; - case GL_FLOAT: return 5; - - default: UNREACHABLE(); return 5; - } -} - -const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute) -{ - return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1]; -} - -bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) -{ - unsigned int elementSize = formatConverter(attrib).outputElementSize; - - if (attrib.mArrayEnabled) - { - unsigned int elementCount = 0; - if (instances == 0 || attrib.mDivisor == 0) - { - elementCount = count; - } - else - { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) - { - // Round up - elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; - } - else - { - elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor; - } - } - - if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return true; - } - else - { - return false; - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return true; - } -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.h b/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.h deleted file mode 100644 index 2f88117bda2..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer9.h +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation. - -#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ -#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ - -#include "libGLESv2/renderer/VertexBuffer.h" - -namespace rx -{ -class Renderer9; - -class VertexBuffer9 : public VertexBuffer -{ - public: - explicit VertexBuffer9(rx::Renderer9 *const renderer); - virtual ~VertexBuffer9(); - - virtual bool initialize(unsigned int size, bool dynamicUsage); - - static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); - - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int offset); - virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); - - virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - - virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; - - unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; - D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const; - - virtual unsigned int getBufferSize() const; - virtual bool setBufferSize(unsigned int size); - virtual bool discard(); - - IDirect3DVertexBuffer9 *getBuffer() const; - - private: - DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); - - rx::Renderer9 *const mRenderer; - - IDirect3DVertexBuffer9 *mVertexBuffer; - unsigned int mBufferSize; - bool mDynamicUsage; - - // Attribute format conversion - enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; - - struct FormatConverter - { - bool identity; - std::size_t outputElementSize; - void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); - D3DDECLTYPE d3dDeclType; - }; - - static bool mTranslationsInitialized; - static void initializeTranslations(DWORD declTypes); - - // [GL types as enumerated by typeIndex()][normalized][size - 1] - static FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - - struct TranslationDescription - { - DWORD capsFlag; - FormatConverter preferredConversion; - FormatConverter fallbackConversion; - }; - - // This table is used to generate mFormatConverters. - // [GL types as enumerated by typeIndex()][normalized][size - 1] - static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - - static unsigned int typeIndex(GLenum type); - static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); - - static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired); -}; - -} - -#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.cpp index 8034aed8c95..6aad5ebb826 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.cpp @@ -13,8 +13,9 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Context.h" +#include "libGLESv2/VertexAttribute.h" #include "libGLESv2/renderer/VertexBuffer.h" +#include "libGLESv2/renderer/Renderer.h" namespace { @@ -26,7 +27,7 @@ namespace namespace rx { -static int elementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size) +static int ElementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size) { // Size cannot be larger than a GLsizei if (size > static_cast<unsigned int>(std::numeric_limits<int>::max())) @@ -56,10 +57,11 @@ VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer) { for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - mCurrentValue[i][0] = std::numeric_limits<float>::quiet_NaN(); - mCurrentValue[i][1] = std::numeric_limits<float>::quiet_NaN(); - mCurrentValue[i][2] = std::numeric_limits<float>::quiet_NaN(); - mCurrentValue[i][3] = std::numeric_limits<float>::quiet_NaN(); + mCurrentValue[i].FloatValues[0] = std::numeric_limits<float>::quiet_NaN(); + mCurrentValue[i].FloatValues[1] = std::numeric_limits<float>::quiet_NaN(); + mCurrentValue[i].FloatValues[2] = std::numeric_limits<float>::quiet_NaN(); + mCurrentValue[i].FloatValues[3] = std::numeric_limits<float>::quiet_NaN(); + mCurrentValue[i].Type = GL_FLOAT; mCurrentValueBuffer[i] = NULL; mCurrentValueOffsets[i] = 0; } @@ -82,17 +84,8 @@ VertexDataManager::~VertexDataManager() } } -static bool directStoragePossible(VertexBufferInterface* vb, const gl::VertexAttribute& attrib) -{ - gl::Buffer *buffer = attrib.mBoundBuffer.get(); - BufferStorage *storage = buffer ? buffer->getStorage() : NULL; - - const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0); - - return storage && storage->supportsDirectBinding() && !vb->getVertexBuffer()->requiresConversion(attrib) && isAligned; -} - -GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) +GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], + gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) { if (!mStreamingBuffer) { @@ -113,7 +106,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) && - !directStoragePossible(staticBuffer, attribs[i])) + !staticBuffer->directStoragePossible(attribs[i], currentValues[i])) { buffer->invalidateStaticData(); } @@ -129,13 +122,13 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); - if (!directStoragePossible(vertexBuffer, attribs[i])) + if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i])) { if (staticBuffer) { if (staticBuffer->getBufferSize() == 0) { - int totalCount = elementsInBuffer(attribs[i], buffer->size()); + int totalCount = ElementsInBuffer(attribs[i], buffer->size()); if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0)) { return GL_OUT_OF_MEMORY; @@ -146,9 +139,9 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], { int totalCount = StreamingBufferElementCount(attribs[i], count, instances); - // Undefined behaviour: + // [OpenGL ES 3.0.2] section 2.9.4 page 40: // We can return INVALID_OPERATION if our vertex attribute does not have enough backing data. - if (buffer && elementsInBuffer(attribs[i], buffer->size()) < totalCount) + if (buffer && ElementsInBuffer(attribs[i], buffer->size()) < totalCount) { return GL_INVALID_OPERATION; } @@ -182,7 +175,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); BufferStorage *storage = buffer ? buffer->getStorage() : NULL; - bool directStorage = directStoragePossible(vertexBuffer, attribs[i]); + bool directStorage = vertexBuffer->directStoragePossible(attribs[i], currentValues[i]); unsigned int streamOffset = 0; unsigned int outputElementSize = 0; @@ -191,7 +184,6 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], { outputElementSize = attribs[i].stride(); streamOffset = attribs[i].mOffset + outputElementSize * start; - storage->markBufferUsage(); } else if (staticBuffer) { @@ -203,10 +195,11 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset)) { // Convert the entire buffer - int totalCount = elementsInBuffer(attribs[i], storage->getSize()); + int totalCount = ElementsInBuffer(attribs[i], storage->getSize()); int startIndex = attribs[i].mOffset / attribs[i].stride(); - if (!staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0, &streamOffset)) + if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount, + 0, &streamOffset)) { return GL_OUT_OF_MEMORY; } @@ -225,7 +218,8 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], { int totalCount = StreamingBufferElementCount(attribs[i], count, instances); if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) || - !mStreamingBuffer->storeVertexAttributes(attribs[i], start, totalCount, instances, &streamOffset)) + !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, totalCount, instances, + &streamOffset)) { return GL_OUT_OF_MEMORY; } @@ -237,6 +231,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], translated[i].divisor = attribs[i].mDivisor; translated[i].attribute = &attribs[i]; + translated[i].currentValueType = currentValues[i].Type; translated[i].stride = outputElementSize; translated[i].offset = streamOffset; } @@ -249,27 +244,20 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i]; - if (mCurrentValue[i][0] != attribs[i].mCurrentValue[0] || - mCurrentValue[i][1] != attribs[i].mCurrentValue[1] || - mCurrentValue[i][2] != attribs[i].mCurrentValue[2] || - mCurrentValue[i][3] != attribs[i].mCurrentValue[3]) + if (mCurrentValue[i] != currentValues[i]) { - unsigned int requiredSpace = sizeof(float) * 4; - if (!buffer->reserveRawDataSpace(requiredSpace)) + if (!buffer->reserveVertexSpace(attribs[i], 1, 0)) { return GL_OUT_OF_MEMORY; } unsigned int streamOffset; - if (!buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace, &streamOffset)) + if (!buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0, &streamOffset)) { return GL_OUT_OF_MEMORY; } - mCurrentValue[i][0] = attribs[i].mCurrentValue[0]; - mCurrentValue[i][1] = attribs[i].mCurrentValue[1]; - mCurrentValue[i][2] = attribs[i].mCurrentValue[2]; - mCurrentValue[i][3] = attribs[i].mCurrentValue[3]; + mCurrentValue[i] = currentValues[i]; mCurrentValueOffsets[i] = streamOffset; } @@ -279,6 +267,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], translated[i].divisor = 0; translated[i].attribute = &attribs[i]; + translated[i].currentValueType = currentValues[i].Type; translated[i].stride = 0; translated[i].offset = mCurrentValueOffsets[i]; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.h b/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.h index 1a8786552a5..1a69245b945 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/VertexDataManager.h @@ -11,12 +11,14 @@ #define LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_ #include "libGLESv2/Constants.h" +#include "libGLESv2/VertexAttribute.h" #include "common/angleutils.h" namespace gl { class VertexAttribute; class ProgramBinary; +struct VertexAttribCurrentValueData; } namespace rx @@ -31,6 +33,7 @@ struct TranslatedAttribute bool active; const gl::VertexAttribute *attribute; + GLenum currentValueType; unsigned int offset; unsigned int stride; // 0 means not to advance the read pointer at all @@ -46,7 +49,8 @@ class VertexDataManager VertexDataManager(rx::Renderer *renderer); virtual ~VertexDataManager(); - GLenum prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances); + GLenum prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], + gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances); private: DISALLOW_COPY_AND_ASSIGN(VertexDataManager); @@ -55,7 +59,8 @@ class VertexDataManager StreamingVertexBufferInterface *mStreamingBuffer; - float mCurrentValue[gl::MAX_VERTEX_ATTRIBS][4]; + gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS]; + StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS]; std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS]; }; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.cpp new file mode 100644 index 00000000000..765089cc969 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.cpp @@ -0,0 +1,23 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// copyimage.cpp: Defines image copying functions + +#include "libGLESv2/renderer/copyImage.h" + +namespace rx +{ + +void CopyBGRAUByteToRGBAUByte(const void *source, void *dest) +{ + unsigned int argb = *(unsigned int*)source; + *(unsigned int*)dest = (argb & 0xFF00FF00) | // Keep alpha and green + (argb & 0x00FF0000) >> 16 | // Move red to blue + (argb & 0x000000FF) << 16; // Move blue to red +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.h b/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.h new file mode 100644 index 00000000000..2f37e1cedd0 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/copyimage.h @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 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. +// + +// copyimage.h: Defines image copying functions + +#ifndef LIBGLESV2_RENDERER_COPYIMAGE_H_ +#define LIBGLESV2_RENDERER_COPYIMAGE_H_ + +#include "common/mathutil.h" +#include "libGLESv2/angletypes.h" + +namespace rx +{ + +template <typename sourceType, typename colorDataType> +void ReadColor(const void *source, void *dest) +{ + sourceType::readColor(reinterpret_cast<gl::Color<colorDataType>*>(dest), reinterpret_cast<const sourceType*>(source)); +} + +template <typename destType, typename colorDataType> +void WriteColor(const void *source, void *dest) +{ + destType::writeColor(reinterpret_cast<destType*>(dest), reinterpret_cast<const gl::Color<colorDataType>*>(source)); +} + +template <typename sourceType, typename destType, typename colorDataType> +void CopyPixel(const void *source, void *dest) +{ + colorType temp; + ReadColor<sourceType, colorDataType>(source, &temp); + WriteColor<destType, colorDataType>(&temp, dest); +} + +void CopyBGRAUByteToRGBAUByte(const void *source, void *dest); + +} + +#endif // LIBGLESV2_RENDERER_COPYIMAGE_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/copyvertex.h b/chromium/third_party/angle/src/libGLESv2/renderer/copyvertex.h new file mode 100644 index 00000000000..aca031701eb --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/copyvertex.h @@ -0,0 +1,309 @@ +// +// Copyright (c) 2013 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. +// + +// copyvertex.h: Defines vertex buffer copying and conversion functions + +#ifndef LIBGLESV2_RENDERER_COPYVERTEX_H_ +#define LIBGLESV2_RENDERER_COPYVERTEX_H_ + +#include "common/mathutil.h" + +// 'widenDefaultValueBits' gives the default value for the alpha channel (4th component) +// the sentinel value 0 means we do not want to widen the input or add an alpha channel +template <typename T, unsigned int componentCount, unsigned int widenDefaultValueBits> +inline void copyVertexData(const void *input, size_t stride, size_t count, void *output) +{ + const unsigned int attribSize = sizeof(T) * componentCount; + const T defaultValue = gl::bitCast<T>(widenDefaultValueBits); + const bool widen = (widenDefaultValueBits != 0); + + if (attribSize == stride && !widen) + { + memcpy(output, input, count * attribSize); + } + else + { + unsigned int outputStride = widen ? 4 : componentCount; + + for (unsigned int i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride); + T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride; + + for (unsigned int j = 0; j < componentCount; j++) + { + offsetOutput[j] = offsetInput[j]; + } + + if (widen) + { + offsetOutput[3] = defaultValue; + } + } + } +} + +template <unsigned int componentCount> +inline void copyFixedVertexData(const void* input, size_t stride, size_t count, void* output) +{ + static const float divisor = 1.0f / (1 << 16); + + for (unsigned int i = 0; i < count; i++) + { + const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i); + float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; + + for (unsigned int j = 0; j < componentCount; j++) + { + offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor; + } + } +} + +template <typename T, unsigned int componentCount, bool normalized> +inline void copyToFloatVertexData(const void* input, size_t stride, size_t count, void* output) +{ + typedef std::numeric_limits<T> NL; + + for (unsigned int i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i); + float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; + + for (unsigned int j = 0; j < componentCount; j++) + { + if (normalized) + { + if (NL::is_signed) + { + const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1); + offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor; + } + else + { + offsetOutput[j] = static_cast<float>(offsetInput[j]) / NL::max(); + } + } + else + { + offsetOutput[j] = static_cast<float>(offsetInput[j]); + } + } + } +} + +inline void copyPackedUnsignedVertexData(const void* input, size_t stride, size_t count, void* output) +{ + const unsigned int attribSize = 4; + + if (attribSize == stride) + { + memcpy(output, input, count * attribSize); + } + else + { + for (unsigned int i = 0; i < count; i++) + { + const GLuint *offsetInput = reinterpret_cast<const GLuint*>(reinterpret_cast<const char*>(input) + (i * stride)); + GLuint *offsetOutput = reinterpret_cast<GLuint*>(output) + (i * attribSize); + + offsetOutput[i] = offsetInput[i]; + } + } +} + +template <bool isSigned, bool normalized, bool toFloat> +static inline void copyPackedRGB(unsigned int data, void *output) +{ + const unsigned int rgbSignMask = 0x200; // 1 set at the 9 bit + const unsigned int negativeMask = 0xFFFFFC00; // All bits from 10 to 31 set to 1 + + if (toFloat) + { + GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output); + if (isSigned) + { + GLfloat finalValue = 0; + if (data & rgbSignMask) + { + int negativeNumber = data | negativeMask; + finalValue = static_cast<GLfloat>(negativeNumber); + } + else + { + finalValue = static_cast<GLfloat>(data); + } + + if (normalized) + { + const int maxValue = 0x1FF; // 1 set in bits 0 through 8 + const int minValue = 0xFFFFFE01; // Inverse of maxValue + + // A 10-bit two's complement number has the possibility of being minValue - 1 but + // OpenGL's normalization rules dictate that it should be clamped to minValue in this + // case. + if (finalValue < minValue) + { + finalValue = minValue; + } + + const int halfRange = (maxValue - minValue) >> 1; + *floatOutput = ((finalValue - minValue) / halfRange) - 1.0f; + } + else + { + *floatOutput = finalValue; + } + } + else + { + if (normalized) + { + const unsigned int maxValue = 0x3FF; // 1 set in bits 0 through 9 + *floatOutput = static_cast<GLfloat>(data) / static_cast<GLfloat>(maxValue); + } + else + { + *floatOutput = static_cast<GLfloat>(data); + } + } + } + else + { + if (isSigned) + { + GLshort *intOutput = reinterpret_cast<GLshort*>(output); + + if (data & rgbSignMask) + { + *intOutput = data | negativeMask; + } + else + { + *intOutput = data; + } + } + else + { + GLushort *uintOutput = reinterpret_cast<GLushort*>(output); + *uintOutput = data; + } + } +} + +template <bool isSigned, bool normalized, bool toFloat> +inline void copyPackedAlpha(unsigned int data, void *output) +{ + if (toFloat) + { + GLfloat *floatOutput = reinterpret_cast<GLfloat*>(output); + if (isSigned) + { + if (normalized) + { + switch (data) + { + case 0x0: *floatOutput = 0.0f; break; + case 0x1: *floatOutput = 1.0f; break; + case 0x2: *floatOutput = -1.0f; break; + case 0x3: *floatOutput = -1.0f; break; + default: UNREACHABLE(); + } + } + else + { + switch (data) + { + case 0x0: *floatOutput = 0.0f; break; + case 0x1: *floatOutput = 1.0f; break; + case 0x2: *floatOutput = -2.0f; break; + case 0x3: *floatOutput = -1.0f; break; + default: UNREACHABLE(); + } + } + } + else + { + if (normalized) + { + switch (data) + { + case 0x0: *floatOutput = 0.0f / 3.0f; break; + case 0x1: *floatOutput = 1.0f / 3.0f; break; + case 0x2: *floatOutput = 2.0f / 3.0f; break; + case 0x3: *floatOutput = 3.0f / 3.0f; break; + default: UNREACHABLE(); + } + } + else + { + switch (data) + { + case 0x0: *floatOutput = 0.0f; break; + case 0x1: *floatOutput = 1.0f; break; + case 0x2: *floatOutput = 2.0f; break; + case 0x3: *floatOutput = 3.0f; break; + default: UNREACHABLE(); + } + } + } + } + else + { + if (isSigned) + { + GLshort *intOutput = reinterpret_cast<GLshort*>(output); + switch (data) + { + case 0x0: *intOutput = 0; break; + case 0x1: *intOutput = 1; break; + case 0x2: *intOutput = -2; break; + case 0x3: *intOutput = -1; break; + default: UNREACHABLE(); + } + } + else + { + GLushort *uintOutput = reinterpret_cast<GLushort*>(output); + switch (data) + { + case 0x0: *uintOutput = 0; break; + case 0x1: *uintOutput = 1; break; + case 0x2: *uintOutput = 2; break; + case 0x3: *uintOutput = 3; break; + default: UNREACHABLE(); + } + } + } +} + +template <bool isSigned, bool normalized, bool toFloat> +inline void copyPackedVertexData(const void* input, size_t stride, size_t count, void* output) +{ + const unsigned int outputComponentSize = toFloat ? 4 : 2; + const unsigned int componentCount = 4; + + const unsigned int rgbMask = 0x3FF; // 1 set in bits 0 through 9 + const unsigned int redShift = 0; // red is bits 0 through 9 + const unsigned int greenShift = 10; // green is bits 10 through 19 + const unsigned int blueShift = 20; // blue is bits 20 through 29 + + const unsigned int alphaMask = 0x3; // 1 set in bits 0 and 1 + const unsigned int alphaShift = 30; // Alpha is the 30 and 31 bits + + for (unsigned int i = 0; i < count; i++) + { + GLuint packedValue = *reinterpret_cast<const GLuint*>(reinterpret_cast<const char*>(input) + (i * stride)); + GLbyte *offsetOutput = reinterpret_cast<GLbyte*>(output) + (i * outputComponentSize * componentCount); + + copyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize)); + copyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize)); + copyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize)); + copyPackedAlpha<isSigned, normalized, toFloat>((packedValue >> alphaShift) & alphaMask, offsetOutput + (3* outputComponentSize)); + } +} + +#endif // LIBGLESV2_RENDERER_COPYVERTEX_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp new file mode 100644 index 00000000000..d3ddd98eea3 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp @@ -0,0 +1,123 @@ +#include "precompiled.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/Program.h" +#include "libGLESv2/main.h" + +#include "common/utilities.h" + +#include "third_party/trace_event/trace_event.h" + +namespace rx +{ + +HLSLCompiler::HLSLCompiler() + : mD3DCompilerModule(NULL), + mD3DCompileFunc(NULL) +{ +} + +HLSLCompiler::~HLSLCompiler() +{ + release(); +} + +bool HLSLCompiler::initialize() +{ + TRACE_EVENT0("gpu", "initializeCompiler"); +#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) + // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. + static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; + + for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) + { + if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3DCompilerModule)) + { + break; + } + } +#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES + + if (!mD3DCompilerModule) + { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. + mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); + } + + if (!mD3DCompilerModule) + { + ERR("No D3D compiler module found - aborting!\n"); + return false; + } + + mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile")); + ASSERT(mD3DCompileFunc); + + return mD3DCompileFunc != NULL; +} + +void HLSLCompiler::release() +{ + if (mD3DCompilerModule) + { + FreeLibrary(mD3DCompilerModule); + mD3DCompilerModule = NULL; + mD3DCompileFunc = NULL; + } +} + +ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, + const UINT optimizationFlags[], const char *flagNames[], int attempts) const +{ + ASSERT(mD3DCompilerModule && mD3DCompileFunc); + + if (!hlsl) + { + return NULL; + } + + pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); + for (int i = 0; i < attempts; ++i) + { + ID3DBlob *errorMessage = NULL; + ID3DBlob *binary = NULL; + + HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage); + + if (errorMessage) + { + const char *message = (const char*)errorMessage->GetBufferPointer(); + + infoLog.appendSanitized(message); + TRACE("\n%s", hlsl); + TRACE("\n%s", message); + + SafeRelease(errorMessage); + } + + if (SUCCEEDED(result)) + { + return (ShaderBlob*)binary; + } + else + { + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); + } + + infoLog.append("Warning: D3D shader compilation failed with "); + infoLog.append(flagNames[i]); + infoLog.append(" flags."); + if (i + 1 < attempts) + { + infoLog.append(" Retrying with "); + infoLog.append(flagNames[i + 1]); + infoLog.append(".\n"); + } + } + } + + return NULL; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h new file mode 100644 index 00000000000..ab685f1f44a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h @@ -0,0 +1,40 @@ +#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ +#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ + +#include "common/angleutils.h" + +#include <windows.h> + +namespace gl +{ +class InfoLog; +} + +namespace rx +{ + +typedef void* ShaderBlob; +typedef void(*CompileFuncPtr)(); + +class HLSLCompiler +{ + public: + HLSLCompiler(); + ~HLSLCompiler(); + + bool initialize(); + void release(); + + ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, + const UINT optimizationFlags[], const char *flagNames[], int attempts) const; + + private: + DISALLOW_COPY_AND_ASSIGN(HLSLCompiler); + + HMODULE mD3DCompilerModule; + CompileFuncPtr mD3DCompileFunc; +}; + +} + +#endif // LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.cpp new file mode 100644 index 00000000000..9a417139301 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.cpp @@ -0,0 +1,1040 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Blit11.cpp: Texture copy utility class. + +#include "libGLESv2/main.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/renderer/d3d11/Blit11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h" + +namespace rx +{ + +static DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource) +{ + ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); + if (!texture) + { + return DXGI_FORMAT_UNKNOWN; + } + + D3D11_TEXTURE2D_DESC desc; + texture->GetDesc(&desc); + + SafeRelease(texture); + + return desc.Format; +} + +static ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context, + ID3D11Resource *source, unsigned int subresource, + const gl::Extents &size, unsigned int cpuAccessFlags) +{ + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = GetTextureFormat(source); + stagingDesc.SampleDesc.Count = 1; + stagingDesc.SampleDesc.Quality = 0; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.CPUAccessFlags = cpuAccessFlags; + stagingDesc.MiscFlags = 0; + stagingDesc.BindFlags = 0; + + ID3D11Texture2D *stagingTexture = NULL; + HRESULT result = device->CreateTexture2D(&stagingDesc, NULL, &stagingTexture); + if (FAILED(result)) + { + ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result); + return NULL; + } + + context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, NULL); + + return stagingTexture; +} + +inline static void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize, + const gl::Box &destArea, const gl::Extents &destSize, + float *x1, float *y1, float *x2, float *y2, + float *u1, float *v1, float *u2, float *v2) +{ + *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f; + *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f; + *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f; + *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f; + + *u1 = sourceArea.x / float(sourceSize.width); + *v1 = sourceArea.y / float(sourceSize.height); + *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width); + *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height); +} + +static void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, + const gl::Box &destArea, const gl::Extents &destSize, + void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology) +{ + float x1, y1, x2, y2, u1, v1, u2, v2; + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2); + + d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(outVertices); + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); + + *outStride = sizeof(d3d11::PositionTexCoordVertex); + *outVertexCount = 4; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; +} + +static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, + const gl::Box &destArea, const gl::Extents &destSize, + void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology) +{ + ASSERT(sourceSize.depth > 0 && destSize.depth > 0); + + float x1, y1, x2, y2, u1, v1, u2, v2; + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2); + + d3d11::PositionLayerTexCoord3DVertex *vertices = static_cast<d3d11::PositionLayerTexCoord3DVertex*>(outVertices); + + for (int i = 0; i < destSize.depth; i++) + { + float readDepth = (float)i / std::max(destSize.depth - 1, 1); + + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth); + + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth); + d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth); + } + + *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex); + *outVertexCount = destSize.depth * 6; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; +} + +Blit11::Blit11(rx::Renderer11 *renderer) + : mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters), + mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL), + mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL), + mQuad2DIL(NULL), mQuad2DVS(NULL), mDepthPS(NULL), + mQuad3DIL(NULL), mQuad3DVS(NULL), mQuad3DGS(NULL), + mSwizzleCB(NULL) +{ + HRESULT result; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) * + 6 * renderer->getMaxTextureDepth(); + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer"); + + D3D11_SAMPLER_DESC pointSamplerDesc; + pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.MipLODBias = 0.0f; + pointSamplerDesc.MaxAnisotropy = 0; + pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + pointSamplerDesc.BorderColor[0] = 0.0f; + pointSamplerDesc.BorderColor[1] = 0.0f; + pointSamplerDesc.BorderColor[2] = 0.0f; + pointSamplerDesc.BorderColor[3] = 0.0f; + pointSamplerDesc.MinLOD = 0.0f; + pointSamplerDesc.MaxLOD = 0.0f; + + result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPointSampler, "Blit11 point sampler"); + + D3D11_SAMPLER_DESC linearSamplerDesc; + linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.MipLODBias = 0.0f; + linearSamplerDesc.MaxAnisotropy = 0; + linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + linearSamplerDesc.BorderColor[0] = 0.0f; + linearSamplerDesc.BorderColor[1] = 0.0f; + linearSamplerDesc.BorderColor[2] = 0.0f; + linearSamplerDesc.BorderColor[3] = 0.0f; + linearSamplerDesc.MinLOD = 0.0f; + linearSamplerDesc.MaxLOD = 0.0f; + + result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler"); + + // Use a rasterizer state that will not cull so that inverted quads will not be culled + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.FrontCounterClockwise = FALSE; + rasterDesc.DepthBias = 0; + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.MultisampleEnable = FALSE; + rasterDesc.AntialiasedLineEnable = FALSE; + + rasterDesc.ScissorEnable = TRUE; + result = device->CreateRasterizerState(&rasterDesc, &mScissorEnabledRasterizerState); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mScissorEnabledRasterizerState, "Blit11 scissoring rasterizer state"); + + rasterDesc.ScissorEnable = FALSE; + result = device->CreateRasterizerState(&rasterDesc, &mScissorDisabledRasterizerState); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mScissorDisabledRasterizerState, "Blit11 no scissoring rasterizer state"); + + D3D11_DEPTH_STENCIL_DESC depthStencilDesc; + depthStencilDesc.DepthEnable = true; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + result = device->CreateDepthStencilState(&depthStencilDesc, &mDepthStencilState); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state"); + + D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = device->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), &mQuad2DIL); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuad2DIL, "Blit11 2D input layout"); + + result = device->CreateVertexShader(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), NULL, &mQuad2DVS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader"); + + result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader"); + + D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout"); + + result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader"); + + result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader"); + + buildShaderMap(); + + D3D11_BUFFER_DESC swizzleBufferDesc; + swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4; + swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + swizzleBufferDesc.MiscFlags = 0; + swizzleBufferDesc.StructureByteStride = 0; + + result = device->CreateBuffer(&swizzleBufferDesc, NULL, &mSwizzleCB); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mSwizzleCB, "Blit11 swizzle constant buffer"); +} + +Blit11::~Blit11() +{ + SafeRelease(mVertexBuffer); + SafeRelease(mPointSampler); + SafeRelease(mLinearSampler); + SafeRelease(mScissorEnabledRasterizerState); + SafeRelease(mScissorDisabledRasterizerState); + SafeRelease(mDepthStencilState); + + SafeRelease(mQuad2DIL); + SafeRelease(mQuad2DVS); + SafeRelease(mDepthPS); + + SafeRelease(mQuad3DIL); + SafeRelease(mQuad3DVS); + SafeRelease(mQuad3DGS); + + SafeRelease(mSwizzleCB); + + clearShaderMap(); +} + +static inline unsigned int GetSwizzleIndex(GLenum swizzle) +{ + unsigned int colorIndex = 0; + + switch (swizzle) + { + case GL_RED: colorIndex = 0; break; + case GL_GREEN: colorIndex = 1; break; + case GL_BLUE: colorIndex = 2; break; + case GL_ALPHA: colorIndex = 3; break; + case GL_ZERO: colorIndex = 4; break; + case GL_ONE: colorIndex = 5; break; + default: UNREACHABLE(); break; + } + + return colorIndex; +} + +bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, + GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +{ + HRESULT result; + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + source->GetDesc(&sourceSRVDesc); + GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion()); + + GLenum shaderType = GL_NONE; + switch (gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion())) + { + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + shaderType = GL_FLOAT; + break; + case GL_INT: + shaderType = GL_INT; + break; + case GL_UNSIGNED_INT: + shaderType = GL_UNSIGNED_INT; + break; + default: + UNREACHABLE(); + break; + } + + SwizzleParameters parameters = { 0 }; + parameters.mDestinationType = shaderType; + parameters.mViewDimension = sourceSRVDesc.ViewDimension; + + SwizzleShaderMap::const_iterator i = mSwizzleShaderMap.find(parameters); + if (i == mSwizzleShaderMap.end()) + { + UNREACHABLE(); + return false; + } + + const Shader &shader = i->second; + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map vertex buffer for texture swizzle, HRESULT: 0x%X.", result); + return false; + } + + UINT stride = 0; + UINT startIdx = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + gl::Box area(0, 0, 0, size.width, size.height, size.depth); + shader.mVertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology); + + deviceContext->Unmap(mVertexBuffer, 0); + + // Set constant buffer + result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map constant buffer for texture swizzle, HRESULT: 0x%X.", result); + return false; + } + + unsigned int *swizzleIndices = reinterpret_cast<unsigned int*>(mappedResource.pData); + swizzleIndices[0] = GetSwizzleIndex(swizzleRed); + swizzleIndices[1] = GetSwizzleIndex(swizzleGreen); + swizzleIndices[2] = GetSwizzleIndex(swizzleBlue); + swizzleIndices[3] = GetSwizzleIndex(swizzleAlpha); + + deviceContext->Unmap(mSwizzleCB, 0); + + // Apply vertex buffer + deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + + // Apply constant buffer + deviceContext->PSSetConstantBuffers(0, 1, &mSwizzleCB); + + // Apply state + deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + deviceContext->RSSetState(mScissorDisabledRasterizerState); + + // Apply shaders + deviceContext->IASetInputLayout(shader.mInputLayout); + deviceContext->IASetPrimitiveTopology(topology); + deviceContext->VSSetShader(shader.mVertexShader, NULL, 0); + + deviceContext->PSSetShader(shader.mPixelShader, NULL, 0); + deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); + + // Unset the currently bound shader resource to avoid conflicts + ID3D11ShaderResourceView *const nullSRV = NULL; + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + // Apply render target + mRenderer->setOneTimeRenderTarget(dest); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = size.width; + viewport.Height = size.height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); + + // Apply textures + deviceContext->PSSetShaderResources(0, 1, &source); + + // Apply samplers + deviceContext->PSSetSamplers(0, 1, &mPointSampler); + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + // Unbind textures and render targets and vertex buffer + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + mRenderer->unapplyRenderTargets(); + + UINT zero = 0; + ID3D11Buffer *const nullBuffer = NULL; + deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + + mRenderer->markAllStateDirty(); + + return true; +} + +bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) +{ + HRESULT result; + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Determine if the source format is a signed integer format, the destFormat will already + // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned. + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + source->GetDesc(&sourceSRVDesc); + GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion()); + + BlitParameters parameters = { 0 }; + parameters.mDestinationFormat = destFormat; + parameters.mSignedInteger = gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion()) == GL_INT; + parameters.m3DBlit = sourceArea.depth > 1; + + BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters); + if (i == mBlitShaderMap.end()) + { + UNREACHABLE(); + return false; + } + + const Shader& shader = i->second; + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); + return false; + } + + UINT stride = 0; + UINT startIdx = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + shader.mVertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, + &stride, &drawCount, &topology); + + deviceContext->Unmap(mVertexBuffer, 0); + + // Apply vertex buffer + deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + + // Apply state + deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + + if (scissor) + { + D3D11_RECT scissorRect; + scissorRect.left = scissor->x; + scissorRect.right = scissor->x + scissor->width; + scissorRect.top = scissor->y; + scissorRect.bottom = scissor->y + scissor->height; + + deviceContext->RSSetScissorRects(1, &scissorRect); + deviceContext->RSSetState(mScissorEnabledRasterizerState); + } + else + { + deviceContext->RSSetState(mScissorDisabledRasterizerState); + } + + // Apply shaders + deviceContext->IASetInputLayout(shader.mInputLayout); + deviceContext->IASetPrimitiveTopology(topology); + deviceContext->VSSetShader(shader.mVertexShader, NULL, 0); + + deviceContext->PSSetShader(shader.mPixelShader, NULL, 0); + deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); + + // Unset the currently bound shader resource to avoid conflicts + ID3D11ShaderResourceView *const nullSRV = NULL; + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + // Apply render target + mRenderer->setOneTimeRenderTarget(dest); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = destSize.width; + viewport.Height = destSize.height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); + + // Apply textures + deviceContext->PSSetShaderResources(0, 1, &source); + + // Apply samplers + ID3D11SamplerState *sampler = NULL; + switch (filter) + { + case GL_NEAREST: sampler = mPointSampler; break; + case GL_LINEAR: sampler = mLinearSampler; break; + default: UNREACHABLE(); return false; + } + deviceContext->PSSetSamplers(0, 1, &sampler); + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + // Unbind textures and render targets and vertex buffer + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + mRenderer->unapplyRenderTargets(); + + UINT zero = 0; + ID3D11Buffer *const nullBuffer = NULL; + deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + + mRenderer->markAllStateDirty(); + + return true; +} + +bool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, + dest, destSubresource, destArea, destSize, + scissor, true); +} + +bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + HRESULT result; + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); + return false; + } + + UINT stride = 0; + UINT startIdx = 0; + UINT drawCount = 0; + D3D11_PRIMITIVE_TOPOLOGY topology; + + Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, + &stride, &drawCount, &topology); + + deviceContext->Unmap(mVertexBuffer, 0); + + // Apply vertex buffer + deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + + // Apply state + deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + deviceContext->OMSetDepthStencilState(mDepthStencilState, 0xFFFFFFFF); + + if (scissor) + { + D3D11_RECT scissorRect; + scissorRect.left = scissor->x; + scissorRect.right = scissor->x + scissor->width; + scissorRect.top = scissor->y; + scissorRect.bottom = scissor->y + scissor->height; + + deviceContext->RSSetScissorRects(1, &scissorRect); + deviceContext->RSSetState(mScissorEnabledRasterizerState); + } + else + { + deviceContext->RSSetState(mScissorDisabledRasterizerState); + } + + // Apply shaders + deviceContext->IASetInputLayout(mQuad2DIL); + deviceContext->IASetPrimitiveTopology(topology); + deviceContext->VSSetShader(mQuad2DVS, NULL, 0); + + deviceContext->PSSetShader(mDepthPS, NULL, 0); + deviceContext->GSSetShader(NULL, NULL, 0); + + // Unset the currently bound shader resource to avoid conflicts + ID3D11ShaderResourceView *const nullSRV = NULL; + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + // Apply render target + deviceContext->OMSetRenderTargets(0, NULL, dest); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = destSize.width; + viewport.Height = destSize.height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); + + // Apply textures + deviceContext->PSSetShaderResources(0, 1, &source); + + // Apply samplers + deviceContext->PSSetSamplers(0, 1, &mPointSampler); + + // Draw the quad + deviceContext->Draw(drawCount, 0); + + // Unbind textures and render targets and vertex buffer + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + mRenderer->unapplyRenderTargets(); + + UINT zero = 0; + ID3D11Buffer *const nullBuffer = NULL; + deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + + mRenderer->markAllStateDirty(); + + return true; +} + +bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) +{ + return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, + dest, destSubresource, destArea, destSize, + scissor, false); +} + +bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly) +{ + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ID3D11Resource *sourceStaging = CreateStagingTexture(device, deviceContext, source, sourceSubresource, sourceSize, D3D11_CPU_ACCESS_READ); + // HACK: Create the destination staging buffer as a read/write texture so ID3D11DevicContext::UpdateSubresource can be called + // using it's mapped data as a source + ID3D11Resource *destStaging = CreateStagingTexture(device, deviceContext, dest, destSubresource, destSize, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE); + + if (!sourceStaging || !destStaging) + { + SafeRelease(sourceStaging); + SafeRelease(destStaging); + return false; + } + + DXGI_FORMAT format = GetTextureFormat(source); + ASSERT(format == GetTextureFormat(dest)); + + unsigned int pixelSize = d3d11::GetFormatPixelBytes(format); + unsigned int copyOffset = 0; + unsigned int copySize = pixelSize; + if (stencilOnly) + { + copyOffset = d3d11::GetStencilOffset(format) / 8; + copySize = d3d11::GetStencilBits(format) / 8; + + // It would be expensive to have non-byte sized stencil sizes since it would + // require reading from the destination, currently there aren't any though. + ASSERT(d3d11::GetStencilBits(format) % 8 == 0 && + d3d11::GetStencilOffset(format) % 8 == 0); + } + + D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping; + deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); + deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); + + if (!sourceMapping.pData || !destMapping.pData) + { + if (!sourceMapping.pData) + { + deviceContext->Unmap(sourceStaging, 0); + } + if (!destMapping.pData) + { + deviceContext->Unmap(destStaging, 0); + } + SafeRelease(sourceStaging); + SafeRelease(destStaging); + return false; + } + + gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); + + // Clip dest area to the destination size + gl::ClipRectangle(clippedDestArea, gl::Rectangle(0, 0, destSize.width, destSize.height), &clippedDestArea); + + // Clip dest area to the scissor + if (scissor) + { + gl::ClipRectangle(clippedDestArea, *scissor, &clippedDestArea); + } + + // Determine if entire rows can be copied at once instead of each individual pixel, requires that there is + // no out of bounds lookups required, the entire pixel is copied and no stretching + bool wholeRowCopy = sourceArea.width == clippedDestArea.width && + sourceArea.x >= 0 && sourceArea.x + sourceArea.width <= sourceSize.width && + copySize == pixelSize; + + for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++) + { + float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1); + + // Interpolate using the original source rectangle to determine which row to sample from while clamping to the edges + unsigned int readRow = gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1); + unsigned int writeRow = y; + + if (wholeRowCopy) + { + void *sourceRow = reinterpret_cast<char*>(sourceMapping.pData) + + readRow * sourceMapping.RowPitch + + sourceArea.x * pixelSize; + + void *destRow = reinterpret_cast<char*>(destMapping.pData) + + writeRow * destMapping.RowPitch + + destArea.x * pixelSize; + + memcpy(destRow, sourceRow, pixelSize * destArea.width); + } + else + { + for (int x = clippedDestArea.x; x < clippedDestArea.x + clippedDestArea.width; x++) + { + float xPerc = static_cast<float>(x - destArea.x) / (destArea.width - 1); + + // Interpolate the original source rectangle to determine which column to sample from while clamping to the edges + unsigned int readColumn = gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1); + unsigned int writeColumn = x; + + void *sourcePixel = reinterpret_cast<char*>(sourceMapping.pData) + + readRow * sourceMapping.RowPitch + + readColumn * pixelSize + + copyOffset; + + void *destPixel = reinterpret_cast<char*>(destMapping.pData) + + writeRow * destMapping.RowPitch + + writeColumn * pixelSize + + copyOffset; + + memcpy(destPixel, sourcePixel, copySize); + } + } + } + + // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion + // according to MSDN. + deviceContext->UpdateSubresource(dest, destSubresource, NULL, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch); + + deviceContext->Unmap(sourceStaging, 0); + deviceContext->Unmap(destStaging, 0); + + // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some + // systems when called repeatedly. + // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, NULL); + + SafeRelease(sourceStaging); + SafeRelease(destStaging); + + return true; +} + +bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b) +{ + return memcmp(&a, &b, sizeof(Blit11::BlitParameters)) < 0; +} + +bool Blit11::compareSwizzleParameters(const SwizzleParameters &a, const SwizzleParameters &b) +{ + return memcmp(&a, &b, sizeof(Blit11::SwizzleParameters)) < 0; +} + +void Blit11::add2DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps) +{ + BlitParameters params = { 0 }; + params.mDestinationFormat = destFormat; + params.mSignedInteger = signedInteger; + params.m3DBlit = false; + + ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end()); + ASSERT(ps); + + Shader shader; + shader.mVertexWriteFunction = Write2DVertices; + shader.mInputLayout = mQuad2DIL; + shader.mVertexShader = mQuad2DVS; + shader.mGeometryShader = NULL; + shader.mPixelShader = ps; + + mBlitShaderMap[params] = shader; +} + +void Blit11::add3DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps) +{ + BlitParameters params = { 0 }; + params.mDestinationFormat = destFormat; + params.mSignedInteger = signedInteger; + params.m3DBlit = true; + + ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end()); + ASSERT(ps); + + Shader shader; + shader.mVertexWriteFunction = Write3DVertices; + shader.mInputLayout = mQuad3DIL; + shader.mVertexShader = mQuad3DVS; + shader.mGeometryShader = mQuad3DGS; + shader.mPixelShader = ps; + + mBlitShaderMap[params] = shader; +} + +void Blit11::addSwizzleShaderToMap(GLenum destType, D3D11_SRV_DIMENSION viewDimension, ID3D11PixelShader *ps) +{ + SwizzleParameters params = { 0 }; + params.mDestinationType = destType; + params.mViewDimension = viewDimension; + + ASSERT(mSwizzleShaderMap.find(params) == mSwizzleShaderMap.end()); + ASSERT(ps); + + Shader shader; + switch (viewDimension) + { + case D3D_SRV_DIMENSION_TEXTURE2D: + shader.mVertexWriteFunction = Write2DVertices; + shader.mInputLayout = mQuad2DIL; + shader.mVertexShader = mQuad2DVS; + shader.mGeometryShader = NULL; + break; + + case D3D_SRV_DIMENSION_TEXTURE3D: + case D3D_SRV_DIMENSION_TEXTURE2DARRAY: + case D3D_SRV_DIMENSION_TEXTURECUBE: + shader.mVertexWriteFunction = Write3DVertices; + shader.mInputLayout = mQuad3DIL; + shader.mVertexShader = mQuad3DVS; + shader.mGeometryShader = mQuad3DGS; + break; + + default: + UNREACHABLE(); + break; + } + shader.mPixelShader = ps; + + mSwizzleShaderMap[params] = shader; +} + +void Blit11::buildShaderMap() +{ + ID3D11Device *device = mRenderer->getDevice(); + + add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" )); + add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" )); + add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" )); + add2DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader" )); + add2DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader" )); + add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" )); + add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" )); + add2DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader" )); + add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" )); + add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" )); + add2DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader" )); + add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" )); + add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" )); + add2DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader" )); + add2DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader" )); + add2DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader")); + + add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" )); + add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" )); + add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" )); + add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" )); + add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" )); + add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" )); + add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" )); + add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); + add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" )); + add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" )); + add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); + add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" )); + add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" )); + add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" )); + add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" )); + add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); + + addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" )); + addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader")); + addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" )); + + addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader" )); + addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader")); + addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader" )); + + addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader" )); + addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader")); + addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader" )); + + addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader" )); + addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader")); + addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader" )); +} + +void Blit11::clearShaderMap() +{ + for (BlitShaderMap::iterator i = mBlitShaderMap.begin(); i != mBlitShaderMap.end(); ++i) + { + Shader &shader = i->second; + SafeRelease(shader.mPixelShader); + } + mBlitShaderMap.clear(); + + for (SwizzleShaderMap::iterator i = mSwizzleShaderMap.begin(); i != mSwizzleShaderMap.end(); ++i) + { + Shader &shader = i->second; + SafeRelease(shader.mPixelShader); + } + mSwizzleShaderMap.clear(); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.h new file mode 100644 index 00000000000..fba89e20ba8 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Blit11.h @@ -0,0 +1,126 @@ +// +// Copyright (c) 2013 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. +// + +// Blit11.cpp: Texture copy utility class. + +#ifndef LIBGLESV2_BLIT11_H_ +#define LIBGLESV2_BLIT11_H_ + +#include "common/angleutils.h" +#include "libGLESv2/angletypes.h" + +namespace rx +{ +class Renderer11; + +enum Filter +{ + Point, + Linear, +}; + +class Blit11 +{ + public: + explicit Blit11(Renderer11 *renderer); + ~Blit11(); + + bool swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, + GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + + bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); + + bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + + bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + + bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + + private: + rx::Renderer11 *mRenderer; + + struct BlitParameters + { + GLenum mDestinationFormat; + bool mSignedInteger; + bool m3DBlit; + }; + + bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly); + + static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b); + + typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize, + const gl::Box &destArea, const gl::Extents &destSize, + void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, + D3D11_PRIMITIVE_TOPOLOGY *outTopology); + + struct Shader + { + WriteVertexFunction mVertexWriteFunction; + ID3D11InputLayout *mInputLayout; + ID3D11VertexShader *mVertexShader; + ID3D11GeometryShader *mGeometryShader; + ID3D11PixelShader *mPixelShader; + }; + + typedef bool (*BlitParametersComparisonFunction)(const BlitParameters&, const BlitParameters &); + typedef std::map<BlitParameters, Shader, BlitParametersComparisonFunction> BlitShaderMap; + BlitShaderMap mBlitShaderMap; + + void add2DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps); + void add3DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps); + + struct SwizzleParameters + { + GLenum mDestinationType; + D3D11_SRV_DIMENSION mViewDimension; + }; + + static bool compareSwizzleParameters(const SwizzleParameters &a, const SwizzleParameters &b); + + typedef bool (*SwizzleParametersComparisonFunction)(const SwizzleParameters&, const SwizzleParameters &); + typedef std::map<SwizzleParameters, Shader, SwizzleParametersComparisonFunction> SwizzleShaderMap; + SwizzleShaderMap mSwizzleShaderMap; + + void addSwizzleShaderToMap(GLenum destType, D3D11_SRV_DIMENSION viewDimension, ID3D11PixelShader *ps); + + void buildShaderMap(); + void clearShaderMap(); + + ID3D11Buffer *mVertexBuffer; + ID3D11SamplerState *mPointSampler; + ID3D11SamplerState *mLinearSampler; + ID3D11RasterizerState *mScissorEnabledRasterizerState; + ID3D11RasterizerState *mScissorDisabledRasterizerState; + ID3D11DepthStencilState *mDepthStencilState; + + ID3D11InputLayout *mQuad2DIL; + ID3D11VertexShader *mQuad2DVS; + ID3D11PixelShader *mDepthPS; + + ID3D11InputLayout *mQuad3DIL; + ID3D11VertexShader *mQuad3DVS; + ID3D11GeometryShader *mQuad3DGS; + + ID3D11Buffer *mSwizzleCB; + + DISALLOW_COPY_AND_ASSIGN(Blit11); +}; + +} + +#endif // LIBGLESV2_BLIT11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp new file mode 100644 index 00000000000..5109779eab0 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp @@ -0,0 +1,869 @@ +#include "precompiled.h" +// +// Copyright (c) 2013-2014 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. +// + +// BufferStorage11.cpp Defines the BufferStorage11 class. + +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/Buffer.h" + +namespace rx +{ + +PackPixelsParams::PackPixelsParams() + : format(GL_NONE), + type(GL_NONE), + outputPitch(0), + packBuffer(NULL), + offset(0) +{} + +PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn, + const gl::PixelPackState &packIn, ptrdiff_t offsetIn) + : area(areaIn), + format(formatIn), + type(typeIn), + outputPitch(outputPitchIn), + packBuffer(packIn.pixelBuffer.get()), + pack(packIn.alignment, packIn.reverseRowOrder), + offset(offsetIn) +{} + +namespace gl_d3d11 +{ + +D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) +{ + bool readBit = ((access & GL_MAP_READ_BIT) != 0); + bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0); + + ASSERT(readBit || writeBit); + + // Note : we ignore the discard bit, because in D3D11, staging buffers + // don't accept the map-discard flag (discard only works for DYNAMIC usage) + + if (readBit && !writeBit) + { + return D3D11_MAP_READ; + } + else if (writeBit && !readBit) + { + return D3D11_MAP_WRITE; + } + else if (writeBit && readBit) + { + return D3D11_MAP_READ_WRITE; + } + else + { + UNREACHABLE(); + return D3D11_MAP_READ; + } +} + +} + +// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points +// - vertex/transform feedback buffers +// - index buffers +// - pixel unpack buffers +// - uniform buffers +class BufferStorage11::TypedBufferStorage11 +{ + public: + virtual ~TypedBufferStorage11() {} + + DataRevision getDataRevision() const { return mRevision; } + BufferUsage getUsage() const { return mUsage; } + size_t getSize() const { return mBufferSize; } + bool isMappable() const { return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_PIXEL_PACK); } + + void setDataRevision(DataRevision rev) { mRevision = rev; } + + virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, + size_t size, size_t destOffset) = 0; + virtual bool resize(size_t size, bool preserveData) = 0; + + virtual void *map(GLbitfield access) = 0; + virtual void unmap() = 0; + + protected: + TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage); + + Renderer11 *mRenderer; + DataRevision mRevision; + const BufferUsage mUsage; + size_t mBufferSize; +}; + +// A native buffer storage represents an underlying D3D11 buffer for a particular +// type of storage. +class BufferStorage11::NativeBuffer11 : public BufferStorage11::TypedBufferStorage11 +{ + public: + NativeBuffer11(Renderer11 *renderer, BufferUsage usage); + ~NativeBuffer11(); + + ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; } + + virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, + size_t size, size_t destOffset); + virtual bool resize(size_t size, bool preserveData); + + virtual void *map(GLbitfield access); + virtual void unmap(); + + private: + ID3D11Buffer *mNativeBuffer; + + static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize); +}; + +// Pack storage represents internal storage for pack buffers. We implement pack buffers +// as CPU memory, tied to a staging texture, for asynchronous texture readback. +class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorage11 +{ + public: + PackStorage11(Renderer11 *renderer); + ~PackStorage11(); + + virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, + size_t size, size_t destOffset); + virtual bool resize(size_t size, bool preserveData); + + virtual void *map(GLbitfield access); + virtual void unmap(); + + void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + + private: + + void flushQueuedPackCommand(); + + ID3D11Texture2D *mStagingTexture; + DXGI_FORMAT mTextureFormat; + gl::Extents mTextureSize; + std::vector<unsigned char> mMemoryBuffer; + PackPixelsParams *mQueuedPackCommand; + PackPixelsParams mPackParams; + bool mDataModified; +}; + +BufferStorage11::BufferStorage11(Renderer11 *renderer) + : mRenderer(renderer), + mMappedStorage(NULL), + mResolvedDataRevision(0), + mReadUsageCount(0), + mSize(0) +{ +} + +BufferStorage11::~BufferStorage11() +{ + for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++) + { + SafeDelete(it->second); + } +} + +BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage) +{ + ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage)); + return static_cast<BufferStorage11*>(bufferStorage); +} + +void *BufferStorage11::getData() +{ + NativeBuffer11 *stagingBuffer = getStagingBuffer(); + + if (!stagingBuffer) + { + // Out-of-memory + return NULL; + } + + if (stagingBuffer->getDataRevision() > mResolvedDataRevision) + { + if (stagingBuffer->getSize() > mResolvedData.size()) + { + mResolvedData.resize(stagingBuffer->getSize()); + } + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + } + + memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize()); + + context->Unmap(stagingBuffer->getNativeBuffer(), 0); + + mResolvedDataRevision = stagingBuffer->getDataRevision(); + } + + mReadUsageCount = 0; + + return mResolvedData.data(); +} + +void BufferStorage11::setData(const void* data, size_t size, size_t offset) +{ + size_t requiredSize = size + offset; + mSize = std::max(mSize, requiredSize); + + if (data) + { + NativeBuffer11 *stagingBuffer = getStagingBuffer(); + + if (!stagingBuffer) + { + // Out-of-memory + return; + } + + // Explicitly resize the staging buffer, preserving data if the new data will not + // completely fill the buffer + if (stagingBuffer->getSize() < requiredSize) + { + bool preserveData = (offset > 0); + if (!stagingBuffer->resize(requiredSize, preserveData)) + { + // Out-of-memory + return; + } + } + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY); + } + + unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset; + memcpy(offsetBufferPointer, data, size); + + context->Unmap(stagingBuffer->getNativeBuffer(), 0); + + stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); + } +} + +void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset) +{ + BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage); + if (sourceStorage11) + { + TypedBufferStorage11 *dest = getLatestStorage(); + if (!dest) + { + dest = getStagingBuffer(); + } + + TypedBufferStorage11 *source = sourceStorage11->getLatestStorage(); + if (source && dest) + { + // If copying to/from a pixel pack buffer, we must have a staging or + // pack buffer partner, because other native buffers can't be mapped + if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable()) + { + source = sourceStorage11->getStagingBuffer(); + } + else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable()) + { + dest = getStagingBuffer(); + } + + dest->copyFromStorage(source, sourceOffset, size, destOffset); + dest->setDataRevision(dest->getDataRevision() + 1); + } + + mSize = std::max<size_t>(mSize, destOffset + size); + } +} + +void BufferStorage11::clear() +{ + mSize = 0; + mResolvedDataRevision = 0; +} + +void BufferStorage11::markTransformFeedbackUsage() +{ + TypedBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + + if (transformFeedbackStorage) + { + transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1); + } +} + +size_t BufferStorage11::getSize() const +{ + return mSize; +} + +bool BufferStorage11::supportsDirectBinding() const +{ + return true; +} + +void BufferStorage11::markBufferUsage() +{ + mReadUsageCount++; + + const unsigned int usageLimit = 5; + + if (mReadUsageCount > usageLimit && mResolvedData.size() > 0) + { + mResolvedData.resize(0); + mResolvedDataRevision = 0; + } +} + +ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage) +{ + markBufferUsage(); + + TypedBufferStorage11 *typedBuffer = getStorage(usage); + + if (!typedBuffer) + { + // Storage out-of-memory + return NULL; + } + + ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, typedBuffer)); + + return static_cast<NativeBuffer11*>(typedBuffer)->getNativeBuffer(); +} + +ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat) +{ + TypedBufferStorage11 *storage = getStorage(BUFFER_USAGE_PIXEL_UNPACK); + + if (!storage) + { + // Storage out-of-memory + return NULL; + } + + ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, storage)); + ID3D11Buffer *buffer = static_cast<NativeBuffer11*>(storage)->getNativeBuffer(); + + 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); + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + bufferSRVDesc.Format = srvFormat; + + HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); + + mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV); + + return bufferSRV; +} + +void BufferStorage11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) +{ + PackStorage11 *packStorage = getPackStorage(); + + TypedBufferStorage11 *latestStorage = getLatestStorage(); + + if (packStorage) + { + packStorage->packPixels(srcTexture, srcSubresource, params); + packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); + } +} + +BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage) +{ + TypedBufferStorage11 *directBuffer = NULL; + auto directBufferIt = mTypedBuffers.find(usage); + if (directBufferIt != mTypedBuffers.end()) + { + directBuffer = directBufferIt->second; + } + + if (!directBuffer) + { + if (usage == BUFFER_USAGE_PIXEL_PACK) + { + directBuffer = new PackStorage11(mRenderer); + } + else + { + // buffer is not allocated, create it + directBuffer = new NativeBuffer11(mRenderer, usage); + } + + mTypedBuffers.insert(std::make_pair(usage, directBuffer)); + } + + // resize buffer + if (directBuffer->getSize() < mSize) + { + if (!directBuffer->resize(mSize, true)) + { + // Out of memory error + return NULL; + } + } + + TypedBufferStorage11 *latestBuffer = getLatestStorage(); + if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision()) + { + // if copying from a pack buffer to a non-staging native buffer, we must first + // copy through the staging buffer, because other native buffers can't be mapped + if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable()) + { + NativeBuffer11 *stagingBuffer = getStagingBuffer(); + + stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0); + directBuffer->setDataRevision(latestBuffer->getDataRevision()); + + latestBuffer = stagingBuffer; + } + + // if copyFromStorage returns true, the D3D buffer has been recreated + // and we should update our serial + if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0)) + { + updateSerial(); + } + directBuffer->setDataRevision(latestBuffer->getDataRevision()); + } + + return directBuffer; +} + +BufferStorage11::TypedBufferStorage11 *BufferStorage11::getLatestStorage() const +{ + // Even though we iterate over all the direct buffers, it is expected that only + // 1 or 2 will be present. + TypedBufferStorage11 *latestStorage = NULL; + DataRevision latestRevision = 0; + for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++) + { + TypedBufferStorage11 *storage = it->second; + if (!latestStorage || storage->getDataRevision() > latestRevision) + { + latestStorage = storage; + latestRevision = storage->getDataRevision(); + } + } + + return latestStorage; +} + +bool BufferStorage11::isMapped() const +{ + return mMappedStorage != NULL; +} + +void *BufferStorage11::map(GLbitfield access) +{ + ASSERT(!mMappedStorage); + + TypedBufferStorage11 *latestStorage = getLatestStorage(); + ASSERT(latestStorage); + + if (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK || + latestStorage->getUsage() == BUFFER_USAGE_STAGING) + { + mMappedStorage = latestStorage; + } + else + { + mMappedStorage = getStagingBuffer(); + } + + if (!mMappedStorage) + { + // Out-of-memory + return NULL; + } + + return mMappedStorage->map(access); +} + +void BufferStorage11::unmap() +{ + ASSERT(mMappedStorage); + mMappedStorage->unmap(); + mMappedStorage = NULL; +} + +BufferStorage11::NativeBuffer11 *BufferStorage11::getStagingBuffer() +{ + TypedBufferStorage11 *stagingStorage = getStorage(BUFFER_USAGE_STAGING); + + if (!stagingStorage) + { + // Out-of-memory + return NULL; + } + + ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, stagingStorage)); + return static_cast<NativeBuffer11*>(stagingStorage); +} + +BufferStorage11::PackStorage11 *BufferStorage11::getPackStorage() +{ + TypedBufferStorage11 *packStorage = getStorage(BUFFER_USAGE_PIXEL_PACK); + + if (!packStorage) + { + // Out-of-memory + return NULL; + } + + ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, packStorage)); + return static_cast<PackStorage11*>(packStorage); +} + +BufferStorage11::TypedBufferStorage11::TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage) + : mRenderer(renderer), + mUsage(usage), + mRevision(0), + mBufferSize(0) +{ +} + +BufferStorage11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage) + : TypedBufferStorage11(renderer, usage), + mNativeBuffer(NULL) +{ +} + +BufferStorage11::NativeBuffer11::~NativeBuffer11() +{ + SafeRelease(mNativeBuffer); +} + +// Returns true if it recreates the direct buffer +bool BufferStorage11::NativeBuffer11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, + size_t size, size_t destOffset) +{ + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + size_t requiredSize = sourceOffset + size; + bool createBuffer = !mNativeBuffer || mBufferSize < requiredSize; + + // (Re)initialize D3D buffer if needed + if (createBuffer) + { + bool preserveData = (destOffset > 0); + resize(source->getSize(), preserveData); + } + + if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK) + { + ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source)); + + unsigned char *sourcePointer = static_cast<unsigned char *>(source->map(GL_MAP_READ_BIT)) + sourceOffset; + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource); + UNUSED_ASSERTION_VARIABLE(hr); + ASSERT(SUCCEEDED(hr)); + + unsigned char *destPointer = static_cast<unsigned char *>(mappedResource.pData) + destOffset; + + // Offset bounds are validated at the API layer + ASSERT(sourceOffset + size <= destOffset + mBufferSize); + memcpy(destPointer, sourcePointer, size); + } + else + { + ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source)); + + D3D11_BOX srcBox; + srcBox.left = sourceOffset; + srcBox.right = sourceOffset + size; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source)); + ID3D11Buffer *sourceBuffer = static_cast<NativeBuffer11*>(source)->getNativeBuffer(); + + context->CopySubresourceRegion(mNativeBuffer, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox); + } + + return createBuffer; +} + +bool BufferStorage11::NativeBuffer11::resize(size_t size, bool preserveData) +{ + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_BUFFER_DESC bufferDesc; + fillBufferDesc(&bufferDesc, mRenderer, mUsage, size); + + ID3D11Buffer *newBuffer; + HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); + + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, false); + } + + if (mNativeBuffer && preserveData) + { + // We don't call resize if the buffer is big enough already. + ASSERT(mBufferSize <= size); + + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.right = mBufferSize; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeBuffer, 0, &srcBox); + } + + // No longer need the old buffer + SafeRelease(mNativeBuffer); + mNativeBuffer = newBuffer; + + mBufferSize = bufferDesc.ByteWidth; + + return true; +} + +void BufferStorage11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, + BufferUsage usage, unsigned int bufferSize) +{ + bufferDesc->ByteWidth = bufferSize; + bufferDesc->MiscFlags = 0; + bufferDesc->StructureByteStride = 0; + + switch (usage) + { + case BUFFER_USAGE_STAGING: + bufferDesc->Usage = D3D11_USAGE_STAGING; + bufferDesc->BindFlags = 0; + bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + break; + + case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_INDEX: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_PIXEL_UNPACK: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_UNIFORM: + bufferDesc->Usage = D3D11_USAGE_DYNAMIC; + bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + // Constant buffers must be of a limited size, and aligned to 16 byte boundaries + // For our purposes we ignore any buffer data past the maximum constant buffer size + bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u); + bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize()); + break; + + default: + UNREACHABLE(); + } +} + +void *BufferStorage11::NativeBuffer11::map(GLbitfield access) +{ + ASSERT(mUsage == BUFFER_USAGE_STAGING); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); + UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); + + HRESULT result = context->Map(mNativeBuffer, 0, d3dMapType, d3dMapFlag, &mappedResource); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); + + return mappedResource.pData; +} + +void BufferStorage11::NativeBuffer11::unmap() +{ + ASSERT(mUsage == BUFFER_USAGE_STAGING); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + context->Unmap(mNativeBuffer, 0); +} + +BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer) + : TypedBufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK), + mStagingTexture(NULL), + mTextureFormat(DXGI_FORMAT_UNKNOWN), + mQueuedPackCommand(NULL), + mDataModified(false) +{ +} + +BufferStorage11::PackStorage11::~PackStorage11() +{ + SafeRelease(mStagingTexture); + SafeDelete(mQueuedPackCommand); +} + +bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset, + size_t size, size_t destOffset) +{ + UNIMPLEMENTED(); + return false; +} + +bool BufferStorage11::PackStorage11::resize(size_t size, bool preserveData) +{ + if (size != mBufferSize) + { + mMemoryBuffer.resize(size, 0); + mBufferSize = size; + } + + return true; +} + +void *BufferStorage11::PackStorage11::map(GLbitfield access) +{ + // TODO: fast path + // We might be able to optimize out one or more memcpy calls by detecting when + // and if D3D packs the staging texture memory identically to how we would fill + // the pack buffer according to the current pack state. + + flushQueuedPackCommand(); + mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); + + return &mMemoryBuffer[0]; +} + +void BufferStorage11::PackStorage11::unmap() +{ + // No-op +} + +void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) +{ + flushQueuedPackCommand(); + mQueuedPackCommand = new PackPixelsParams(params); + + D3D11_TEXTURE2D_DESC textureDesc; + srcTexure->GetDesc(&textureDesc); + + if (mStagingTexture != NULL && + (mTextureFormat != textureDesc.Format || + mTextureSize.width != params.area.width || + mTextureSize.height != params.area.height)) + { + SafeRelease(mStagingTexture); + mTextureSize.width = 0; + mTextureSize.height = 0; + mTextureFormat = DXGI_FORMAT_UNKNOWN; + } + + if (mStagingTexture == NULL) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT hr; + + mTextureSize.width = params.area.width; + mTextureSize.height = params.area.height; + mTextureFormat = textureDesc.Format; + + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = params.area.width; + stagingDesc.Height = params.area.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = mTextureFormat; + stagingDesc.SampleDesc.Count = 1; + stagingDesc.SampleDesc.Quality = 0; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture); + ASSERT(SUCCEEDED(hr)); + } + + if (textureDesc.SampleDesc.Count > 1) + { + UNIMPLEMENTED(); + } + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + D3D11_BOX srcBox; + srcBox.left = params.area.x; + srcBox.right = params.area.x + params.area.width; + srcBox.top = params.area.y; + srcBox.bottom = params.area.y + params.area.height; + srcBox.front = 0; + srcBox.back = 1; + + // Asynchronous copy + immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); +} + +void BufferStorage11::PackStorage11::flushQueuedPackCommand() +{ + ASSERT(!mMemoryBuffer.empty()); + + if (mQueuedPackCommand) + { + mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]); + SafeDelete(mQueuedPackCommand); + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h new file mode 100644 index 00000000000..7934de192c1 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h @@ -0,0 +1,100 @@ +// +// Copyright (c) 2013-2014 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. +// + +// BufferStorage11.h Defines the BufferStorage11 class. + +#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ +#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ + +#include "libGLESv2/renderer/BufferStorage.h" +#include "libGLESv2/angletypes.h" + +namespace rx +{ +class Renderer; +class Renderer11; + +enum BufferUsage +{ + BUFFER_USAGE_STAGING, + BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, + BUFFER_USAGE_INDEX, + BUFFER_USAGE_PIXEL_UNPACK, + BUFFER_USAGE_PIXEL_PACK, + BUFFER_USAGE_UNIFORM, +}; + +struct PackPixelsParams +{ + PackPixelsParams(); + PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, + const gl::PixelPackState &pack, ptrdiff_t offset); + + gl::Rectangle area; + GLenum format; + GLenum type; + GLuint outputPitch; + gl::Buffer *packBuffer; + gl::PixelPackState pack; + ptrdiff_t offset; +}; + +typedef size_t DataRevision; + +class BufferStorage11 : public BufferStorage +{ + public: + explicit BufferStorage11(Renderer11 *renderer); + virtual ~BufferStorage11(); + + static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage); + + virtual void *getData(); + virtual void setData(const void* data, size_t size, size_t offset); + virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset); + virtual void clear(); + virtual void markTransformFeedbackUsage(); + virtual size_t getSize() const; + virtual bool supportsDirectBinding() const; + + ID3D11Buffer *getBuffer(BufferUsage usage); + ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); + void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + + virtual bool isMapped() const; + virtual void *map(GLbitfield access); + virtual void unmap(); + + private: + class TypedBufferStorage11; + class NativeBuffer11; + class PackStorage11; + + Renderer11 *mRenderer; + TypedBufferStorage11 *mMappedStorage; + + std::map<BufferUsage, TypedBufferStorage11*> mTypedBuffers; + + typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair; + std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews; + + std::vector<unsigned char> mResolvedData; + DataRevision mResolvedDataRevision; + unsigned int mReadUsageCount; + + size_t mSize; + + void markBufferUsage(); + NativeBuffer11 *getStagingBuffer(); + PackStorage11 *getPackStorage(); + + TypedBufferStorage11 *getStorage(BufferUsage usage); + TypedBufferStorage11 *getLatestStorage() const; +}; + +} + +#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.cpp new file mode 100644 index 00000000000..bb73241378e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.cpp @@ -0,0 +1,557 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Clear11.cpp: Framebuffer clear utility class. + +#include "libGLESv2/renderer/d3d11/Clear11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" + +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h" + +namespace rx +{ + +template <typename T> +static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangle *scissor, const gl::Color<T> &color, float depth, void *buffer) +{ + d3d11::PositionDepthColorVertex<T> *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex<T>*>(buffer); + + float depthClear = gl::clamp01(depth); + float left = -1.0f; + float right = 1.0f; + float top = -1.0f; + float bottom = 1.0f; + + // Clip the quad coordinates to the scissor if needed + if (scissor != NULL) + { + left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f); + right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f); + top = std::max(top, ((framebufferSize.height - scissor->y - scissor->height) / float(framebufferSize.height)) * 2.0f - 1.0f); + bottom = std::min(bottom, ((framebufferSize.height - scissor->y) / float(framebufferSize.height)) * 2.0f - 1.0f); + } + + d3d11::SetPositionDepthColorVertex<T>(vertices + 0, left, bottom, depthClear, color); + d3d11::SetPositionDepthColorVertex<T>(vertices + 1, left, top, depthClear, color); + d3d11::SetPositionDepthColorVertex<T>(vertices + 2, right, bottom, depthClear, color); + d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top, depthClear, color); +} + +template <unsigned int vsSize, unsigned int psSize> +Clear11::ClearShader Clear11::CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize]) +{ + HRESULT result; + + ClearShader shader = { 0 }; + + D3D11_INPUT_ELEMENT_DESC quadLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = device->CreateInputLayout(quadLayout, ArraySize(quadLayout), vsByteCode, vsSize, &shader.inputLayout); + ASSERT(SUCCEEDED(result)); + + result = device->CreateVertexShader(vsByteCode, vsSize, NULL, &shader.vertexShader); + ASSERT(SUCCEEDED(result)); + + result = device->CreatePixelShader(psByteCode, psSize, NULL, &shader.pixelShader); + ASSERT(SUCCEEDED(result)); + + return shader; +} + +Clear11::Clear11(Renderer11 *renderer) + : mRenderer(renderer), mClearBlendStates(StructLessThan<ClearBlendInfo>), mClearDepthStencilStates(StructLessThan<ClearDepthStencilInfo>), + mVertexBuffer(NULL), mRasterizerState(NULL) +{ + HRESULT result; + ID3D11Device *device = renderer->getDevice(); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex<float>) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer"); + + D3D11_RASTERIZER_DESC rsDesc; + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.FrontCounterClockwise = FALSE; + rsDesc.DepthBias = 0; + rsDesc.DepthBiasClamp = 0.0f; + rsDesc.SlopeScaledDepthBias = 0.0f; + rsDesc.DepthClipEnable = FALSE; + rsDesc.ScissorEnable = FALSE; + rsDesc.MultisampleEnable = FALSE; + rsDesc.AntialiasedLineEnable = FALSE; + + result = device->CreateRasterizerState(&rsDesc, &mRasterizerState); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state"); + + mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat); + mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint ); + mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint ); +} + +Clear11::~Clear11() +{ + for (ClearBlendStateMap::iterator i = mClearBlendStates.begin(); i != mClearBlendStates.end(); i++) + { + SafeRelease(i->second); + } + mClearBlendStates.clear(); + + SafeRelease(mFloatClearShader.inputLayout); + SafeRelease(mFloatClearShader.vertexShader); + SafeRelease(mFloatClearShader.pixelShader); + + SafeRelease(mUintClearShader.inputLayout); + SafeRelease(mUintClearShader.vertexShader); + SafeRelease(mUintClearShader.pixelShader); + + SafeRelease(mIntClearShader.inputLayout); + SafeRelease(mIntClearShader.vertexShader); + SafeRelease(mIntClearShader.pixelShader); + + for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++) + { + SafeRelease(i->second); + } + mClearDepthStencilStates.clear(); + + SafeRelease(mVertexBuffer); + SafeRelease(mRasterizerState); +} + +void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +{ + // First determine if a scissored clear is needed, this will always require drawing a quad. + // + // Otherwise, iterate over the color buffers which require clearing and determine if they can be + // cleared with ID3D11DeviceContext::ClearRenderTargetView... This requires: + // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer + // render targets as expected but does not work the other way around) + // 2) The format of the render target has no color channels that are currently masked out. + // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work. + // + // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView + // by checking if the stencil write mask covers the entire stencil. + // + // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color + // attribute. + + gl::Extents framebufferSize; + if (frameBuffer->getFirstColorbuffer() != NULL) + { + gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); + framebufferSize.width = attachment->getWidth(); + framebufferSize.height = attachment->getHeight(); + framebufferSize.depth = 1; + } + else if (frameBuffer->getDepthOrStencilbuffer() != NULL) + { + gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); + framebufferSize.width = attachment->getWidth(); + framebufferSize.height = attachment->getHeight(); + framebufferSize.depth = 1; + } + else + { + UNREACHABLE(); + return; + } + + if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || + clearParams.scissor.y >= framebufferSize.height || + clearParams.scissor.x + clearParams.scissor.width <= 0 || + clearParams.scissor.y + clearParams.scissor.height <= 0)) + { + // Scissor is enabled and the scissor rectangle is outside the renderbuffer + return; + } + + bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || + clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || + clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + std::vector<RenderTarget11*> maskedClearRenderTargets; + RenderTarget11* maskedClearDepthStencil = NULL; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + if (clearParams.clearColor[colorAttachment] && frameBuffer->isEnabledColorAttachment(colorAttachment)) + { + gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment); + if (attachment) + { + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getRenderTarget()); + if (!renderTarget) + { + ERR("Render target pointer unexpectedly null."); + return; + } + + GLenum internalFormat = attachment->getInternalFormat(); + GLenum actualFormat = attachment->getActualFormat(); + GLenum componentType = gl::GetComponentType(internalFormat, clientVersion); + if (clearParams.colorClearType == GL_FLOAT && + !(componentType == GL_FLOAT || componentType == GL_UNSIGNED_NORMALIZED || componentType == GL_SIGNED_NORMALIZED)) + { + ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-" + "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, internalFormat); + } + + GLuint internalRedBits = gl::GetRedBits(internalFormat, clientVersion); + GLuint internalGreenBits = gl::GetGreenBits(internalFormat, clientVersion); + GLuint internalBlueBits = gl::GetBlueBits(internalFormat, clientVersion); + GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat, clientVersion); + + if ((internalRedBits == 0 || !clearParams.colorMaskRed) && + (internalGreenBits == 0 || !clearParams.colorMaskGreen) && + (internalBlueBits == 0 || !clearParams.colorMaskBlue) && + (internalAlphaBits == 0 || !clearParams.colorMaskAlpha)) + { + // Every channel either does not exist in the render target or is masked out + continue; + } + else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT || + (internalRedBits > 0 && !clearParams.colorMaskRed) || + (internalGreenBits > 0 && !clearParams.colorMaskGreen) || + (internalBlueBits > 0 && !clearParams.colorMaskBlue) || + (internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) + { + // A scissored or masked clear is required + maskedClearRenderTargets.push_back(renderTarget); + } + else + { + // ID3D11DeviceContext::ClearRenderTargetView is possible + + ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); + if (!framebufferRTV) + { + ERR("Render target view pointer unexpectedly null."); + return; + } + + // Check if the actual format has a channel that the internal format does not and set them to the + // default values + GLuint actualRedBits = gl::GetRedBits(actualFormat, clientVersion); + GLuint actualGreenBits = gl::GetGreenBits(actualFormat, clientVersion); + GLuint actualBlueBits = gl::GetBlueBits(actualFormat, clientVersion); + GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat, clientVersion); + + const float clearValues[4] = + { + ((internalRedBits == 0 && actualRedBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + ((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + ((internalBlueBits == 0 && actualBlueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), + ((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + }; + + deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); + } + } + } + } + + if (clearParams.clearDepth || clearParams.clearStencil) + { + gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); + if (attachment) + { + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getDepthStencil()); + if (!renderTarget) + { + ERR("Depth stencil render target pointer unexpectedly null."); + return; + } + + GLenum actualFormat = attachment->getActualFormat(); + + unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << gl::GetStencilBits(actualFormat, clientVersion)) - 1 : 0; + bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + + if (needScissoredClear || needMaskedStencilClear) + { + maskedClearDepthStencil = renderTarget; + } + else + { + ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); + if (!framebufferDSV) + { + ERR("Depth stencil view pointer unexpectedly null."); + return; + } + + UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | + (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); + FLOAT depthClear = gl::clamp01(clearParams.depthClearValue); + UINT8 stencilClear = clearParams.stencilClearValue & 0xFF; + + deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); + } + } + } + + if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil) + { + // To clear the render targets and depth stencil in one pass: + // + // Render a quad clipped to the scissor rectangle which draws the clear color and a blend + // state that will perform the required color masking. + // + // The quad's depth is equal to the depth clear value with a depth stencil state that + // will enable or disable depth test/writes if the depth buffer should be cleared or not. + // + // The rasterizer state's stencil is set to always pass or fail based on if the stencil + // should be cleared or not with a stencil write mask of the stencil clear value. + // + // ====================================================================================== + // + // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- + // buffer that is not normalized fixed point or floating point with floating point values + // are undefined so we can just write floats to them and D3D11 will bit cast them to + // integers. + // + // Also, we don't have to worry about attempting to clear a normalized fixed/floating point + // buffer with integer values because there is no gl API call which would allow it, + // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to + // be a compatible clear type. + + // Bind all the render targets which need clearing + ASSERT(maskedClearRenderTargets.size() <= mRenderer->getMaxRenderTargets()); + std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size()); + for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) + { + ID3D11RenderTargetView *renderTarget = maskedClearRenderTargets[i]->getRenderTargetView(); + if (!renderTarget) + { + ERR("Render target pointer unexpectedly null."); + return; + } + + rtvs[i] = renderTarget; + } + ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL; + + ID3D11BlendState *blendState = getBlendState(clearParams, maskedClearRenderTargets); + const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + const UINT sampleMask = 0xFFFFFFFF; + + ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); + const UINT stencilClear = clearParams.stencilClearValue & 0xFF; + + // Set the vertices + UINT vertexStride = 0; + const UINT startIdx = 0; + const ClearShader* shader = NULL; + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); + return; + } + + const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL; + switch (clearParams.colorClearType) + { + case GL_FLOAT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); + vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>); + shader = &mFloatClearShader; + break; + + case GL_UNSIGNED_INT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); + vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>); + shader = &mUintClearShader; + break; + + case GL_INT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); + vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>); + shader = &mIntClearShader; + break; + + default: + UNREACHABLE(); + break; + } + + deviceContext->Unmap(mVertexBuffer, 0); + + // Set the viewport to be the same size as the framebuffer + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = framebufferSize.width; + viewport.Height = framebufferSize.height; + viewport.MinDepth = 0; + viewport.MaxDepth = 1; + deviceContext->RSSetViewports(1, &viewport); + + // Apply state + deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); + deviceContext->OMSetDepthStencilState(dsState, stencilClear); + deviceContext->RSSetState(mRasterizerState); + + // Apply shaders + deviceContext->IASetInputLayout(shader->inputLayout); + deviceContext->VSSetShader(shader->vertexShader, NULL, 0); + deviceContext->PSSetShader(shader->pixelShader, NULL, 0); + deviceContext->GSSetShader(NULL, NULL, 0); + + // Apply vertex buffer + deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); + deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // Apply render targets + deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv); + + // Draw the clear quad + deviceContext->Draw(4, 0); + + // Clean up + mRenderer->markAllStateDirty(); + } +} + +ID3D11BlendState *Clear11::getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + ClearBlendInfo blendKey = { 0 }; + for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if (i < rts.size()) + { + GLint internalFormat = rts[i]->getInternalFormat(); + + blendKey.maskChannels[i][0] = clearParams.clearColor ? (clearParams.colorMaskRed && gl::GetRedBits(internalFormat, clientVersion) > 0) : false; + blendKey.maskChannels[i][1] = clearParams.clearColor ? (clearParams.colorMaskGreen && gl::GetGreenBits(internalFormat, clientVersion) > 0) : false; + blendKey.maskChannels[i][2] = clearParams.clearColor ? (clearParams.colorMaskBlue && gl::GetBlueBits(internalFormat, clientVersion) > 0) : false; + blendKey.maskChannels[i][3] = clearParams.clearColor ? (clearParams.colorMaskAlpha && gl::GetAlphaBits(internalFormat, clientVersion) > 0) : false; + } + else + { + blendKey.maskChannels[i][0] = false; + blendKey.maskChannels[i][1] = false; + blendKey.maskChannels[i][2] = false; + blendKey.maskChannels[i][3] = false; + } + } + + ClearBlendStateMap::const_iterator i = mClearBlendStates.find(blendKey); + if (i != mClearBlendStates.end()) + { + return i->second; + } + else + { + D3D11_BLEND_DESC blendDesc = { 0 }; + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = (rts.size() > 1) ? TRUE : FALSE; + + for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + blendDesc.RenderTarget[i].BlendEnable = FALSE; + blendDesc.RenderTarget[i].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[i][0], + blendKey.maskChannels[i][1], + blendKey.maskChannels[i][2], + blendKey.maskChannels[i][3]); + } + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11BlendState* blendState = NULL; + HRESULT result = device->CreateBlendState(&blendDesc, &blendState); + if (FAILED(result) || !blendState) + { + ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); + return NULL; + } + + mClearBlendStates[blendKey] = blendState; + + return blendState; + } +} + +ID3D11DepthStencilState *Clear11::getDepthStencilState(const gl::ClearParameters &clearParams) +{ + ClearDepthStencilInfo dsKey = { 0 }; + dsKey.clearDepth = clearParams.clearDepth; + dsKey.clearStencil = clearParams.clearStencil; + dsKey.stencilWriteMask = clearParams.stencilWriteMask & 0xFF; + + ClearDepthStencilStateMap::const_iterator i = mClearDepthStencilStates.find(dsKey); + if (i != mClearDepthStencilStates.end()) + { + return i->second; + } + else + { + D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 }; + dsDesc.DepthEnable = dsKey.clearDepth ? TRUE : FALSE; + dsDesc.DepthWriteMask = dsKey.clearDepth ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.StencilEnable = dsKey.clearStencil ? TRUE : FALSE; + dsDesc.StencilReadMask = 0; + dsDesc.StencilWriteMask = dsKey.stencilWriteMask; + dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DepthStencilState* dsState = NULL; + HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState); + if (FAILED(result) || !dsState) + { + ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); + return NULL; + } + + mClearDepthStencilStates[dsKey] = dsState; + + return dsState; + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.h new file mode 100644 index 00000000000..e8e4c9ea2f1 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Clear11.h @@ -0,0 +1,77 @@ +// +// Copyright (c) 2013 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. +// + +// Clear11.h: Framebuffer clear utility class. + +#ifndef LIBGLESV2_RENDERER_CLEAR11_H_ +#define LIBGLESV2_RENDERER_CLEAR11_H_ + +#include "libGLESv2/angletypes.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class Renderer11; +class RenderTarget11; + +class Clear11 +{ + public: + explicit Clear11(Renderer11 *renderer); + ~Clear11(); + + // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied. + void clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + + private: + Renderer11 *mRenderer; + + struct ClearBlendInfo + { + bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; + }; + typedef bool (*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &); + typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap; + ClearBlendStateMap mClearBlendStates; + + ID3D11BlendState *getBlendState(const gl::ClearParameters &clearParams, const std::vector<RenderTarget11*>& rts); + + struct ClearShader + { + ID3D11InputLayout *inputLayout; + ID3D11VertexShader *vertexShader; + ID3D11PixelShader *pixelShader; + }; + ClearShader mFloatClearShader; + ClearShader mUintClearShader; + ClearShader mIntClearShader; + + template <unsigned int vsSize, unsigned int psSize> + static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize]); + + struct ClearDepthStencilInfo + { + bool clearDepth; + bool clearStencil; + UINT8 stencilWriteMask; + }; + typedef bool (*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &); + typedef std::map<ClearDepthStencilInfo, ID3D11DepthStencilState*, ClearDepthStencilInfoComparisonFunction> ClearDepthStencilStateMap; + ClearDepthStencilStateMap mClearDepthStencilStates; + + ID3D11DepthStencilState *getDepthStencilState(const gl::ClearParameters &clearParams); + + ID3D11Buffer *mVertexBuffer; + ID3D11RasterizerState *mRasterizerState; +}; + +} + +#endif // LIBGLESV2_RENDERER_CLEAR11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp new file mode 100644 index 00000000000..f2a75438fba --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp @@ -0,0 +1,71 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. + +#include "libGLESv2/renderer/d3d11/Fence11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +namespace rx +{ + +Fence11::Fence11(rx::Renderer11 *renderer) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Fence11::~Fence11() +{ + SafeRelease(mQuery); +} + +bool Fence11::isSet() const +{ + return mQuery != NULL; +} + +void Fence11::set() +{ + if (!mQuery) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + mRenderer->getDeviceContext()->End(mQuery); +} + +bool Fence11::test(bool flushCommandBuffer) +{ + ASSERT(mQuery); + + UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags); + + if (mRenderer->isDeviceLost()) + { + return gl::error(GL_OUT_OF_MEMORY, true); + } + + ASSERT(result == S_OK || result == S_FALSE); + return (result == S_OK); +} + +bool Fence11::hasError() const +{ + return mRenderer->isDeviceLost(); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Fence11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Fence11.h index a5398bca149..50c76217764 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Fence11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Fence11.h @@ -21,11 +21,10 @@ class Fence11 : public FenceImpl explicit Fence11(rx::Renderer11 *renderer); virtual ~Fence11(); - GLboolean isFence(); - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - void getFenceiv(GLenum pname, GLint *params); + bool isSet() const; + void set(); + bool test(bool flushCommandBuffer); + bool hasError() const; private: DISALLOW_COPY_AND_ASSIGN(Fence11); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Image11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Image11.cpp new file mode 100644 index 00000000000..aa9260d678a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Image11.cpp @@ -0,0 +1,461 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// Image11.h: Implements the rx::Image11 class, which acts as the interface to +// the actual underlying resources of a Texture + +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" + +#include "libGLESv2/main.h" +#include "common/utilities.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" + +namespace rx +{ + +Image11::Image11() +{ + mStagingTexture = NULL; + mRenderer = NULL; + mDXGIFormat = DXGI_FORMAT_UNKNOWN; +} + +Image11::~Image11() +{ + SafeRelease(mStagingTexture); +} + +Image11 *Image11::makeImage11(Image *img) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); + return static_cast<rx::Image11*>(img); +} + +void Image11::generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src) +{ + ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); + ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); + ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); + + MipGenerationFunction mipFunction = d3d11::GetMipGenerationFunction(src->getDXGIFormat()); + ASSERT(mipFunction != NULL); + + D3D11_MAPPED_SUBRESOURCE destMapped; + HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); + if (FAILED(destMapResult)) + { + ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult); + return; + } + + D3D11_MAPPED_SUBRESOURCE srcMapped; + HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped); + if (FAILED(srcMapResult)) + { + ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult); + + dest->unmap(); + return; + } + + const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData); + unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData); + + mipFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, + destData, destMapped.RowPitch, destMapped.DepthPitch); + + dest->unmap(); + src->unmap(); + + dest->markDirty(); +} + +bool Image11::isDirty() const +{ + // Make sure that this image is marked as dirty even if the staging texture hasn't been created yet + // if initialization is required before use. + return (mDirty && (mStagingTexture || gl_d3d11::RequiresTextureDataInitialization(mInternalFormat))); +} + +bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, 0, width, height, 1); +} + +bool Image11::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, 0, width, height, 1); +} + +bool Image11::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +{ + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, zoffset, width, height, depth); +} + +bool Image11::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) +{ + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, arrayLayer, xoffset, yoffset, 0, width, height, 1); +} + +bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) +{ + if (mWidth != width || + mHeight != height || + mInternalFormat != internalformat || + forceRelease) + { + mRenderer = Renderer11::makeRenderer11(renderer); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mWidth = width; + mHeight = height; + mDepth = depth; + mInternalFormat = internalformat; + mTarget = target; + + // compute the d3d format that will be used + mDXGIFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion); + mActualFormat = d3d11_gl::GetInternalFormat(mDXGIFormat, clientVersion); + mRenderable = gl_d3d11::GetRTVFormat(internalformat, clientVersion) != DXGI_FORMAT_UNKNOWN; + + SafeRelease(mStagingTexture); + mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat); + + return true; + } + + return false; +} + +DXGI_FORMAT Image11::getDXGIFormat() const +{ + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN); + + return mDXGIFormat; +} + +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input +// into the target pixel rectangle. +void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, clientVersion, width, unpackAlignment); + GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, type, clientVersion, width, height, unpackAlignment); + GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); + + LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, type, clientVersion); + ASSERT(loadFunction != NULL); + + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + if (FAILED(result)) + { + ERR("Could not map image for loading."); + return; + } + + void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch)); + loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); + + unmap(); +} + +void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) +{ + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, 1); + GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, height, 1); + + GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); + GLuint outputBlockWidth = d3d11::GetBlockWidth(mDXGIFormat); + GLuint outputBlockHeight = d3d11::GetBlockHeight(mDXGIFormat); + + ASSERT(xoffset % outputBlockWidth == 0); + ASSERT(yoffset % outputBlockHeight == 0); + + LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion); + ASSERT(loadFunction != NULL); + + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + if (FAILED(result)) + { + ERR("Could not map image for loading."); + return; + } + + void* offsetMappedData = (void*)((BYTE*)mappedImage.pData + ((yoffset / outputBlockHeight) * mappedImage.RowPitch + + (xoffset / outputBlockWidth) * outputPixelSize + + zoffset * mappedImage.DepthPitch)); + + loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch, + offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); + + unmap(); +} + +void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +{ + gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); + + if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat) + { + // No conversion needed-- use copyback fastpath + ID3D11Texture2D *colorBufferTexture = NULL; + unsigned int subresourceIndex = 0; + + if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + { + D3D11_TEXTURE2D_DESC textureDesc; + colorBufferTexture->GetDesc(&textureDesc); + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ID3D11Texture2D* srcTex = NULL; + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); + if (FAILED(result)) + { + ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); + return; + } + + deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); + subresourceIndex = 0; + } + else + { + srcTex = colorBufferTexture; + srcTex->AddRef(); + } + + D3D11_BOX srcBox; + srcBox.left = x; + srcBox.right = x + width; + srcBox.top = y; + srcBox.bottom = y + height; + srcBox.front = 0; + srcBox.back = 1; + + deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox); + + SafeRelease(srcTex); + SafeRelease(colorBufferTexture); + } + } + else + { + // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + if (FAILED(result)) + { + ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result); + return; + } + + // determine the offset coordinate into the destination buffer + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei rowOffset = gl::GetPixelBytes(mActualFormat, clientVersion) * xoffset; + void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; + + GLenum format = gl::GetFormat(mInternalFormat, clientVersion); + GLenum type = gl::GetType(mInternalFormat, clientVersion); + + mRenderer->readPixels(source, x, y, width, height, format, type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + + unmap(); + } +} + +ID3D11Resource *Image11::getStagingTexture() +{ + createStagingTexture(); + + return mStagingTexture; +} + +unsigned int Image11::getStagingSubresource() +{ + createStagingTexture(); + + return mStagingSubresource; +} + +void Image11::createStagingTexture() +{ + if (mStagingTexture) + { + return; + } + + const DXGI_FORMAT dxgiFormat = getDXGIFormat(); + + if (mWidth > 0 && mHeight > 0 && mDepth > 0) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + int lodOffset = 1; + GLsizei width = mWidth; + GLsizei height = mHeight; + + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); + + if (mTarget == GL_TEXTURE_3D) + { + ID3D11Texture3D *newTexture = NULL; + + D3D11_TEXTURE3D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.Depth = mDepth; + desc.MipLevels = lodOffset + 1; + desc.Format = dxgiFormat; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + { + std::vector<D3D11_SUBRESOURCE_DATA> initialData; + std::vector< std::vector<BYTE> > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height, + mDepth, lodOffset + 1, &initialData, &textureData); + + result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); + } + else + { + result = device->CreateTexture3D(&desc, NULL, &newTexture); + } + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + return gl::error(GL_OUT_OF_MEMORY); + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) + { + ID3D11Texture2D *newTexture = NULL; + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + { + std::vector<D3D11_SUBRESOURCE_DATA> initialData; + std::vector< std::vector<BYTE> > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getCurrentClientVersion(), width, height, + 1, lodOffset + 1, &initialData, &textureData); + + result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); + } + else + { + result = device->CreateTexture2D(&desc, NULL, &newTexture); + } + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + return gl::error(GL_OUT_OF_MEMORY); + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else + { + UNREACHABLE(); + } + } + + mDirty = false; +} + +HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +{ + createStagingTexture(); + + HRESULT result = E_FAIL; + + if (mStagingTexture) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); + + // this can fail if the device is removed (from TDR) + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } + else if (SUCCEEDED(result)) + { + mDirty = true; + } + } + + return result; +} + +void Image11::unmap() +{ + if (mStagingTexture) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->Unmap(mStagingTexture, mStagingSubresource); + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Image11.h index 11a6492dc86..300774cf231 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Image11.h @@ -34,24 +34,25 @@ class Image11 : public Image static Image11 *makeImage11(Image *img); - static void generateMipmap(Image11 *dest, Image11 *src); + static void generateMipmap(GLuint clientVersion, Image11 *dest, Image11 *src); virtual bool isDirty() const; - virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height); - virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); + virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); - virtual bool isRenderableFormat() const; DXGI_FORMAT getDXGIFormat() const; - virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input); + virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input); - virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); protected: HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); @@ -60,14 +61,14 @@ class Image11 : public Image private: DISALLOW_COPY_AND_ASSIGN(Image11); - ID3D11Texture2D *getStagingTexture(); + ID3D11Resource *getStagingTexture(); unsigned int getStagingSubresource(); void createStagingTexture(); Renderer11 *mRenderer; DXGI_FORMAT mDXGIFormat; - ID3D11Texture2D *mStagingTexture; + ID3D11Resource *mStagingTexture; unsigned int mStagingSubresource; }; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp index 66604c45582..afceac7012b 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer11.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp @@ -7,8 +7,8 @@ // IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. -#include "libGLESv2/renderer/IndexBuffer11.h" -#include "libGLESv2/renderer/Renderer11.h" +#include "libGLESv2/renderer/d3d11/IndexBuffer11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" namespace rx { @@ -22,20 +22,12 @@ IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) IndexBuffer11::~IndexBuffer11() { - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } + SafeRelease(mBuffer); } bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } + SafeRelease(mBuffer); updateSerial(); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h index 39a61946ad6..39a61946ad6 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/InputLayoutCache.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp index 1552f3a326e..7092dc5ddd4 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/InputLayoutCache.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp @@ -8,19 +8,35 @@ // InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches // D3D11 input layouts. -#include "libGLESv2/renderer/InputLayoutCache.h" -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage11.h" -#include "libGLESv2/renderer/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d11/InputLayoutCache.h" +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" #include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Context.h" +#include "libGLESv2/VertexAttribute.h" #include "libGLESv2/renderer/VertexDataManager.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" #include "third_party/murmurhash/MurmurHash3.h" namespace rx { +static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS], + gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) +{ + for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex]; + + if (translatedAttributes[attributeIndex].active) + { + inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute, + translatedAttribute.currentValueType); + } + } +} + const unsigned int InputLayoutCache::kMaxInputLayouts = 1024; InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts) @@ -31,7 +47,7 @@ InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInp mCurrentIL = NULL; for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - mCurrentBuffers[i] = -1; + mCurrentBuffers[i] = NULL; mCurrentVertexStrides[i] = -1; mCurrentVertexOffsets[i] = -1; } @@ -53,7 +69,7 @@ void InputLayoutCache::clear() { for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) { - i->second.inputLayout->Release(); + SafeRelease(i->second.inputLayout); } mInputLayoutMap.clear(); markDirty(); @@ -64,7 +80,7 @@ void InputLayoutCache::markDirty() mCurrentIL = NULL; for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - mCurrentBuffers[i] = -1; + mCurrentBuffers[i] = NULL; mCurrentVertexStrides[i] = -1; mCurrentVertexOffsets[i] = -1; } @@ -84,22 +100,17 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M InputLayoutKey ilKey = { 0 }; - ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL }; - unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - static const char* semanticName = "TEXCOORD"; for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { if (attributes[i].active) { - VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer); - BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL; - D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType); + DXGI_FORMAT dxgiFormat = gl_d3d11::GetNativeVertexFormat(vertexFormat); + // Record the type of the associated vertex shader vector in our key // This will prevent mismatched vertex shaders from using the same input layout GLint attributeSize; @@ -107,31 +118,28 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i]; - ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; + ilKey.elements[ilKey.elementCount].desc.Format = dxgiFormat; ilKey.elements[ilKey.elementCount].desc.InputSlot = i; ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor; ilKey.elementCount++; - - vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer(); - vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial(); - vertexStrides[i] = attributes[i].stride; - vertexOffsets[i] = attributes[i].offset; } } ID3D11InputLayout *inputLayout = NULL; - InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey); - if (i != mInputLayoutMap.end()) + InputLayoutMap::iterator keyIter = mInputLayoutMap.find(ilKey); + if (keyIter != mInputLayoutMap.end()) { - inputLayout = i->second.inputLayout; - i->second.lastUsedTime = mCounter++; + inputLayout = keyIter->second.inputLayout; + keyIter->second.lastUsedTime = mCounter++; } else { - ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); + gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; + GetInputLayout(attributes, shaderInputLayout); + ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout)); D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; for (unsigned int j = 0; j < ilKey.elementCount; ++j) @@ -159,7 +167,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M leastRecentlyUsed = i; } } - leastRecentlyUsed->second.inputLayout->Release(); + SafeRelease(leastRecentlyUsed->second.inputLayout); mInputLayoutMap.erase(leastRecentlyUsed); } @@ -176,16 +184,43 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M mCurrentIL = inputLayout; } + bool dirtyBuffers = false; + size_t minDiff = gl::MAX_VERTEX_ATTRIBS; + size_t maxDiff = 0; for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] || - vertexOffsets[i] != mCurrentVertexOffsets[i]) + ID3D11Buffer *buffer = NULL; + + if (attributes[i].active) { - mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]); - mCurrentBuffers[i] = vertexBufferSerials[i]; - mCurrentVertexStrides[i] = vertexStrides[i]; - mCurrentVertexOffsets[i] = vertexOffsets[i]; + VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer); + BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL; + + buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK) + : vertexBuffer->getBuffer(); } + + UINT vertexStride = attributes[i].stride; + UINT vertexOffset = attributes[i].offset; + + if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] || + vertexOffset != mCurrentVertexOffsets[i]) + { + dirtyBuffers = true; + minDiff = std::min(minDiff, static_cast<size_t>(i)); + maxDiff = std::max(maxDiff, static_cast<size_t>(i)); + + mCurrentBuffers[i] = buffer; + mCurrentVertexStrides[i] = vertexStride; + mCurrentVertexOffsets[i] = vertexOffset; + } + } + + if (dirtyBuffers) + { + ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS); + mDeviceContext->IASetVertexBuffers(minDiff, maxDiff - minDiff + 1, mCurrentBuffers + minDiff, + mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff); } return GL_NO_ERROR; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/InputLayoutCache.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h index bb1a8eebcf7..5d0ac60537d 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/InputLayoutCache.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h @@ -67,7 +67,7 @@ class InputLayoutCache }; ID3D11InputLayout *mCurrentIL; - unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; + ID3D11Buffer *mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.cpp new file mode 100644 index 00000000000..dcd1f99ab95 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.cpp @@ -0,0 +1,252 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// PixelTransfer11.cpp: +// Implementation for buffer-to-texture and texture-to-buffer copies. +// Used to implement pixel transfers from unpack and to pack buffers. +// + +#include "libGLESv2/renderer/d3d11/PixelTransfer11.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/Context.h" + +// Precompiled shaders +#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h" + +namespace rx +{ + +PixelTransfer11::PixelTransfer11(Renderer11 *renderer) + : mRenderer(renderer), + mBufferToTextureVS(NULL), + mBufferToTextureGS(NULL), + mParamsConstantBuffer(NULL), + mCopyRasterizerState(NULL), + mCopyDepthStencilState(NULL) +{ + HRESULT result = S_OK; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.FrontCounterClockwise = FALSE; + rasterDesc.DepthBias = 0; + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.ScissorEnable = FALSE; + rasterDesc.MultisampleEnable = FALSE; + rasterDesc.AntialiasedLineEnable = FALSE; + + result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState); + ASSERT(SUCCEEDED(result)); + + D3D11_DEPTH_STENCIL_DESC depthStencilDesc; + depthStencilDesc.DepthEnable = true; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState); + ASSERT(SUCCEEDED(result)); + + D3D11_BUFFER_DESC constantBufferDesc = { 0 }; + constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u); + constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constantBufferDesc.MiscFlags = 0; + constantBufferDesc.StructureByteStride = 0; + + result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer"); + + // init shaders + mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); + mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); + + buildShaderMap(); + + StructZero(&mParamsData); +} + +PixelTransfer11::~PixelTransfer11() +{ + for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + { + SafeRelease(shaderMapIt->second); + } + + mBufferToTexturePSMap.clear(); + + SafeRelease(mBufferToTextureVS); + SafeRelease(mBufferToTextureGS); + SafeRelease(mParamsConstantBuffer); + SafeRelease(mCopyRasterizerState); + SafeRelease(mCopyDepthStencilState); +} + +void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, + const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut) +{ + StructZero(parametersOut); + + float texelCenterX = 0.5f / static_cast<float>(destSize.width - 1); + float texelCenterY = 0.5f / static_cast<float>(destSize.height - 1); + + unsigned int bytesPerPixel = gl::GetPixelBytes(internalFormat, 3); + unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment); + unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel); + + parametersOut->FirstPixelOffset = offset; + parametersOut->PixelsPerRow = static_cast<unsigned int>(destArea.width); + parametersOut->RowStride = roundUp(parametersOut->PixelsPerRow, alignmentPixels); + parametersOut->RowsPerSlice = static_cast<unsigned int>(destArea.height); + parametersOut->PositionOffset[0] = texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f; + parametersOut->PositionOffset[1] = texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f; + parametersOut->PositionScale[0] = 2.0f / static_cast<float>(destSize.width); + parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height); +} + +bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +{ + gl::Extents destSize = destRenderTarget->getExtents(); + + if (destArea.x < 0 || destArea.x + destArea.width > destSize.width || + destArea.y < 0 || destArea.y + destArea.height > destSize.height || + destArea.z < 0 || destArea.z + destArea.depth > destSize.depth ) + { + return false; + } + + int clientVersion = mRenderer->getCurrentClientVersion(); + const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get(); + + ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); + + ID3D11PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); + ASSERT(pixelShader); + + // The SRV must be in the proper read format, which may be different from the destination format + // EG: for half float data, we can load full precision floats with implicit conversion + GLenum unsizedFormat = gl::GetFormat(destinationFormat, clientVersion); + GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType, clientVersion); + + DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat, clientVersion); + ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); + BufferStorage11 *bufferStorage11 = BufferStorage11::makeBufferStorage11(sourceBuffer.getStorage()); + ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); + ASSERT(bufferSRV != NULL); + + ID3D11RenderTargetView *textureRTV = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(textureRTV != NULL); + + CopyShaderParams shaderParams; + setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ID3D11ShaderResourceView *nullSRV = NULL; + ID3D11Buffer *nullBuffer = NULL; + UINT zero = 0; + + // Are we doing a 2D or 3D copy? + ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL); + + deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); + deviceContext->GSSetShader(geometryShader, NULL, 0); + deviceContext->PSSetShader(pixelShader, NULL, 0); + deviceContext->PSSetShaderResources(0, 1, &bufferSRV); + deviceContext->IASetInputLayout(NULL); + deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + + deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF); + deviceContext->RSSetState(mCopyRasterizerState); + + mRenderer->setOneTimeRenderTarget(textureRTV); + + if (!StructEquals(mParamsData, shaderParams)) + { + d3d11::SetBufferData(deviceContext, mParamsConstantBuffer, shaderParams); + mParamsData = shaderParams; + } + + deviceContext->VSSetConstantBuffers(0, 1, &mParamsConstantBuffer); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = destSize.width; + viewport.Height = destSize.height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); + + UINT numPixels = (destArea.width * destArea.height * destArea.depth); + deviceContext->Draw(numPixels, 0); + + // Unbind textures and render targets and vertex buffer + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); + + mRenderer->markAllStateDirty(); + + return true; +} + +void PixelTransfer11::buildShaderMap() +{ + ID3D11Device *device = mRenderer->getDevice(); + + mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps"); + mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps"); + mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps"); +} + +ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const +{ + int clientVersion = mRenderer->getCurrentClientVersion(); + GLenum componentType = gl::GetComponentType(internalFormat, clientVersion); + + if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED) + { + componentType = GL_FLOAT; + } + + auto shaderMapIt = mBufferToTexturePSMap.find(componentType); + return (shaderMapIt == mBufferToTexturePSMap.end() ? NULL : shaderMapIt->second); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.h new file mode 100644 index 00000000000..574140d1984 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/PixelTransfer11.h @@ -0,0 +1,80 @@ +// +// Copyright (c) 2013 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. +// + +// PixelTransfer11.h: +// Buffer-to-Texture and Texture-to-Buffer data transfers. +// Used to implement pixel unpack and pixel pack buffers in ES3. + +#ifndef LIBGLESV2_PIXELTRANSFER11_H_ +#define LIBGLESV2_PIXELTRANSFER11_H_ + +namespace gl +{ + +class Buffer; +struct Box; +struct Extents; +struct PixelUnpackState; + +} + +namespace rx +{ +class Renderer11; +class RenderTarget; + +class PixelTransfer11 +{ + public: + explicit PixelTransfer11(Renderer11 *renderer); + ~PixelTransfer11(); + + static bool supportsBufferToTextureCopy(GLenum internalFormat); + + // unpack: the source buffer is stored in the unpack state, and buffer strides + // offset: the start of the data within the unpack buffer + // destRenderTarget: individual slice/layer of a target texture + // destinationFormat/sourcePixelsType: determines shaders + shader parameters + // destArea: the sub-section of destRenderTarget to copy to + bool copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + + private: + + struct CopyShaderParams + { + unsigned int FirstPixelOffset; + unsigned int PixelsPerRow; + unsigned int RowStride; + unsigned int RowsPerSlice; + float PositionOffset[2]; + float PositionScale[2]; + int TexLocationOffset[2]; + int TexLocationScale[2]; + }; + + static void setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, + const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut); + + void buildShaderMap(); + ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const; + + Renderer11 *mRenderer; + + std::map<GLenum, ID3D11PixelShader *> mBufferToTexturePSMap; + ID3D11VertexShader *mBufferToTextureVS; + ID3D11GeometryShader *mBufferToTextureGS; + ID3D11Buffer *mParamsConstantBuffer; + CopyShaderParams mParamsData; + + ID3D11RasterizerState *mCopyRasterizerState; + ID3D11DepthStencilState *mCopyDepthStencilState; + +}; + +} + +#endif // LIBGLESV2_PIXELTRANSFER11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Query11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Query11.cpp new file mode 100644 index 00000000000..203f61f9f0a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Query11.cpp @@ -0,0 +1,155 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. + +#include "libGLESv2/renderer/d3d11/Query11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +static bool checkOcclusionQuery(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPixels) +{ + HRESULT result = context->GetData(query, numPixels, sizeof(UINT64), 0); + return (result == S_OK); +} + +static bool checkStreamOutPrimitivesWritten(ID3D11DeviceContext *context, ID3D11Query *query, UINT64 *numPrimitives) +{ + D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; + HRESULT result = context->GetData(query, &soStats, sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); + *numPrimitives = soStats.NumPrimitivesWritten; + return (result == S_OK); +} + +Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Query11::~Query11() +{ + SafeRelease(mQuery); +} + +void Query11::begin() +{ + if (mQuery == NULL) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); + queryDesc.MiscFlags = 0; + + if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + mRenderer->getDeviceContext()->Begin(mQuery); +} + +void Query11::end() +{ + ASSERT(mQuery); + mRenderer->getDeviceContext()->End(mQuery); + + mStatus = GL_FALSE; + mResult = GL_FALSE; +} + +GLuint Query11::getResult() +{ + if (mQuery != NULL) + { + while (!testQuery()) + { + Sleep(0); + // explicitly check for device loss, some drivers seem to return S_FALSE + // if the device is lost + if (mRenderer->testDeviceLost(true)) + { + return gl::error(GL_OUT_OF_MEMORY, 0); + } + } + } + + return mResult; +} + +GLboolean Query11::isResultAvailable() +{ + if (mQuery != NULL) + { + testQuery(); + } + + return mStatus; +} + +GLboolean Query11::testQuery() +{ + if (mQuery != NULL && mStatus != GL_TRUE) + { + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + bool queryFinished = false; + switch (getType()) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + { + UINT64 numPixels = 0; + queryFinished = checkOcclusionQuery(context, mQuery, &numPixels); + if (queryFinished) + { + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + } + } + break; + + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + { + UINT64 numPrimitives = 0; + queryFinished = checkStreamOutPrimitivesWritten(context, mQuery, &numPrimitives); + if (queryFinished) + { + mResult = static_cast<GLuint>(numPrimitives); + } + } + break; + + default: + UNREACHABLE(); + break; + } + + if (queryFinished) + { + mStatus = GL_TRUE; + } + else if (mRenderer->testDeviceLost(true)) + { + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + return mStatus; + } + + return GL_TRUE; // prevent blocking when query is null +} + +bool Query11::isStarted() const +{ + return (mQuery != NULL); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Query11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Query11.h index 0a03de77ca3..7a3df46d4f7 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Query11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Query11.h @@ -21,10 +21,11 @@ class Query11 : public QueryImpl Query11(rx::Renderer11 *renderer, GLenum type); virtual ~Query11(); - void begin(); - void end(); - GLuint getResult(); - GLboolean isResultAvailable(); + virtual void begin(); + virtual void end(); + virtual GLuint getResult(); + virtual GLboolean isResultAvailable(); + virtual bool isStarted() const; private: DISALLOW_COPY_AND_ASSIGN(Query11); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp index b3111af72be..b58569ad1fb 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderStateCache.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -8,8 +8,11 @@ // RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render // state objects. -#include "libGLESv2/renderer/RenderStateCache.h" -#include "libGLESv2/renderer/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/RenderStateCache.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" #include "common/debug.h" #include "third_party/murmurhash/MurmurHash3.h" @@ -17,6 +20,16 @@ namespace rx { +template <typename mapType> +static void ClearStateMap(mapType &map) +{ + for (mapType::iterator i = map.begin(); i != map.end(); i++) + { + SafeRelease(i->second.first); + } + map.clear(); +} + // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum // number of unique states of each type an application can create is 4096 @@ -46,32 +59,13 @@ void RenderStateCache::initialize(ID3D11Device *device) void RenderStateCache::clear() { - for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) - { - i->second.first->Release(); - } - mBlendStateCache.clear(); - - for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) - { - i->second.first->Release(); - } - mRasterizerStateCache.clear(); - - for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) - { - i->second.first->Release(); - } - mDepthStencilStateCache.clear(); - - for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) - { - i->second.first->Release(); - } - mSamplerStateCache.clear(); + ClearStateMap(mBlendStateCache); + ClearStateMap(mRasterizerStateCache); + ClearStateMap(mDepthStencilStateCache); + ClearStateMap(mSamplerStateCache); } -std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState) +std::size_t RenderStateCache::hashBlendState(const BlendStateKey &blendState) { static const unsigned int seed = 0xABCDEF98; @@ -80,12 +74,12 @@ std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState) return hash; } -bool RenderStateCache::compareBlendStates(const gl::BlendState &a, const gl::BlendState &b) +bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendStateKey &b) { - return memcmp(&a, &b, sizeof(gl::BlendState)) == 0; + return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; } -ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendState) +ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState) { if (!mDevice) { @@ -93,10 +87,38 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta return NULL; } - BlendStateMap::iterator i = mBlendStateCache.find(blendState); - if (i != mBlendStateCache.end()) + bool mrt = false; + + BlendStateKey key = { 0 }; + key.blendState = blendState; + for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { - BlendStateCounterPair &state = i->second; + gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i); + if (attachment) + { + if (i > 0) + { + mrt = true; + } + + key.rtChannels[i][0] = attachment->getRedSize() > 0; + key.rtChannels[i][1] = attachment->getGreenSize() > 0; + key.rtChannels[i][2] = attachment->getBlueSize() > 0; + key.rtChannels[i][3] = attachment->getAlphaSize() > 0; + } + else + { + key.rtChannels[i][0] = false; + key.rtChannels[i][1] = false; + key.rtChannels[i][2] = false; + key.rtChannels[i][3] = false; + } + } + + BlendStateMap::iterator keyIter = mBlendStateCache.find(key); + if (keyIter != mBlendStateCache.end()) + { + BlendStateCounterPair &state = keyIter->second; state.second = mCounter++; return state.first; } @@ -115,14 +137,14 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta leastRecentlyUsed = i; } } - leastRecentlyUsed->second.first->Release(); + SafeRelease(leastRecentlyUsed->second.first); mBlendStateCache.erase(leastRecentlyUsed); } // Create a new blend state and insert it into the cache D3D11_BLEND_DESC blendDesc = { 0 }; blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; - blendDesc.IndependentBlendEnable = FALSE; + blendDesc.IndependentBlendEnable = mrt ? TRUE : FALSE; for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { @@ -140,10 +162,10 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); } - rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendState.colorMaskRed, - blendState.colorMaskGreen, - blendState.colorMaskBlue, - blendState.colorMaskAlpha); + rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(key.rtChannels[i][0] && blendState.colorMaskRed, + key.rtChannels[i][1] && blendState.colorMaskGreen, + key.rtChannels[i][2] && blendState.colorMaskBlue, + key.rtChannels[i][3] && blendState.colorMaskAlpha); } ID3D11BlendState *dx11BlendState = NULL; @@ -154,7 +176,7 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendSta return NULL; } - mBlendStateCache.insert(std::make_pair(blendState, std::make_pair(dx11BlendState, mCounter++))); + mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++))); return dx11BlendState; } @@ -174,8 +196,7 @@ bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, cons return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; } -ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, - bool scissorEnabled, unsigned int depthSize) +ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled) { if (!mDevice) { @@ -183,15 +204,14 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer return NULL; } - RasterizerStateKey key; + RasterizerStateKey key = { 0 }; key.rasterizerState = rasterState; key.scissorEnabled = scissorEnabled; - key.depthSize = depthSize; - RasterizerStateMap::iterator i = mRasterizerStateCache.find(key); - if (i != mRasterizerStateCache.end()) + RasterizerStateMap::iterator keyIter = mRasterizerStateCache.find(key); + if (keyIter != mRasterizerStateCache.end()) { - RasterizerStateCounterPair &state = i->second; + RasterizerStateCounterPair &state = keyIter->second; state.second = mCounter++; return state.first; } @@ -210,7 +230,7 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer leastRecentlyUsed = i; } } - leastRecentlyUsed->second.first->Release(); + SafeRelease(leastRecentlyUsed->second.first); mRasterizerStateCache.erase(leastRecentlyUsed); } @@ -226,14 +246,23 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.CullMode = cullMode; rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE; - rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(depthSize)); rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though. - rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; rasterDesc.DepthClipEnable = TRUE; rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; rasterDesc.MultisampleEnable = rasterState.multiSample; rasterDesc.AntialiasedLineEnable = FALSE; + if (rasterState.polygonOffsetFill) + { + rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; + rasterDesc.DepthBias = (INT)rasterState.polygonOffsetUnits; + } + else + { + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBias = 0; + } + ID3D11RasterizerState *dx11RasterizerState = NULL; HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); if (FAILED(result) || !dx11RasterizerState) @@ -270,10 +299,10 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS return NULL; } - DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState); - if (i != mDepthStencilStateCache.end()) + DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState); + if (keyIter != mDepthStencilStateCache.end()) { - DepthStencilStateCounterPair &state = i->second; + DepthStencilStateCounterPair &state = keyIter->second; state.second = mCounter++; return state.first; } @@ -292,7 +321,7 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS leastRecentlyUsed = i; } } - leastRecentlyUsed->second.first->Release(); + SafeRelease(leastRecentlyUsed->second.first); mDepthStencilStateCache.erase(leastRecentlyUsed); } @@ -348,10 +377,10 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa return NULL; } - SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState); - if (i != mSamplerStateCache.end()) + SamplerStateMap::iterator keyIter = mSamplerStateCache.find(samplerState); + if (keyIter != mSamplerStateCache.end()) { - SamplerStateCounterPair &state = i->second; + SamplerStateCounterPair &state = keyIter->second; state.second = mCounter++; return state.first; } @@ -370,24 +399,25 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa leastRecentlyUsed = i; } } - leastRecentlyUsed->second.first->Release(); + SafeRelease(leastRecentlyUsed->second.first); mSamplerStateCache.erase(leastRecentlyUsed); } D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy); + samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, + samplerState.maxAnisotropy, samplerState.compareMode); samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS); samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT); - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MipLODBias = static_cast<float>(samplerState.lodOffset); + samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.wrapR); + samplerDesc.MipLODBias = 0; samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.compareFunc); samplerDesc.BorderColor[0] = 0.0f; samplerDesc.BorderColor[1] = 0.0f; samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset); - samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset); + samplerDesc.MinLOD = samplerState.minLod; + samplerDesc.MaxLOD = samplerState.maxLod; ID3D11SamplerState *dx11SamplerState = NULL; HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); @@ -403,4 +433,4 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa } } -}
\ No newline at end of file +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderStateCache.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h index f8b5111de48..7f3349627ae 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderStateCache.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -13,6 +13,11 @@ #include "libGLESv2/angletypes.h" #include "common/angleutils.h" +namespace gl +{ +class Framebuffer; +} + namespace rx { @@ -25,10 +30,8 @@ class RenderStateCache void initialize(ID3D11Device *device); void clear(); - // Increments refcount on the returned blend state, Release() must be called. - ID3D11BlendState *getBlendState(const gl::BlendState &blendState); - ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, - bool scissorEnabled, unsigned int depthSize); + ID3D11BlendState *getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState); + ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled); ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState); ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState); @@ -38,14 +41,19 @@ class RenderStateCache unsigned long long mCounter; // Blend state cache - static std::size_t hashBlendState(const gl::BlendState &blendState); - static bool compareBlendStates(const gl::BlendState &a, const gl::BlendState &b); + struct BlendStateKey + { + gl::BlendState blendState; + bool rtChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; + }; + static std::size_t hashBlendState(const BlendStateKey &blendState); + static bool compareBlendStates(const BlendStateKey &a, const BlendStateKey &b); static const unsigned int kMaxBlendStates; - typedef std::size_t (*BlendStateHashFunction)(const gl::BlendState &); - typedef bool (*BlendStateEqualityFunction)(const gl::BlendState &, const gl::BlendState &); + typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &); + typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &); typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair; - typedef std::unordered_map<gl::BlendState, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap; + typedef std::unordered_map<BlendStateKey, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap; BlendStateMap mBlendStateCache; // Rasterizer state cache @@ -53,7 +61,6 @@ class RenderStateCache { gl::RasterizerState rasterizerState; bool scissorEnabled; - unsigned int depthSize; }; static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState); static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp index 2667cc6fa78..38c55f3b2e2 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget11.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp @@ -8,26 +8,67 @@ // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers // retained by Renderbuffers. -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/Renderer11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" -#include "libGLESv2/renderer/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" #include "libGLESv2/main.h" namespace rx { -static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view) +static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) +{ + ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource); + if (texture1D) + { + D3D11_TEXTURE1D_DESC texDesc; + texture1D->GetDesc(&texDesc); + SafeRelease(texture1D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); + if (texture2D) + { + D3D11_TEXTURE2D_DESC texDesc; + texture2D->GetDesc(&texDesc); + SafeRelease(texture2D); + + *mipLevels = texDesc.MipLevels; + *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0; + + return true; + } + + ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource); + if (texture3D) + { + D3D11_TEXTURE3D_DESC texDesc; + texture3D->GetDesc(&texDesc); + SafeRelease(texture3D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + return false; +} + +static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; view->GetDesc(&rtvDesc); - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - unsigned int mipSlice = 0; unsigned int arraySlice = 0; - unsigned int mipLevels = texDesc.MipLevels; switch (rtvDesc.ViewDimension) { @@ -76,20 +117,19 @@ static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11Rende break; } + unsigned int mipLevels, samples; + getTextureProperties(resource, &mipLevels, &samples); + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view) +static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; view->GetDesc(&dsvDesc); - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - unsigned int mipSlice = 0; unsigned int arraySlice = 0; - unsigned int mipLevels = texDesc.MipLevels; switch (dsvDesc.ViewDimension) { @@ -123,7 +163,7 @@ static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11Depth arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; break; - case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_DSV_DIMENSION_UNKNOWN: UNIMPLEMENTED(); break; @@ -132,16 +172,37 @@ static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11Depth break; } + unsigned int mipLevels, samples; + getTextureProperties(resource, &mipLevels, &samples); + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) +RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) { mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = tex; + + mTexture = resource; + if (mTexture) + { + mTexture->AddRef(); + } + mRenderTarget = rtv; + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + mDepthStencil = NULL; + mShaderResource = srv; + if (mShaderResource) + { + mShaderResource->AddRef(); + } + mSubresourceIndex = 0; if (mRenderTarget && mTexture) @@ -149,26 +210,45 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, D3D11_RENDER_TARGET_VIEW_DESC desc; mRenderTarget->GetDesc(&desc); - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); + unsigned int mipLevels, samples; + getTextureProperties(mTexture, &mipLevels, &samples); mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); mWidth = width; mHeight = height; - mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; + mDepth = depth; + mSamples = samples; - mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); + mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); } } -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) +RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) { mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = tex; + + mTexture = resource; + if (mTexture) + { + mTexture->AddRef(); + } + mRenderTarget = NULL; + mDepthStencil = dsv; + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + mShaderResource = srv; + if (mShaderResource) + { + mShaderResource->AddRef(); + } + mSubresourceIndex = 0; if (mDepthStencil && mTexture) @@ -176,20 +256,21 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, D3D11_DEPTH_STENCIL_VIEW_DESC desc; mDepthStencil->GetDesc(&desc); - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); + unsigned int mipLevels, samples; + getTextureProperties(mTexture, &mipLevels, &samples); mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); mWidth = width; mHeight = height; - mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; + mDepth = depth; + mSamples = samples; - mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); + mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); } } -RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth) +RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) { mRenderer = Renderer11::makeRenderer11(renderer); mTexture = NULL; @@ -197,9 +278,15 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height mDepthStencil = NULL; mShaderResource = NULL; - DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format); + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion); + DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat, clientVersion); + DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat, clientVersion); + DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat, clientVersion); - int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); + DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat); + int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples); if (supportedSamples < 0) { gl::error(GL_OUT_OF_MEMORY); @@ -214,16 +301,35 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = requestedFormat; + desc.Format = texFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; - desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)); + + // If a rendertarget or depthstencil format exists for this texture format, + // we'll flag it to allow binding that way. Shader resource views are a little + // more complicated. + bool bindRTV = false, bindDSV = false, bindSRV = false; + bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN); + if (srvFormat != DXGI_FORMAT_UNKNOWN) + { + // Multisample targets flagged for binding as depth stencil cannot also be + // flagged for binding as SRV, so make certain not to add the SRV flag for + // these targets. + bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + } + + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + ID3D11Texture2D *texture = NULL; + HRESULT result = device->CreateTexture2D(&desc, NULL, &texture); + mTexture = texture; if (result == E_OUTOFMEMORY) { @@ -232,10 +338,28 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height } ASSERT(SUCCEEDED(result)); - if (depth) + if (bindSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = srvFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(mTexture); + gl::error(GL_OUT_OF_MEMORY); + return; + } + ASSERT(SUCCEEDED(result)); + } + + if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = requestedFormat; + dsvDesc.Format = dsvFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; @@ -243,82 +367,57 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (result == E_OUTOFMEMORY) { - mTexture->Release(); - mTexture = NULL; + SafeRelease(mTexture); + SafeRelease(mShaderResource); gl::error(GL_OUT_OF_MEMORY); + return; } ASSERT(SUCCEEDED(result)); } - else + + if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = requestedFormat; + rtvDesc.Format = rtvFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); if (result == E_OUTOFMEMORY) { - mTexture->Release(); - mTexture = NULL; + SafeRelease(mTexture); + SafeRelease(mShaderResource); + SafeRelease(mDepthStencil); gl::error(GL_OUT_OF_MEMORY); return; } ASSERT(SUCCEEDED(result)); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = requestedFormat; - srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); - - if (result == E_OUTOFMEMORY) + if (gl_d3d11::RequiresTextureDataInitialization(internalFormat)) { - mTexture->Release(); - mTexture = NULL; - mRenderTarget->Release(); - mRenderTarget = NULL; - gl::error(GL_OUT_OF_MEMORY); - return; + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + context->ClearRenderTargetView(mRenderTarget, clearValues); } - ASSERT(SUCCEEDED(result)); } } mWidth = width; mHeight = height; - mInternalFormat = format; + mDepth = 1; + mInternalFormat = internalFormat; mSamples = supportedSamples; - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat); + mActualFormat = d3d11_gl::GetInternalFormat(texFormat, renderer->getCurrentClientVersion()); mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); } RenderTarget11::~RenderTarget11() { - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mRenderTarget) - { - mRenderTarget->Release(); - mRenderTarget = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } - - if (mShaderResource) - { - mShaderResource->Release(); - mShaderResource = NULL; - } + SafeRelease(mTexture); + SafeRelease(mRenderTarget); + SafeRelease(mDepthStencil); + SafeRelease(mShaderResource); } RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) @@ -327,7 +426,12 @@ RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) return static_cast<rx::RenderTarget11*>(target); } -ID3D11Texture2D *RenderTarget11::getTexture() const +void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) +{ + // Currently a no-op +} + +ID3D11Resource *RenderTarget11::getTexture() const { return mTexture; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h index 97827f26397..ba9f76e5dec 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h @@ -20,14 +20,17 @@ class Renderer11; class RenderTarget11 : public RenderTarget { public: - RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); - RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); - RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth); + // RenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them + RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); + RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); + RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples); virtual ~RenderTarget11(); static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); - ID3D11Texture2D *getTexture() const; + virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height); + + ID3D11Resource *getTexture() const; ID3D11RenderTargetView *getRenderTargetView() const; ID3D11DepthStencilView *getDepthStencilView() const; ID3D11ShaderResourceView *getShaderResourceView() const; @@ -38,7 +41,7 @@ class RenderTarget11 : public RenderTarget DISALLOW_COPY_AND_ASSIGN(RenderTarget11); unsigned int mSubresourceIndex; - ID3D11Texture2D *mTexture; + ID3D11Resource *mTexture; ID3D11RenderTargetView *mRenderTarget; ID3D11DepthStencilView *mDepthStencil; ID3D11ShaderResourceView *mShaderResource; @@ -48,4 +51,4 @@ class RenderTarget11 : public RenderTarget } -#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_
\ No newline at end of file +#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp index 13ba355d582..c0ad111e8a9 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer11.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -8,38 +8,37 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. #include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" +#include "common/utilities.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/ShaderExecutable11.h" -#include "libGLESv2/renderer/SwapChain11.h" -#include "libGLESv2/renderer/Image11.h" -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/IndexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage11.h" +#include "libGLESv2/RenderBuffer.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d11/SwapChain11.h" +#include "libGLESv2/renderer/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/d3d11/IndexBuffer11.h" +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" #include "libGLESv2/renderer/VertexDataManager.h" #include "libGLESv2/renderer/IndexDataManager.h" -#include "libGLESv2/renderer/TextureStorage11.h" -#include "libGLESv2/renderer/Query11.h" -#include "libGLESv2/renderer/Fence11.h" - -#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h" - -#include "libGLESv2/renderer/shaders/compiled/clear11vs.h" -#include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h" -#include "libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h" - +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" +#include "libGLESv2/renderer/d3d11/Query11.h" +#include "libGLESv2/renderer/d3d11/Fence11.h" +#include "libGLESv2/renderer/d3d11/Blit11.h" +#include "libGLESv2/renderer/d3d11/Clear11.h" +#include "libGLESv2/renderer/d3d11/PixelTransfer11.h" #include "libEGL/Display.h" +// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process +// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed. +#ifndef ANGLE_SKIP_DXGI_1_2_CHECK +#define ANGLE_SKIP_DXGI_1_2_CHECK 0 +#endif + #ifdef _DEBUG // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples // and conformance tests. to enable all warnings, remove this define. @@ -74,24 +73,10 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc( mLineLoopIB = NULL; mTriangleFanIB = NULL; - mCopyResourcesInitialized = false; - mCopyVB = NULL; - mCopySampler = NULL; - mCopyIL = NULL; - mCopyVS = NULL; - mCopyRGBAPS = NULL; - mCopyRGBPS = NULL; - mCopyLumPS = NULL; - mCopyLumAlphaPS = NULL; - - mClearResourcesInitialized = false; - mClearVB = NULL; - mClearIL = NULL; - mClearVS = NULL; - mClearSinglePS = NULL; - mClearMultiplePS = NULL; - mClearScissorRS = NULL; - mClearNoScissorRS = NULL; + mBlit = NULL; + mPixelTransfer = NULL; + + mClear = NULL; mSyncQuery = NULL; @@ -112,7 +97,10 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc( mBGRATextureSupport = false; - mIsGeometryShaderActive = false; + mAppliedVertexShader = NULL; + mAppliedGeometryShader = NULL; + mCurPointGeometryShader = NULL; + mAppliedPixelShader = NULL; } Renderer11::~Renderer11() @@ -132,7 +120,7 @@ Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) EGLint Renderer11::initialize() { - if (!initializeCompiler()) + if (!mCompiler.initialize()) { return EGL_NOT_INITIALIZED; } @@ -203,6 +191,36 @@ EGLint Renderer11::initialize() } } +#if !ANGLE_SKIP_DXGI_1_2_CHECK + // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. + // The easiest way to check is to query for a IDXGIDevice2. + bool requireDXGI1_2 = false; + HWND hwnd = WindowFromDC(mDc); + if (hwnd) + { + DWORD currentProcessId = GetCurrentProcessId(); + DWORD wndProcessId; + GetWindowThreadProcessId(hwnd, &wndProcessId); + requireDXGI1_2 = (currentProcessId != wndProcessId); + } + else + { + requireDXGI1_2 = true; + } + + if (requireDXGI1_2) + { + IDXGIDevice2 *dxgiDevice2 = NULL; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2); + if (FAILED(result)) + { + ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n"); + return EGL_NOT_INITIALIZED; + } + SafeRelease(dxgiDevice2); + } +#endif + IDXGIDevice *dxgiDevice = NULL; result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); @@ -220,7 +238,7 @@ EGLint Renderer11::initialize() return EGL_NOT_INITIALIZED; } - dxgiDevice->Release(); + SafeRelease(dxgiDevice); mDxgiAdapter->GetDesc(&mAdapterDescription); memset(mDescription, 0, sizeof(mDescription)); @@ -251,43 +269,19 @@ EGLint Renderer11::initialize() filter.DenyList.pIDList = hideMessages; infoQueue->AddStorageFilterEntries(&filter); - - infoQueue->Release(); + SafeRelease(infoQueue); } #endif - unsigned int maxSupportedSamples = 0; - unsigned int rtFormatCount = ArraySize(RenderTargetFormats); - unsigned int dsFormatCount = ArraySize(DepthStencilFormats); - for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i) - { - DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount]; - if (format != DXGI_FORMAT_UNKNOWN) - { - UINT formatSupport; - result = mDevice->CheckFormatSupport(format, &formatSupport); - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) - { - MultisampleSupportInfo supportInfo; - - for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++) - { - result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]); - if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0) - { - maxSupportedSamples = std::max(j, maxSupportedSamples); - } - else - { - supportInfo.qualityLevels[j - 1] = 0; - } - } + mMaxSupportedSamples = 0; - mMultisampleSupportMap.insert(std::make_pair(format, supportInfo)); - } - } + const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats(); + for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i) + { + MultisampleSupportInfo support = getMultisampleSupportInfo(*i); + mMultisampleSupportMap.insert(std::make_pair(*i, support)); + mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples); } - mMaxSupportedSamples = maxSupportedSamples; initializeDevice(); @@ -361,6 +355,31 @@ EGLint Renderer11::initialize() } } + DXGI_FORMAT rgTextureFormats[] = + { + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + }; + + mRGTextureSupport = true; + for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++) + { + if (SUCCEEDED(mDevice->CheckFormatSupport(rgTextureFormats[i], &formatSupport))) + { + mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags; + mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags; + mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags; + } + else + { + mRGTextureSupport = false; + } + } + // Check compressed texture support const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D; @@ -429,6 +448,15 @@ void Renderer11::initializeDevice() mVertexDataManager = new VertexDataManager(this); mIndexDataManager = new IndexDataManager(this); + ASSERT(!mBlit); + mBlit = new Blit11(this); + + ASSERT(!mClear); + mClear = new Clear11(this); + + ASSERT(!mPixelTransfer); + mPixelTransfer = new PixelTransfer11(this); + markAllStateDirty(); } @@ -456,18 +484,23 @@ int Renderer11::generateConfigs(ConfigDesc **configDescList) if (depthStencilFormat != DXGI_FORMAT_UNKNOWN) { - UINT formatSupport = 0; - result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport); - depthStencilFormatOK = SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); + UINT depthStencilSupport = 0; + result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport); + depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); } if (depthStencilFormatOK) { + // FIXME: parse types from context version + ASSERT(d3d11_gl::GetInternalFormat(renderTargetFormat, 2) == d3d11_gl::GetInternalFormat(renderTargetFormat, 3)); + ASSERT(d3d11_gl::GetInternalFormat(depthStencilFormat, 2) == d3d11_gl::GetInternalFormat(depthStencilFormat, 3)); + ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat); + newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat, getCurrentClientVersion()); + newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat, getCurrentClientVersion()); newConfig.multiSample = 0; // FIXME: enumerate multi-sampling newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast + newConfig.es3Capable = true; (*configDescList)[numConfigs++] = newConfig; } @@ -527,6 +560,21 @@ SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum b return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); } +void Renderer11::generateSwizzle(gl::Texture *texture) +{ + if (texture) + { + TextureStorageInterface *texStorage = texture->getNativeTexture(); + if (texStorage) + { + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); + + storage11->generateSwizzles(texture->getSwizzleRed(), texture->getSwizzleGreen(), texture->getSwizzleBlue(), + texture->getSwizzleAlpha()); + } + } +} + void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { if (type == gl::SAMPLER_PIXEL) @@ -585,7 +633,6 @@ void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::Samp void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { ID3D11ShaderResourceView *textureSRV = NULL; - unsigned int serial = 0; bool forceSetTexture = false; if (texture) @@ -594,14 +641,15 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur if (texStorage) { TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); - textureSRV = storage11->getSRV(); + gl::SamplerState samplerState; + texture->getSamplerState(&samplerState); + textureSRV = storage11->getSRV(samplerState); } // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly // missing the shader resource view ASSERT(textureSRV != NULL); - serial = texture->getTextureSerial(); forceSetTexture = texture->hasDirtyImages(); } @@ -613,12 +661,12 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur return; } - if (forceSetTexture || mCurPixelTextureSerials[index] != serial) + if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) { mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); } - mCurPixelTextureSerials[index] = serial; + mCurPixelSRVs[index] = textureSRV; } else if (type == gl::SAMPLER_VERTEX) { @@ -628,22 +676,70 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur return; } - if (forceSetTexture || mCurVertexTextureSerials[index] != serial) + if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) { mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); } - mCurVertexTextureSerials[index] = serial; + mCurVertexSRVs[index] = textureSRV; } else UNREACHABLE(); } +bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) +{ + for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) + { + const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex]; + if (uniformBuffer) + { + BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage()); + ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + + if (!constantBuffer) + { + return false; + } + + if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial()) + { + mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex, + 1, &constantBuffer); + mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); + } + } + } + + for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) + { + const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex]; + if (uniformBuffer) + { + BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage()); + ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + + if (!constantBuffer) + { + return false; + } + + if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial()) + { + mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex, + 1, &constantBuffer); + mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); + } + } + } + + return true; +} + void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) { if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) { - ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled, - mCurDepthSize); + ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled); if (!dxRasterState) { ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" @@ -658,15 +754,15 @@ void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) mForceSetRasterState = false; } -void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, +void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) { if (mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 || - memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 || + memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 || sampleMask != mCurSampleMask) { - ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState); + ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState); if (!dxBlendState) { ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " @@ -723,7 +819,13 @@ void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilS "setting the default depth stencil state."); } - mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef)); + // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer + // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops + META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF); + META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF); + UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); + + mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); mCurDepthStencilState = depthStencilState; mCurStencilRef = stencilRef; @@ -877,7 +979,7 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment); + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment); if (!colorbuffer) { @@ -918,29 +1020,13 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) missingColorRenderTarget = false; } -#ifdef _DEBUG - // Workaround for Debug SETSHADERRESOURCES_HAZARD D3D11 warnings - for (unsigned int vertexSerialIndex = 0; vertexSerialIndex < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; vertexSerialIndex++) - { - if (colorbuffer->getTextureSerial() != 0 && mCurVertexTextureSerials[vertexSerialIndex] == colorbuffer->getTextureSerial()) - { - setTexture(gl::SAMPLER_VERTEX, vertexSerialIndex, NULL); - } - } - - for (unsigned int pixelSerialIndex = 0; pixelSerialIndex < gl::MAX_TEXTURE_IMAGE_UNITS; pixelSerialIndex++) - { - if (colorbuffer->getTextureSerial() != 0 && mCurPixelTextureSerials[pixelSerialIndex] == colorbuffer->getTextureSerial()) - { - setTexture(gl::SAMPLER_PIXEL, pixelSerialIndex, NULL); - } - } -#endif + // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent + // D3D11 warnings. } } // Get the depth stencil render buffer and serials - gl::Renderbuffer *depthStencil = NULL; + gl::FramebufferAttachment *depthStencil = NULL; unsigned int depthbufferSerial = 0; unsigned int stencilbufferSerial = 0; if (framebuffer->getDepthbufferType() != GL_NONE) @@ -968,9 +1054,6 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) stencilbufferSerial = depthStencil->getSerial(); } - // Extract the depth stencil sizes and view - unsigned int depthSize = 0; - unsigned int stencilSize = 0; ID3D11DepthStencilView* framebufferDSV = NULL; if (depthStencil) { @@ -998,9 +1081,6 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) renderTargetHeight = depthStencil->getHeight(); renderTargetFormat = depthStencil->getActualFormat(); } - - depthSize = depthStencil->getDepthSize(); - stencilSize = depthStencil->getStencilSize(); } // Apply the render target and depth stencil @@ -1016,15 +1096,13 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) mRenderTargetDesc.format = renderTargetFormat; mForceSetViewport = true; mForceSetScissor = true; + mForceSetBlendState = true; - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) + if (!mDepthStencilInitialized) { - mCurDepthSize = depthSize; mForceSetRasterState = true; } - mCurStencilSize = stencilSize; - for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) { mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex]; @@ -1035,13 +1113,16 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) mDepthStencilInitialized = true; } + invalidateFramebufferSwizzles(framebuffer); + return true; } -GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) +GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); + GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); if (err != GL_NO_ERROR) { return err; @@ -1056,28 +1137,27 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr if (err == GL_NO_ERROR) { - if (indexInfo->storage) - { - if (indexInfo->serial != mAppliedStorageIBSerial || indexInfo->startOffset != mAppliedIBOffset) - { - BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage); - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); - mDeviceContext->IASetIndexBuffer(storage->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset); + ID3D11Buffer *buffer = NULL; + DXGI_FORMAT bufferFormat = indexBuffer->getIndexFormat(); - mAppliedIBSerial = 0; - mAppliedStorageIBSerial = storage->getSerial(); - mAppliedIBOffset = indexInfo->startOffset; - } + if (indexInfo->storage) + { + BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage); + buffer = storage->getBuffer(BUFFER_USAGE_INDEX); } - else if (indexInfo->serial != mAppliedIBSerial || indexInfo->startOffset != mAppliedIBOffset) + else { - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + buffer = indexBuffer->getBuffer(); + } - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset); + if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) + { + mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); - mAppliedIBSerial = indexInfo->serial; - mAppliedStorageIBSerial = 0; + mAppliedIB = buffer; + mAppliedIBFormat = bufferFormat; mAppliedIBOffset = indexInfo->startOffset; } } @@ -1085,9 +1165,79 @@ GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementAr return err; } -void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) +void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) { - if (mode == GL_LINE_LOOP) + ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + bool requiresUpdate = false; + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + if (transformFeedbackBuffers[i]) + { + BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage()); + ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + + d3dBuffers[i] = buffer; + d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1; + } + else + { + d3dBuffers[i] = NULL; + d3dOffsets[i] = 0; + } + + if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i]) + { + requiresUpdate = true; + } + } + + if (requiresUpdate) + { + mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets); + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + mAppliedTFBuffers[i] = d3dBuffers[i]; + mAppliedTFOffsets[i] = offsets[i]; + } + } +} + +void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +{ + if (mode == GL_POINTS && transformFeedbackActive) + { + // Since point sprites are generated with a geometry shader, too many vertices will + // be written if transform feedback is active. To work around this, draw only the points + // with the stream out shader and no pixel shader to feed the stream out buffers and then + // draw again with the point sprite geometry shader to rasterize the point sprites. + + mDeviceContext->PSSetShader(NULL, NULL, 0); + + if (instances > 0) + { + mDeviceContext->DrawInstanced(count, instances, 0, 0); + } + else + { + mDeviceContext->Draw(count, 0); + } + + mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0); + mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0); + + if (instances > 0) + { + mDeviceContext->DrawInstanced(count, instances, 0, 0); + } + else + { + mDeviceContext->Draw(count, 0); + } + + mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0); + } + else if (mode == GL_LINE_LOOP) { drawLineLoop(count, GL_NONE, NULL, 0, NULL); } @@ -1105,7 +1255,8 @@ void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) } } -void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) +void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) { if (mode == GL_LINE_LOOP) { @@ -1215,13 +1366,15 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, return gl::error(GL_OUT_OF_MEMORY); } - if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset) - { - IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); + IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); + ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) + { mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); - mAppliedIBSerial = mLineLoopIB->getSerial(); - mAppliedStorageIBSerial = 0; + mAppliedIB = d3dIndexBuffer; + mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; } @@ -1324,13 +1477,15 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic return gl::error(GL_OUT_OF_MEMORY); } - if (mAppliedIBSerial != mTriangleFanIB->getSerial() || mAppliedIBOffset != indexBufferOffset) - { - IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); + IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); + ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) + { mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); - mAppliedIBSerial = mTriangleFanIB->getSerial(); - mAppliedStorageIBSerial = 0; + mAppliedIB = d3dIndexBuffer; + mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; } @@ -1344,54 +1499,72 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } } -void Renderer11::applyShaders(gl::ProgramBinary *programBinary) +void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]) { - unsigned int programBinarySerial = programBinary->getSerial(); - const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial); + ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); + ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); + ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); - if (updateProgramState) + ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); + + ID3D11PixelShader *pixelShader = NULL; + // Skip pixel shader if we're doing rasterizer discard. + if (!rasterizerDiscard) { - ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); - ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); + pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL); + } - ID3D11VertexShader *vertexShader = NULL; - if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader(); + ID3D11GeometryShader *geometryShader = NULL; + if (transformFeedbackActive) + { + geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL); + } + else if (mCurRasterState.pointDrawMode) + { + geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL); + } - ID3D11PixelShader *pixelShader = NULL; - if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader(); + bool dirtyUniforms = false; - mDeviceContext->PSSetShader(pixelShader, NULL, 0); + if (vertexShader != mAppliedVertexShader) + { mDeviceContext->VSSetShader(vertexShader, NULL, 0); + mAppliedVertexShader = vertexShader; + dirtyUniforms = true; + } - programBinary->dirtyAllUniforms(); - - mAppliedProgramBinarySerial = programBinarySerial; + if (geometryShader != mAppliedGeometryShader) + { + mDeviceContext->GSSetShader(geometryShader, NULL, 0); + mAppliedGeometryShader = geometryShader; + dirtyUniforms = true; } - // Only use the geometry shader currently for point sprite drawing - const bool usesGeometryShader = (programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode); + if (geometryExe && mCurRasterState.pointDrawMode) + { + mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader(); + } + else + { + mCurPointGeometryShader = NULL; + } - if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive) + if (pixelShader != mAppliedPixelShader) { - if (usesGeometryShader) - { - ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); - ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader(); - mDeviceContext->GSSetShader(geometryShader, NULL, 0); - } - else - { - mDeviceContext->GSSetShader(NULL, NULL, 0); - } + mDeviceContext->PSSetShader(pixelShader, NULL, 0); + mAppliedPixelShader = pixelShader; + dirtyUniforms = true; + } - mIsGeometryShaderActive = usesGeometryShader; + if (dirtyUniforms) + { + programBinary->dirtyAllUniforms(); } } -void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) +void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) { - ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); - ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable()); + const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountPS = 0; @@ -1399,25 +1572,30 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra bool vertexUniformsDirty = false; bool pixelUniformsDirty = false; - for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) + for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) { - const gl::Uniform *uniform = *uniform_iterator; + const gl::LinkedUniform &uniform = *uniformArray[uniformIndex]; - if (uniform->vsRegisterIndex >= 0) + if (uniform.isReferencedByVertexShader() && !uniform.isSampler()) { - totalRegisterCountVS += uniform->registerCount; - vertexUniformsDirty = vertexUniformsDirty || uniform->dirty; + totalRegisterCountVS += uniform.registerCount; + vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty); } - if (uniform->psRegisterIndex >= 0) + if (uniform.isReferencedByFragmentShader() && !uniform.isSampler()) { - totalRegisterCountPS += uniform->registerCount; - pixelUniformsDirty = pixelUniformsDirty || uniform->dirty; + totalRegisterCountPS += uniform.registerCount; + pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty); } } - ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS); - ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS); + const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage()); + const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage()); + ASSERT(vertexUniformStorage); + ASSERT(fragmentUniformStorage); + + ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer(); + ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer(); float (*mapVS)[4] = NULL; float (*mapPS)[4] = NULL; @@ -1426,6 +1604,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra { D3D11_MAPPED_SUBRESOURCE map = {0}; HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mapVS = (float(*)[4])map.pData; } @@ -1434,28 +1613,32 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra { D3D11_MAPPED_SUBRESOURCE map = {0}; HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mapPS = (float(*)[4])map.pData; } - for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) + for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) { - gl::Uniform *uniform = *uniform_iterator; + gl::LinkedUniform *uniform = uniformArray[uniformIndex]; - if (uniform->type != GL_SAMPLER_2D && uniform->type != GL_SAMPLER_CUBE) + if (!uniform->isSampler()) { - if (uniform->vsRegisterIndex >= 0 && mapVS) + unsigned int componentCount = (4 - uniform->registerElement); + + // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would + // overwrite previously written regions of memory. + + if (uniform->isReferencedByVertexShader() && mapVS) { - memcpy(mapVS + uniform->vsRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); + memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); } - if (uniform->psRegisterIndex >= 0 && mapPS) + if (uniform->isReferencedByFragmentShader() && mapPS) { - memcpy(mapPS + uniform->psRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); + memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); } } - - uniform->dirty = false; } if (mapVS) @@ -1492,6 +1675,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra constantBufferDescription.StructureByteStride = 0; HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); @@ -1508,6 +1692,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra constantBufferDescription.StructureByteStride = 0; HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); @@ -1535,265 +1720,8 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { - bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha; - bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && - !(clearParams.colorMaskRed && clearParams.colorMaskGreen && - clearParams.colorMaskBlue && alphaUnmasked); - - unsigned int stencilUnmasked = 0x0; - if (frameBuffer->hasStencil()) - { - unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); - stencilUnmasked = (0x1 << stencilSize) - 1; - } - bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && - (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; - - bool needScissoredClear = mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 || - mCurScissor.x + mCurScissor.width < mRenderTargetDesc.width || - mCurScissor.y + mCurScissor.height < mRenderTargetDesc.height); - - if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear) - { - maskedClear(clearParams, frameBuffer->usingExtendedDrawBuffers()); - } - else - { - if (clearParams.mask & GL_COLOR_BUFFER_BIT) - { - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) - { - if (frameBuffer->isEnabledColorAttachment(colorAttachment)) - { - gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer(colorAttachment); - if (renderbufferObject) - { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget()); - if (!renderTarget) - { - ERR("render target pointer unexpectedly null."); - return; - } - - ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); - if (!framebufferRTV) - { - ERR("render target view pointer unexpectedly null."); - return; - } - - const float clearValues[4] = { clearParams.colorClearValue.red, - clearParams.colorClearValue.green, - clearParams.colorClearValue.blue, - clearParams.colorClearValue.alpha }; - mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues); - } - } - } - } - if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT) - { - gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer(); - if (renderbufferObject) - { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getDepthStencil()); - if (!renderTarget) - { - ERR("render target pointer unexpectedly null."); - return; - } - - ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - ERR("depth stencil view pointer unexpectedly null."); - return; - } - - UINT clearFlags = 0; - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) - { - clearFlags |= D3D11_CLEAR_DEPTH; - } - if (clearParams.mask & GL_STENCIL_BUFFER_BIT) - { - clearFlags |= D3D11_CLEAR_STENCIL; - } - - float depthClear = gl::clamp01(clearParams.depthClearValue); - UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF; - - mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); - } - } - } -} - -void Renderer11::maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers) -{ - HRESULT result; - - if (!mClearResourcesInitialized) - { - ASSERT(!mClearVB && !mClearVS && !mClearSinglePS && !mClearMultiplePS && !mClearScissorRS && !mClearNoScissorRS); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - result = mDevice->CreateBuffer(&vbDesc, NULL, &mClearVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearVB, "Renderer11 masked clear vertex buffer"); - - D3D11_INPUT_ELEMENT_DESC quadLayout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &mClearIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearIL, "Renderer11 masked clear input layout"); - - result = mDevice->CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &mClearVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader"); - - result = mDevice->CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &mClearSinglePS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearSinglePS, "Renderer11 masked clear pixel shader (1 RT)"); - - result = mDevice->CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &mClearMultiplePS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearMultiplePS, "Renderer11 masked clear pixel shader (MRT)"); - - D3D11_RASTERIZER_DESC rsScissorDesc; - rsScissorDesc.FillMode = D3D11_FILL_SOLID; - rsScissorDesc.CullMode = D3D11_CULL_NONE; - rsScissorDesc.FrontCounterClockwise = FALSE; - rsScissorDesc.DepthBias = 0; - rsScissorDesc.DepthBiasClamp = 0.0f; - rsScissorDesc.SlopeScaledDepthBias = 0.0f; - rsScissorDesc.DepthClipEnable = FALSE; - rsScissorDesc.ScissorEnable = TRUE; - rsScissorDesc.MultisampleEnable = FALSE; - rsScissorDesc.AntialiasedLineEnable = FALSE; - - result = mDevice->CreateRasterizerState(&rsScissorDesc, &mClearScissorRS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearScissorRS, "Renderer11 masked clear scissor rasterizer state"); - - D3D11_RASTERIZER_DESC rsNoScissorDesc; - rsNoScissorDesc.FillMode = D3D11_FILL_SOLID; - rsNoScissorDesc.CullMode = D3D11_CULL_NONE; - rsNoScissorDesc.FrontCounterClockwise = FALSE; - rsNoScissorDesc.DepthBias = 0; - rsNoScissorDesc.DepthBiasClamp = 0.0f; - rsNoScissorDesc.SlopeScaledDepthBias = 0.0f; - rsNoScissorDesc.DepthClipEnable = FALSE; - rsNoScissorDesc.ScissorEnable = FALSE; - rsNoScissorDesc.MultisampleEnable = FALSE; - rsNoScissorDesc.AntialiasedLineEnable = FALSE; - - result = mDevice->CreateRasterizerState(&rsNoScissorDesc, &mClearNoScissorRS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearNoScissorRS, "Renderer11 masked clear no scissor rasterizer state"); - - mClearResourcesInitialized = true; - } - - // Prepare the depth stencil state to write depth values if the depth should be cleared - // and stencil values if the stencil should be cleared - gl::DepthStencilState glDSState; - glDSState.depthTest = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; - glDSState.depthFunc = GL_ALWAYS; - glDSState.depthMask = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; - glDSState.stencilTest = (clearParams.mask & GL_STENCIL_BUFFER_BIT) != 0; - glDSState.stencilFunc = GL_ALWAYS; - glDSState.stencilMask = 0; - glDSState.stencilFail = GL_REPLACE; - glDSState.stencilPassDepthFail = GL_REPLACE; - glDSState.stencilPassDepthPass = GL_REPLACE; - glDSState.stencilWritemask = clearParams.stencilWriteMask; - glDSState.stencilBackFunc = GL_ALWAYS; - glDSState.stencilBackMask = 0; - glDSState.stencilBackFail = GL_REPLACE; - glDSState.stencilBackPassDepthFail = GL_REPLACE; - glDSState.stencilBackPassDepthPass = GL_REPLACE; - glDSState.stencilBackWritemask = clearParams.stencilWriteMask; - - int stencilClear = clearParams.stencilClearValue & 0x000000FF; - - ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState); - - // Prepare the blend state to use a write mask if the color buffer should be cleared - gl::BlendState glBlendState; - glBlendState.blend = false; - glBlendState.sourceBlendRGB = GL_ONE; - glBlendState.destBlendRGB = GL_ZERO; - glBlendState.sourceBlendAlpha = GL_ONE; - glBlendState.destBlendAlpha = GL_ZERO; - glBlendState.blendEquationRGB = GL_FUNC_ADD; - glBlendState.blendEquationAlpha = GL_FUNC_ADD; - glBlendState.colorMaskRed = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false; - glBlendState.colorMaskGreen = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false; - glBlendState.colorMaskBlue = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false; - glBlendState.colorMaskAlpha = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false; - glBlendState.sampleAlphaToCoverage = false; - glBlendState.dither = false; - - static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - static const UINT sampleMask = 0xFFFFFFFF; - - ID3D11BlendState *blendState = mStateCache.getBlendState(glBlendState); - - // Set the vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = mDeviceContext->Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); - return; - } - - d3d11::PositionDepthColorVertex *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex*>(mappedResource.pData); - - float depthClear = gl::clamp01(clearParams.depthClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[0], -1.0f, 1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[2], 1.0f, 1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[3], 1.0f, -1.0f, depthClear, clearParams.colorClearValue); - - mDeviceContext->Unmap(mClearVB, 0); - - // Apply state - mDeviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); - mDeviceContext->OMSetDepthStencilState(dsState, stencilClear); - mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS); - - // Apply shaders - ID3D11PixelShader *pixelShader = usingExtendedDrawBuffers ? mClearMultiplePS : mClearSinglePS; - - mDeviceContext->IASetInputLayout(mClearIL); - mDeviceContext->VSSetShader(mClearVS, NULL, 0); - mDeviceContext->PSSetShader(pixelShader, NULL, 0); - mDeviceContext->GSSetShader(NULL, NULL, 0); - - // Apply vertex buffer - static UINT stride = sizeof(d3d11::PositionDepthColorVertex); - static UINT startIdx = 0; - mDeviceContext->IASetVertexBuffers(0, 1, &mClearVB, &stride, &startIdx); - mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // Draw the clear quad - mDeviceContext->Draw(4, 0); - - // Clean up - markAllStateDirty(); + mClear->clearFramebuffer(clearParams, frameBuffer); + invalidateFramebufferSwizzles(frameBuffer); } void Renderer11::markAllStateDirty() @@ -1810,12 +1738,12 @@ void Renderer11::markAllStateDirty() for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) { mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; + mCurVertexSRVs[i] = NULL; } for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) { mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; + mCurPixelSRVs[i] = NULL; } mForceSetBlendState = true; @@ -1824,16 +1752,32 @@ void Renderer11::markAllStateDirty() mForceSetScissor = true; mForceSetViewport = true; - mAppliedIBSerial = 0; - mAppliedStorageIBSerial = 0; + mAppliedIB = NULL; + mAppliedIBFormat = DXGI_FORMAT_UNKNOWN; mAppliedIBOffset = 0; - mAppliedProgramBinarySerial = 0; + mAppliedVertexShader = NULL; + mAppliedGeometryShader = NULL; + mCurPointGeometryShader = NULL; + mAppliedPixelShader = NULL; + + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + { + mAppliedTFBuffers[i] = NULL; + mAppliedTFOffsets[i] = 0; + } + memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); mInputLayoutCache.markDirty(); + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++) + { + mCurrentConstantBufferVS[i] = -1; + mCurrentConstantBufferPS[i] = -1; + } + mCurrentVertexConstantBuffer = NULL; mCurrentPixelConstantBuffer = NULL; mCurrentGeometryConstantBuffer = NULL; @@ -1846,39 +1790,13 @@ void Renderer11::releaseDeviceResources() mStateCache.clear(); mInputLayoutCache.clear(); - delete mVertexDataManager; - mVertexDataManager = NULL; - - delete mIndexDataManager; - mIndexDataManager = NULL; - - delete mLineLoopIB; - mLineLoopIB = NULL; - - delete mTriangleFanIB; - mTriangleFanIB = NULL; - - SafeRelease(mCopyVB); - SafeRelease(mCopySampler); - SafeRelease(mCopyIL); - SafeRelease(mCopyIL); - SafeRelease(mCopyVS); - SafeRelease(mCopyRGBAPS); - SafeRelease(mCopyRGBPS); - SafeRelease(mCopyLumPS); - SafeRelease(mCopyLumAlphaPS); - - mCopyResourcesInitialized = false; - - SafeRelease(mClearVB); - SafeRelease(mClearIL); - SafeRelease(mClearVS); - SafeRelease(mClearSinglePS); - SafeRelease(mClearMultiplePS); - SafeRelease(mClearScissorRS); - SafeRelease(mClearNoScissorRS); - - mClearResourcesInitialized = false; + SafeDelete(mVertexDataManager); + SafeDelete(mIndexDataManager); + SafeDelete(mLineLoopIB); + SafeDelete(mTriangleFanIB); + SafeDelete(mBlit); + SafeDelete(mClear); + SafeDelete(mPixelTransfer); SafeRelease(mDriverConstantBufferVS); SafeRelease(mDriverConstantBufferPS); @@ -1969,8 +1887,8 @@ bool Renderer11::testDeviceResettable() return false; } - dummyContext->Release(); - dummyDevice->Release(); + SafeRelease(dummyContext); + SafeRelease(dummyDevice); return true; } @@ -1979,31 +1897,17 @@ void Renderer11::release() { releaseDeviceResources(); - if (mDxgiFactory) - { - mDxgiFactory->Release(); - mDxgiFactory = NULL; - } - - if (mDxgiAdapter) - { - mDxgiAdapter->Release(); - mDxgiAdapter = NULL; - } + SafeRelease(mDxgiFactory); + SafeRelease(mDxgiAdapter); if (mDeviceContext) { mDeviceContext->ClearState(); mDeviceContext->Flush(); - mDeviceContext->Release(); - mDeviceContext = NULL; + SafeRelease(mDeviceContext); } - if (mDevice) - { - mDevice->Release(); - mDevice = NULL; - } + SafeRelease(mDevice); if (mD3d11Module) { @@ -2016,6 +1920,8 @@ void Renderer11::release() FreeLibrary(mDxgiModule); mDxgiModule = NULL; } + + mCompiler.release(); } bool Renderer11::resetDevice() @@ -2068,17 +1974,17 @@ bool Renderer11::getBGRATextureSupport() const return mBGRATextureSupport; } -bool Renderer11::getDXT1TextureSupport() +bool Renderer11::getDXT1TextureSupport() const { return mDXT1TextureSupport; } -bool Renderer11::getDXT3TextureSupport() +bool Renderer11::getDXT3TextureSupport() const { return mDXT3TextureSupport; } -bool Renderer11::getDXT5TextureSupport() +bool Renderer11::getDXT5TextureSupport() const { return mDXT5TextureSupport; } @@ -2088,35 +1994,66 @@ bool Renderer11::getDepthTextureSupport() const return mDepthTextureSupport; } -bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable) +bool Renderer11::getFloat32TextureSupport() const { - *renderable = mFloat32RenderSupport; - *filtering = mFloat32FilterSupport; return mFloat32TextureSupport; } -bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable) +bool Renderer11::getFloat32TextureFilteringSupport() const +{ + return mFloat32FilterSupport; +} + +bool Renderer11::getFloat32TextureRenderingSupport() const +{ + return mFloat32RenderSupport; +} + +bool Renderer11::getFloat16TextureSupport() const { - *renderable = mFloat16RenderSupport; - *filtering = mFloat16FilterSupport; return mFloat16TextureSupport; } -bool Renderer11::getLuminanceTextureSupport() +bool Renderer11::getFloat16TextureFilteringSupport() const +{ + return mFloat16FilterSupport; +} + +bool Renderer11::getFloat16TextureRenderingSupport() const +{ + return mFloat16RenderSupport; +} + +bool Renderer11::getRGB565TextureSupport() const +{ + return false; +} + +bool Renderer11::getLuminanceTextureSupport() const { return false; } -bool Renderer11::getLuminanceAlphaTextureSupport() +bool Renderer11::getLuminanceAlphaTextureSupport() const { return false; } +bool Renderer11::getRGTextureSupport() const +{ + return mRGTextureSupport; +} + bool Renderer11::getTextureFilterAnisotropySupport() const { return true; } +bool Renderer11::getPBOSupport() const +{ + return true; +} + float Renderer11::getTextureMaxAnisotropy() const { switch (mFeatureLevel) @@ -2131,7 +2068,7 @@ float Renderer11::getTextureMaxAnisotropy() const } } -bool Renderer11::getEventQuerySupport() +bool Renderer11::getEventQuerySupport() const { return true; } @@ -2196,13 +2133,125 @@ unsigned int Renderer11::getMaxFragmentUniformVectors() const unsigned int Renderer11::getMaxVaryingVectors() const { META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); + META_ASSERT(D3D11_VS_OUTPUT_REGISTER_COUNT <= D3D11_PS_INPUT_REGISTER_COUNT); + META_ASSERT(D3D10_VS_OUTPUT_REGISTER_COUNT <= D3D10_PS_INPUT_REGISTER_COUNT); + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings(); + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getMaxVertexShaderUniformBuffers() const +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT && + gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + switch (mFeatureLevel) { case D3D_FEATURE_LEVEL_11_0: - return D3D11_VS_OUTPUT_REGISTER_COUNT; + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: - return D3D10_VS_OUTPUT_REGISTER_COUNT; + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getMaxFragmentShaderUniformBuffers() const +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT && + gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers(); + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers(); + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getReservedVertexUniformBuffers() const +{ + // we reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +unsigned int Renderer11::getReservedFragmentUniformBuffers() const +{ + // we reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +unsigned int Renderer11::getReservedVaryings() const +{ + // We potentially reserve varyings for gl_Position, _dx_Position, gl_FragCoord and gl_PointSize + return 4; +} + + +unsigned int Renderer11::getMaxTransformFeedbackBuffers() const +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D11_SO_BUFFER_SLOT_COUNT && + gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D10_SO_BUFFER_SLOT_COUNT); + + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SO_BUFFER_SLOT_COUNT; + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SO_BUFFER_SLOT_COUNT; + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SO_BUFFER_SLOT_COUNT; + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getMaxTransformFeedbackSeparateComponents() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return getMaxTransformFeedbackInterleavedComponents() / getMaxTransformFeedbackBuffers(); + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero + // is used. + return 4; + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getMaxTransformFeedbackInterleavedComponents() const +{ + return (getMaxVaryingVectors() * 4); +} + +unsigned int Renderer11::getMaxUniformBufferSize() const +{ + // Each component is a 4-element vector of 4-byte units (floats) + const unsigned int bytesPerComponent = 4 * sizeof(float); + + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; default: UNREACHABLE(); return 0; } @@ -2274,6 +2323,24 @@ bool Renderer11::getPostSubBufferSupport() const return false; } +int Renderer11::getMaxRecommendedElementsIndices() const +{ + META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience. + return std::numeric_limits<GLint>::max(); +} + +int Renderer11::getMaxRecommendedElementsVertices() const +{ + META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience. + return std::numeric_limits<GLint>::max(); +} + int Renderer11::getMajorShaderModel() const { switch (mFeatureLevel) @@ -2344,6 +2411,28 @@ int Renderer11::getMaxTextureHeight() const } } +int Renderer11::getMaxTextureDepth() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; // 2048 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; // 2048 + default: UNREACHABLE(); return 0; + } +} + +int Renderer11::getMaxTextureArrayLayers() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; // 2048 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; // 512 + default: UNREACHABLE(); return 0; + } +} + bool Renderer11::get32BitIndexSupport() const { switch (mFeatureLevel) @@ -2370,6 +2459,66 @@ int Renderer11::getMaxSupportedSamples() const return mMaxSupportedSamples; } +GLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const +{ + DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion()); + MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); + return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0; +} + +GLsizei Renderer11::getNumSampleCounts(GLenum internalFormat) const +{ + unsigned int numCounts = 0; + + // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not + GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion()); + if (componentType != GL_INT && componentType != GL_UNSIGNED_INT) + { + DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion()); + MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); + + if (iter != mMultisampleSupportMap.end()) + { + const MultisampleSupportInfo& info = iter->second; + for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) + { + if (info.qualityLevels[i] > 0) + { + numCounts++; + } + } + } + } + + return numCounts; +} + +void Renderer11::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const +{ + // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not + GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion()); + if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) + { + return; + } + + DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion()); + MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); + + if (iter != mMultisampleSupportMap.end()) + { + const MultisampleSupportInfo& info = iter->second; + int bufPos = 0; + for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--) + { + if (info.qualityLevels[i] > 0) + { + params[bufPos++] = i + 1; + } + } + } +} + int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const { if (requested == 0) @@ -2404,7 +2553,10 @@ unsigned int Renderer11::getMaxRenderTargets() const return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: - return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 + // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader + // outputs to multiple RTs that are not bound. + // TODO: Remove pixel shader outputs for render targets that are not bound. + return 1; default: UNREACHABLE(); return 1; @@ -2418,7 +2570,10 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStor TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance()); TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance()); - mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); + mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); + + dest11->invalidateSwizzleCache(); + return true; } @@ -2432,7 +2587,44 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSt TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance()); TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance()); - mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); + mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); + + dest11->invalidateSwizzleCache(); + + return true; + } + + return false; +} + +bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +{ + if (source && dest) + { + TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance()); + TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance()); + + mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); + + dest11->invalidateSwizzleCache(); + + return true; + } + + return false; +} + +bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +{ + if (source && dest) + { + TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance()); + TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance()); + + mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); + + dest11->invalidateSwizzleCache(); + return true; } @@ -2442,7 +2634,7 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSt bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) { - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) { ERR("Failed to retrieve the color buffer from the frame buffer."); @@ -2484,14 +2676,18 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - gl::Rectangle destRect; - destRect.x = xoffset; - destRect.y = yoffset; - destRect.width = sourceRect.width; - destRect.height = sourceRect.height; + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + + gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), - dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); + // Use nearest filtering because source and destination are the same size for the direct + // copy + bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST); + + storage11->invalidateSwizzleCacheLevel(level); return ret; } @@ -2499,7 +2695,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) { - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) { ERR("Failed to retrieve the color buffer from the frame buffer."); @@ -2527,7 +2723,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level)); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2541,194 +2737,144 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - gl::Rectangle destRect; - destRect.x = xoffset; - destRect.y = yoffset; - destRect.width = sourceRect.width; - destRect.height = sourceRect.height; + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + + gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), - dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); + // Use nearest filtering because source and destination are the same size for the direct + // copy + bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST); + + storage11->invalidateSwizzleCacheLevel(level); return ret; } -bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, - ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat) +bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) { - HRESULT result; - - if (!mCopyResourcesInitialized) + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); + if (!colorbuffer) { - ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer"); - - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MipLODBias = 0.0f; - samplerDesc.MaxAnisotropy = 0; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - samplerDesc.BorderColor[0] = 0.0f; - samplerDesc.BorderColor[1] = 0.0f; - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = 0.0f; - samplerDesc.MaxLOD = 0.0f; - - result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler"); - - D3D11_INPUT_ELEMENT_DESC quadLayout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout"); - - result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader"); - - mCopyResourcesInitialized = true; + ERR("Failed to retrieve the color buffer from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); } - // Verify the source and destination area sizes - if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast<int>(sourceWidth) || - sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast<int>(sourceHeight) || - destArea.x < 0 || destArea.x + destArea.width > static_cast<int>(destWidth) || - destArea.y < 0 || destArea.y + destArea.height > static_cast<int>(destHeight)) + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (!sourceRenderTarget) { - return gl::error(GL_INVALID_VALUE, false); + ERR("Failed to retrieve the render target from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); } - // Set vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) + ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + if (!source) { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); + ERR("Failed to retrieve the render target view from the render target."); return gl::error(GL_OUT_OF_MEMORY, false); } - d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData); + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); + if (!storage11) + { + ERR("Failed to retrieve the texture storage from the destination."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Create a quad in homogeneous coordinates - float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f; - float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f; - float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f; - float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f; + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + if (!destRenderTarget) + { + ERR("Failed to retrieve the render target from the destination storage."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - float u1 = sourceArea.x / float(sourceWidth); - float v1 = sourceArea.y / float(sourceHeight); - float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth); - float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight); + ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); + if (!dest) + { + ERR("Failed to retrieve the render target view from the destination render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); - mDeviceContext->Unmap(mCopyVB, 0); + gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - static UINT stride = sizeof(d3d11::PositionTexCoordVertex); - static UINT startIdx = 0; - mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx); + // Use nearest filtering because source and destination are the same size for the direct + // copy + bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST); - // Apply state - mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); - mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); - mDeviceContext->RSSetState(NULL); + storage11->invalidateSwizzleCacheLevel(level); - // Apply shaders - mDeviceContext->IASetInputLayout(mCopyIL); - mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - mDeviceContext->VSSetShader(mCopyVS, NULL, 0); + return ret; +} - ID3D11PixelShader *ps = NULL; - switch(destFormat) +bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) +{ + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); + if (!colorbuffer) { - case GL_RGBA: ps = mCopyRGBAPS; break; - case GL_RGB: ps = mCopyRGBPS; break; - case GL_ALPHA: ps = mCopyRGBAPS; break; - case GL_BGRA_EXT: ps = mCopyRGBAPS; break; - case GL_LUMINANCE: ps = mCopyLumPS; break; - case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break; - default: UNREACHABLE(); ps = NULL; break; + ERR("Failed to retrieve the color buffer from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); } - mDeviceContext->PSSetShader(ps, NULL, 0); - mDeviceContext->GSSetShader(NULL, NULL, 0); - - // Unset the currently bound shader resource to avoid conflicts - static ID3D11ShaderResourceView *const nullSRV = NULL; - mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (!sourceRenderTarget) + { + ERR("Failed to retrieve the render target from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Apply render target - setOneTimeRenderTarget(dest); + ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + if (!source) + { + ERR("Failed to retrieve the render target view from the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = destWidth; - viewport.Height = destHeight; - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - mDeviceContext->RSSetViewports(1, &viewport); + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance()); + if (!storage11) + { + SafeRelease(source); + ERR("Failed to retrieve the texture storage from the destination."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Apply textures - mDeviceContext->PSSetShaderResources(0, 1, &source); - mDeviceContext->PSSetSamplers(0, 1, &mCopySampler); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + if (!destRenderTarget) + { + SafeRelease(source); + ERR("Failed to retrieve the render target from the destination storage."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Draw the quad - mDeviceContext->Draw(4, 0); + ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); + if (!dest) + { + ERR("Failed to retrieve the render target view from the destination render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } - // Unbind textures and render targets and vertex buffer - mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); - unapplyRenderTargets(); + gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - UINT zero = 0; - ID3D11Buffer *const nullBuffer = NULL; - mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + // Use nearest filtering because source and destination are the same size for the direct + // copy + bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST); - markAllStateDirty(); + storage11->invalidateSwizzleCacheLevel(level); - return true; + return ret; } void Renderer11::unapplyRenderTargets() @@ -2760,8 +2906,9 @@ RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) { // Note: depth stencil may be NULL for 0 sized surfaces renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), - swapChain11->getDepthStencilTexture(), NULL, - swapChain11->getWidth(), swapChain11->getHeight()); + swapChain11->getDepthStencilTexture(), + swapChain11->getDepthStencilShaderResource(), + swapChain11->getWidth(), swapChain11->getHeight(), 1); } else { @@ -2769,56 +2916,87 @@ RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getOffscreenTexture(), swapChain11->getRenderTargetShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight()); + swapChain11->getWidth(), swapChain11->getHeight(), 1); } return renderTarget; } -RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) +RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples) { - RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth); + RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples); return renderTarget; } -ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type) +ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers) { ShaderExecutable11 *executable = NULL; + HRESULT result; switch (type) { case rx::SHADER_VERTEX: { - ID3D11VertexShader *vshader = NULL; - HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader); + ID3D11VertexShader *vertexShader = NULL; + ID3D11GeometryShader *streamOutShader = NULL; + + result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); ASSERT(SUCCEEDED(result)); - if (vshader) + if (transformFeedbackVaryings.size() > 0) + { + std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration; + for (size_t i = 0; i < transformFeedbackVaryings.size(); i++) + { + const gl::LinkedVarying &varying = transformFeedbackVaryings[i]; + for (size_t j = 0; j < varying.semanticIndexCount; j++) + { + D3D11_SO_DECLARATION_ENTRY entry = { 0 }; + entry.Stream = 0; + entry.SemanticName = varying.semanticName.c_str(); + entry.SemanticIndex = varying.semanticIndex + j; + entry.StartComponent = 0; + entry.ComponentCount = gl::VariableRowCount(type); + entry.OutputSlot = (separatedOutputBuffers ? i : 0); + soDeclaration.push_back(entry); + } + } + + result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(), + NULL, 0, 0, NULL, &streamOutShader); + ASSERT(SUCCEEDED(result)); + } + + if (vertexShader) { - executable = new ShaderExecutable11(function, length, vshader); + executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); } } break; case rx::SHADER_PIXEL: { - ID3D11PixelShader *pshader = NULL; - HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader); + ID3D11PixelShader *pixelShader = NULL; + + result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); ASSERT(SUCCEEDED(result)); - if (pshader) + if (pixelShader) { - executable = new ShaderExecutable11(function, length, pshader); + executable = new ShaderExecutable11(function, length, pixelShader); } } break; case rx::SHADER_GEOMETRY: { - ID3D11GeometryShader *gshader = NULL; - HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader); + ID3D11GeometryShader *geometryShader = NULL; + + result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); ASSERT(SUCCEEDED(result)); - if (gshader) + if (geometryShader) { - executable = new ShaderExecutable11(function, length, gshader); + executable = new ShaderExecutable11(function, length, geometryShader); } } break; @@ -2830,36 +3008,98 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length return executable; } -ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) +ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround) { - const char *profile = NULL; - + const char *profileType = NULL; switch (type) { case rx::SHADER_VERTEX: - profile = "vs_4_0"; + profileType = "vs"; break; case rx::SHADER_PIXEL: - profile = "ps_4_0"; + profileType = "ps"; break; case rx::SHADER_GEOMETRY: - profile = "gs_4_0"; + profileType = "gs"; + break; + default: + UNREACHABLE(); + return NULL; + } + + const char *profileVersion = NULL; + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + profileVersion = "5_0"; + break; + case D3D_FEATURE_LEVEL_10_1: + profileVersion = "4_1"; + break; + case D3D_FEATURE_LEVEL_10_0: + profileVersion = "4_0"; break; default: UNREACHABLE(); return NULL; } - ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false); + char profile[32]; + snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion); + + UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0; + + if (gl::perfActive()) + { +#ifndef NDEBUG + flags = D3DCOMPILE_SKIP_OPTIMIZATION; +#endif + + flags |= D3DCOMPILE_DEBUG; + + std::string sourcePath = getTempPath(); + std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); + } + + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. + // Try the default flags first and if compilation fails, try some alternatives. + const UINT extraFlags[] = + { + flags, + flags | D3DCOMPILE_SKIP_VALIDATION, + flags | D3DCOMPILE_SKIP_OPTIMIZATION + }; + + const static char *extraFlagNames[] = + { + "default", + "skip validation", + "skip optimization" + }; + + int attempts = ArraySize(extraFlags); + + ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); if (!binary) + { return NULL; + } - ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type); - binary->Release(); + ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers); + SafeRelease(binary); return executable; } +rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize) +{ + return new UniformStorage11(this, storageSize); +} + VertexBuffer *Renderer11::createVertexBuffer() { return new VertexBuffer11(this); @@ -2885,7 +3125,51 @@ FenceImpl *Renderer11::createFence() return new Fence11(this); } -bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) +bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const +{ + 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, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +{ + ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); + return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); +} + +bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) { ASSERT(colorbuffer != NULL); @@ -2902,8 +3186,8 @@ bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned if (textureResource) { - HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)resource); - textureResource->Release(); + HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource); + SafeRelease(textureResource); if (SUCCEEDED(result)) { @@ -2922,11 +3206,11 @@ bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned } bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil) + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) { if (blitRenderTarget) { - gl::Renderbuffer *readBuffer = readTarget->getReadColorbuffer(); + gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer(); if (!readBuffer) { @@ -2940,7 +3224,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read { if (drawTarget->isEnabledColorAttachment(colorAttachment)) { - gl::Renderbuffer *drawBuffer = drawTarget->getColorbuffer(colorAttachment); + gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment); if (!drawBuffer) { @@ -2950,7 +3234,8 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false)) + if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, + blitRenderTarget, false, false)) { return false; } @@ -2958,10 +3243,10 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read } } - if (blitDepthStencil) + if (blitDepth || blitStencil) { - gl::Renderbuffer *readBuffer = readTarget->getDepthOrStencilbuffer(); - gl::Renderbuffer *drawBuffer = drawTarget->getDepthOrStencilbuffer(); + gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer(); + gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer(); if (!readBuffer) { @@ -2978,22 +3263,25 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true)) + if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, + false, blitDepth, blitStencil)) { return false; } } + invalidateFramebufferSwizzles(drawTarget); + return true; } -void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) +void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) { ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) { @@ -3003,11 +3291,18 @@ void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsi area.width = width; area.height = height; - readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, - packReverseRowOrder, packAlignment, pixels); + if (pack.pixelBuffer.get() != NULL) + { + rx::BufferStorage11 *packBufferStorage = BufferStorage11::makeBufferStorage11(pack.pixelBuffer.get()->getStorage()); + PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); + packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + } + else + { + readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + } - colorBufferTexture->Release(); - colorBufferTexture = NULL; + SafeRelease(colorBufferTexture); } } @@ -3020,7 +3315,7 @@ void Renderer11::generateMipmap(Image *dest, Image *src) { Image11 *dest11 = Image11::makeImage11(dest); Image11 *src11 = Image11::makeImage11(src); - Image11::generateMipmap(dest11, src11); + Image11::generateMipmap(getCurrentClientVersion(), dest11, src11); } TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) @@ -3029,278 +3324,58 @@ TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) return new TextureStorage11_2D(this, swapChain11); } -TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) +TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) { - return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height); + return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels); } -TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) +TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) { - return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size); + return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels); } -static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) +TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) { - if (sourceFormat == DXGI_FORMAT_A8_UNORM && - destFormat == GL_ALPHA && - destType == GL_UNSIGNED_BYTE) - { - return 1; - } - else if (sourceFormat == DXGI_FORMAT_R8G8B8A8_UNORM && - destFormat == GL_RGBA && - destType == GL_UNSIGNED_BYTE) - { - return 4; - } - else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM && - destFormat == GL_BGRA_EXT && - destType == GL_UNSIGNED_BYTE) - { - return 4; - } - else if (sourceFormat == DXGI_FORMAT_R16G16B16A16_FLOAT && - destFormat == GL_RGBA && - destType == GL_HALF_FLOAT_OES) - { - return 8; - } - else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT && - destFormat == GL_RGB && - destType == GL_FLOAT) - { - return 12; - } - else if (sourceFormat == DXGI_FORMAT_R32G32B32A32_FLOAT && - destFormat == GL_RGBA && - destType == GL_FLOAT) - { - return 16; - } - else - { - return 0; - } + return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels); } -static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, unsigned int x, - unsigned int y, int inputPitch, gl::Color *outColor) +TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) { - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - unsigned int rgba = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch); - outColor->red = (rgba & 0x000000FF) * (1.0f / 0x000000FF); - outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00); - outColor->blue = (rgba & 0x00FF0000) * (1.0f / 0x00FF0000); - outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000); - } - break; - - case DXGI_FORMAT_A8_UNORM: - { - outColor->red = 0.0f; - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = *(data + x + y * inputPitch) / 255.0f; - } - break; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - outColor->red = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 0); - outColor->green = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 1); - outColor->blue = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 2); - outColor->alpha = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 3); - } - break; - - case DXGI_FORMAT_R32G32B32_FLOAT: - { - outColor->red = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 0); - outColor->green = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 1); - outColor->blue = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 2); - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 0)); - outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 1)); - outColor->blue = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 2)); - outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 3)); - } - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - { - unsigned int bgra = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch); - outColor->red = (bgra & 0x00FF0000) * (1.0f / 0x00FF0000); - outColor->blue = (bgra & 0x000000FF) * (1.0f / 0x000000FF); - outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00); - outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000); - } - break; - - case DXGI_FORMAT_R8_UNORM: - { - outColor->red = *(data + x + y * inputPitch) / 255.0f; - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R8G8_UNORM: - { - unsigned short rg = *reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch); - - outColor->red = (rg & 0xFF00) * (1.0f / 0xFF00); - outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF); - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch)); - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16G16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 0)); - outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 1)); - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - default: - ERR("ReadPixelColor not implemented for DXGI format %u.", format); - UNIMPLEMENTED(); - break; - } + return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); } -static inline void writePixelColor(const gl::Color &color, GLenum format, GLenum type, unsigned int x, - unsigned int y, int outputPitch, void *outData) +void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels) { - unsigned char* byteData = reinterpret_cast<unsigned char*>(outData); - unsigned short* shortData = reinterpret_cast<unsigned short*>(outData); - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f); - byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f); - byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f); - byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f); - break; - - default: - ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; - - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.blue + 0.5f); - byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f); - byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.red + 0.5f); - byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f); - break; - - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast<unsigned short>(15 * color.alpha + 0.5f) << 12) | - (static_cast<unsigned short>(15 * color.red + 0.5f) << 8) | - (static_cast<unsigned short>(15 * color.green + 0.5f) << 4) | - (static_cast<unsigned short>(15 * color.blue + 0.5f) << 0); - break; - - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast<unsigned short>( color.alpha + 0.5f) << 15) | - (static_cast<unsigned short>(31 * color.red + 0.5f) << 10) | - (static_cast<unsigned short>(31 * color.green + 0.5f) << 5) | - (static_cast<unsigned short>(31 * color.blue + 0.5f) << 0); - break; - - default: - ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; + ASSERT(area.width >= 0); + ASSERT(area.height >= 0); - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_SHORT_5_6_5: - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast<unsigned short>(31 * color.blue + 0.5f) << 0) | - (static_cast<unsigned short>(63 * color.green + 0.5f) << 5) | - (static_cast<unsigned short>(31 * color.red + 0.5f) << 11); - break; + D3D11_TEXTURE2D_DESC textureDesc; + texture->GetDesc(&textureDesc); - case GL_UNSIGNED_BYTE: - byteData[3 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f); - byteData[3 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f); - byteData[3 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f); - break; + // Clamp read region to the defined texture boundaries, preventing out of bounds reads + // and reads of uninitialized data. + gl::Rectangle safeArea; + safeArea.x = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width)); + safeArea.y = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height)); + safeArea.width = gl::clamp(area.width + std::min(area.x, 0), 0, + static_cast<int>(textureDesc.Width) - safeArea.x); + safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0, + static_cast<int>(textureDesc.Height) - safeArea.y); - default: - ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; + ASSERT(safeArea.x >= 0 && safeArea.y >= 0); + ASSERT(safeArea.x + safeArea.width <= static_cast<int>(textureDesc.Width)); + ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height)); - default: - ERR("WritePixelColor not implemented for format 0x%X.", format); - UNIMPLEMENTED(); - break; + if (safeArea.width == 0 || safeArea.height == 0) + { + // no work to do + return; } -} - -void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, - GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, - GLint packAlignment, void *pixels) -{ - D3D11_TEXTURE2D_DESC textureDesc; - texture->GetDesc(&textureDesc); D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = area.width; - stagingDesc.Height = area.height; + stagingDesc.Width = safeArea.width; + stagingDesc.Height = safeArea.height; stagingDesc.MipLevels = 1; stagingDesc.ArraySize = 1; stagingDesc.Format = textureDesc.Format; @@ -3339,7 +3414,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou if (FAILED(result)) { ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result); - stagingTex->Release(); + SafeRelease(stagingTex); return; } @@ -3353,26 +3428,38 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou } D3D11_BOX srcBox; - srcBox.left = area.x; - srcBox.right = area.x + area.width; - srcBox.top = area.y; - srcBox.bottom = area.y + area.height; - srcBox.front = 0; - srcBox.back = 1; + srcBox.left = static_cast<UINT>(safeArea.x); + srcBox.right = static_cast<UINT>(safeArea.x + safeArea.width); + srcBox.top = static_cast<UINT>(safeArea.y); + srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height); + srcBox.front = 0; + srcBox.back = 1; mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox); - srcTex->Release(); - srcTex = NULL; + SafeRelease(srcTex); + + PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); + packPixels(stagingTex, packParams, pixels); + + SafeRelease(stagingTex); +} + +void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, void *pixelsOut) +{ + D3D11_TEXTURE2D_DESC textureDesc; + readTexture->GetDesc(&textureDesc); D3D11_MAPPED_SUBRESOURCE mapping; - mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping); + HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping); + UNUSED_ASSERTION_VARIABLE(hr); + ASSERT(SUCCEEDED(hr)); unsigned char *source; int inputPitch; - if (packReverseRowOrder) + if (params.pack.reverseRowOrder) { - source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (area.height - 1); + source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); inputPitch = -static_cast<int>(mapping.RowPitch); } else @@ -3381,57 +3468,81 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou inputPitch = static_cast<int>(mapping.RowPitch); } - unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, format, type); - if (fastPixelSize != 0) + GLuint clientVersion = getCurrentClientVersion(); + + GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format, clientVersion); + GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion); + GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion); + + GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion); + + if (sourceFormat == params.format && sourceType == params.type) { - unsigned char *dest = static_cast<unsigned char*>(pixels); - for (int j = 0; j < area.height; j++) + unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset; + for (int y = 0; y < params.area.height; y++) { - memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize); + memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize); } } - else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM && - format == GL_RGBA && - type == GL_UNSIGNED_BYTE) + else { - // Fast path for swapping red with blue - unsigned char *dest = static_cast<unsigned char*>(pixels); + GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type, clientVersion); + GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion); - for (int j = 0; j < area.height; j++) + ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type); + if (fastCopyFunc) { - for (int i = 0; i < area.width; i++) + // Fast copy is possible through some special function + for (int y = 0; y < params.area.height; y++) { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - *(unsigned int*)(dest + 4 * i + j * outputPitch) = - (argb & 0xFF00FF00) | // Keep alpha and green - (argb & 0x00FF0000) >> 16 | // Move red to blue - (argb & 0x000000FF) << 16; // Move blue to red + for (int x = 0; x < params.area.width; x++) + { + void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize; + void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + + fastCopyFunc(src, dest); + } } } - } - else - { - gl::Color pixelColor; - for (int j = 0; j < area.height; j++) + else { - for (int i = 0; i < area.width; i++) + ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format); + ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type, clientVersion); + + unsigned char temp[16]; // Maximum size of any Color<T> type used. + META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) && + sizeof(temp) >= sizeof(gl::ColorUI) && + sizeof(temp) >= sizeof(gl::ColorI)); + + for (int y = 0; y < params.area.height; y++) { - readPixelColor(source, textureDesc.Format, i, j, inputPitch, &pixelColor); - writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels); + for (int x = 0; x < params.area.width; x++) + { + void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize; + void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + + // readFunc and writeFunc will be using the same type of color, CopyTexImage + // will not allow the copy otherwise. + readFunc(src, temp); + writeFunc(temp, dest); + } } } } - mDeviceContext->Unmap(stagingTex, 0); - - stagingTex->Release(); - stagingTex = NULL; + mDeviceContext->Unmap(readTexture, 0); } -bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, bool wholeBufferCopy) +bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit) { - ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height); + // Since blitRenderbufferRect is called for each render buffer that needs to be blitted, + // it should never be the case that both color and depth/stencil need to be blitted at + // at the same time. + ASSERT(colorBlit != (depthBlit || stencilBlit)); + + bool result = true; RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); if (!drawRenderTarget) @@ -3440,8 +3551,10 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R return gl::error(GL_OUT_OF_MEMORY, false); } - ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture(); + ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); + ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView(); + ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView(); RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); if (!readRenderTarget) @@ -3450,44 +3563,152 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R return gl::error(GL_OUT_OF_MEMORY, false); } - ID3D11Texture2D *readTexture = NULL; + ID3D11Resource *readTexture = NULL; + ID3D11ShaderResourceView *readSRV = NULL; unsigned int readSubresource = 0; if (readRenderTarget->getSamples() > 0) { - readTexture = resolveMultisampledTexture(readRenderTarget11->getTexture(), readRenderTarget11->getSubresourceIndex()); - readSubresource = 0; + ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture(); + ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource); + + if (unresolvedTexture) + { + readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex()); + readSubresource = 0; + + SafeRelease(unresolvedTexture); + + HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV); + if (FAILED(hresult)) + { + SafeRelease(readTexture); + return gl::error(GL_OUT_OF_MEMORY, false); + } + } } else { readTexture = readRenderTarget11->getTexture(); readTexture->AddRef(); readSubresource = readRenderTarget11->getSubresourceIndex(); + readSRV = readRenderTarget11->getShaderResourceView(); + readSRV->AddRef(); } - if (!readTexture) + if (!readTexture || !readSRV) { + SafeRelease(readTexture); + SafeRelease(readSRV); ERR("Failed to retrieve the read render target view from the read render target."); return gl::error(GL_OUT_OF_MEMORY, false); } - D3D11_BOX readBox; - readBox.left = readRect.x; - readBox.right = readRect.x + readRect.width; - readBox.top = readRect.y; - readBox.bottom = readRect.y + readRect.height; - readBox.front = 0; - readBox.back = 1; + gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); + gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); + + bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); + + bool wholeBufferCopy = !scissorNeeded && + readRect.x == 0 && readRect.width == readSize.width && + readRect.y == 0 && readRect.height == readSize.height && + drawRect.x == 0 && drawRect.width == drawSize.width && + drawRect.y == 0 && drawRect.height == drawSize.height; + + bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height; + + bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0; + + bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width || + readRect.y < 0 || readRect.y + readRect.height > readSize.height || + drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || + drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; + + bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0; + bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0; + bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit); + + if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && + !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && + (!(depthBlit || stencilBlit) || wholeBufferCopy)) + { + UINT dstX = drawRect.x; + UINT dstY = drawRect.y; + + D3D11_BOX readBox; + readBox.left = readRect.x; + readBox.right = readRect.x + readRect.width; + readBox.top = readRect.y; + readBox.bottom = readRect.y + readRect.height; + readBox.front = 0; + readBox.back = 1; + + if (scissorNeeded) + { + // drawRect is guaranteed to have positive width and height because stretchRequired is false. + ASSERT(drawRect.width >= 0 || drawRect.height >= 0); + + if (drawRect.x < scissor->x) + { + dstX = scissor->x; + readBox.left += (scissor->x - drawRect.x); + } + if (drawRect.y < scissor->y) + { + dstY = scissor->y; + readBox.top += (scissor->y - drawRect.y); + } + if (drawRect.x + drawRect.width > scissor->x + scissor->width) + { + readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width)); + } + if (drawRect.y + drawRect.height > scissor->y + scissor->height) + { + readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height)); + } + } - // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox - // We also require complete framebuffer copies for depth-stencil blit. - D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; + // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox + // We also require complete framebuffer copies for depth-stencil blit. + D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; - mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0, - readTexture, readSubresource, pSrcBox); + mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, + readTexture, readSubresource, pSrcBox); + result = true; + } + else + { + gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1); + gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1); + + if (depthBlit && stencilBlit) + { + result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize, + drawTexture, drawSubresource, drawArea, drawSize, + scissor); + } + else if (depthBlit) + { + result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize, + scissor); + } + else if (stencilBlit) + { + result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize, + drawTexture, drawSubresource, drawArea, drawSize, + scissor); + } + else + { + GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat(), getCurrentClientVersion()); + result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, + scissor, format, filter); + } + } SafeRelease(readTexture); + SafeRelease(readSRV); - return true; + return result; } ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) @@ -3528,6 +3749,47 @@ ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, } } +void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel) +{ + ASSERT(attachment->isTexture()); + TextureStorage *texStorage = attachment->getTextureStorage(); + if (texStorage) + { + TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); + if (!texStorage11) + { + ERR("texture storage pointer unexpectedly null."); + return; + } + + texStorage11->invalidateSwizzleCacheLevel(mipLevel); + } +} + +void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer) +{ + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment); + if (attachment && attachment->isTexture()) + { + invalidateFBOAttachmentSwizzles(attachment, framebuffer->getColorbufferMipLevel(colorAttachment)); + } + } + + gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer(); + if (depthAttachment && depthAttachment->isTexture()) + { + invalidateFBOAttachmentSwizzles(depthAttachment, framebuffer->getDepthbufferMipLevel()); + } + + gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer(); + if (stencilAttachment && stencilAttachment->isTexture()) + { + invalidateFBOAttachmentSwizzles(stencilAttachment, framebuffer->getStencilbufferMipLevel()); + } +} + bool Renderer11::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; @@ -3548,4 +3810,47 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } +GLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const +{ + int clientVersion = getCurrentClientVersion(); + return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat, clientVersion), clientVersion); +} + +rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +{ + return gl_d3d11::GetVertexConversionType(vertexFormat); +} + +GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +{ + return d3d11::GetComponentType(gl_d3d11::GetNativeVertexFormat(vertexFormat)); +} + +Renderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format) +{ + MultisampleSupportInfo supportInfo = { 0 }; + + UINT formatSupport; + HRESULT result; + + result = mDevice->CheckFormatSupport(format, &formatSupport); + if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) + { + for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) + { + result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]); + if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0) + { + supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i); + } + else + { + supportInfo.qualityLevels[i - 1] = 0; + } + } + } + + return supportInfo; +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Renderer11.h index b86f485f40c..bbd0de49bc9 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/Renderer11.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -11,16 +11,17 @@ #include "common/angleutils.h" #include "libGLESv2/angletypes.h" -#include "libGLESv2/mathutil.h" +#include "common/mathutil.h" #include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/RenderStateCache.h" -#include "libGLESv2/renderer/InputLayoutCache.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/renderer/d3d11/RenderStateCache.h" +#include "libGLESv2/renderer/d3d11/InputLayoutCache.h" #include "libGLESv2/renderer/RenderTarget.h" namespace gl { -class Renderbuffer; +class FramebufferAttachment; } namespace rx @@ -29,6 +30,10 @@ namespace rx class VertexDataManager; class IndexDataManager; class StreamingIndexBufferInterface; +class Blit11; +class Clear11; +class PixelTransfer11; +struct PackPixelsParams; enum { @@ -54,11 +59,14 @@ class Renderer11 : public Renderer virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + virtual void generateSwizzle(gl::Texture *texture); virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask); virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW); @@ -69,13 +77,16 @@ class Renderer11 : public Renderer virtual bool applyPrimitiveType(GLenum mode, GLsizei count); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary); - virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); + virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]); + virtual void applyUniforms(const gl::ProgramBinary &programBinary); + virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); @@ -93,14 +104,20 @@ class Renderer11 : public Renderer virtual GUID getAdapterIdentifier() const; virtual bool getBGRATextureSupport() const; - virtual bool getDXT1TextureSupport(); - virtual bool getDXT3TextureSupport(); - virtual bool getDXT5TextureSupport(); - virtual bool getEventQuerySupport(); - virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); - virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); - virtual bool getLuminanceTextureSupport(); - virtual bool getLuminanceAlphaTextureSupport(); + virtual bool getDXT1TextureSupport() const; + virtual bool getDXT3TextureSupport() const; + virtual bool getDXT5TextureSupport() const; + virtual bool getEventQuerySupport() const; + virtual bool getFloat32TextureSupport() const; + virtual bool getFloat32TextureFilteringSupport() const; + virtual bool getFloat32TextureRenderingSupport() const; + virtual bool getFloat16TextureSupport() const; + virtual bool getFloat16TextureFilteringSupport() const; + virtual bool getFloat16TextureRenderingSupport() const; + virtual bool getRGB565TextureSupport() const; + virtual bool getLuminanceTextureSupport() const; + virtual bool getLuminanceAlphaTextureSupport() const; + virtual bool getRGTextureSupport() const; virtual unsigned int getMaxVertexTextureImageUnits() const; virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; @@ -108,26 +125,43 @@ class Renderer11 : public Renderer virtual unsigned int getMaxVertexUniformVectors() const; virtual unsigned int getMaxFragmentUniformVectors() const; virtual unsigned int getMaxVaryingVectors() const; + virtual unsigned int getMaxVertexShaderUniformBuffers() const; + virtual unsigned int getMaxFragmentShaderUniformBuffers() const; + virtual unsigned int getReservedVertexUniformBuffers() const; + virtual unsigned int getReservedFragmentUniformBuffers() const; + unsigned int getReservedVaryings() const; + virtual unsigned int getMaxTransformFeedbackBuffers() const; + virtual unsigned int getMaxTransformFeedbackSeparateComponents() const; + virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const; + virtual unsigned int getMaxUniformBufferSize() const; virtual bool getNonPower2TextureSupport() const; virtual bool getDepthTextureSupport() const; virtual bool getOcclusionQuerySupport() const; virtual bool getInstancingSupport() const; virtual bool getTextureFilterAnisotropySupport() const; + virtual bool getPBOSupport() const; virtual float getTextureMaxAnisotropy() const; virtual bool getShareHandleSupport() const; virtual bool getDerivativeInstructionSupport() const; virtual bool getPostSubBufferSupport() const; + virtual int getMaxRecommendedElementsIndices() const; + virtual int getMaxRecommendedElementsVertices() const; virtual int getMajorShaderModel() const; virtual float getMaxPointSize() const; virtual int getMaxViewportDimension() const; virtual int getMaxTextureWidth() const; virtual int getMaxTextureHeight() const; + virtual int getMaxTextureDepth() const; + virtual int getMaxTextureArrayLayers() const; virtual bool get32BitIndexSupport() const; virtual int getMinSwapInterval() const; virtual int getMaxSwapInterval() const; virtual GLsizei getMaxSupportedSamples() const; + virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const; + virtual GLsizei getNumSampleCounts(GLenum internalFormat) const; + virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const; int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const; virtual unsigned int getMaxRenderTargets() const; @@ -135,34 +169,44 @@ class Renderer11 : public Renderer // Pixel operations virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); + virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source); + virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source); virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); - - bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, - ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); + virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); + virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); // Shader operations - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround); + virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers); + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround); + virtual UniformStorage *createUniformStorage(size_t storageSize); // Image operations virtual Image *createImage(); virtual void generateMipmap(Image *dest, Image *source); virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); - virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels); + virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Buffer creation virtual VertexBuffer *createVertexBuffer(); @@ -178,11 +222,22 @@ class Renderer11 : public Renderer ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; - bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); + Blit11 *getBlitter() { return mBlit; } + + // Buffer-to-texture and Texture-to-buffer copies + virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; + virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + + bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); void unapplyRenderTargets(); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); + void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, void *pixelsOut); virtual bool getLUID(LUID *adapterLuid) const; + virtual GLenum getNativeTextureFormat(GLenum internalFormat) const; + virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; + virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; private: DISALLOW_COPY_AND_ASSIGN(Renderer11); @@ -190,21 +245,25 @@ class Renderer11 : public Renderer void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); - void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, - GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, - GLint packAlignment, void *pixels); + void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels); - void maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers); rx::Range getViewportBounds() const; - bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, bool wholeBufferCopy); + bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); + static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer); + HMODULE mD3d11Module; HMODULE mDxgiModule; HDC mDc; + HLSLCompiler mCompiler; + bool mDeviceLost; void initializeDevice(); @@ -227,15 +286,19 @@ class Renderer11 : public Renderer bool mDXT3TextureSupport; bool mDXT5TextureSupport; + bool mRGTextureSupport; + bool mDepthTextureSupport; // Multisample format support struct MultisampleSupportInfo { unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT]; + unsigned int maxSupportedSamples; }; + MultisampleSupportInfo getMultisampleSupportInfo(DXGI_FORMAT format); - typedef std::unordered_map<DXGI_FORMAT, MultisampleSupportInfo, std::hash<int> > MultisampleSupportMap; + typedef std::unordered_map<DXGI_FORMAT, MultisampleSupportInfo> MultisampleSupportMap; MultisampleSupportMap mMultisampleSupportMap; unsigned int mMaxSupportedSamples; @@ -247,8 +310,6 @@ class Renderer11 : public Renderer bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; rx::RenderTarget::Desc mRenderTargetDesc; - unsigned int mCurDepthSize; - unsigned int mCurStencilSize; // Currently applied sampler states bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; @@ -258,13 +319,13 @@ class Renderer11 : public Renderer gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; // Currently applied textures - unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; + ID3D11ShaderResourceView *mCurVertexSRVs[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + ID3D11ShaderResourceView *mCurPixelSRVs[gl::MAX_TEXTURE_IMAGE_UNITS]; // Currently applied blend state bool mForceSetBlendState; gl::BlendState mCurBlendState; - gl::Color mCurBlendColor; + gl::ColorF mCurBlendColor; unsigned int mCurSampleMask; // Currently applied rasterizer state @@ -291,22 +352,32 @@ class Renderer11 : public Renderer // Currently applied primitive topology D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; - unsigned int mAppliedIBSerial; - unsigned int mAppliedStorageIBSerial; + // Currently applied index buffer + ID3D11Buffer *mAppliedIB; + DXGI_FORMAT mAppliedIBFormat; unsigned int mAppliedIBOffset; - unsigned int mAppliedProgramBinarySerial; - bool mIsGeometryShaderActive; + // Currently applied transform feedback buffers + ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + + // Currently applied shaders + ID3D11VertexShader *mAppliedVertexShader; + ID3D11GeometryShader *mAppliedGeometryShader; + ID3D11GeometryShader *mCurPointGeometryShader; + ID3D11PixelShader *mAppliedPixelShader; dx_VertexConstants mVertexConstants; dx_VertexConstants mAppliedVertexConstants; ID3D11Buffer *mDriverConstantBufferVS; ID3D11Buffer *mCurrentVertexConstantBuffer; + unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; dx_PixelConstants mPixelConstants; dx_PixelConstants mAppliedPixelConstants; ID3D11Buffer *mDriverConstantBufferPS; ID3D11Buffer *mCurrentPixelConstantBuffer; + unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; ID3D11Buffer *mCurrentGeometryConstantBuffer; @@ -319,25 +390,11 @@ class Renderer11 : public Renderer StreamingIndexBufferInterface *mTriangleFanIB; // Texture copy resources - bool mCopyResourcesInitialized; - ID3D11Buffer *mCopyVB; - ID3D11SamplerState *mCopySampler; - ID3D11InputLayout *mCopyIL; - ID3D11VertexShader *mCopyVS; - ID3D11PixelShader *mCopyRGBAPS; - ID3D11PixelShader *mCopyRGBPS; - ID3D11PixelShader *mCopyLumPS; - ID3D11PixelShader *mCopyLumAlphaPS; + Blit11 *mBlit; + PixelTransfer11 *mPixelTransfer; // Masked clear resources - bool mClearResourcesInitialized; - ID3D11Buffer *mClearVB; - ID3D11InputLayout *mClearIL; - ID3D11VertexShader *mClearVS; - ID3D11PixelShader *mClearSinglePS; - ID3D11PixelShader *mClearMultiplePS; - ID3D11RasterizerState *mClearScissorRS; - ID3D11RasterizerState *mClearNoScissorRS; + Clear11 *mClear; // Sync query ID3D11Query *mSyncQuery; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp index e1eb5603348..de2eeda4fc8 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -8,9 +8,9 @@ // ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader // executable implementation details. -#include "libGLESv2/renderer/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" -#include "common/debug.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" namespace rx { @@ -21,18 +21,16 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D mPixelExecutable = executable; mVertexExecutable = NULL; mGeometryExecutable = NULL; - - mConstantBuffer = NULL; + mStreamOutExecutable = NULL; } -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable) +ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable, ID3D11GeometryShader *streamOut) : ShaderExecutable(function, length) { mVertexExecutable = executable; mPixelExecutable = NULL; mGeometryExecutable = NULL; - - mConstantBuffer = NULL; + mStreamOutExecutable = streamOut; } ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable) @@ -41,29 +39,15 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D mGeometryExecutable = executable; mVertexExecutable = NULL; mPixelExecutable = NULL; - - mConstantBuffer = NULL; + mStreamOutExecutable = NULL; } ShaderExecutable11::~ShaderExecutable11() { - if (mVertexExecutable) - { - mVertexExecutable->Release(); - } - if (mPixelExecutable) - { - mPixelExecutable->Release(); - } - if (mGeometryExecutable) - { - mGeometryExecutable->Release(); - } - - if (mConstantBuffer) - { - mConstantBuffer->Release(); - } + SafeRelease(mVertexExecutable); + SafeRelease(mPixelExecutable); + SafeRelease(mGeometryExecutable); + SafeRelease(mStreamOutExecutable); } ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable) @@ -87,23 +71,42 @@ ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const return mGeometryExecutable; } -ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount) +ID3D11GeometryShader *ShaderExecutable11::getStreamOutShader() const { - if (!mConstantBuffer && registerCount > 0) + return mStreamOutExecutable; +} + +UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize) + : UniformStorage(initialSize), + mConstantBuffer(NULL) +{ + ID3D11Device *d3d11Device = renderer->getDevice(); + + if (initialSize > 0) { D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = registerCount * sizeof(float[4]); + constantBufferDescription.ByteWidth = initialSize; constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; constantBufferDescription.MiscFlags = 0; constantBufferDescription.StructureByteStride = 0; - HRESULT result = device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); + HRESULT result = d3d11Device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } +} - return mConstantBuffer; +UniformStorage11::~UniformStorage11() +{ + SafeRelease(mConstantBuffer); } -}
\ No newline at end of file +const UniformStorage11 *UniformStorage11::makeUniformStorage11(const UniformStorage *uniformStorage) +{ + ASSERT(HAS_DYNAMIC_TYPE(const UniformStorage11*, uniformStorage)); + return static_cast<const UniformStorage11*>(uniformStorage); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h index c6ec1cf7d2c..74a1e03915e 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -14,12 +14,14 @@ namespace rx { +class Renderer11; +class UniformStorage11; class ShaderExecutable11 : public ShaderExecutable { public: ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable); - ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable); + ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable, ID3D11GeometryShader *streamOut); ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable); virtual ~ShaderExecutable11(); @@ -29,8 +31,7 @@ class ShaderExecutable11 : public ShaderExecutable ID3D11PixelShader *getPixelShader() const; ID3D11VertexShader *getVertexShader() const; ID3D11GeometryShader *getGeometryShader() const; - - ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount); + ID3D11GeometryShader *getStreamOutShader() const; private: DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11); @@ -38,7 +39,20 @@ class ShaderExecutable11 : public ShaderExecutable ID3D11PixelShader *mPixelExecutable; ID3D11VertexShader *mVertexExecutable; ID3D11GeometryShader *mGeometryExecutable; + ID3D11GeometryShader *mStreamOutExecutable; +}; + +class UniformStorage11 : public UniformStorage +{ + public: + UniformStorage11(Renderer11 *renderer, size_t initialSize); + virtual ~UniformStorage11(); + + static const UniformStorage11 *makeUniformStorage11(const UniformStorage *uniformStorage); + ID3D11Buffer *getConstantBuffer() const { return mConstantBuffer; } + + private: ID3D11Buffer *mConstantBuffer; }; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp index 022cfe430dd..a15d061feaf 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain11.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp @@ -1,18 +1,19 @@ #include "precompiled.h" // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. -#include "libGLESv2/renderer/SwapChain11.h" +#include "libGLESv2/renderer/d3d11/SwapChain11.h" -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h" namespace rx { @@ -29,6 +30,7 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, mOffscreenSRView = NULL; mDepthStencilTexture = NULL; mDepthStencilDSView = NULL; + mDepthStencilSRView = NULL; mQuadVB = NULL; mPassThroughSampler = NULL; mPassThroughIL = NULL; @@ -48,83 +50,20 @@ SwapChain11::~SwapChain11() void SwapChain11::release() { - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBufferTexture) - { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; - } - - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mOffscreenRTView) - { - mOffscreenRTView->Release(); - mOffscreenRTView = NULL; - } - - if (mOffscreenSRView) - { - mOffscreenSRView->Release(); - mOffscreenSRView = NULL; - } - - if (mDepthStencilTexture) - { - mDepthStencilTexture->Release(); - mDepthStencilTexture = NULL; - } - - if (mDepthStencilDSView) - { - mDepthStencilDSView->Release(); - mDepthStencilDSView = NULL; - } - - if (mQuadVB) - { - mQuadVB->Release(); - mQuadVB = NULL; - } - - if (mPassThroughSampler) - { - mPassThroughSampler->Release(); - mPassThroughSampler = NULL; - } - - if (mPassThroughIL) - { - mPassThroughIL->Release(); - mPassThroughIL = NULL; - } - - if (mPassThroughVS) - { - mPassThroughVS->Release(); - mPassThroughVS = NULL; - } - - if (mPassThroughPS) - { - mPassThroughPS->Release(); - mPassThroughPS = NULL; - } + SafeRelease(mSwapChain); + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); + SafeRelease(mOffscreenTexture); + SafeRelease(mOffscreenRTView); + SafeRelease(mOffscreenSRView); + SafeRelease(mDepthStencilTexture); + SafeRelease(mDepthStencilDSView); + SafeRelease(mDepthStencilSRView); + SafeRelease(mQuadVB); + SafeRelease(mPassThroughSampler); + SafeRelease(mPassThroughIL); + SafeRelease(mPassThroughVS); + SafeRelease(mPassThroughPS); if (!mAppCreatedShareHandle) { @@ -134,35 +73,12 @@ void SwapChain11::release() void SwapChain11::releaseOffscreenTexture() { - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mOffscreenRTView) - { - mOffscreenRTView->Release(); - mOffscreenRTView = NULL; - } - - if (mOffscreenSRView) - { - mOffscreenSRView->Release(); - mOffscreenSRView = NULL; - } - - if (mDepthStencilTexture) - { - mDepthStencilTexture->Release(); - mDepthStencilTexture = NULL; - } - - if (mDepthStencilDSView) - { - mDepthStencilDSView->Release(); - mDepthStencilDSView = NULL; - } + SafeRelease(mOffscreenTexture); + SafeRelease(mOffscreenRTView); + SafeRelease(mOffscreenSRView); + SafeRelease(mDepthStencilTexture); + SafeRelease(mDepthStencilDSView); + SafeRelease(mDepthStencilSRView); } EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight) @@ -201,7 +117,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); - tempResource11->Release(); + SafeRelease(tempResource11); if (FAILED(result)) { @@ -216,7 +132,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (offscreenTextureDesc.Width != (UINT)backbufferWidth || offscreenTextureDesc.Height != (UINT)backbufferHeight - || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat) + || offscreenTextureDesc.Format != gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()) || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) { @@ -232,7 +148,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); + offscreenTextureDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()); offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; @@ -259,7 +175,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } } - d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture"); + d3d11::SetDebugName(mOffscreenTexture, "Offscreen back buffer texture"); // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client if (useSharedResource) @@ -275,7 +191,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei else { result = offscreenTextureResource->GetSharedHandle(&mShareHandle); - offscreenTextureResource->Release(); + SafeRelease(offscreenTextureResource); if (FAILED(result)) { @@ -285,32 +201,43 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } } } - - HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView); + + D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; + offscreenRTVDesc.Format = gl_d3d11::GetRTVFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()); + offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + offscreenRTVDesc.Texture2D.MipSlice = 0; + + HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, &offscreenRTVDesc, &mOffscreenRTView); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target"); + d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); + + D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; + offscreenSRVDesc.Format = gl_d3d11::GetSRVFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()); + offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + offscreenSRVDesc.Texture2D.MostDetailedMip = 0; + offscreenSRVDesc.Texture2D.MipLevels = -1; - result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView); + result = device->CreateShaderResourceView(mOffscreenTexture, &offscreenSRVDesc, &mOffscreenSRView); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource"); + d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource"); if (mDepthBufferFormat != GL_NONE) { - D3D11_TEXTURE2D_DESC depthStencilDesc = {0}; - depthStencilDesc.Width = backbufferWidth; - depthStencilDesc.Height = backbufferHeight; - depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat); - depthStencilDesc.MipLevels = 1; - depthStencilDesc.ArraySize = 1; - depthStencilDesc.SampleDesc.Count = 1; - depthStencilDesc.SampleDesc.Quality = 0; - depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; - depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - depthStencilDesc.CPUAccessFlags = 0; - depthStencilDesc.MiscFlags = 0; - - result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture); + D3D11_TEXTURE2D_DESC depthStencilTextureDesc; + depthStencilTextureDesc.Width = backbufferWidth; + depthStencilTextureDesc.Height = backbufferHeight; + depthStencilTextureDesc.Format = gl_d3d11::GetTexFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion()); + depthStencilTextureDesc.MipLevels = 1; + depthStencilTextureDesc.ArraySize = 1; + depthStencilTextureDesc.SampleDesc.Count = 1; + depthStencilTextureDesc.SampleDesc.Quality = 0; + depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; + depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + depthStencilTextureDesc.CPUAccessFlags = 0; + depthStencilTextureDesc.MiscFlags = 0; + + result = device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture); if (FAILED(result)) { ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); @@ -325,11 +252,27 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei return EGL_BAD_ALLOC; } } - d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture"); + d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); + + D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; + depthStencilDesc.Format = gl_d3d11::GetDSVFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion()); + depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + depthStencilDesc.Flags = 0; + depthStencilDesc.Texture2D.MipSlice = 0; - result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView); + result = device->CreateDepthStencilView(mDepthStencilTexture, &depthStencilDesc, &mDepthStencilDSView); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view"); + d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); + + D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; + depthStencilSRVDesc.Format = gl_d3d11::GetSRVFormat(mDepthBufferFormat, mRenderer->getCurrentClientVersion()); + depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; + depthStencilSRVDesc.Texture2D.MipLevels = -1; + + result = device->CreateShaderResourceView(mDepthStencilTexture, &depthStencilSRVDesc, &mDepthStencilSRView); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mDepthStencilSRView, "Offscreen depth stencil shader resource"); } mWidth = backbufferWidth; @@ -349,7 +292,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei const int yoffset = std::max(mHeight - previousHeight, 0); deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); - previousOffscreenTexture->Release(); + SafeRelease(previousOffscreenTexture); if (mSwapChain) { @@ -369,24 +312,21 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ACCESS; } - // Can only call resize if we have already created our swap buffer and resources - ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); - - if (mBackBufferTexture) + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains + if (backbufferWidth < 1 || backbufferHeight < 1) { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; + return EGL_SUCCESS; } - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } + // Can only call resize if we have already created our swap buffer and resources + ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); + + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); // Resize swap chain - DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); - HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); + DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()); + HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); if (FAILED(result)) { @@ -431,23 +371,9 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap // Release specific resources to free up memory for the new render target, while the // old render target still exists for the purpose of preserving its contents. - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBufferTexture) - { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; - } - - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } + SafeRelease(mSwapChain); + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); mSwapInterval = static_cast<unsigned int>(swapInterval); if (mSwapInterval > 4) @@ -468,20 +394,21 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap IDXGIFactory *factory = mRenderer->getDxgiFactory(); DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; - swapChainDesc.BufferCount = 2; - swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); swapChainDesc.BufferDesc.Width = backbufferWidth; swapChainDesc.BufferDesc.Height = backbufferHeight; - swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.Flags = 0; - swapChainDesc.OutputWindow = mWindow; + swapChainDesc.BufferDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat, mRenderer->getCurrentClientVersion()); + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 1; + swapChainDesc.OutputWindow = mWindow; swapChainDesc.Windowed = TRUE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Flags = 0; HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); @@ -496,21 +423,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap } else { - // We cannot create a swap chain for an HWND that is owned by a different process on some versions of - // windows - DWORD currentProcessId = GetCurrentProcessId(); - DWORD wndProcessId; - GetWindowThreadProcessId(mWindow, &wndProcessId); - - if (currentProcessId != wndProcessId) - { - ERR("Could not create swap chain, window owned by different process"); - return EGL_BAD_NATIVE_WINDOW; - } - else - { - return EGL_BAD_ALLOC; - } + return EGL_BAD_ALLOC; } } @@ -580,15 +493,15 @@ void SwapChain11::initPassThroughResources() { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL); + result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), &mPassThroughIL); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout"); - result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS); + result = device->CreateVertexShader(g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), NULL, &mPassThroughVS); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader"); - result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS); + result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mPassThroughPS); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); } @@ -680,6 +593,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) if (result == DXGI_ERROR_DEVICE_REMOVED) { HRESULT removedReason = device->GetDeviceRemovedReason(); + UNUSED_ASSERTION_VARIABLE(removedReason); ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason); return EGL_CONTEXT_LOST; } @@ -703,61 +617,33 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return EGL_SUCCESS; } -// Increments refcount on texture. -// caller must Release() the returned texture ID3D11Texture2D *SwapChain11::getOffscreenTexture() { - if (mOffscreenTexture) - { - mOffscreenTexture->AddRef(); - } - return mOffscreenTexture; } -// Increments refcount on view. -// caller must Release() the returned view ID3D11RenderTargetView *SwapChain11::getRenderTarget() { - if (mOffscreenRTView) - { - mOffscreenRTView->AddRef(); - } - return mOffscreenRTView; } -// Increments refcount on view. -// caller must Release() the returned view ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource() { - if (mOffscreenSRView) - { - mOffscreenSRView->AddRef(); - } - return mOffscreenSRView; } -// Increments refcount on view. -// caller must Release() the returned view ID3D11DepthStencilView *SwapChain11::getDepthStencil() { - if (mDepthStencilDSView) - { - mDepthStencilDSView->AddRef(); - } - return mDepthStencilDSView; } -ID3D11Texture2D *SwapChain11::getDepthStencilTexture() +ID3D11ShaderResourceView * SwapChain11::getDepthStencilShaderResource() { - if (mDepthStencilTexture) - { - mDepthStencilTexture->AddRef(); - } + return mDepthStencilSRView; +} +ID3D11Texture2D *SwapChain11::getDepthStencilTexture() +{ return mDepthStencilTexture; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h index 800104602e3..fb0afd70e34 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h @@ -34,6 +34,7 @@ class SwapChain11 : public SwapChain virtual ID3D11Texture2D *getDepthStencilTexture(); virtual ID3D11DepthStencilView *getDepthStencil(); + virtual ID3D11ShaderResourceView *getDepthStencilShaderResource(); EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } @@ -66,6 +67,7 @@ class SwapChain11 : public SwapChain ID3D11Texture2D *mDepthStencilTexture; ID3D11DepthStencilView *mDepthStencilDSView; + ID3D11ShaderResourceView *mDepthStencilSRView; ID3D11Buffer *mQuadVB; ID3D11SamplerState *mPassThroughSampler; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp new file mode 100644 index 00000000000..7e024accb80 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp @@ -0,0 +1,1567 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. + +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" + +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/SwapChain11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/Blit11.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" + +#include "common/utilities.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +TextureStorage11::SwizzleCacheValue::SwizzleCacheValue() + : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE) +{ +} + +TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha) + : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha) +{ +} + +bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const +{ + return swizzleRed == other.swizzleRed && + swizzleGreen == other.swizzleGreen && + swizzleBlue == other.swizzleBlue && + swizzleAlpha == other.swizzleAlpha; +} + +bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const +{ + return !(*this == other); +} + +TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) + : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle) +{ +} + +bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const +{ + return baseLevel == rhs.baseLevel && + mipLevels == rhs.mipLevels && + swizzle == rhs.swizzle; +} + +TextureStorage11::SRVCache::~SRVCache() +{ + for (size_t i = 0; i < cache.size(); i++) + { + SafeRelease(cache[i].srv); + } +} + +ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const +{ + for (size_t i = 0; i < cache.size(); i++) + { + if (cache[i].key == key) + { + return cache[i].srv; + } + } + + return NULL; +} + +ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv) +{ + SRVPair pair = {key, srv}; + cache.push_back(pair); + + return srv; +} + +TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) + : mBindFlags(bindFlags), + mTopLevel(0), + mMipLevels(0), + mTextureFormat(DXGI_FORMAT_UNKNOWN), + mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), + mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), + mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), + mTextureWidth(0), + mTextureHeight(0), + mTextureDepth(0) +{ + mRenderer = Renderer11::makeRenderer11(renderer); + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mLevelSRVs[i] = NULL; + } +} + +TextureStorage11::~TextureStorage11() +{ + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + SafeRelease(mLevelSRVs[level]); + } +} + +TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage)); + return static_cast<TextureStorage11*>(storage); +} + +DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, GLuint clientVersion, bool renderTarget) +{ + UINT bindFlags = 0; + + if (gl_d3d11::GetSRVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN) + { + bindFlags |= D3D11_BIND_SHADER_RESOURCE; + } + if (gl_d3d11::GetDSVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN) + { + bindFlags |= D3D11_BIND_DEPTH_STENCIL; + } + if (gl_d3d11::GetRTVFormat(internalFormat, clientVersion) != DXGI_FORMAT_UNKNOWN && renderTarget) + { + bindFlags |= D3D11_BIND_RENDER_TARGET; + } + + return bindFlags; +} + +UINT TextureStorage11::getBindFlags() const +{ + return mBindFlags; +} + +int TextureStorage11::getTopLevel() const +{ + return mTopLevel; +} + +bool TextureStorage11::isRenderTarget() const +{ + return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; +} + +bool TextureStorage11::isManaged() const +{ + return false; +} + +int TextureStorage11::getLevelCount() const +{ + return mMipLevels - mTopLevel; +} + +int TextureStorage11::getLevelWidth(int mipLevel) const +{ + return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1); +} + +int TextureStorage11::getLevelHeight(int mipLevel) const +{ + return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1); +} + +int TextureStorage11::getLevelDepth(int mipLevel) const +{ + return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1); +} + +UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const +{ + UINT index = 0; + if (getResource()) + { + index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels); + } + return index; +} + +ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) +{ + bool swizzleRequired = samplerState.swizzleRequired(); + bool mipmapping = gl::IsMipmapFiltered(samplerState); + unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1; + + // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0) + mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel); + + if (swizzleRequired) + { + verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha); + } + + SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired); + ID3D11ShaderResourceView *srv = srvCache.find(key); + + if(srv) + { + return srv; + } + + DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); + ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource(); + + srv = createSRV(samplerState.baseLevel, mipLevels, format, texture); + + return srvCache.add(key, srv); +} + +ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mLevelSRVs[mipLevel]) + { + mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource()); + } + + return mLevelSRVs[mipLevel]; + } + else + { + return NULL; + } +} + +void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +{ + SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + for (int level = 0; level < getLevelCount(); level++) + { + // Check if the swizzle for this level is out of date + if (mSwizzleCache[level] != swizzleTarget) + { + // Need to re-render the swizzle for this level + ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level); + ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level); + + gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); + + Blit11 *blitter = mRenderer->getBlitter(); + + if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha)) + { + mSwizzleCache[level] = swizzleTarget; + } + else + { + ERR("Failed to swizzle texture."); + } + } + } +} + +void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) +{ + if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache)) + { + // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a + // valid swizzle combination + mSwizzleCache[mipLevel] = SwizzleCacheValue(); + } +} + +void TextureStorage11::invalidateSwizzleCache() +{ + for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++) + { + invalidateSwizzleCacheLevel(mipLevel); + } +} + +bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, + int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth) +{ + if (srcTexture) + { + invalidateSwizzleCacheLevel(level); + + gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); + gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth); + + bool fullCopy = copyArea.x == 0 && + copyArea.y == 0 && + copyArea.z == 0 && + copyArea.width == texSize.width && + copyArea.height == texSize.height && + copyArea.depth == texSize.depth; + + ID3D11Resource *dstTexture = getResource(); + unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + + ASSERT(dstTexture); + + if (!fullCopy && (d3d11::GetDepthBits(mTextureFormat) > 0 || d3d11::GetStencilBits(mTextureFormat) > 0)) + { + // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead + Blit11 *blitter = mRenderer->getBlitter(); + + return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, + dstTexture, dstSubresource, copyArea, texSize, + NULL); + } + else + { + D3D11_BOX srcBox; + srcBox.left = copyArea.x; + srcBox.top = copyArea.y; + srcBox.right = copyArea.x + roundUp((unsigned int)width, d3d11::GetBlockWidth(mTextureFormat)); + srcBox.bottom = copyArea.y + roundUp((unsigned int)height, d3d11::GetBlockHeight(mTextureFormat)); + srcBox.front = copyArea.z; + srcBox.back = copyArea.z + copyArea.depth; + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, + srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); + return true; + } + } + + return false; +} + +void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) +{ + if (source && dest) + { + ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); + ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); + + if (sourceSRV && destRTV) + { + gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); + gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); + + gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); + gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); + + Blit11 *blitter = mRenderer->getBlitter(); + + blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, + gl::GetFormat(source->getInternalFormat(), mRenderer->getCurrentClientVersion()), + GL_LINEAR); + } + } +} + +void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +{ + SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + for (unsigned int level = 0; level < mMipLevels; level++) + { + ASSERT(mSwizzleCache[level] == swizzleTarget); + } +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) + : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) +{ + mTexture = swapchain->getOffscreenTexture(); + mTexture->AddRef(); + mSwizzleTexture = NULL; + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mRenderTarget[i] = NULL; + mSwizzleRenderTargets[i] = NULL; + } + + D3D11_TEXTURE2D_DESC texDesc; + mTexture->GetDesc(&texDesc); + mMipLevels = texDesc.MipLevels; + mTextureFormat = texDesc.Format; + mTextureWidth = texDesc.Width; + mTextureHeight = texDesc.Height; + mTextureDepth = 1; + + ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srv->GetDesc(&srvDesc); + mShaderResourceFormat = srvDesc.Format; + + ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + offscreenRTV->GetDesc(&rtvDesc); + mRenderTargetFormat = rtvDesc.Format; + + GLint internalFormat = d3d11_gl::GetInternalFormat(mTextureFormat, renderer->getCurrentClientVersion()); + mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalFormat, renderer); + mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalFormat, renderer); + mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalFormat, renderer); + + mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget)) +{ + mTexture = NULL; + mSwizzleTexture = NULL; + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mRenderTarget[i] = NULL; + mSwizzleRenderTargets[i] = NULL; + } + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion); + mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion); + mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion); + mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion); + mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer); + mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer); + mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer); + + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (width > 0 && height > 0) + { + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; // Compressed texture size constraints? + desc.Height = height; + desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); + desc.ArraySize = 1; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + gl::error(GL_OUT_OF_MEMORY); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = 1; + } + } +} + +TextureStorage11_2D::~TextureStorage11_2D() +{ + SafeRelease(mTexture); + SafeRelease(mSwizzleTexture); + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + SafeDelete(mRenderTarget[i]); + SafeRelease(mSwizzleRenderTargets[i]); + } +} + +TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage)); + return static_cast<TextureStorage11_2D*>(storage); +} + +ID3D11Resource *TextureStorage11_2D::getResource() const +{ + return mTexture; +} + +RenderTarget *TextureStorage11_2D::getRenderTarget(int level) +{ + if (level >= 0 && level < getLevelCount()) + { + if (!mRenderTarget[level]) + { + ID3D11ShaderResourceView *srv = getSRVLevel(level); + if (!srv) + { + return NULL; + } + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv; + HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + } + else + { + UNREACHABLE(); + } + } + + return mRenderTarget[level]; + } + else + { + return NULL; + } +} + +ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2D.MipLevels = mipLevels; + + ID3D11ShaderResourceView *SRV = NULL; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + + if (result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + } + ASSERT(SUCCEEDED(result)); + + return SRV; +} + +void TextureStorage11_2D::generateMipmap(int level) +{ + invalidateSwizzleCacheLevel(level); + + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + + generateMipmapLayer(source, dest); +} + +ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() +{ + if (!mSwizzleTexture) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = mSwizzleTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleTexture; +} + +ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mSwizzleRenderTargets[mipLevel]) + { + ID3D11Resource *swizzleTexture = getSwizzleTexture(); + if (!swizzleTexture) + { + return NULL; + } + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleRenderTargets[mipLevel]; + } + else + { + return NULL; + } +} + +unsigned int TextureStorage11_2D::getTextureLevelDepth(int mipLevel) const +{ + return 1; +} + +TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget)) +{ + mTexture = NULL; + mSwizzleTexture = NULL; + + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + mSwizzleRenderTargets[level] = NULL; + for (unsigned int face = 0; face < 6; face++) + { + mRenderTarget[face][level] = NULL; + } + } + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion); + mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion); + mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion); + mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion); + mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer); + mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer); + mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer); + + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (size > 0) + { + // adjust size if needed for compressed textures + int height = size; + d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = size; + desc.Height = size; + desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); + desc.ArraySize = 6; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = 1; + } + } +} + +TextureStorage11_Cube::~TextureStorage11_Cube() +{ + SafeRelease(mTexture); + SafeRelease(mSwizzleTexture); + + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + SafeRelease(mSwizzleRenderTargets[level]); + for (unsigned int face = 0; face < 6; face++) + { + SafeDelete(mRenderTarget[face][level]); + } + } +} + +TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage)); + return static_cast<TextureStorage11_Cube*>(storage); +} + +ID3D11Resource *TextureStorage11_Cube::getResource() const +{ + return mTexture; +} + +RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level) +{ + if (level >= 0 && level < getLevelCount()) + { + int faceIndex = gl::TextureCubeMap::targetToIndex(faceTarget); + if (!mRenderTarget[faceIndex][level]) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = faceIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; + rtvDesc.Texture2DArray.ArraySize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; + dsvDesc.Texture2DArray.ArraySize = 1; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + SafeRelease(srv); + } + else + { + UNREACHABLE(); + } + } + + return mRenderTarget[faceIndex][level]; + } + else + { + return NULL; + } +} + +ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + + // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures + bool unnormalizedInteger = (d3d11::GetComponentType(mTextureFormat) == GL_INT || + d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT); + + if(unnormalizedInteger) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = 6; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = mipLevels; + srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; + } + + ID3D11ShaderResourceView *SRV = NULL; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + + if (result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + } + ASSERT(SUCCEEDED(result)); + + return SRV; +} + +void TextureStorage11_Cube::generateMipmap(int faceIndex, int level) +{ + invalidateSwizzleCacheLevel(level); + + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level)); + + generateMipmapLayer(source, dest); +} + +ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() +{ + if (!mSwizzleTexture) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 6; + desc.Format = mSwizzleTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleTexture; +} + +ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mSwizzleRenderTargets[mipLevel]) + { + ID3D11Resource *swizzleTexture = getSwizzleTexture(); + if (!swizzleTexture) + { + return NULL; + } + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = 6; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleRenderTargets[mipLevel]; + } + else + { + return NULL; + } +} + +unsigned int TextureStorage11_Cube::getTextureLevelDepth(int mipLevel) const +{ + return 6; +} + +TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget)) +{ + mTexture = NULL; + mSwizzleTexture = NULL; + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mLevelRenderTargets[i] = NULL; + mSwizzleRenderTargets[i] = NULL; + } + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion); + mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion); + mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion); + mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion); + mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer); + mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer); + mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer); + + // If the width, height or depth are not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (width > 0 && height > 0 && depth > 0) + { + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.Depth = depth; + desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); + desc.Format = mTextureFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + gl::error(GL_OUT_OF_MEMORY); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = desc.Depth; + } + } +} + +TextureStorage11_3D::~TextureStorage11_3D() +{ + SafeRelease(mTexture); + SafeRelease(mSwizzleTexture); + + for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++) + { + SafeDelete(i->second); + } + mLevelLayerRenderTargets.clear(); + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + SafeDelete(mLevelRenderTargets[i]); + SafeRelease(mSwizzleRenderTargets[i]); + } +} + +TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage)); + return static_cast<TextureStorage11_3D*>(storage); +} + +ID3D11Resource *TextureStorage11_3D::getResource() const +{ + return mTexture; +} + +ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = baseLevel; + srvDesc.Texture3D.MipLevels = mipLevels; + + ID3D11ShaderResourceView *SRV = NULL; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + + if (result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + } + ASSERT(SUCCEEDED(result)); + + return SRV; +} + +RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mLevelRenderTargets[mipLevel]) + { + ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); + if (!srv) + { + return NULL; + } + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; + + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel)); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } + else + { + UNREACHABLE(); + } + } + + return mLevelRenderTargets[mipLevel]; + } + else + { + return NULL; + } +} + +RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + // TODO, what kind of SRV is expected here? + ID3D11ShaderResourceView *srv = NULL; + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = layer; + rtvDesc.Texture3D.WSize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else + { + UNREACHABLE(); + } + } + + return mLevelLayerRenderTargets[key]; + } + else + { + return NULL; + } +} + +void TextureStorage11_3D::generateMipmap(int level) +{ + invalidateSwizzleCacheLevel(level); + + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + + generateMipmapLayer(source, dest); +} + +ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() +{ + if (!mSwizzleTexture) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mSwizzleTextureFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleTexture; +} + +ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mSwizzleRenderTargets[mipLevel]) + { + ID3D11Resource *swizzleTexture = getSwizzleTexture(); + if (!swizzleTexture) + { + return NULL; + } + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleRenderTargets[mipLevel]; + } + else + { + return NULL; + } +} + +unsigned int TextureStorage11_3D::getTextureLevelDepth(int mipLevel) const +{ + return std::max(mTextureDepth >> mipLevel, 1U); +} + + +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget)) +{ + mTexture = NULL; + mSwizzleTexture = NULL; + + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + mSwizzleRenderTargets[level] = NULL; + } + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + mTextureFormat = gl_d3d11::GetTexFormat(internalformat, clientVersion); + mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat, clientVersion); + mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat, clientVersion); + mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat, clientVersion); + mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat, renderer); + mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat, renderer); + mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat, renderer); + + // if the width, height or depth is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (width > 0 && height > 0 && depth > 0) + { + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); + desc.ArraySize = depth; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + gl::error(GL_OUT_OF_MEMORY); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = desc.ArraySize; + } + } +} + +TextureStorage11_2DArray::~TextureStorage11_2DArray() +{ + SafeRelease(mTexture); + SafeRelease(mSwizzleTexture); + + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + SafeRelease(mSwizzleRenderTargets[level]); + } + + for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++) + { + SafeDelete(i->second); + } + mRenderTargets.clear(); +} + +TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage)); + return static_cast<TextureStorage11_2DArray*>(storage); +} + +ID3D11Resource *TextureStorage11_2DArray::getResource() const +{ + return mTexture; +} + +ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; + srvDesc.Texture2DArray.MipLevels = mipLevels; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = mTextureDepth; + + ID3D11ShaderResourceView *SRV = NULL; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + + if (result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + } + ASSERT(SUCCEEDED(result)); + + return SRV; +} + +RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + LevelLayerKey key(mipLevel, layer); + if (mRenderTargets.find(key) == mRenderTargets.end()) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = layer; + srvDesc.Texture2DArray.ArraySize = 1; + + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = layer; + rtvDesc.Texture2DArray.ArraySize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + SafeRelease(srv); + return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + + mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else + { + UNREACHABLE(); + } + } + + return mRenderTargets[key]; + } + else + { + return NULL; + } +} + +void TextureStorage11_2DArray::generateMipmap(int level) +{ + invalidateSwizzleCacheLevel(level); + for (unsigned int layer = 0; layer < mTextureDepth; layer++) + { + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer)); + + generateMipmapLayer(source, dest); + } +} + +ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture() +{ + if (!mSwizzleTexture) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mSwizzleTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleTexture; +} + +ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel) +{ + if (mipLevel >= 0 && mipLevel < getLevelCount()) + { + if (!mSwizzleRenderTargets[mipLevel]) + { + ID3D11Resource *swizzleTexture = getSwizzleTexture(); + if (!swizzleTexture) + { + return NULL; + } + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSwizzleRenderTargets[mipLevel]; + } + else + { + return NULL; + } +} + +unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const +{ + return mTextureDepth; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h new file mode 100644 index 00000000000..8a612bdd110 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h @@ -0,0 +1,278 @@ +// +// Copyright (c) 2012-2013 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. +// + +// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. + +#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ +#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ + +#include "libGLESv2/Texture.h" +#include "libGLESv2/renderer/TextureStorage.h" + +namespace rx +{ +class RenderTarget; +class RenderTarget11; +class Renderer; +class Renderer11; +class SwapChain11; + +class TextureStorage11 : public TextureStorage +{ + public: + virtual ~TextureStorage11(); + + static TextureStorage11 *makeTextureStorage11(TextureStorage *storage); + + static DWORD GetTextureBindFlags(GLenum internalFormat, GLuint clientVersion, bool renderTarget); + + UINT getBindFlags() const; + + virtual ID3D11Resource *getResource() const = 0; + virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState); + virtual RenderTarget *getRenderTarget(int level) { return NULL; } + virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; } + virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; } + + virtual void generateMipmap(int level) {}; + virtual void generateMipmap(int face, int level) {}; + + virtual int getTopLevel() const; + virtual bool isRenderTarget() const; + virtual bool isManaged() const; + virtual int getLevelCount() const; + UINT getSubresourceIndex(int mipLevel, int layerTarget) const; + + void generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + void invalidateSwizzleCacheLevel(int mipLevel); + void invalidateSwizzleCache(); + + bool updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, int level, + int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth); + + protected: + TextureStorage11(Renderer *renderer, UINT bindFlags); + void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); + int getLevelWidth(int mipLevel) const; + int getLevelHeight(int mipLevel) const; + int getLevelDepth(int mipLevel) const; + + virtual ID3D11Resource *getSwizzleTexture() = 0; + virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel) = 0; + ID3D11ShaderResourceView *getSRVLevel(int mipLevel); + + virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) = 0; + + void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + + virtual unsigned int getTextureLevelDepth(int mipLevel) const = 0; + + Renderer11 *mRenderer; + int mTopLevel; + unsigned int mMipLevels; + + DXGI_FORMAT mTextureFormat; + DXGI_FORMAT mShaderResourceFormat; + DXGI_FORMAT mRenderTargetFormat; + DXGI_FORMAT mDepthStencilFormat; + DXGI_FORMAT mSwizzleTextureFormat; + DXGI_FORMAT mSwizzleShaderResourceFormat; + DXGI_FORMAT mSwizzleRenderTargetFormat; + unsigned int mTextureWidth; + unsigned int mTextureHeight; + unsigned int mTextureDepth; + + struct SwizzleCacheValue + { + GLenum swizzleRed; + GLenum swizzleGreen; + GLenum swizzleBlue; + GLenum swizzleAlpha; + + SwizzleCacheValue(); + SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha); + + bool operator ==(const SwizzleCacheValue &other) const; + bool operator !=(const SwizzleCacheValue &other) const; + }; + SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + struct SRVKey + { + SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); + + bool operator==(const SRVKey &rhs) const; + + int baseLevel; + int mipLevels; + bool swizzle; + }; + + struct SRVPair + { + SRVKey key; + ID3D11ShaderResourceView *srv; + }; + + struct SRVCache + { + ~SRVCache(); + + ID3D11ShaderResourceView *find(const SRVKey &key) const; + ID3D11ShaderResourceView *add(const SRVKey &key, ID3D11ShaderResourceView *srv); + + std::vector<SRVPair> cache; + }; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11); + + const UINT mBindFlags; + + SRVCache srvCache; + ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +class TextureStorage11_2D : public TextureStorage11 +{ + public: + TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); + TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + virtual ~TextureStorage11_2D(); + + static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); + + virtual ID3D11Resource *getResource() const; + virtual RenderTarget *getRenderTarget(int level); + + virtual void generateMipmap(int level); + + protected: + virtual ID3D11Resource *getSwizzleTexture(); + virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + + virtual unsigned int getTextureLevelDepth(int mipLevel) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); + + virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + + ID3D11Texture2D *mTexture; + RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + ID3D11Texture2D *mSwizzleTexture; + ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +class TextureStorage11_Cube : public TextureStorage11 +{ + public: + TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); + virtual ~TextureStorage11_Cube(); + + static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); + + virtual ID3D11Resource *getResource() const; + virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); + + virtual void generateMipmap(int faceIndex, int level); + + protected: + virtual ID3D11Resource *getSwizzleTexture(); + virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + + virtual unsigned int getTextureLevelDepth(int mipLevel) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); + + virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + + ID3D11Texture2D *mTexture; + RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + ID3D11Texture2D *mSwizzleTexture; + ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +class TextureStorage11_3D : public TextureStorage11 +{ + public: + TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual ~TextureStorage11_3D(); + + static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage); + + virtual ID3D11Resource *getResource() const; + virtual RenderTarget *getRenderTarget(int mipLevel); + virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer); + + virtual void generateMipmap(int level); + + protected: + virtual ID3D11Resource *getSwizzleTexture(); + virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + + virtual unsigned int getTextureLevelDepth(int mipLevel) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D); + + virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + + typedef std::pair<int, int> LevelLayerKey; + typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap; + RenderTargetMap mLevelLayerRenderTargets; + + RenderTarget11 *mLevelRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + ID3D11Texture3D *mTexture; + ID3D11Texture3D *mSwizzleTexture; + ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +class TextureStorage11_2DArray : public TextureStorage11 +{ + public: + TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual ~TextureStorage11_2DArray(); + + static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); + + virtual ID3D11Resource *getResource() const; + virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer); + + virtual void generateMipmap(int level); + + protected: + virtual ID3D11Resource *getSwizzleTexture(); + virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + + virtual unsigned int getTextureLevelDepth(int mipLevel) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray); + + virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + + typedef std::pair<int, int> LevelLayerKey; + typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap; + RenderTargetMap mRenderTargets; + + ID3D11Texture2D *mTexture; + + ID3D11Texture2D *mSwizzleTexture; + ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +} + +#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp new file mode 100644 index 00000000000..d69668d8a37 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp @@ -0,0 +1,223 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. + +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/BufferStorage.h" + +#include "libGLESv2/Buffer.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" + +namespace rx +{ + +VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) +{ + mBuffer = NULL; + mBufferSize = 0; + mDynamicUsage = false; +} + +VertexBuffer11::~VertexBuffer11() +{ + SafeRelease(mBuffer); +} + +bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) +{ + SafeRelease(mBuffer); + + updateSerial(); + + if (size > 0) + { + ID3D11Device* dxDevice = mRenderer->getDevice(); + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = size; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); + if (FAILED(result)) + { + return false; + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + return true; +} + +VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); + return static_cast<VertexBuffer11*>(vetexBuffer); +} + +bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) +{ + if (mBuffer) + { + gl::Buffer *buffer = attrib.mBoundBuffer.get(); + int inputStride = attrib.stride(); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Vertex buffer map failed with error 0x%08x", result); + return false; + } + + char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; + + const char *input = NULL; + if (attrib.mArrayEnabled) + { + if (buffer) + { + BufferStorage *storage = buffer->getStorage(); + input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); + } + else + { + input = static_cast<const char*>(attrib.mPointer); + } + } + else + { + input = reinterpret_cast<const char*>(currentValue.FloatValues); + } + + if (instances == 0 || attrib.mDivisor == 0) + { + input += inputStride * start; + } + + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + VertexCopyFunction conversionFunc = gl_d3d11::GetVertexCopyFunction(vertexFormat); + ASSERT(conversionFunc != NULL); + conversionFunc(input, inputStride, count, output); + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, + GLsizei instances, unsigned int *outSpaceRequired) const +{ + unsigned int elementCount = 0; + if (attrib.mArrayEnabled) + { + if (instances == 0 || attrib.mDivisor == 0) + { + elementCount = count; + } + else + { + if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.mDivisor); + } + else + { + elementCount = instances / attrib.mDivisor; + } + } + + gl::VertexFormat vertexFormat(attrib); + unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat)); + if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; + } + } + else + { + const unsigned int elementSize = 4; + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * 4; + } + return true; + } +} + +unsigned int VertexBuffer11::getBufferSize() const +{ + return mBufferSize; +} + +bool VertexBuffer11::setBufferSize(unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(size, mDynamicUsage); + } + else + { + return true; + } +} + +bool VertexBuffer11::discard() +{ + if (mBuffer) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Vertex buffer map failed with error 0x%08x", result); + return false; + } + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +ID3D11Buffer *VertexBuffer11::getBuffer() const +{ + return mBuffer; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h index eceb426e82d..191791af3c4 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexBuffer11.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h @@ -25,22 +25,16 @@ class VertexBuffer11 : public VertexBuffer static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int offset); - virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset); virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; - virtual unsigned int getBufferSize() const; virtual bool setBufferSize(unsigned int size); virtual bool discard(); - unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; - DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const; - ID3D11Buffer *getBuffer() const; private: @@ -51,22 +45,6 @@ class VertexBuffer11 : public VertexBuffer ID3D11Buffer *mBuffer; unsigned int mBufferSize; bool mDynamicUsage; - - typedef void (*VertexConversionFunction)(const void *, unsigned int, unsigned int, void *); - struct VertexConverter - { - VertexConversionFunction conversionFunc; - bool identity; - DXGI_FORMAT dxgiFormat; - unsigned int outputElementSize; - }; - - enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; - - // This table is used to generate mAttributeTypes. - static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1] - - static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute); }; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.cpp new file mode 100644 index 00000000000..695e168478f --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.cpp @@ -0,0 +1,1665 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// formatutils11.cpp: Queries for GL image formats and their translations to D3D11 +// formats. + +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "libGLESv2/renderer/generatemip.h" +#include "libGLESv2/renderer/loadimage.h" +#include "libGLESv2/renderer/copyimage.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/copyvertex.h" + +namespace rx +{ + +struct D3D11ES3FormatInfo +{ + DXGI_FORMAT mTexFormat; + DXGI_FORMAT mSRVFormat; + DXGI_FORMAT mRTVFormat; + DXGI_FORMAT mDSVFormat; + + D3D11ES3FormatInfo() + : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN) + { } + + D3D11ES3FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) + : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat) + { } +}; + +// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows +// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal +// format. +typedef std::pair<GLenum, D3D11ES3FormatInfo> D3D11ES3FormatPair; +typedef std::map<GLenum, D3D11ES3FormatInfo> D3D11ES3FormatMap; + +static D3D11ES3FormatMap BuildD3D11ES3FormatMap() +{ + D3D11ES3FormatMap map; + + // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | + map.insert(D3D11ES3FormatPair(GL_NONE, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R8, D3D11ES3FormatInfo(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB565, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA4, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB5_A1, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB10_A2, D3D11ES3FormatInfo(DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB10_A2UI, D3D11ES3FormatInfo(DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_SRGB8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_SRGB8_ALPHA8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R11F_G11F_B10F, D3D11ES3FormatInfo(DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB9_E5, D3D11ES3FormatInfo(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R8I, D3D11ES3FormatInfo(DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R8UI, D3D11ES3FormatInfo(DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R16I, D3D11ES3FormatInfo(DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R16UI, D3D11ES3FormatInfo(DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R32I, D3D11ES3FormatInfo(DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_R32UI, D3D11ES3FormatInfo(DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG8I, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG8UI, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG16I, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG16UI, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG32I, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RG32UI, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB8I, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB8UI, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB16I, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB16UI, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB32I, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB32UI, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA8I, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA8UI, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA16I, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA16UI, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA32I, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA32UI, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); + + // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format? + map.insert(D3D11ES3FormatPair(GL_ALPHA, D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGB, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_RGBA, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_BGRA_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + + // From GL_EXT_texture_storage + // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | + map.insert(D3D11ES3FormatPair(GL_ALPHA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_ALPHA32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_ALPHA16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_BGRA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_BGRA4_ANGLEX, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + map.insert(D3D11ES3FormatPair(GL_BGR5_A1_ANGLEX, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + + // Depth stencil formats + map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT16, D3D11ES3FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM ))); + map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT24, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT ))); + map.insert(D3D11ES3FormatPair(GL_DEPTH24_STENCIL8, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + map.insert(D3D11ES3FormatPair(GL_DEPTH32F_STENCIL8, D3D11ES3FormatInfo(DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT))); + map.insert(D3D11ES3FormatPair(GL_STENCIL_INDEX8, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + + // From GL_ANGLE_depth_texture + map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + + // Compressed formats, From ES 3.0.1 spec, table 3.16 + // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_R11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_R11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RG11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_RG11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA8_ETC2_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + + // From GL_EXT_texture_compression_dxt1 + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + + // From GL_ANGLE_texture_compression_dxt3 + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11ES3FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + + // From GL_ANGLE_texture_compression_dxt5 + map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11ES3FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + + return map; +} + +static bool GetD3D11ES3FormatInfo(GLenum internalFormat, GLuint clientVersion, D3D11ES3FormatInfo *outFormatInfo) +{ + static const D3D11ES3FormatMap formatMap = BuildD3D11ES3FormatMap(); + D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +// ES3 image loading functions vary based on the internal format and data type given, +// this map type determines the loading function from the internal format and type supplied +// to glTex*Image*D and the destination DXGI_FORMAT. Source formats and types are taken from +// Tables 3.2 and 3.3 of the ES 3 spec. +typedef std::pair<GLenum, GLenum> InternalFormatTypePair; +typedef std::pair<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionPair; +typedef std::map<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionMap; + +static void UnimplementedLoadFunction(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + UNIMPLEMENTED(); +} + +static void UnreachableLoadFunction(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + UNREACHABLE(); +} + +// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters. +static inline void insertLoadFunction(D3D11LoadFunctionMap *map, GLenum internalFormat, GLenum type, + LoadImageFunction loadFunc) +{ + map->insert(D3D11LoadFunctionPair(InternalFormatTypePair(internalFormat, type), loadFunc)); +} + +D3D11LoadFunctionMap buildD3D11LoadFunctionMap() +{ + D3D11LoadFunctionMap map; + + // | Internal format | Type | Load function | + insertLoadFunction(&map, GL_RGBA8, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_RGBA8_SNORM, GL_BYTE, loadToNative<GLbyte, 4> ); + insertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, loadRGBA4444DataToRGBA ); + insertLoadFunction(&map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, loadToNative<GLuint, 1> ); + insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, loadRGBA5551DataToRGBA ); + insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, loadRGBA2101010ToRGBA ); + insertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, loadToNative<GLhalf, 4> ); + insertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, loadToNative<GLfloat, 4> ); + insertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, loadFloatDataToHalfFloat<4> ); + insertLoadFunction(&map, GL_RGBA8UI, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_RGBA8I, GL_BYTE, loadToNative<GLbyte, 4> ); + insertLoadFunction(&map, GL_RGBA16UI, GL_UNSIGNED_SHORT, loadToNative<GLushort, 4> ); + insertLoadFunction(&map, GL_RGBA16I, GL_SHORT, loadToNative<GLshort, 4> ); + insertLoadFunction(&map, GL_RGBA32UI, GL_UNSIGNED_INT, loadToNative<GLuint, 4> ); + insertLoadFunction(&map, GL_RGBA32I, GL_INT, loadToNative<GLint, 4> ); + insertLoadFunction(&map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, loadToNative<GLuint, 1> ); + insertLoadFunction(&map, GL_RGB8, GL_UNSIGNED_BYTE, loadRGBUByteDataToRGBA ); + insertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_BYTE, loadToNative3To4<GLubyte, 0xFF> ); + insertLoadFunction(&map, GL_SRGB8, GL_UNSIGNED_BYTE, loadToNative3To4<GLubyte, 0xFF> ); + insertLoadFunction(&map, GL_RGB8_SNORM, GL_BYTE, loadRGBSByteDataToRGBA ); + insertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, loadRGB565DataToRGBA ); + insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV, loadToNative<GLuint, 1> ); + insertLoadFunction(&map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV, loadToNative<GLuint, 1> ); + insertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT, loadToNative3To4<GLhalf, gl::Float16One>); + insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, loadRGBHalfFloatDataTo111110Float ); + insertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, loadRGBHalfFloatDataTo999E5 ); + insertLoadFunction(&map, GL_RGB32F, GL_FLOAT, loadToNative3To4<GLfloat, gl::Float32One>); + insertLoadFunction(&map, GL_RGB16F, GL_FLOAT, loadFloatRGBDataToHalfFloatRGBA ); + insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, loadRGBFloatDataTo111110Float ); + insertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, loadRGBFloatDataTo999E5 ); + insertLoadFunction(&map, GL_RGB8UI, GL_UNSIGNED_BYTE, loadToNative3To4<GLubyte, 0x01> ); + insertLoadFunction(&map, GL_RGB8I, GL_BYTE, loadToNative3To4<GLbyte, 0x01> ); + insertLoadFunction(&map, GL_RGB16UI, GL_UNSIGNED_SHORT, loadToNative3To4<GLushort, 0x0001> ); + insertLoadFunction(&map, GL_RGB16I, GL_SHORT, loadToNative3To4<GLshort, 0x0001> ); + insertLoadFunction(&map, GL_RGB32UI, GL_UNSIGNED_INT, loadToNative3To4<GLuint, 0x00000001> ); + insertLoadFunction(&map, GL_RGB32I, GL_INT, loadToNative3To4<GLint, 0x00000001> ); + insertLoadFunction(&map, GL_RG8, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 2> ); + insertLoadFunction(&map, GL_RG8_SNORM, GL_BYTE, loadToNative<GLbyte, 2> ); + insertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT, loadToNative<GLhalf, 2> ); + insertLoadFunction(&map, GL_RG32F, GL_FLOAT, loadToNative<GLfloat, 2> ); + insertLoadFunction(&map, GL_RG16F, GL_FLOAT, loadFloatDataToHalfFloat<2> ); + insertLoadFunction(&map, GL_RG8UI, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 2> ); + insertLoadFunction(&map, GL_RG8I, GL_BYTE, loadToNative<GLbyte, 2> ); + insertLoadFunction(&map, GL_RG16UI, GL_UNSIGNED_SHORT, loadToNative<GLushort, 2> ); + insertLoadFunction(&map, GL_RG16I, GL_SHORT, loadToNative<GLshort, 2> ); + insertLoadFunction(&map, GL_RG32UI, GL_UNSIGNED_INT, loadToNative<GLuint, 2> ); + insertLoadFunction(&map, GL_RG32I, GL_INT, loadToNative<GLint, 2> ); + insertLoadFunction(&map, GL_R8, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 1> ); + insertLoadFunction(&map, GL_R8_SNORM, GL_BYTE, loadToNative<GLbyte, 1> ); + insertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT, loadToNative<GLhalf, 1> ); + insertLoadFunction(&map, GL_R32F, GL_FLOAT, loadToNative<GLfloat, 1> ); + insertLoadFunction(&map, GL_R16F, GL_FLOAT, loadFloatDataToHalfFloat<1> ); + insertLoadFunction(&map, GL_R8UI, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 1> ); + insertLoadFunction(&map, GL_R8I, GL_BYTE, loadToNative<GLbyte, 1> ); + insertLoadFunction(&map, GL_R16UI, GL_UNSIGNED_SHORT, loadToNative<GLushort, 1> ); + insertLoadFunction(&map, GL_R16I, GL_SHORT, loadToNative<GLshort, 1> ); + insertLoadFunction(&map, GL_R32UI, GL_UNSIGNED_INT, loadToNative<GLuint, 1> ); + insertLoadFunction(&map, GL_R32I, GL_INT, loadToNative<GLint, 1> ); + insertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, loadToNative<GLushort, 1> ); + insertLoadFunction(&map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT, loadG8R24DataToR24G8 ); + insertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, loadUintDataToUshort ); + insertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, loadToNative<GLfloat, 1> ); + insertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, loadG8R24DataToR24G8 ); + insertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, loadToNative<GLuint, 2> ); + + // Unsized formats + // Load functions are unreachable because they are converted to sized internal formats based on + // the format and type before loading takes place. + insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_RGB, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); + insertLoadFunction(&map, GL_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); + + // From GL_OES_texture_float + insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, loadLuminanceAlphaFloatDataToRGBA ); + insertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, loadLuminanceFloatDataToRGB ); + insertLoadFunction(&map, GL_ALPHA, GL_FLOAT, loadAlphaFloatDataToRGBA ); + + // From GL_OES_texture_half_float + insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, loadLuminanceAlphaHalfFloatDataToRGBA); + insertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, loadLuminanceHalfFloatDataToRGBA ); + insertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, loadAlphaHalfFloatDataToRGBA ); + + // From GL_EXT_texture_storage + insertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 1> ); + insertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, loadLuminanceDataToBGRA ); + insertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, loadLuminanceAlphaDataToBGRA ); + insertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, loadAlphaFloatDataToRGBA ); + insertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, loadLuminanceFloatDataToRGB ); + insertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, loadLuminanceAlphaFloatDataToRGBA ); + insertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, loadAlphaHalfFloatDataToRGBA ); + insertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, loadLuminanceHalfFloatDataToRGBA ); + insertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, loadLuminanceAlphaHalfFloatDataToRGBA); + + insertLoadFunction(&map, GL_BGRA8_EXT, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, loadRGBA4444DataToRGBA ); + insertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + insertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, loadRGBA5551DataToRGBA ); + insertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, loadToNative<GLubyte, 4> ); + + // Compressed formats + // From ES 3.0.1 spec, table 3.16 + // | Internal format | Type | Load function | + insertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); + + // From GL_EXT_texture_compression_dxt1 + insertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 8>); + insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 8>); + + // From GL_ANGLE_texture_compression_dxt3 + insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>); + + // From GL_ANGLE_texture_compression_dxt5 + insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>); + + return map; +} + +struct D3D11ES2FormatInfo +{ + DXGI_FORMAT mTexFormat; + DXGI_FORMAT mSRVFormat; + DXGI_FORMAT mRTVFormat; + DXGI_FORMAT mDSVFormat; + + LoadImageFunction mLoadImageFunction; + + D3D11ES2FormatInfo() + : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), + mSRVFormat(DXGI_FORMAT_UNKNOWN), mLoadImageFunction(NULL) + { } + + D3D11ES2FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat, + LoadImageFunction loadFunc) + : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat), + mLoadImageFunction(loadFunc) + { } +}; + +// ES2 internal formats can map to DXGI formats and loading functions +typedef std::pair<GLenum, D3D11ES2FormatInfo> D3D11ES2FormatPair; +typedef std::map<GLenum, D3D11ES2FormatInfo> D3D11ES2FormatMap; + +static D3D11ES2FormatMap BuildD3D11ES2FormatMap() +{ + D3D11ES2FormatMap map; + + // | Internal format | | Texture format | SRV format | RTV format | DSV format | Load function | + map.insert(D3D11ES2FormatPair(GL_NONE, D3D11ES2FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, UnreachableLoadFunction ))); + map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT16, D3D11ES2FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM, UnreachableLoadFunction ))); + map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT, UnreachableLoadFunction ))); + map.insert(D3D11ES2FormatPair(GL_DEPTH24_STENCIL8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT, UnreachableLoadFunction ))); + map.insert(D3D11ES2FormatPair(GL_STENCIL_INDEX8, D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT, UnreachableLoadFunction ))); + + map.insert(D3D11ES2FormatPair(GL_RGBA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBAFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_RGB32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_ALPHA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadAlphaFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaFloatDataToRGBA ))); + + map.insert(D3D11ES2FormatPair(GL_RGBA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBAHalfFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_RGB16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBHalfFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_ALPHA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadAlphaHalfFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceHalfFloatDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaHalfFloatDataToRGBA ))); + + map.insert(D3D11ES2FormatPair(GL_ALPHA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, loadAlphaDataToNative ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadLuminanceDataToBGRA ))); + map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaDataToBGRA ))); + + map.insert(D3D11ES2FormatPair(GL_RGB8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBUByteDataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_RGB565, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGB565DataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_RGBA8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBAUByteDataToNative ))); + map.insert(D3D11ES2FormatPair(GL_RGBA4, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA4444DataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_RGB5_A1, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA5551DataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_BGRA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadBGRADataToBGRA ))); + map.insert(D3D11ES2FormatPair(GL_BGRA4_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA4444DataToRGBA ))); + map.insert(D3D11ES2FormatPair(GL_BGR5_A1_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA5551DataToRGBA ))); + + // From GL_EXT_texture_rg + map.insert(D3D11ES2FormatPair(GL_R8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, loadToNative<GLubyte, 1> ))); + map.insert(D3D11ES2FormatPair(GL_R32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, loadToNative<GLfloat, 1> ))); + map.insert(D3D11ES2FormatPair(GL_R16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN, loadToNative<GLhalf, 1> ))); + map.insert(D3D11ES2FormatPair(GL_RG8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN, loadToNative<GLubyte, 2> ))); + map.insert(D3D11ES2FormatPair(GL_RG32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN, loadToNative<GLfloat, 2> ))); + map.insert(D3D11ES2FormatPair(GL_RG16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN, loadToNative<GLhalf, 2> ))); + + map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 8>))); + map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 8>))); + map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 16>))); + map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 16>))); + + return map; +} + +static bool GetD3D11ES2FormatInfo(GLenum internalFormat, GLuint clientVersion, D3D11ES2FormatInfo *outFormatInfo) +{ + static const D3D11ES2FormatMap formatMap = BuildD3D11ES2FormatMap(); + D3D11ES2FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +// A map to determine the pixel size and mipmap generation function of a given DXGI format +struct DXGIFormatInfo +{ + GLuint mPixelBits; + GLuint mBlockWidth; + GLuint mBlockHeight; + GLenum mComponentType; + + MipGenerationFunction mMipGenerationFunction; + ColorReadFunction mColorReadFunction; + + DXGIFormatInfo() + : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mComponentType(GL_NONE), mMipGenerationFunction(NULL), + mColorReadFunction(NULL) + { } + + DXGIFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum componentType, + MipGenerationFunction mipFunc, ColorReadFunction readFunc) + : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mComponentType(componentType), + mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) + { } +}; + +typedef std::map<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoMap; + +void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, + GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc) +{ + map->insert(std::make_pair(dxgiFormat, DXGIFormatInfo(pixelBits, blockWidth, blockHeight, componentType, mipFunc, readFunc))); +} + +static DXGIFormatInfoMap BuildDXGIFormatInfoMap() +{ + DXGIFormatInfoMap map; + + // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function + AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL); + + AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<A8>, ReadColor<A8, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8>, ReadColor<R8, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8>, ReadColor<R8G8, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat>); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, 8, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8S>, ReadColor<R8S, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8S>, ReadColor<R8G8S, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLfloat>); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, 8, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8>, ReadColor<R8, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16>, ReadColor<R16, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32>, ReadColor<R32, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8>, ReadColor<R8G8, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16>, ReadColor<R16G16, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32>, ReadColor<R32G32, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, 96, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32>, ReadColor<R32G32B32, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R8G8B8A8>, ReadColor<R8G8B8A8, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip<R16G16B16A16>, ReadColor<R16G16B16A16, GLuint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, 128, 1, 1, GL_UNSIGNED_INT, GenerateMip<R32G32B32A32>, ReadColor<R32G32B32A32, GLuint>); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, 8, 1, 1, GL_INT, GenerateMip<R8S>, ReadColor<R8S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, 16, 1, 1, GL_INT, GenerateMip<R16S>, ReadColor<R16S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, 32, 1, 1, GL_INT, GenerateMip<R32S>, ReadColor<R32S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, 16, 1, 1, GL_INT, GenerateMip<R8G8S>, ReadColor<R8G8S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, 32, 1, 1, GL_INT, GenerateMip<R16G16S>, ReadColor<R16G16S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, 64, 1, 1, GL_INT, GenerateMip<R32G32S>, ReadColor<R32G32S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, 96, 1, 1, GL_INT, GenerateMip<R32G32B32S>, ReadColor<R32G32B32S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, 32, 1, 1, GL_INT, GenerateMip<R8G8B8A8S>, ReadColor<R8G8B8A8S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, 64, 1, 1, GL_INT, GenerateMip<R16G16B16A16S>, ReadColor<R16G16B16A16S, GLint>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, 128, 1, 1, GL_INT, GenerateMip<R32G32B32A32S>, ReadColor<R32G32B32A32S, GLint>); + + AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip<R10G10B10A2>, ReadColor<R10G10B10A2, GLuint>); + + AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, 16, 1, 1, GL_FLOAT, GenerateMip<R16F>, ReadColor<R16F, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>); + + AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R32F>, ReadColor<R32F, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, 96, 1, 1, GL_FLOAT, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 1, 1, GL_FLOAT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>); + + AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 32, 1, 1, GL_FLOAT, GenerateMip<R9G9B9E5>, ReadColor<R9G9B9E5, GLfloat>); + AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip<R11G11B10F>, ReadColor<R11G11B10F, GLfloat>); + + AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, 16, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 32, 1, 1, GL_UNSIGNED_INT, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 64, 1, 1, GL_UNSIGNED_INT, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, 32, 1, 1, GL_FLOAT, NULL, NULL); + + AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, 64, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL); + + // Useful formats for vertex buffers + AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 64, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 64, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL); + + return map; +} + +typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap; + +inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) +{ + map->insert(std::make_pair(key, value)); +} + +static DXGIToESFormatMap BuildCommonDXGIToESFormatMap() +{ + DXGIToESFormatMap map; + + AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); + + AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM, GL_ALPHA8_EXT); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM, GL_R8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM, GL_RG8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_RGBA8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8); + AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM, GL_R8_SNORM); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM, GL_RG8_SNORM); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT, GL_R8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT, GL_R16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT, GL_R32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT, GL_RG8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT, GL_RG16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT, GL_RG32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT, GL_RGB32UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT, GL_R8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT, GL_R16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT, GL_R32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT, GL_RG8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT, GL_RG16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT, GL_RG32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT, GL_RGB32I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_RGBA8I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_RGBA16I); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_RGBA32I); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT, GL_R32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT, GL_RG32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_RGB32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5); + AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT16); + AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_DEPTH32F_STENCIL8); + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8); + + AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); + AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); + AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); + + return map; +} + +static DXGIToESFormatMap BuildDXGIToES2FormatMap() +{ + DXGIToESFormatMap map = BuildCommonDXGIToESFormatMap(); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32_OES); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32_OES); + + return map; +} + +static DXGIToESFormatMap BuildDXGIToES3FormatMap() +{ + DXGIToESFormatMap map = BuildCommonDXGIToESFormatMap(); + + AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); + + return map; +} + +static const DXGIFormatInfoMap &GetDXGIFormatInfoMap() +{ + static const DXGIFormatInfoMap infoMap = BuildDXGIFormatInfoMap(); + return infoMap; +} + +static bool GetDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo) +{ + const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap(); + DXGIFormatInfoMap::const_iterator iter = infoMap.find(format); + if (iter != infoMap.end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +static d3d11::DXGIFormatSet BuildAllDXGIFormatSet() +{ + d3d11::DXGIFormatSet set; + + const DXGIFormatInfoMap &infoMap = GetDXGIFormatInfoMap(); + for (DXGIFormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i) + { + set.insert(i->first); + } + + return set; +} + +struct D3D11FastCopyFormat +{ + DXGI_FORMAT mSourceFormat; + GLenum mDestFormat; + GLenum mDestType; + + D3D11FastCopyFormat(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) + : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType) + { } + + bool operator<(const D3D11FastCopyFormat& other) const + { + return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; + } +}; + +typedef std::map<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyMap; +typedef std::pair<D3D11FastCopyFormat, ColorCopyFunction> D3D11FastCopyPair; + +static D3D11FastCopyMap BuildFastCopyMap() +{ + D3D11FastCopyMap map; + + map.insert(D3D11FastCopyPair(D3D11FastCopyFormat(DXGI_FORMAT_B8G8R8A8_UNORM, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte)); + + return map; +} + +struct DXGIDepthStencilInfo +{ + unsigned int mDepthBits; + unsigned int mDepthOffset; + unsigned int mStencilBits; + unsigned int mStencilOffset; + + DXGIDepthStencilInfo() + : mDepthBits(0), mDepthOffset(0), mStencilBits(0), mStencilOffset(0) + { } + + DXGIDepthStencilInfo(unsigned int depthBits, unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) + : mDepthBits(depthBits), mDepthOffset(depthOffset), mStencilBits(stencilBits), mStencilOffset(stencilOffset) + { } +}; + +typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap; +typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair; + +static DepthStencilInfoMap BuildDepthStencilInfoMap() +{ + DepthStencilInfoMap map; + + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_TYPELESS, DXGIDepthStencilInfo(16, 0, 0, 0))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R16_UNORM, DXGIDepthStencilInfo(16, 0, 0, 0))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_D16_UNORM, DXGIDepthStencilInfo(16, 0, 0, 0))); + + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24G8_TYPELESS, DXGIDepthStencilInfo(24, 0, 8, 24))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGIDepthStencilInfo(24, 0, 8, 24))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_D24_UNORM_S8_UINT, DXGIDepthStencilInfo(24, 0, 8, 24))); + + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_TYPELESS, DXGIDepthStencilInfo(32, 0, 0, 0))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT, DXGIDepthStencilInfo(32, 0, 0, 0))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT, DXGIDepthStencilInfo(32, 0, 0, 0))); + + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32G8X24_TYPELESS, DXGIDepthStencilInfo(32, 0, 8, 32))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGIDepthStencilInfo(32, 0, 8, 32))); + map.insert(DepthStencilInfoPair(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGIDepthStencilInfo(32, 0, 8, 32))); + + return map; +} + +static const DepthStencilInfoMap &GetDepthStencilInfoMap() +{ + static const DepthStencilInfoMap infoMap = BuildDepthStencilInfoMap(); + return infoMap; +} + +bool GetDepthStencilInfo(DXGI_FORMAT format, DXGIDepthStencilInfo *outDepthStencilInfo) +{ + const DepthStencilInfoMap& infoMap = GetDepthStencilInfoMap(); + DepthStencilInfoMap::const_iterator iter = infoMap.find(format); + if (iter != infoMap.end()) + { + if (outDepthStencilInfo) + { + *outDepthStencilInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +struct SwizzleSizeType +{ + unsigned int mMaxComponentSize; + GLenum mComponentType; + + SwizzleSizeType() + : mMaxComponentSize(0), mComponentType(GL_NONE) + { } + + SwizzleSizeType(unsigned int maxComponentSize, GLenum componentType) + : mMaxComponentSize(maxComponentSize), mComponentType(componentType) + { } + + bool operator<(const SwizzleSizeType& other) const + { + return (mMaxComponentSize != other.mMaxComponentSize) ? (mMaxComponentSize < other.mMaxComponentSize) + : (mComponentType < other.mComponentType); + } +}; + +struct SwizzleFormatInfo +{ + DXGI_FORMAT mTexFormat; + DXGI_FORMAT mSRVFormat; + DXGI_FORMAT mRTVFormat; + + SwizzleFormatInfo() + : mTexFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN) + { } + + SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat) + : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat) + { } +}; + +typedef std::map<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoMap; +typedef std::pair<SwizzleSizeType, SwizzleFormatInfo> SwizzleInfoPair; + +static SwizzleInfoMap BuildSwizzleInfoMap() +{ + SwizzleInfoMap map; + + map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM ))); + map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM))); + map.insert(SwizzleInfoPair(SwizzleSizeType(24, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); + map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); + + map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_SIGNED_NORMALIZED ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM ))); + + map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT))); + map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); + + map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT ))); + map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT ))); + map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT ))); + + map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT ))); + map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT ))); + map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT ))); + + return map; +} +typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair; +typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap; + +static InternalFormatInitializerMap BuildInternalFormatInitializerMap() +{ + InternalFormatInitializerMap map; + + map.insert(InternalFormatInitializerPair(GL_RGB8, initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> )); + map.insert(InternalFormatInitializerPair(GL_RGB565, initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> )); + map.insert(InternalFormatInitializerPair(GL_SRGB8, initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF> )); + map.insert(InternalFormatInitializerPair(GL_RGB16F, initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); + map.insert(InternalFormatInitializerPair(GL_RGB32F, initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); + map.insert(InternalFormatInitializerPair(GL_RGB8UI, initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01> )); + map.insert(InternalFormatInitializerPair(GL_RGB8I, initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01> )); + map.insert(InternalFormatInitializerPair(GL_RGB16UI, initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001> )); + map.insert(InternalFormatInitializerPair(GL_RGB16I, initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001> )); + map.insert(InternalFormatInitializerPair(GL_RGB32UI, initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001> )); + map.insert(InternalFormatInitializerPair(GL_RGB32I, initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001> )); + + return map; +} + +static const SwizzleInfoMap &GetSwizzleInfoMap() +{ + static const SwizzleInfoMap map = BuildSwizzleInfoMap(); + return map; +} + +static const SwizzleFormatInfo GetSwizzleFormatInfo(GLint internalFormat, GLuint clientVersion) +{ + // Get the maximum sized component + unsigned int maxBits = 1; + + if (gl::IsFormatCompressed(internalFormat, clientVersion)) + { + unsigned int compressedBitsPerBlock = gl::GetPixelBytes(internalFormat, clientVersion) * 8; + unsigned int blockSize = gl::GetCompressedBlockWidth(internalFormat, clientVersion) * + gl::GetCompressedBlockHeight(internalFormat, clientVersion); + maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); + } + else + { + maxBits = std::max(maxBits, gl::GetAlphaBits( internalFormat, clientVersion)); + maxBits = std::max(maxBits, gl::GetRedBits( internalFormat, clientVersion)); + maxBits = std::max(maxBits, gl::GetGreenBits( internalFormat, clientVersion)); + maxBits = std::max(maxBits, gl::GetBlueBits( internalFormat, clientVersion)); + maxBits = std::max(maxBits, gl::GetLuminanceBits(internalFormat, clientVersion)); + maxBits = std::max(maxBits, gl::GetDepthBits( internalFormat, clientVersion)); + } + + maxBits = roundUp(maxBits, 8U); + + GLenum componentType = gl::GetComponentType(internalFormat, clientVersion); + + const SwizzleInfoMap &map = GetSwizzleInfoMap(); + SwizzleInfoMap::const_iterator iter = map.find(SwizzleSizeType(maxBits, componentType)); + + if (iter != map.end()) + { + return iter->second; + } + else + { + UNREACHABLE(); + static const SwizzleFormatInfo defaultFormatInfo; + return defaultFormatInfo; + } +} + +static const InternalFormatInitializerMap &GetInternalFormatInitializerMap() +{ + static const InternalFormatInitializerMap map = BuildInternalFormatInitializerMap(); + return map; +} + +namespace d3d11 +{ + +MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format) +{ + DXGIFormatInfo formatInfo; + if (GetDXGIFormatInfo(format, &formatInfo)) + { + return formatInfo.mMipGenerationFunction; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type, GLuint clientVersion) +{ + if (clientVersion == 2) + { + D3D11ES2FormatInfo d3d11FormatInfo; + if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mLoadImageFunction; + } + else + { + UNREACHABLE(); + return NULL; + } + } + else if (clientVersion == 3) + { + static const D3D11LoadFunctionMap loadImageMap = buildD3D11LoadFunctionMap(); + D3D11LoadFunctionMap::const_iterator iter = loadImageMap.find(InternalFormatTypePair(internalFormat, type)); + if (iter != loadImageMap.end()) + { + return iter->second; + } + else + { + UNREACHABLE(); + return NULL; + } + } + else + { + UNREACHABLE(); + return NULL; + } +} + +GLuint GetFormatPixelBytes(DXGI_FORMAT format) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + return dxgiFormatInfo.mPixelBits / 8; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlockWidth(DXGI_FORMAT format) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + return dxgiFormatInfo.mBlockWidth; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlockHeight(DXGI_FORMAT format) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + return dxgiFormatInfo.mBlockHeight; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLenum GetComponentType(DXGI_FORMAT format) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + return dxgiFormatInfo.mComponentType; + } + else + { + UNREACHABLE(); + return GL_NONE; + } +} + +GLuint GetDepthBits(DXGI_FORMAT format) +{ + DXGIDepthStencilInfo dxgiDSInfo; + if (GetDepthStencilInfo(format, &dxgiDSInfo)) + { + return dxgiDSInfo.mDepthBits; + } + else + { + // Since the depth stencil info map does not contain all used DXGI formats, + // we should not assert that the format exists + return 0; + } +} + +GLuint GetDepthOffset(DXGI_FORMAT format) +{ + DXGIDepthStencilInfo dxgiDSInfo; + if (GetDepthStencilInfo(format, &dxgiDSInfo)) + { + return dxgiDSInfo.mDepthOffset; + } + else + { + // Since the depth stencil info map does not contain all used DXGI formats, + // we should not assert that the format exists + return 0; + } +} + +GLuint GetStencilBits(DXGI_FORMAT format) +{ + DXGIDepthStencilInfo dxgiDSInfo; + if (GetDepthStencilInfo(format, &dxgiDSInfo)) + { + return dxgiDSInfo.mStencilBits; + } + else + { + // Since the depth stencil info map does not contain all used DXGI formats, + // we should not assert that the format exists + return 0; + } +} + +GLuint GetStencilOffset(DXGI_FORMAT format) +{ + DXGIDepthStencilInfo dxgiDSInfo; + if (GetDepthStencilInfo(format, &dxgiDSInfo)) + { + return dxgiDSInfo.mStencilOffset; + } + else + { + // Since the depth stencil info map does not contain all used DXGI formats, + // we should not assert that the format exists + return 0; + } +} + +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + int upsampleCount = 0; + + GLsizei blockWidth = dxgiFormatInfo.mBlockWidth; + GLsizei blockHeight = dxgiFormatInfo.mBlockHeight; + + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) + { + while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; + } + else + { + UNREACHABLE(); + } +} + +const DXGIFormatSet &GetAllUsedDXGIFormats() +{ + static DXGIFormatSet formatSet = BuildAllDXGIFormatSet(); + return formatSet; +} + +ColorReadFunction GetColorReadFunction(DXGI_FORMAT format) +{ + DXGIFormatInfo dxgiFormatInfo; + if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + { + return dxgiFormatInfo.mColorReadFunction; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) +{ + static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); + D3D11FastCopyMap::const_iterator iter = fastCopyMap.find(D3D11FastCopyFormat(sourceFormat, destFormat, destType)); + return (iter != fastCopyMap.end()) ? iter->second : NULL; +} + +} + +namespace gl_d3d11 +{ + +DXGI_FORMAT GetTexFormat(GLenum internalFormat, GLuint clientVersion) +{ + if (clientVersion == 2) + { + D3D11ES2FormatInfo d3d11FormatInfo; + if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mTexFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else if (clientVersion == 3) + { + D3D11ES3FormatInfo d3d11FormatInfo; + if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mTexFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT GetSRVFormat(GLenum internalFormat, GLuint clientVersion) +{ + if (clientVersion == 2) + { + D3D11ES2FormatInfo d3d11FormatInfo; + if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mSRVFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else if (clientVersion == 3) + { + D3D11ES3FormatInfo d3d11FormatInfo; + if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mSRVFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT GetRTVFormat(GLenum internalFormat, GLuint clientVersion) +{ + if (clientVersion == 2) + { + D3D11ES2FormatInfo d3d11FormatInfo; + if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mRTVFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else if (clientVersion == 3) + { + D3D11ES3FormatInfo d3d11FormatInfo; + if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mRTVFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT GetDSVFormat(GLenum internalFormat, GLuint clientVersion) +{ + if (clientVersion == 2) + { + D3D11ES2FormatInfo d3d11FormatInfo; + if (GetD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mDSVFormat; + } + else + { + return DXGI_FORMAT_UNKNOWN; + } + } + else if (clientVersion == 3) + { + D3D11ES3FormatInfo d3d11FormatInfo; + if (GetD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo)) + { + return d3d11FormatInfo.mDSVFormat; + } + else + { + return DXGI_FORMAT_UNKNOWN; + } + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +// Given a GL internal format, this function returns the DSV format if it is depth- or stencil-renderable, +// the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise. +DXGI_FORMAT GetRenderableFormat(GLenum internalFormat, GLuint clientVersion) +{ + DXGI_FORMAT targetFormat = GetDSVFormat(internalFormat, clientVersion); + if (targetFormat == DXGI_FORMAT_UNKNOWN) + targetFormat = GetRTVFormat(internalFormat, clientVersion); + if (targetFormat == DXGI_FORMAT_UNKNOWN) + targetFormat = GetTexFormat(internalFormat, clientVersion); + + return targetFormat; +} + +DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat, const Renderer *renderer) +{ + GLuint clientVersion = renderer->getCurrentClientVersion(); + if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer)) + { + const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion); + return swizzleInfo.mTexFormat; + } + else + { + return GetTexFormat(internalFormat, clientVersion); + } +} + +DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat, const Renderer *renderer) +{ + GLuint clientVersion = renderer->getCurrentClientVersion(); + if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer)) + { + const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion); + return swizzleInfo.mSRVFormat; + } + else + { + return GetTexFormat(internalFormat, clientVersion); + } +} + +DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat, const Renderer *renderer) +{ + GLuint clientVersion = renderer->getCurrentClientVersion(); + if (gl::GetComponentCount(internalFormat, clientVersion) != 4 || !gl::IsColorRenderingSupported(internalFormat, renderer)) + { + const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat, clientVersion); + return swizzleInfo.mRTVFormat; + } + else + { + return GetTexFormat(internalFormat, clientVersion); + } +} + +bool RequiresTextureDataInitialization(GLint internalFormat) +{ + const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); + return map.find(internalFormat) != map.end(); +} + +InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) +{ + const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); + InternalFormatInitializerMap::const_iterator iter = map.find(internalFormat); + if (iter != map.end()) + { + return iter->second; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +struct D3D11VertexFormatInfo +{ + rx::VertexConversionType mConversionType; + DXGI_FORMAT mNativeFormat; + VertexCopyFunction mCopyFunction; + + D3D11VertexFormatInfo() + : mConversionType(VERTEX_CONVERT_NONE), + mNativeFormat(DXGI_FORMAT_UNKNOWN), + mCopyFunction(NULL) + {} + + D3D11VertexFormatInfo(VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) + : mConversionType(conversionType), + mNativeFormat(nativeFormat), + mCopyFunction(copyFunction) + {} +}; + +typedef std::map<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatInfoMap; + +typedef std::pair<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatPair; + +static void addVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount, + VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) +{ + gl::VertexFormat inputFormat(inputType, normalized, componentCount, false); + map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction))); +} + +static void addIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount, + VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) +{ + gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true); + map->insert(D3D11VertexFormatPair(inputFormat, D3D11VertexFormatInfo(conversionType, nativeFormat, copyFunction))); +} + +static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() +{ + D3D11VertexFormatInfoMap map; + + // TODO: column legend + + // + // Float formats + // + + // GL_BYTE -- un-normalized + addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, ©VertexData<GLbyte, 1, 0>); + addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, ©VertexData<GLbyte, 2, 0>); + addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 3, 1>); + addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 4, 0>); + + // GL_BYTE -- normalized + addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, ©VertexData<GLbyte, 1, 0>); + addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, ©VertexData<GLbyte, 2, 0>); + addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, ©VertexData<GLbyte, 3, INT8_MAX>); + addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, ©VertexData<GLbyte, 4, 0>); + + // GL_UNSIGNED_BYTE -- un-normalized + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, ©VertexData<GLubyte, 1, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, ©VertexData<GLubyte, 2, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 3, 1>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 4, 0>); + + // GL_UNSIGNED_BYTE -- normalized + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, ©VertexData<GLubyte, 1, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, ©VertexData<GLubyte, 2, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, ©VertexData<GLubyte, 3, UINT8_MAX>); + addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, ©VertexData<GLubyte, 4, 0>); + + // GL_SHORT -- un-normalized + addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, ©VertexData<GLshort, 1, 0>); + addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, ©VertexData<GLshort, 2, 0>); + addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 1>); + addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 0>); + + // GL_SHORT -- normalized + addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, ©VertexData<GLshort, 1, 0>); + addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, ©VertexData<GLshort, 2, 0>); + addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, ©VertexData<GLshort, 3, INT16_MAX>); + addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, ©VertexData<GLshort, 4, 0>); + + // GL_UNSIGNED_SHORT -- un-normalized + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, ©VertexData<GLushort, 1, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, ©VertexData<GLushort, 2, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 3, 1>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 4, 0>); + + // GL_UNSIGNED_SHORT -- normalized + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, ©VertexData<GLushort, 1, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, ©VertexData<GLushort, 2, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, ©VertexData<GLushort, 3, UINT16_MAX>); + addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, ©VertexData<GLushort, 4, 0>); + + // GL_INT -- un-normalized + addVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, ©VertexData<GLint, 1, 0>); + addVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLint, 2, 0>); + addVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLint, 3, 0>); + addVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLint, 4, 0>); + + // GL_INT -- normalized + addVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, ©ToFloatVertexData<GLint, 1, true>); + addVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, ©ToFloatVertexData<GLint, 2, true>); + addVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©ToFloatVertexData<GLint, 3, true>); + addVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©ToFloatVertexData<GLint, 4, true>); + + // GL_UNSIGNED_INT -- un-normalized + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, ©VertexData<GLuint, 1, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, ©VertexData<GLuint, 2, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, ©VertexData<GLuint, 3, 0>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, ©VertexData<GLuint, 4, 0>); + + // GL_UNSIGNED_INT -- normalized + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, ©ToFloatVertexData<GLuint, 1, true>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, ©ToFloatVertexData<GLuint, 2, true>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©ToFloatVertexData<GLuint, 3, true>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, ©ToFloatVertexData<GLuint, 4, true>); + + // GL_FIXED + addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, ©FixedVertexData<1>); + addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, ©FixedVertexData<2>); + addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, ©FixedVertexData<3>); + addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©FixedVertexData<4>); + + // GL_HALF_FLOAT + addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, ©VertexData<GLhalf, 1, 0>); + addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, ©VertexData<GLhalf, 2, 0>); + addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, ©VertexData<GLhalf, 3, gl::Float16One>); + addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, ©VertexData<GLhalf, 4, 0>); + + // GL_FLOAT + addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, ©VertexData<GLfloat, 1, 0>); + addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, ©VertexData<GLfloat, 2, 0>); + addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, ©VertexData<GLfloat, 3, 0>); + addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, ©VertexData<GLfloat, 4, 0>); + + // GL_INT_2_10_10_10_REV + addVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©PackedVertexData<true, false, true>); + addVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©PackedVertexData<true, true, true>); + + // GL_UNSIGNED_INT_2_10_10_10_REV + addVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, ©PackedVertexData<false, false, true>); + addVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, ©PackedUnsignedVertexData); + + // + // Integer Formats + // + + // GL_BYTE + addIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, ©VertexData<GLbyte, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, ©VertexData<GLbyte, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 3, 1>); + addIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, ©VertexData<GLbyte, 4, 0>); + + // GL_UNSIGNED_BYTE + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, ©VertexData<GLubyte, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, ©VertexData<GLubyte, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 3, 1>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, ©VertexData<GLubyte, 4, 0>); + + // GL_SHORT + addIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, ©VertexData<GLshort, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, ©VertexData<GLshort, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 3, 1>); + addIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, ©VertexData<GLshort, 4, 0>); + + // GL_UNSIGNED_SHORT + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, ©VertexData<GLushort, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, ©VertexData<GLushort, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 3, 1>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, ©VertexData<GLushort, 4, 0>); + + // GL_INT + addIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, ©VertexData<GLint, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLint, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLint, 3, 0>); + addIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLint, 4, 0>); + + // GL_UNSIGNED_INT + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, ©VertexData<GLuint, 1, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, ©VertexData<GLuint, 2, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, ©VertexData<GLuint, 3, 0>); + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, ©VertexData<GLuint, 4, 0>); + + // GL_INT_2_10_10_10_REV + addIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, ©PackedVertexData<true, true, false>); + + // GL_UNSIGNED_INT_2_10_10_10_REV + addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, ©PackedUnsignedVertexData); + + return map; +} + +static bool GetD3D11VertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D11VertexFormatInfo *outVertexFormatInfo) +{ + static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap(); + + D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat); + if (iter != vertexFormatMap.end()) + { + if (outVertexFormatInfo) + { + *outVertexFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat) +{ + D3D11VertexFormatInfo vertexFormatInfo; + if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) + { + return vertexFormatInfo.mCopyFunction; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat) +{ + D3D11VertexFormatInfo vertexFormatInfo; + if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) + { + // FIXME: should not need a client version, and is not a pixel! + return d3d11::GetFormatPixelBytes(vertexFormatInfo.mNativeFormat); + } + else + { + UNREACHABLE(); + return 0; + } +} + +rx::VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat) +{ + D3D11VertexFormatInfo vertexFormatInfo; + if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) + { + return vertexFormatInfo.mConversionType; + } + else + { + UNREACHABLE(); + return VERTEX_CONVERT_NONE; + } +} + +DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat) +{ + D3D11VertexFormatInfo vertexFormatInfo; + if (GetD3D11VertexFormatInfo(vertexFormat, &vertexFormatInfo)) + { + return vertexFormatInfo.mNativeFormat; + } + else + { + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +} + +namespace d3d11_gl +{ + +GLenum GetInternalFormat(DXGI_FORMAT format, GLuint clientVersion) +{ + if (clientVersion == 2) + { + static DXGIToESFormatMap es2FormatMap = BuildDXGIToES2FormatMap(); + auto formatIt = es2FormatMap.find(format); + if (formatIt != es2FormatMap.end()) + { + return formatIt->second; + } + } + else if (clientVersion == 3) + { + static DXGIToESFormatMap es3FormatMap = BuildDXGIToES3FormatMap(); + auto formatIt = es3FormatMap.find(format); + if (formatIt != es3FormatMap.end()) + { + return formatIt->second; + } + } + + UNREACHABLE(); + return GL_NONE; +} + +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.h new file mode 100644 index 00000000000..d7ae4e0b9d9 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/formatutils11.h @@ -0,0 +1,79 @@ +// +// Copyright (c) 2013 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. +// + +// formatutils11.h: Queries for GL image formats and their translations to D3D11 +// formats. + +#ifndef LIBGLESV2_RENDERER_FORMATUTILS11_H_ +#define LIBGLESV2_RENDERER_FORMATUTILS11_H_ + +#include "libGLESv2/formatutils.h" + +namespace rx +{ + +class Renderer; + +namespace d3d11 +{ + +typedef std::set<DXGI_FORMAT> DXGIFormatSet; + +MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format); +LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type, GLuint clientVersion); + +GLuint GetFormatPixelBytes(DXGI_FORMAT format); +GLuint GetBlockWidth(DXGI_FORMAT format); +GLuint GetBlockHeight(DXGI_FORMAT format); +GLenum GetComponentType(DXGI_FORMAT format); + +GLuint GetDepthBits(DXGI_FORMAT format); +GLuint GetDepthOffset(DXGI_FORMAT format); +GLuint GetStencilBits(DXGI_FORMAT format); +GLuint GetStencilOffset(DXGI_FORMAT format); + +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + +const DXGIFormatSet &GetAllUsedDXGIFormats(); + +ColorReadFunction GetColorReadFunction(DXGI_FORMAT format); +ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType); + +} + +namespace gl_d3d11 +{ + +DXGI_FORMAT GetTexFormat(GLenum internalFormat, GLuint clientVersion); +DXGI_FORMAT GetSRVFormat(GLenum internalFormat, GLuint clientVersion); +DXGI_FORMAT GetRTVFormat(GLenum internalFormat, GLuint clientVersion); +DXGI_FORMAT GetDSVFormat(GLenum internalFormat, GLuint clientVersion); +DXGI_FORMAT GetRenderableFormat(GLenum internalFormat, GLuint clientVersion); + +DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat, const Renderer *renderer); +DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat, const Renderer *renderer); +DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat, const Renderer *renderer); + +bool RequiresTextureDataInitialization(GLint internalFormat); +InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + +VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat); +size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat); +VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat); +DXGI_FORMAT GetNativeVertexFormat(const gl::VertexFormat &vertexFormat); + +} + +namespace d3d11_gl +{ + +GLenum GetInternalFormat(DXGI_FORMAT format, GLuint clientVersion); + +} + +} + +#endif // LIBGLESV2_RENDERER_FORMATUTILS11_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp new file mode 100644 index 00000000000..327d2f04f61 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp @@ -0,0 +1,280 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// renderer11_utils.cpp: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/formatutils11.h" +#include "common/debug.h" + +namespace rx +{ + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) +{ + D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; + + switch (glBlend) + { + case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; + case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; + case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; + case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; + case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; + case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; + case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; + case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; + case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; + case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; + case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; + case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; + case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; + case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; + default: UNREACHABLE(); + } + + return d3dBlend; +} + +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) +{ + D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; + + switch (glBlendOp) + { + case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; + case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; + case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; + case GL_MIN: d3dBlendOp = D3D11_BLEND_OP_MIN; break; + case GL_MAX: d3dBlendOp = D3D11_BLEND_OP_MAX; break; + default: UNREACHABLE(); + } + + return d3dBlendOp; +} + +UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + UINT8 mask = 0; + if (red) + { + mask |= D3D11_COLOR_WRITE_ENABLE_RED; + } + if (green) + { + mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; + } + if (blue) + { + mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; + } + if (alpha) + { + mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + } + return mask; +} + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) +{ + D3D11_CULL_MODE cull = D3D11_CULL_NONE; + + if (cullEnabled) + { + switch (cullMode) + { + case GL_FRONT: cull = D3D11_CULL_FRONT; break; + case GL_BACK: cull = D3D11_CULL_BACK; break; + case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; + default: UNREACHABLE(); + } + } + else + { + cull = D3D11_CULL_NONE; + } + + return cull; +} + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) +{ + D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; + switch (comparison) + { + case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; + case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; + case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; + case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; + case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; + case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; + case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; + case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; + default: UNREACHABLE(); + } + + return d3dComp; +} + +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) +{ + return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; +} + +UINT8 ConvertStencilMask(GLuint stencilmask) +{ + return static_cast<UINT8>(stencilmask); +} + +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) +{ + D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; + case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; + case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; + case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; + case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; + case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; + case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; + case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; + default: UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode) +{ + bool comparison = comparisonMode != GL_NONE; + + if (maxAnisotropy > 1.0f) + { + return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison)); + } + else + { + D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; + D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; + switch (minFilter) + { + case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; + case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; + default: UNREACHABLE(); + } + + D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; + switch (magFilter) + { + case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; + default: UNREACHABLE(); + } + + return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison)); + } +} + +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; + case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; + case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; + default: UNREACHABLE(); + } + + return D3D11_TEXTURE_ADDRESS_WRAP; +} + +D3D11_QUERY ConvertQueryType(GLenum queryType) +{ + switch (queryType) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS; + default: UNREACHABLE(); return D3D11_QUERY_EVENT; + } +} + +} + +namespace d3d11 +{ + +void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth, + GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, + std::vector< std::vector<BYTE> > *outData) +{ + InitializeTextureDataFunction initializeFunc = gl_d3d11::GetTextureDataInitializationFunction(internalFormat); + DXGI_FORMAT dxgiFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion); + + outSubresourceData->resize(mipLevels); + outData->resize(mipLevels); + + for (unsigned int i = 0; i < mipLevels; i++) + { + unsigned int mipWidth = std::max(width >> i, 1U); + unsigned int mipHeight = std::max(height >> i, 1U); + unsigned int mipDepth = std::max(depth >> i, 1U); + + unsigned int rowWidth = d3d11::GetFormatPixelBytes(dxgiFormat) * mipWidth; + unsigned int imageSize = rowWidth * height; + + outData->at(i).resize(rowWidth * mipHeight * mipDepth); + initializeFunc(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); + + outSubresourceData->at(i).pSysMem = outData->at(i).data(); + outSubresourceData->at(i).SysMemPitch = rowWidth; + outSubresourceData->at(i).SysMemSlicePitch = imageSize; + } +} + +void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) +{ + vertex->x = x; + vertex->y = y; + vertex->u = u; + vertex->v = v; +} + +void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y, + unsigned int layer, float u, float v, float s) +{ + vertex->x = x; + vertex->y = y; + vertex->l = layer; + vertex->u = u; + vertex->v = v; + vertex->s = s; +} + +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) +{ +#if defined(_DEBUG) + return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); +#else + return S_OK; +#endif +} + +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h new file mode 100644 index 00000000000..94bb8f88fe2 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h @@ -0,0 +1,165 @@ +// +// Copyright (c) 2012 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. +// + +// renderer11_utils.h: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H +#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H + +#include "libGLESv2/angletypes.h" + +namespace rx +{ + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); +UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode); + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); +UINT8 ConvertStencilMask(GLuint stencilmask); +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); + +D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode); +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); + +D3D11_QUERY ConvertQueryType(GLenum queryType); + +} + +namespace d3d11 +{ + +void GenerateInitialTextureData(GLint internalFormat, GLuint clientVersion, GLuint width, GLuint height, GLuint depth, + GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, + std::vector< std::vector<BYTE> > *outData); + +struct PositionTexCoordVertex +{ + float x, y; + float u, v; +}; +void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v); + +struct PositionLayerTexCoord3DVertex +{ + float x, y; + unsigned int l; + float u, v, s; +}; +void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y, + unsigned int layer, float u, float v, float s); + +template <typename T> +struct PositionDepthColorVertex +{ + float x, y, z; + T r, g, b, a; +}; + +template <typename T> +void SetPositionDepthColorVertex(PositionDepthColorVertex<T>* vertex, float x, float y, float z, + const gl::Color<T> &color) +{ + vertex->x = x; + vertex->y = y; + vertex->z = z; + vertex->r = color.red; + vertex->g = color.green; + vertex->b = color.blue; + vertex->a = color.alpha; +} + +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); + +template <typename outType> +outType* DynamicCastComObject(IUnknown* object) +{ + outType *outObject = NULL; + HRESULT result = object->QueryInterface(__uuidof(outType), reinterpret_cast<void**>(&outObject)); + if (SUCCEEDED(result)) + { + return outObject; + } + else + { + SafeRelease(outObject); + return NULL; + } +} + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case DXGI_ERROR_DEVICE_HUNG: + case DXGI_ERROR_DEVICE_REMOVED: + case DXGI_ERROR_DEVICE_RESET: + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return true; + default: + return false; + } +} + +template <unsigned int N> +inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +{ + ID3D11VertexShader *vs = NULL; + HRESULT result = device->CreateVertexShader(byteCode, N, NULL, &vs); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); + SetDebugName(vs, name); + return vs; +} + +template <unsigned int N> +inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +{ + ID3D11GeometryShader *gs = NULL; + HRESULT result = device->CreateGeometryShader(byteCode, N, NULL, &gs); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); + SetDebugName(gs, name); + return gs; +} + +template <unsigned int N> +inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +{ + ID3D11PixelShader *ps = NULL; + HRESULT result = device->CreatePixelShader(byteCode, N, NULL, &ps); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); + SetDebugName(ps, name); + return ps; +} + +// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to +// represent an entire buffer. +template <class T> +inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value) +{ + D3D11_MAPPED_SUBRESOURCE mappedResource; + context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + + memcpy(mappedResource.pData, &value, sizeof(T)); + + context->Unmap(constantBuffer, 0); +} + +} + +} + +#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/BufferToTexture11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/BufferToTexture11.hlsl new file mode 100644 index 00000000000..20e6623a30c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/BufferToTexture11.hlsl @@ -0,0 +1,76 @@ +Buffer<float4> Buffer4F : register(t0); +Buffer<int4> Buffer4I : register(t0); +Buffer<uint4> Buffer4UI : register(t0); + +struct VS_OUTPUT +{ + float4 position : SV_Position; + uint index : TEXCOORD0; + uint slice : LAYER; +}; + +struct GS_OUTPUT +{ + float4 position : SV_Position; + uint index : TEXCOORD0; + uint slice : SV_RenderTargetArrayIndex; +}; + +cbuffer BufferCopyParams : register(b0) +{ + uint FirstPixelOffset; + uint PixelsPerRow; + uint RowStride; + uint RowsPerSlice; + float2 PositionOffset; + float2 PositionScale; + int2 TexLocationOffset; + int2 TexLocationScale; +} + +void ComputePositionAndIndex(uint vertexID, out VS_OUTPUT outVertex) +{ + uint PixelsPerSlice = PixelsPerRow * RowsPerSlice; + uint SliceStride = RowStride * RowsPerSlice; + + uint slice = vertexID / PixelsPerSlice; + uint sliceOffset = slice * PixelsPerSlice; + uint row = (vertexID - sliceOffset) / PixelsPerRow; + uint col = vertexID - sliceOffset - (row * PixelsPerRow); + + float2 coords = float2(float(col), float(row)); + + outVertex.position = float4(PositionOffset + PositionScale * coords, 0.0f, 1.0f); + outVertex.index = FirstPixelOffset + slice * SliceStride + row * RowStride + col; + outVertex.slice = slice; +} + +void VS_BufferToTexture(in uint vertexID : SV_VertexID, out VS_OUTPUT outVertex) +{ + ComputePositionAndIndex(vertexID, outVertex); +} + +[maxvertexcount(1)] +void GS_BufferToTexture(point VS_OUTPUT inVertex[1], inout PointStream<GS_OUTPUT> outStream) +{ + GS_OUTPUT outVertex; + outVertex.position = inVertex[0].position; + outVertex.index = inVertex[0].index; + outVertex.slice = inVertex[0].slice; + outStream.Append(outVertex); +} + +float4 PS_BufferToTexture_4F(in float4 inPosition : SV_Position, in uint inIndex : TEXCOORD0) : SV_Target +{ + return Buffer4F.Load(inIndex); +} + +int4 PS_BufferToTexture_4I(in float4 inPosition : SV_Position, in uint inIndex : TEXCOORD0) : SV_Target +{ + return Buffer4I.Load(inIndex); +} + +uint4 PS_BufferToTexture_4UI(in float4 inPosition : SV_Position, in uint inIndex : TEXCOORD0) : SV_Target +{ + return Buffer4UI.Load(inIndex); +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl new file mode 100644 index 00000000000..6deef2ba19c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl @@ -0,0 +1,102 @@ +// Assume we are in SM4+, which has 8 color outputs + +void VS_ClearFloat( in float3 inPosition : POSITION, in float4 inColor : COLOR, + out float4 outPosition : SV_POSITION, out float4 outColor : COLOR) +{ + outPosition = float4(inPosition, 1.0f); + outColor = inColor; +} + +struct PS_OutputFloat +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float4 color4 : SV_TARGET4; + float4 color5 : SV_TARGET5; + float4 color6 : SV_TARGET6; + float4 color7 : SV_TARGET7; +}; + +PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) +{ + PS_OutputFloat outColor; + outColor.color0 = inColor; + outColor.color1 = inColor; + outColor.color2 = inColor; + outColor.color3 = inColor; + outColor.color4 = inColor; + outColor.color5 = inColor; + outColor.color6 = inColor; + outColor.color7 = inColor; + return outColor; +} + + +void VS_ClearUint( in float3 inPosition : POSITION, in uint4 inColor : COLOR, + out float4 outPosition : SV_POSITION, out uint4 outColor : COLOR) +{ + outPosition = float4(inPosition, 1.0f); + outColor = inColor; +} + +struct PS_OutputUint +{ + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + uint4 color3 : SV_TARGET3; + uint4 color4 : SV_TARGET4; + uint4 color5 : SV_TARGET5; + uint4 color6 : SV_TARGET6; + uint4 color7 : SV_TARGET7; +}; + +PS_OutputUint PS_ClearUint(in float4 inPosition : SV_POSITION, in uint4 inColor : COLOR) +{ + PS_OutputUint outColor; + outColor.color0 = inColor; + outColor.color1 = inColor; + outColor.color2 = inColor; + outColor.color3 = inColor; + outColor.color4 = inColor; + outColor.color5 = inColor; + outColor.color6 = inColor; + outColor.color7 = inColor; + return outColor; +} + + +void VS_ClearSint( in float3 inPosition : POSITION, in int4 inColor : COLOR, + out float4 outPosition : SV_POSITION, out int4 outColor : COLOR) +{ + outPosition = float4(inPosition, 1.0f); + outColor = inColor; +} + +struct PS_OutputSint +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + int4 color3 : SV_TARGET3; + int4 color4 : SV_TARGET4; + int4 color5 : SV_TARGET5; + int4 color6 : SV_TARGET6; + int4 color7 : SV_TARGET7; +}; + +PS_OutputSint PS_ClearSint(in float4 inPosition : SV_POSITION, in int4 inColor : COLOR) +{ + PS_OutputSint outColor; + outColor.color0 = inColor; + outColor.color1 = inColor; + outColor.color2 = inColor; + outColor.color3 = inColor; + outColor.color4 = inColor; + outColor.color5 = inColor; + outColor.color6 = inColor; + outColor.color7 = inColor; + return outColor; +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough2D11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough2D11.hlsl new file mode 100644 index 00000000000..8671c39fb7a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough2D11.hlsl @@ -0,0 +1,111 @@ +Texture2D<float4> TextureF : register(t0); +Texture2D<uint4> TextureUI : register(t0); +Texture2D<int4> TextureI : register(t0); + +SamplerState Sampler : register(s0); + +void VS_Passthrough2D( in float2 inPosition : POSITION, in float2 inTexCoord : TEXCOORD0, + out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0) +{ + outPosition = float4(inPosition, 0.0f, 1.0f); + outTexCoord = inTexCoord; +} + +float PS_PassthroughDepth2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_DEPTH +{ + return TextureF.Sample(Sampler, inTexCoord).r; +} + +float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return TextureF.Sample(Sampler, inTexCoord).rgba; +} + +uint4 PS_PassthroughRGBA2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureUI.GetDimensions(size.x, size.y); + + return TextureUI.Load(int3(size * inTexCoord, 0)).rgba; +} + +int4 PS_PassthroughRGBA2DI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureI.GetDimensions(size.x, size.y); + + return TextureI.Load(int3(size * inTexCoord, 0)).rgba; +} + +float4 PS_PassthroughRGB2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, inTexCoord).rgb, 1.0f); +} + +uint4 PS_PassthroughRGB2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureUI.GetDimensions(size.x, size.y); + + return uint4(TextureUI.Load(int3(size * inTexCoord, 0)).rgb, 0); +} + +int4 PS_PassthroughRGB2DI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureI.GetDimensions(size.x, size.y); + + return int4(TextureI.Load(int3(size * inTexCoord, 0)).rgb, 0); +} + +float4 PS_PassthroughRG2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, inTexCoord).rg, 0.0f, 1.0f); +} + +uint4 PS_PassthroughRG2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureUI.GetDimensions(size.x, size.y); + + return uint4(TextureUI.Load(int3(size * inTexCoord, 0)).rg, 0, 0); +} + +int4 PS_PassthroughRG2DI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureI.GetDimensions(size.x, size.y); + + return int4(TextureI.Load(int3(size * inTexCoord, 0)).rg, 0, 0); +} + +float4 PS_PassthroughR2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, inTexCoord).r, 0.0f, 0.0f, 1.0f); +} + +uint4 PS_PassthroughR2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureUI.GetDimensions(size.x, size.y); + + return uint4(TextureUI.Load(int3(size * inTexCoord, 0)).r, 0, 0, 0); +} + +int4 PS_PassthroughR2DI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureI.GetDimensions(size.x, size.y); + + return int4(TextureI.Load(int3(size * inTexCoord, 0)).r, 0, 0, 0); +} + +float4 PS_PassthroughLum2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, inTexCoord).rrr, 1.0f); +} + +float4 PS_PassthroughLumAlpha2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return TextureF.Sample(Sampler, inTexCoord).rrra; +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough3D11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough3D11.hlsl new file mode 100644 index 00000000000..c23c9032ec2 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough3D11.hlsl @@ -0,0 +1,146 @@ +Texture3D<float4> TextureF : register(t0); +Texture3D<uint4> TextureUI : register(t0); +Texture3D<int4> TextureI : register(t0); + +SamplerState Sampler : register(s0); + +struct VS_INPUT +{ + float2 Position : POSITION; + uint Layer : LAYER; + float3 TexCoord : TEXCOORD; +}; + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + uint Layer : LAYER; + float3 TexCoord : TEXCOORD; +}; + +struct GS_OUTPUT +{ + float4 Position : SV_POSITION; + uint Layer : SV_RENDERTARGETARRAYINDEX; + float3 TexCoord : TEXCOORD; +}; + +VS_OUTPUT VS_Passthrough3D(VS_INPUT input) +{ + VS_OUTPUT output; + + output.Position = float4(input.Position, 0.0f, 1.0f); + output.Layer = input.Layer; + output.TexCoord = input.TexCoord; + + return output; +} + +[maxvertexcount(3)] +void GS_Passthrough3D(triangle VS_OUTPUT input[3], inout TriangleStream<GS_OUTPUT> outputStream) +{ + GS_OUTPUT output; + + for (int i = 0; i < 3; i++) + { + output.Position = input[i].Position; + output.Layer = input[i].Layer; + output.TexCoord = input[i].TexCoord; + + outputStream.Append(output); + } +} + +float4 PS_PassthroughRGBA3D(GS_OUTPUT input) : SV_TARGET0 +{ + return TextureF.Sample(Sampler, input.TexCoord).rgba; +} + +uint4 PS_PassthroughRGBA3DUI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureUI.GetDimensions(size.x, size.y, size.z); + + return TextureUI.Load(int4(size * input.TexCoord, 0)).rgba; +} + +int4 PS_PassthroughRGBA3DI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureI.GetDimensions(size.x, size.y, size.z); + + return TextureI.Load(int4(size * input.TexCoord, 0)).rgba; +} + +float4 PS_PassthroughRGB3D(GS_OUTPUT input) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, input.TexCoord).rgb, 1.0f); +} + +uint4 PS_PassthroughRGB3DUI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureUI.GetDimensions(size.x, size.y, size.z); + + return uint4(TextureUI.Load(int4(size * input.TexCoord, 0)).rgb, 0); +} + +int4 PS_PassthroughRGB3DI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureI.GetDimensions(size.x, size.y, size.z); + + return int4(TextureI.Load(int4(size * input.TexCoord, 0)).rgb, 0); +} + +float4 PS_PassthroughRG3D(GS_OUTPUT input) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, input.TexCoord).rg, 0.0f, 1.0f); +} + +uint4 PS_PassthroughRG3DUI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureUI.GetDimensions(size.x, size.y, size.z); + + return uint4(TextureUI.Load(int4(size * input.TexCoord, 0)).rg, 0, 0); +} + +int4 PS_PassthroughRG3DI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureI.GetDimensions(size.x, size.y, size.z); + + return int4(TextureI.Load(int4(size * input.TexCoord, 0)).rg, 0, 0); +} + +float4 PS_PassthroughR3D(GS_OUTPUT input) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, input.TexCoord).r, 0.0f, 0.0f, 1.0f); +} + +uint4 PS_PassthroughR3DUI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureUI.GetDimensions(size.x, size.y, size.z); + + return uint4(TextureUI.Load(int4(size * input.TexCoord, 0)).r, 0, 0, 0); +} + +int4 PS_PassthroughR3DI(GS_OUTPUT input) : SV_TARGET0 +{ + uint3 size; + TextureI.GetDimensions(size.x, size.y, size.z); + + return int4(TextureI.Load(int4(size * input.TexCoord, 0)).r, 0, 0, 0); +} + +float4 PS_PassthroughLum3D(GS_OUTPUT input) : SV_TARGET0 +{ + return float4(TextureF.Sample(Sampler, input.TexCoord).rrr, 1.0f); +} + +float4 PS_PassthroughLumAlpha3D(GS_OUTPUT input) : SV_TARGET0 +{ + return TextureF.Sample(Sampler, input.TexCoord).rrra; +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Swizzle11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Swizzle11.hlsl new file mode 100644 index 00000000000..505e2221376 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/Swizzle11.hlsl @@ -0,0 +1,99 @@ +Texture2D<float4> TextureF2D : register(t0); +Texture2D<uint4> TextureUI2D : register(t0); +Texture2D<int4> TextureI2D : register(t0); + +Texture3D<float4> TextureF3D : register(t0); +Texture3D<uint4> TextureUI3D : register(t0); +Texture3D<int4> TextureI3D : register(t0); + +Texture2DArray<float4> TextureF2DArray : register(t0); +Texture2DArray<uint4> TextureUI2DArray : register(t0); +Texture2DArray<int4> TextureI2DArray : register(t0); + +SamplerState Sampler : register(s0); + +cbuffer SwizzleProperties : register(b0) +{ + uint4 SwizzleIndices : packoffset(c0); +} + +float4 SwizzleLookup(in float4 sample) +{ + float lookup[6] = { sample[0], sample[1], sample[2], sample[3], 0.0f, 1.0f }; + return float4(lookup[SwizzleIndices[0]], lookup[SwizzleIndices[1]], lookup[SwizzleIndices[2]], lookup[SwizzleIndices[3]]); +} + +int4 SwizzleLookup(in int4 sample) +{ + int lookup[6] = { sample[0], sample[1], sample[2], sample[3], 0.0f, 1.0f }; + return int4(lookup[SwizzleIndices[0]], lookup[SwizzleIndices[1]], lookup[SwizzleIndices[2]], lookup[SwizzleIndices[3]]); +} + +uint4 SwizzleLookup(in uint4 sample) +{ + uint lookup[6] = { sample[0], sample[1], sample[2], sample[3], 0.0f, 1.0f }; + return uint4(lookup[SwizzleIndices[0]], lookup[SwizzleIndices[1]], lookup[SwizzleIndices[2]], lookup[SwizzleIndices[3]]); +} + +float4 PS_SwizzleF2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return SwizzleLookup(TextureF2D.Sample(Sampler, inTexCoord)); +} + +int4 PS_SwizzleI2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureI2D.GetDimensions(size.x, size.y); + + return SwizzleLookup(TextureI2D.Load(int3(size * inTexCoord, 0))); +} + +uint4 PS_SwizzleUI2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint2 size; + TextureUI2D.GetDimensions(size.x, size.y); + + return SwizzleLookup(TextureUI2D.Load(int3(size * inTexCoord, 0))); +} + +float4 PS_SwizzleF3D(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return SwizzleLookup(TextureF3D.Sample(Sampler, inTexCoord)); +} + +int4 PS_SwizzleI3D(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint3 size; + TextureI3D.GetDimensions(size.x, size.y, size.z); + + return SwizzleLookup(TextureI3D.Load(int4(size * inTexCoord, 0))); +} + +uint4 PS_SwizzleUI3D(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint3 size; + TextureUI3D.GetDimensions(size.x, size.y, size.z); + + return SwizzleLookup(TextureUI3D.Load(int4(size * inTexCoord, 0))); +} + +float4 PS_SwizzleF2DArray(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return SwizzleLookup(TextureF2DArray.Sample(Sampler, float3(inTexCoord.xy, inLayer))); +} + +int4 PS_SwizzleI2DArray(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint3 size; + TextureI2DArray.GetDimensions(size.x, size.y, size.z); + + return SwizzleLookup(TextureI2DArray.Load(int4(size.xy * inTexCoord.xy, inLayer, 0))); +} + +uint4 PS_SwizzleUI2DArray(in float4 inPosition : SV_POSITION, in uint inLayer : SV_RENDERTARGETARRAYINDEX, in float3 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + uint3 size; + TextureUI2DArray.GetDimensions(size.x, size.y, size.z); + + return SwizzleLookup(TextureUI2DArray.Load(int4(size.xy * inTexCoord.xy, inLayer, 0))); +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h new file mode 100644 index 00000000000..8259bc8eb01 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_gs.h @@ -0,0 +1,166 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// LAYER 0 y 1 NONE uint y +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// SV_RenderTargetArrayIndex 0 y 1 RTINDEX uint y +// +gs_4_0 +dcl_input_siv v[1][0].xyzw, position +dcl_input v[1][1].x +dcl_input v[1][1].y +dcl_inputprimitive point +dcl_outputtopology pointlist +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output_siv o1.y, rendertarget_array_index +dcl_maxout 1 +mov o0.xyzw, v[0][0].xyzw +mov o1.x, v[0][1].x +mov o1.y, v[0][1].y +emit +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_GS_BufferToTexture[] = +{ + 68, 88, 66, 67, 76, 247, + 16, 54, 179, 210, 24, 242, + 185, 199, 67, 148, 241, 107, + 16, 2, 1, 0, 0, 0, + 212, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 0, 1, + 0, 0, 136, 1, 0, 0, + 88, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 83, 71, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 108, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 2, 2, 0, 0, + 83, 86, 95, 80, 111, 115, + 105, 116, 105, 111, 110, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 76, 65, 89, + 69, 82, 0, 171, 79, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 14, + 0, 0, 101, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 13, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 82, 101, 110, 100, + 101, 114, 84, 97, 114, 103, + 101, 116, 65, 114, 114, 97, + 121, 73, 110, 100, 101, 120, + 0, 171, 83, 72, 68, 82, + 200, 0, 0, 0, 64, 0, + 2, 0, 50, 0, 0, 0, + 97, 0, 0, 5, 242, 16, + 32, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 95, 0, 0, 4, + 18, 16, 32, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 95, 0, 0, 4, 34, 16, + 32, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 93, 8, + 0, 1, 92, 8, 0, 1, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 18, 32, 16, 0, + 1, 0, 0, 0, 103, 0, + 0, 4, 34, 32, 16, 0, + 1, 0, 0, 0, 4, 0, + 0, 0, 94, 0, 0, 2, + 1, 0, 0, 0, 54, 0, + 0, 6, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 32, 16, 0, + 1, 0, 0, 0, 10, 16, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 54, 0, + 0, 6, 34, 32, 16, 0, + 1, 0, 0, 0, 26, 16, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 19, 0, + 0, 1, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h new file mode 100644 index 00000000000..ce4ca086698 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4f.h @@ -0,0 +1,223 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer BufferCopyParams +// { +// +// uint FirstPixelOffset; // Offset: 0 Size: 4 [unused] +// uint PixelsPerRow; // Offset: 4 Size: 4 [unused] +// uint RowStride; // Offset: 8 Size: 4 [unused] +// uint RowsPerSlice; // Offset: 12 Size: 4 [unused] +// float2 PositionOffset; // Offset: 16 Size: 8 [unused] +// float2 PositionScale; // Offset: 24 Size: 8 [unused] +// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused] +// int2 TexLocationScale; // Offset: 40 Size: 8 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4F texture float4 buf 0 1 +// BufferCopyParams cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_buffer (float,float,float,float) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4F[] = +{ + 68, 88, 66, 67, 161, 212, + 38, 156, 243, 82, 97, 91, + 138, 4, 55, 121, 28, 62, + 245, 159, 1, 0, 0, 0, + 216, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 104, 2, 0, 0, 192, 2, + 0, 0, 244, 2, 0, 0, + 92, 3, 0, 0, 82, 68, + 69, 70, 44, 2, 0, 0, + 1, 0, 0, 0, 120, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 249, 1, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 5, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 66, 117, 102, 102, + 101, 114, 52, 70, 0, 66, + 117, 102, 102, 101, 114, 67, + 111, 112, 121, 80, 97, 114, + 97, 109, 115, 0, 171, 171, + 101, 0, 0, 0, 8, 0, + 0, 0, 144, 0, 0, 0, + 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 80, 1, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 100, 1, + 0, 0, 0, 0, 0, 0, + 116, 1, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 100, 1, + 0, 0, 0, 0, 0, 0, + 129, 1, 0, 0, 8, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 100, 1, + 0, 0, 0, 0, 0, 0, + 139, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 100, 1, + 0, 0, 0, 0, 0, 0, + 152, 1, 0, 0, 16, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 168, 1, + 0, 0, 0, 0, 0, 0, + 184, 1, 0, 0, 24, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 168, 1, + 0, 0, 0, 0, 0, 0, + 198, 1, 0, 0, 32, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 216, 1, + 0, 0, 0, 0, 0, 0, + 232, 1, 0, 0, 40, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 216, 1, + 0, 0, 0, 0, 0, 0, + 70, 105, 114, 115, 116, 80, + 105, 120, 101, 108, 79, 102, + 102, 115, 101, 116, 0, 171, + 171, 171, 0, 0, 19, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 80, 105, 120, 101, 108, 115, + 80, 101, 114, 82, 111, 119, + 0, 82, 111, 119, 83, 116, + 114, 105, 100, 101, 0, 82, + 111, 119, 115, 80, 101, 114, + 83, 108, 105, 99, 101, 0, + 80, 111, 115, 105, 116, 105, + 111, 110, 79, 102, 102, 115, + 101, 116, 0, 171, 1, 0, + 3, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 80, 111, 115, 105, + 116, 105, 111, 110, 83, 99, + 97, 108, 101, 0, 84, 101, + 120, 76, 111, 99, 97, 116, + 105, 111, 110, 79, 102, 102, + 115, 101, 116, 0, 1, 0, + 2, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 84, 101, 120, 76, + 111, 99, 97, 116, 105, 111, + 110, 83, 99, 97, 108, 101, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 68, 82, 96, 0, + 0, 0, 64, 0, 0, 0, + 24, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 88, 8, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 85, 85, 0, 0, + 98, 8, 0, 3, 18, 16, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 32, + 16, 0, 0, 0, 0, 0, + 6, 16, 16, 0, 1, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h new file mode 100644 index 00000000000..666930a471d --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4i.h @@ -0,0 +1,129 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4I texture sint4 buf 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_buffer (sint,sint,sint,sint) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4I[] = +{ + 68, 88, 66, 67, 178, 234, + 204, 249, 218, 40, 155, 155, + 252, 18, 110, 38, 237, 186, + 217, 231, 1, 0, 0, 0, + 20, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 152, 1, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 66, 117, 102, 102, 101, 114, + 52, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 1, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 97, 114, 103, 101, 116, 0, + 171, 171, 83, 72, 68, 82, + 80, 0, 0, 0, 64, 0, + 0, 0, 20, 0, 0, 0, + 88, 8, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 8, + 0, 3, 18, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 45, 0, + 0, 7, 242, 32, 16, 0, + 0, 0, 0, 0, 6, 16, + 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h new file mode 100644 index 00000000000..1c3a3e1b707 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h @@ -0,0 +1,130 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4UI texture uint4 buf 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 x 1 NONE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_buffer (uint,uint,uint,uint) t0 +dcl_input_ps constant v1.x +dcl_output o0.xyzw +ld o0.xyzw, v1.xxxx, t0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_BufferToTexture_4UI[] = +{ + 68, 88, 66, 67, 209, 204, + 134, 75, 28, 212, 134, 131, + 219, 18, 16, 227, 99, 23, + 205, 131, 1, 0, 0, 0, + 24, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 16, 1, + 0, 0, 68, 1, 0, 0, + 156, 1, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 66, 117, 102, 102, 101, 114, + 52, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 1, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 68, 82, 80, 0, + 0, 0, 64, 0, 0, 0, + 20, 0, 0, 0, 88, 8, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 8, 0, 3, + 18, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 32, 16, 0, 0, 0, + 0, 0, 6, 16, 16, 0, + 1, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h new file mode 100644 index 00000000000..1331f3aa3b1 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/buffertotexture11_vs.h @@ -0,0 +1,303 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer BufferCopyParams +// { +// +// uint FirstPixelOffset; // Offset: 0 Size: 4 +// uint PixelsPerRow; // Offset: 4 Size: 4 +// uint RowStride; // Offset: 8 Size: 4 +// uint RowsPerSlice; // Offset: 12 Size: 4 +// float2 PositionOffset; // Offset: 16 Size: 8 +// float2 PositionScale; // Offset: 24 Size: 8 +// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused] +// int2 TexLocationScale; // Offset: 40 Size: 8 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// BufferCopyParams cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 x 1 NONE uint x +// LAYER 0 y 1 NONE uint y +// +vs_4_0 +dcl_constantbuffer cb0[2], immediateIndexed +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output o1.y +dcl_temps 2 +mov o0.zw, l(0,0,0,1.000000) +imul null, r0.xy, cb0[0].wwww, cb0[0].yzyy +udiv r0.z, null, v0.x, r0.x +imad r0.x, -r0.z, r0.x, v0.x +imad r0.y, r0.z, r0.y, cb0[0].x +mov o1.y, r0.z +udiv r0.z, null, r0.x, cb0[0].y +imad r0.x, -r0.z, cb0[0].y, r0.x +utof r1.xy, r0.xzxx +imad r0.y, r0.z, cb0[0].z, r0.y +iadd o1.x, r0.x, r0.y +mad o0.xy, cb0[1].zwzz, r1.xyxx, cb0[1].xyxx +ret +// Approximately 13 instruction slots used +#endif + +const BYTE g_VS_BufferToTexture[] = +{ + 68, 88, 66, 67, 158, 32, + 140, 89, 212, 226, 251, 197, + 186, 151, 46, 176, 250, 58, + 75, 228, 1, 0, 0, 0, + 104, 5, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 64, 2, 0, 0, 116, 2, + 0, 0, 232, 2, 0, 0, + 236, 4, 0, 0, 82, 68, + 69, 70, 4, 2, 0, 0, + 1, 0, 0, 0, 80, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 209, 1, 0, 0, 60, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 66, 117, 102, 102, 101, 114, + 67, 111, 112, 121, 80, 97, + 114, 97, 109, 115, 0, 171, + 171, 171, 60, 0, 0, 0, + 8, 0, 0, 0, 104, 0, + 0, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 40, 1, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 60, 1, 0, 0, 0, 0, + 0, 0, 76, 1, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 60, 1, 0, 0, 0, 0, + 0, 0, 89, 1, 0, 0, + 8, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 60, 1, 0, 0, 0, 0, + 0, 0, 99, 1, 0, 0, + 12, 0, 0, 0, 4, 0, + 0, 0, 2, 0, 0, 0, + 60, 1, 0, 0, 0, 0, + 0, 0, 112, 1, 0, 0, + 16, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, + 128, 1, 0, 0, 0, 0, + 0, 0, 144, 1, 0, 0, + 24, 0, 0, 0, 8, 0, + 0, 0, 2, 0, 0, 0, + 128, 1, 0, 0, 0, 0, + 0, 0, 158, 1, 0, 0, + 32, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, + 176, 1, 0, 0, 0, 0, + 0, 0, 192, 1, 0, 0, + 40, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, + 176, 1, 0, 0, 0, 0, + 0, 0, 70, 105, 114, 115, + 116, 80, 105, 120, 101, 108, + 79, 102, 102, 115, 101, 116, + 0, 171, 171, 171, 0, 0, + 19, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 80, 105, 120, 101, + 108, 115, 80, 101, 114, 82, + 111, 119, 0, 82, 111, 119, + 83, 116, 114, 105, 100, 101, + 0, 82, 111, 119, 115, 80, + 101, 114, 83, 108, 105, 99, + 101, 0, 80, 111, 115, 105, + 116, 105, 111, 110, 79, 102, + 102, 115, 101, 116, 0, 171, + 1, 0, 3, 0, 1, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 111, + 115, 105, 116, 105, 111, 110, + 83, 99, 97, 108, 101, 0, + 84, 101, 120, 76, 111, 99, + 97, 116, 105, 111, 110, 79, + 102, 102, 115, 101, 116, 0, + 1, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 101, + 120, 76, 111, 99, 97, 116, + 105, 111, 110, 83, 99, 97, + 108, 101, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 83, 86, + 95, 86, 101, 114, 116, 101, + 120, 73, 68, 0, 79, 83, + 71, 78, 108, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 14, + 0, 0, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 13, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 76, + 65, 89, 69, 82, 0, 171, + 83, 72, 68, 82, 252, 1, + 0, 0, 64, 0, 1, 0, + 127, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 96, 0, 0, 4, + 18, 16, 16, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 18, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 34, 32, 16, 0, + 1, 0, 0, 0, 104, 0, + 0, 2, 2, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 38, 0, 0, 10, + 0, 208, 0, 0, 50, 0, + 16, 0, 0, 0, 0, 0, + 246, 143, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 150, 133, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 78, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, + 0, 208, 0, 0, 10, 16, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 35, 0, 0, 10, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 16, + 16, 0, 0, 0, 0, 0, + 35, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 34, 32, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 78, 0, 0, 9, 66, 0, + 16, 0, 0, 0, 0, 0, + 0, 208, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 26, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 35, 0, 0, 11, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 26, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 1, 0, + 0, 0, 134, 0, 16, 0, + 0, 0, 0, 0, 35, 0, + 0, 10, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 30, 0, 0, 7, + 18, 32, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 50, 0, 0, 11, 50, 32, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 13, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h index 82a1493f8c8..a0ddf37211f 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11ps.h @@ -48,7 +48,7 @@ ret // Approximately 9 instruction slots used #endif -const BYTE g_PS_ClearMultiple[] = +const BYTE g_PS_ClearFloat[] = { 68, 88, 66, 67, 92, 54, 120, 105, 166, 196, 132, 158, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clear11vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h index c3a3f38a319..19401092750 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clear11vs.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearfloat11vs.h @@ -32,7 +32,7 @@ ret // Approximately 4 instruction slots used #endif -const BYTE g_VS_Clear[] = +const BYTE g_VS_ClearFloat[] = { 68, 88, 66, 67, 97, 5, 13, 163, 160, 254, 95, 127, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h new file mode 100644 index 00000000000..43081ad9727 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11ps.h @@ -0,0 +1,196 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE int xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// SV_TARGET 1 xyzw 1 TARGET int xyzw +// SV_TARGET 2 xyzw 2 TARGET int xyzw +// SV_TARGET 3 xyzw 3 TARGET int xyzw +// SV_TARGET 4 xyzw 4 TARGET int xyzw +// SV_TARGET 5 xyzw 5 TARGET int xyzw +// SV_TARGET 6 xyzw 6 TARGET int xyzw +// SV_TARGET 7 xyzw 7 TARGET int xyzw +// +ps_4_0 +dcl_input_ps constant v1.xyzw +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output o7.xyzw +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +mov o4.xyzw, v1.xyzw +mov o5.xyzw, v1.xyzw +mov o6.xyzw, v1.xyzw +mov o7.xyzw, v1.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearSint[] = +{ + 68, 88, 66, 67, 254, 74, + 218, 24, 78, 136, 223, 133, + 92, 40, 115, 152, 188, 11, + 222, 36, 1, 0, 0, 0, + 88, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 224, 0, + 0, 0, 188, 1, 0, 0, + 220, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171, 79, 83, 71, 78, + 212, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, + 200, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 2, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 3, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 4, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 6, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 24, 1, + 0, 0, 64, 0, 0, 0, + 70, 0, 0, 0, 98, 8, + 0, 3, 242, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 3, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 5, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 6, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 7, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 4, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 5, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 6, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 7, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h new file mode 100644 index 00000000000..f49d9fbb319 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsint11vs.h @@ -0,0 +1,131 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyz 0 NONE float xyz +// COLOR 0 xyzw 1 NONE int xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// COLOR 0 xyzw 1 NONE int xyzw +// +vs_4_0 +dcl_input v0.xyz +dcl_input v1.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyzw +mov o0.xyz, v0.xyzx +mov o0.w, l(1.000000) +mov o1.xyzw, v1.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_ClearSint[] = +{ + 68, 88, 66, 67, 254, 10, + 228, 23, 109, 37, 56, 192, + 81, 175, 113, 148, 13, 249, + 236, 118, 1, 0, 0, 0, + 48, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 220, 0, + 0, 0, 48, 1, 0, 0, + 180, 1, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 72, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 7, 7, 0, 0, + 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 67, 79, 76, + 79, 82, 0, 171, 79, 83, + 71, 78, 76, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 67, 79, 76, 79, + 82, 0, 171, 171, 83, 72, + 68, 82, 124, 0, 0, 0, + 64, 0, 1, 0, 31, 0, + 0, 0, 95, 0, 0, 3, + 114, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 1, 0, + 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 5, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h new file mode 100644 index 00000000000..42a21f9a370 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11ps.h @@ -0,0 +1,196 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE uint xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// SV_TARGET 1 xyzw 1 TARGET uint xyzw +// SV_TARGET 2 xyzw 2 TARGET uint xyzw +// SV_TARGET 3 xyzw 3 TARGET uint xyzw +// SV_TARGET 4 xyzw 4 TARGET uint xyzw +// SV_TARGET 5 xyzw 5 TARGET uint xyzw +// SV_TARGET 6 xyzw 6 TARGET uint xyzw +// SV_TARGET 7 xyzw 7 TARGET uint xyzw +// +ps_4_0 +dcl_input_ps constant v1.xyzw +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +dcl_output o4.xyzw +dcl_output o5.xyzw +dcl_output o6.xyzw +dcl_output o7.xyzw +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +mov o4.xyzw, v1.xyzw +mov o5.xyzw, v1.xyzw +mov o6.xyzw, v1.xyzw +mov o7.xyzw, v1.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearUint[] = +{ + 68, 88, 66, 67, 199, 72, + 167, 165, 16, 175, 86, 185, + 38, 71, 2, 169, 180, 38, + 231, 204, 1, 0, 0, 0, + 88, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 224, 0, + 0, 0, 188, 1, 0, 0, + 220, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171, 79, 83, 71, 78, + 212, 0, 0, 0, 8, 0, + 0, 0, 8, 0, 0, 0, + 200, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 4, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 5, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 6, 0, + 0, 0, 15, 0, 0, 0, + 200, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 7, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 24, 1, + 0, 0, 64, 0, 0, 0, + 70, 0, 0, 0, 98, 8, + 0, 3, 242, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 3, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 5, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 6, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 7, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 4, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 5, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 6, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 7, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h new file mode 100644 index 00000000000..9fe00021f0e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/clearuint11vs.h @@ -0,0 +1,131 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyz 0 NONE float xyz +// COLOR 0 xyzw 1 NONE uint xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// COLOR 0 xyzw 1 NONE uint xyzw +// +vs_4_0 +dcl_input v0.xyz +dcl_input v1.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyzw +mov o0.xyz, v0.xyzx +mov o0.w, l(1.000000) +mov o1.xyzw, v1.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_ClearUint[] = +{ + 68, 88, 66, 67, 143, 217, + 8, 75, 126, 180, 129, 114, + 145, 192, 142, 211, 178, 208, + 255, 251, 1, 0, 0, 0, + 48, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 220, 0, + 0, 0, 48, 1, 0, 0, + 180, 1, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 72, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 7, 7, 0, 0, + 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 67, 79, 76, + 79, 82, 0, 171, 79, 83, + 71, 78, 76, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 67, 79, 76, 79, + 82, 0, 171, 171, 83, 72, + 68, 82, 124, 0, 0, 0, + 64, 0, 1, 0, 31, 0, + 0, 0, 95, 0, 0, 3, + 114, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 1, 0, + 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 5, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthrough11vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h index bbe1be9433b..e4e2c12b5d6 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthrough11vs.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h @@ -32,7 +32,7 @@ ret // Approximately 4 instruction slots used #endif -const BYTE g_VS_Passthrough[] = +const BYTE g_VS_Passthrough2D[] = { 68, 88, 66, 67, 197, 214, 184, 85, 240, 94, 71, 48, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h new file mode 100644 index 00000000000..6bf18125ba7 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h @@ -0,0 +1,192 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +gs_4_0 +dcl_input_siv v[3][0].xyzw, position +dcl_input v[3][1].x +dcl_input v[3][2].xyz +dcl_temps 1 +dcl_inputprimitive triangle +dcl_outputtopology trianglestrip +dcl_output_siv o0.xyzw, position +dcl_output_siv o1.x, rendertarget_array_index +dcl_output o2.xyz +dcl_maxout 3 +mov r0.x, l(0) +loop + ige r0.y, r0.x, l(3) + breakc_nz r0.y + mov o0.xyzw, v[r0.x + 0][0].xyzw + mov o1.x, v[r0.x + 0][1].x + mov o2.xyz, v[r0.x + 0][2].xyzx + emit + iadd r0.x, r0.x, l(1) +endloop +ret +// Approximately 11 instruction slots used +#endif + +const BYTE g_GS_Passthrough3D[] = +{ + 68, 88, 66, 67, 21, 92, + 188, 203, 22, 49, 177, 239, + 121, 233, 148, 135, 212, 27, + 172, 209, 1, 0, 0, 0, + 72, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 0, 1, + 0, 0, 136, 1, 0, 0, + 204, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 83, 71, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 108, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 98, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 7, 7, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 76, 65, 89, 69, 82, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 14, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 8, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 83, 72, 68, 82, + 60, 1, 0, 0, 64, 0, + 2, 0, 79, 0, 0, 0, + 97, 0, 0, 5, 242, 16, + 32, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 95, 0, 0, 4, + 18, 16, 32, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 95, 0, 0, 4, 114, 16, + 32, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 93, 24, 0, 1, 92, 40, + 0, 1, 103, 0, 0, 4, + 242, 32, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 103, 0, 0, 4, 18, 32, + 16, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 101, 0, + 0, 3, 114, 32, 16, 0, + 2, 0, 0, 0, 94, 0, + 0, 2, 3, 0, 0, 0, + 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 48, 0, 0, 1, + 33, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 3, 0, + 4, 3, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 160, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 18, 32, 16, 0, 1, 0, + 0, 0, 10, 16, 160, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 7, 114, 32, + 16, 0, 2, 0, 0, 0, + 70, 18, 160, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 19, 0, + 0, 1, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 22, 0, 0, 1, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 11, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 5, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h new file mode 100644 index 00000000000..03097d2ad62 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h @@ -0,0 +1,156 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// LAYER 0 x 1 NONE uint x +// TEXCOORD 0 xyz 2 NONE float xyz +// +vs_4_0 +dcl_input v0.xy +dcl_input v1.x +dcl_input v2.xyz +dcl_output_siv o0.xyzw, position +dcl_output o1.x +dcl_output o2.xyz +mov o0.xy, v0.xyxx +mov o0.zw, l(0,0,0,1.000000) +mov o1.x, v1.x +mov o2.xyz, v2.xyzx +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_VS_Passthrough3D[] = +{ + 68, 88, 66, 67, 92, 60, + 15, 188, 90, 157, 249, 215, + 202, 142, 58, 127, 103, 200, + 181, 87, 1, 0, 0, 0, + 168, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 252, 0, + 0, 0, 112, 1, 0, 0, + 44, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 254, 255, 0, 1, 0, 0, + 28, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 104, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 0, 0, + 89, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 95, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 7, 7, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 76, 65, 89, + 69, 82, 0, 84, 69, 88, + 67, 79, 79, 82, 68, 0, + 79, 83, 71, 78, 108, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 14, 0, 0, 98, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 8, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 76, 65, + 89, 69, 82, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 83, 72, 68, 82, + 180, 0, 0, 0, 64, 0, + 1, 0, 45, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 0, 0, 0, 0, + 95, 0, 0, 3, 18, 16, + 16, 0, 1, 0, 0, 0, + 95, 0, 0, 3, 114, 16, + 16, 0, 2, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 18, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 114, 32, 16, 0, + 2, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 54, 0, 0, 5, + 18, 32, 16, 0, 1, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, + 2, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h new file mode 100644 index 00000000000..d9864c665d4 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h @@ -0,0 +1,146 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_DEPTH 0 N/A oDepth DEPTH float YES +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output oDepth +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov oDepth, r0.x +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_PassthroughDepth2D[] = +{ + 68, 88, 66, 67, 205, 127, + 148, 170, 168, 91, 194, 133, + 180, 181, 17, 51, 13, 53, + 48, 72, 1, 0, 0, 0, + 100, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 52, 1, + 0, 0, 104, 1, 0, 0, + 232, 1, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 255, 255, + 255, 255, 1, 14, 0, 0, + 83, 86, 95, 68, 69, 80, + 84, 72, 0, 171, 171, 171, + 83, 72, 68, 82, 120, 0, + 0, 0, 64, 0, 0, 0, + 30, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 2, + 1, 192, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 69, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 4, 1, 192, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h index 73c4892cab6..141b183a50f 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h @@ -9,7 +9,7 @@ // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // Sampler sampler NA NA 0 1 -// Texture texture float4 2d 0 1 +// TextureF texture float4 2d 0 1 // // // @@ -40,12 +40,12 @@ ret // Approximately 4 instruction slots used #endif -const BYTE g_PS_PassthroughLum[] = +const BYTE g_PS_PassthroughLum2D[] = { - 68, 88, 66, 67, 244, 9, - 213, 147, 19, 249, 70, 111, - 157, 92, 243, 160, 40, 144, - 238, 221, 1, 0, 0, 0, + 68, 88, 66, 67, 75, 65, + 224, 54, 123, 121, 78, 132, + 180, 89, 93, 146, 31, 209, + 114, 35, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, 0, 0, 52, 1, @@ -56,7 +56,7 @@ const BYTE g_PS_PassthroughLum[] = 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, - 108, 0, 0, 0, 92, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -69,16 +69,16 @@ const BYTE g_PS_PassthroughLum[] = 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, - 120, 116, 117, 114, 101, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 57, - 46, 51, 48, 46, 57, 50, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h new file mode 100644 index 00000000000..df25c15a966 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h @@ -0,0 +1,161 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xxxx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughLum3D[] = +{ + 68, 88, 66, 67, 139, 183, + 126, 70, 59, 171, 117, 78, + 58, 168, 253, 206, 241, 67, + 236, 117, 1, 0, 0, 0, + 176, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 52, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 148, 0, + 0, 0, 64, 0, 0, 0, + 37, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h index 90007ef7d58..ad7efb3afc2 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h @@ -9,7 +9,7 @@ // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // Sampler sampler NA NA 0 1 -// Texture texture float4 2d 0 1 +// TextureF texture float4 2d 0 1 // // // @@ -39,12 +39,12 @@ ret // Approximately 3 instruction slots used #endif -const BYTE g_PS_PassthroughLumAlpha[] = +const BYTE g_PS_PassthroughLumAlpha2D[] = { - 68, 88, 66, 67, 185, 14, - 84, 223, 192, 42, 16, 133, - 46, 100, 95, 221, 183, 97, - 192, 23, 1, 0, 0, 0, + 68, 88, 66, 67, 211, 12, + 122, 206, 209, 255, 137, 132, + 163, 164, 87, 202, 31, 60, + 79, 244, 1, 0, 0, 0, 108, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, 0, 0, 52, 1, @@ -55,7 +55,7 @@ const BYTE g_PS_PassthroughLumAlpha[] = 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, - 108, 0, 0, 0, 92, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -68,16 +68,16 @@ const BYTE g_PS_PassthroughLumAlpha[] = 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, - 120, 116, 117, 114, 101, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 57, - 46, 51, 48, 46, 57, 50, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h new file mode 100644 index 00000000000..6a3093b965f --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h @@ -0,0 +1,157 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyzw, r0.xxxw +ret +// Approximately 3 instruction slots used +#endif + +const BYTE g_PS_PassthroughLumAlpha3D[] = +{ + 68, 88, 66, 67, 79, 152, + 38, 183, 191, 232, 234, 74, + 20, 216, 159, 98, 130, 89, + 67, 230, 1, 0, 0, 0, + 156, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 32, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 128, 0, + 0, 0, 64, 0, 0, 0, + 32, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 6, 12, + 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h new file mode 100644 index 00000000000..ba802a8f167 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h @@ -0,0 +1,154 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2D[] = +{ + 68, 88, 66, 67, 165, 241, + 169, 123, 72, 216, 126, 110, + 212, 26, 98, 247, 42, 20, + 73, 129, 1, 0, 0, 0, + 140, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 52, 1, + 0, 0, 104, 1, 0, 0, + 16, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 160, 0, + 0, 0, 64, 0, 0, 0, + 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h new file mode 100644 index 00000000000..78d780989a2 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h @@ -0,0 +1,168 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DI[] = +{ + 68, 88, 66, 67, 175, 34, + 58, 63, 77, 138, 186, 41, + 33, 239, 107, 231, 51, 122, + 194, 229, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 12, 1, 0, 0, 64, 0, + 0, 0, 67, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 226, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h new file mode 100644 index 00000000000..db32b558ea9 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h @@ -0,0 +1,169 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR2DUI[] = +{ + 68, 88, 66, 67, 166, 175, + 86, 113, 175, 196, 222, 119, + 102, 108, 1, 17, 158, 88, + 24, 124, 1, 0, 0, 0, + 212, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 16, 1, + 0, 0, 68, 1, 0, 0, + 88, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 12, 1, + 0, 0, 64, 0, 0, 0, + 67, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h new file mode 100644 index 00000000000..317502be72f --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h @@ -0,0 +1,163 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3D[] = +{ + 68, 88, 66, 67, 154, 126, + 157, 110, 55, 22, 118, 195, + 222, 16, 4, 44, 4, 186, + 175, 193, 1, 0, 0, 0, + 188, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 64, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 160, 0, + 0, 0, 64, 0, 0, 0, + 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h new file mode 100644 index 00000000000..f6c44744e84 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h @@ -0,0 +1,175 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3DI[] = +{ + 68, 88, 66, 67, 32, 229, + 168, 57, 179, 12, 205, 158, + 146, 39, 161, 133, 6, 137, + 250, 121, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 128, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 7, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 86, + 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, + 73, 78, 68, 69, 88, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 0, 1, 0, 0, 64, 0, + 0, 0, 64, 0, 0, 0, + 88, 40, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 114, 16, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 226, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h new file mode 100644 index 00000000000..56c10c6c140 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h @@ -0,0 +1,176 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.x, r0.x +mov o0.yzw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughR3DUI[] = +{ + 68, 88, 66, 67, 8, 69, + 203, 31, 19, 83, 247, 164, + 150, 170, 250, 231, 193, 198, + 155, 234, 1, 0, 0, 0, + 248, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 64, 1, + 0, 0, 116, 1, 0, 0, + 124, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 0, 1, + 0, 0, 64, 0, 0, 0, + 64, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 2, 0, + 0, 0, 27, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h new file mode 100644 index 00000000000..d8f0e5864b7 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h @@ -0,0 +1,154 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2D[] = +{ + 68, 88, 66, 67, 106, 129, + 89, 74, 87, 68, 176, 125, + 58, 44, 17, 208, 223, 126, + 71, 132, 1, 0, 0, 0, + 140, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 52, 1, + 0, 0, 104, 1, 0, 0, + 16, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 160, 0, + 0, 0, 64, 0, 0, 0, + 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h new file mode 100644 index 00000000000..0dd83a2ec8c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h @@ -0,0 +1,168 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DI[] = +{ + 68, 88, 66, 67, 0, 22, + 144, 161, 146, 93, 225, 81, + 225, 191, 53, 51, 239, 96, + 173, 21, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 12, 1, 0, 0, 64, 0, + 0, 0, 67, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 32, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 194, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h new file mode 100644 index 00000000000..f4ed9e6c69b --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h @@ -0,0 +1,169 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG2DUI[] = +{ + 68, 88, 66, 67, 130, 164, + 140, 202, 225, 164, 4, 123, + 218, 122, 13, 46, 22, 3, + 146, 201, 1, 0, 0, 0, + 212, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 16, 1, + 0, 0, 68, 1, 0, 0, + 88, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 12, 1, + 0, 0, 64, 0, 0, 0, + 67, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h new file mode 100644 index 00000000000..23a6f05f802 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h @@ -0,0 +1,163 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3D[] = +{ + 68, 88, 66, 67, 142, 241, + 58, 49, 223, 78, 87, 10, + 12, 78, 47, 182, 66, 149, + 242, 111, 1, 0, 0, 0, + 188, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 64, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 160, 0, + 0, 0, 64, 0, 0, 0, + 40, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h new file mode 100644 index 00000000000..3e3b1331f09 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h @@ -0,0 +1,175 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3DI[] = +{ + 68, 88, 66, 67, 177, 20, + 184, 219, 63, 125, 238, 228, + 90, 44, 180, 111, 221, 4, + 193, 138, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 128, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 7, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 86, + 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, + 73, 78, 68, 69, 88, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 0, 1, 0, 0, 64, 0, + 0, 0, 64, 0, 0, 0, + 88, 40, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 114, 16, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 50, 32, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 194, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h new file mode 100644 index 00000000000..3ea21273d55 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h @@ -0,0 +1,176 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xy, r0.xyxx +mov o0.zw, l(0,0,0,0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRG3DUI[] = +{ + 68, 88, 66, 67, 44, 75, + 122, 141, 176, 19, 231, 192, + 165, 252, 210, 30, 121, 18, + 77, 89, 1, 0, 0, 0, + 248, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 64, 1, + 0, 0, 116, 1, 0, 0, + 124, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 0, 1, + 0, 0, 64, 0, 0, 0, + 64, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 2, 0, + 0, 0, 27, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h index a99c5411124..32863fc63ad 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h @@ -9,7 +9,7 @@ // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // Sampler sampler NA NA 0 1 -// Texture texture float4 2d 0 1 +// TextureF texture float4 2d 0 1 // // // @@ -40,12 +40,12 @@ ret // Approximately 4 instruction slots used #endif -const BYTE g_PS_PassthroughRGB[] = +const BYTE g_PS_PassthroughRGB2D[] = { - 68, 88, 66, 67, 125, 186, - 250, 242, 113, 255, 59, 239, - 119, 158, 237, 78, 220, 43, - 160, 46, 1, 0, 0, 0, + 68, 88, 66, 67, 173, 177, + 43, 26, 103, 245, 60, 209, + 56, 67, 66, 231, 81, 165, + 64, 69, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, 0, 0, 52, 1, @@ -56,7 +56,7 @@ const BYTE g_PS_PassthroughRGB[] = 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, - 108, 0, 0, 0, 92, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -69,16 +69,16 @@ const BYTE g_PS_PassthroughRGB[] = 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, - 120, 116, 117, 114, 101, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 57, - 46, 51, 48, 46, 57, 50, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h new file mode 100644 index 00000000000..3fbd9ee54cd --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h @@ -0,0 +1,166 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DI[] = +{ + 68, 88, 66, 67, 249, 26, + 212, 170, 3, 17, 240, 188, + 220, 164, 244, 167, 202, 103, + 2, 190, 1, 0, 0, 0, + 196, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 72, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 0, 1, 0, 0, 64, 0, + 0, 0, 64, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h new file mode 100644 index 00000000000..f1be28582aa --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h @@ -0,0 +1,167 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB2DUI[] = +{ + 68, 88, 66, 67, 158, 133, + 153, 245, 14, 212, 29, 23, + 89, 41, 242, 173, 58, 186, + 36, 20, 1, 0, 0, 0, + 200, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 16, 1, + 0, 0, 68, 1, 0, 0, + 76, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 0, 1, + 0, 0, 64, 0, 0, 0, + 64, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h new file mode 100644 index 00000000000..466756c313e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h @@ -0,0 +1,161 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov o0.xyz, r0.xyzx +mov o0.w, l(1.000000) +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3D[] = +{ + 68, 88, 66, 67, 151, 192, + 30, 128, 185, 187, 67, 126, + 162, 19, 147, 24, 96, 236, + 66, 114, 1, 0, 0, 0, + 176, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 52, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 148, 0, + 0, 0, 64, 0, 0, 0, + 37, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h new file mode 100644 index 00000000000..99073a2e767 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h @@ -0,0 +1,173 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3DI[] = +{ + 68, 88, 66, 67, 159, 150, + 210, 67, 149, 116, 221, 62, + 207, 82, 157, 210, 9, 100, + 131, 204, 1, 0, 0, 0, + 232, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 108, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 128, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 7, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 86, + 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, + 73, 78, 68, 69, 88, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 244, 0, 0, 0, 64, 0, + 0, 0, 61, 0, 0, 0, + 88, 40, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 114, 16, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h new file mode 100644 index 00000000000..627b216a2a7 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h @@ -0,0 +1,174 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov o0.xyz, r0.xyzx +mov o0.w, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGB3DUI[] = +{ + 68, 88, 66, 67, 120, 50, + 182, 251, 216, 8, 85, 92, + 127, 151, 194, 64, 248, 151, + 55, 163, 1, 0, 0, 0, + 236, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 64, 1, + 0, 0, 116, 1, 0, 0, + 112, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 244, 0, + 0, 0, 64, 0, 0, 0, + 61, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 2, 0, + 0, 0, 27, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 114, 32, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 32, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h index bf9ee709f78..54abeda0bac 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h @@ -9,7 +9,7 @@ // Name Type Format Dim Slot Elements // ------------------------------ ---------- ------- ----------- ---- -------- // Sampler sampler NA NA 0 1 -// Texture texture float4 2d 0 1 +// TextureF texture float4 2d 0 1 // // // @@ -37,12 +37,12 @@ ret // Approximately 2 instruction slots used #endif -const BYTE g_PS_PassthroughRGBA[] = +const BYTE g_PS_PassthroughRGBA2D[] = { - 68, 88, 66, 67, 151, 152, - 8, 102, 174, 135, 76, 57, - 100, 146, 59, 74, 205, 35, - 206, 21, 1, 0, 0, 0, + 68, 88, 66, 67, 185, 246, + 217, 85, 112, 245, 247, 121, + 114, 229, 186, 138, 215, 134, + 18, 1, 1, 0, 0, 0, 80, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0, 0, 0, 52, 1, @@ -53,7 +53,7 @@ const BYTE g_PS_PassthroughRGBA[] = 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, - 108, 0, 0, 0, 92, 0, + 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -66,16 +66,16 @@ const BYTE g_PS_PassthroughRGBA[] = 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, - 120, 116, 117, 114, 101, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 57, - 46, 51, 48, 46, 57, 50, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h new file mode 100644 index 00000000000..8513bebce2e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h @@ -0,0 +1,158 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DI[] = +{ + 68, 88, 66, 67, 154, 22, + 19, 195, 64, 124, 15, 43, + 32, 163, 142, 31, 97, 239, + 22, 9, 1, 0, 0, 0, + 156, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 32, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 216, 0, 0, 0, 64, 0, + 0, 0, 54, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 7, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h new file mode 100644 index 00000000000..6f1062f14be --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h @@ -0,0 +1,158 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DUI[] = +{ + 68, 88, 66, 67, 70, 254, + 149, 124, 180, 164, 152, 186, + 218, 175, 81, 67, 76, 30, + 28, 75, 1, 0, 0, 0, + 160, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 16, 1, + 0, 0, 68, 1, 0, 0, + 36, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 216, 0, + 0, 0, 64, 0, 0, 0, + 54, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 27, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 7, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h new file mode 100644 index 00000000000..a2df7ed87db --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h @@ -0,0 +1,150 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +sample o0.xyzw, v2.xyzx, t0.xyzw, s0 +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3D[] = +{ + 68, 88, 66, 67, 210, 245, + 69, 229, 208, 176, 191, 93, + 81, 12, 174, 136, 0, 184, + 83, 208, 1, 0, 0, 0, + 128, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 4, 2, 0, 0, 82, 68, + 69, 70, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 109, 0, 0, 0, 92, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 100, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 83, 97, 109, 112, + 108, 101, 114, 0, 84, 101, + 120, 116, 117, 114, 101, 70, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 100, 0, + 0, 0, 64, 0, 0, 0, + 25, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 69, 0, 0, 9, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h new file mode 100644 index 00000000000..0fcfe3932bf --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h @@ -0,0 +1,165 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3DI[] = +{ + 68, 88, 66, 67, 152, 248, + 214, 130, 39, 9, 70, 81, + 25, 166, 69, 85, 30, 229, + 132, 197, 1, 0, 0, 0, + 192, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 68, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 69, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 73, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 73, 83, 71, 78, 128, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 7, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 86, + 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, + 73, 78, 68, 69, 88, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 204, 0, 0, 0, 64, 0, + 0, 0, 51, 0, 0, 0, + 88, 40, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 98, 16, + 0, 3, 114, 16, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, + 7, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h new file mode 100644 index 00000000000..748195ea587 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h @@ -0,0 +1,165 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld o0.xyzw, r0.xyzw, t0.xyzw +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA3DUI[] = +{ + 68, 88, 66, 67, 24, 171, + 238, 127, 243, 33, 183, 183, + 228, 225, 69, 159, 98, 227, + 253, 69, 1, 0, 0, 0, + 196, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 184, 0, 0, 0, 64, 1, + 0, 0, 116, 1, 0, 0, + 72, 2, 0, 0, 82, 68, + 69, 70, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 70, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 85, 73, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 171, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 204, 0, + 0, 0, 64, 0, 0, 0, + 51, 0, 0, 0, 88, 40, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 68, 68, + 0, 0, 98, 16, 0, 3, + 114, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, + 0, 7, 242, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 86, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 70, 18, 16, 0, 2, 0, + 0, 0, 27, 0, 0, 5, + 114, 0, 16, 0, 0, 0, + 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 7, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h new file mode 100644 index 00000000000..6e531b329a9 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h @@ -0,0 +1,279 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF2DArray texture float4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture2darray (float,float,float,float) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +utof r0.z, v1.x +mov r0.xy, v2.xyxx +sample r0.xyzw, r0.xyzx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 18 instruction slots used +#endif + +const BYTE g_PS_SwizzleF2DArray[] = +{ + 68, 88, 66, 67, 161, 112, + 176, 131, 216, 246, 27, 65, + 39, 246, 72, 161, 231, 81, + 229, 143, 1, 0, 0, 0, + 204, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 104, 1, 0, 0, 240, 1, + 0, 0, 36, 2, 0, 0, + 80, 4, 0, 0, 82, 68, + 69, 70, 44, 1, 0, 0, + 1, 0, 0, 0, 168, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 248, 0, 0, 0, 124, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 132, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 5, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 148, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 83, 97, + 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, + 101, 70, 50, 68, 65, 114, + 114, 97, 121, 0, 83, 119, + 105, 122, 122, 108, 101, 80, + 114, 111, 112, 101, 114, 116, + 105, 101, 115, 0, 171, 171, + 148, 0, 0, 0, 1, 0, + 0, 0, 192, 0, 0, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 216, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 232, 0, + 0, 0, 0, 0, 0, 0, + 83, 119, 105, 122, 122, 108, + 101, 73, 110, 100, 105, 99, + 101, 115, 0, 171, 1, 0, + 19, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 51, 48, 46, + 57, 50, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 171, + 73, 83, 71, 78, 128, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 1, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 83, 86, + 95, 82, 69, 78, 68, 69, + 82, 84, 65, 82, 71, 69, + 84, 65, 82, 82, 65, 89, + 73, 78, 68, 69, 88, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 79, 83, + 71, 78, 44, 0, 0, 0, + 1, 0, 0, 0, 8, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 84, + 65, 82, 71, 69, 84, 0, + 171, 171, 83, 72, 68, 82, + 36, 2, 0, 0, 64, 0, + 0, 0, 137, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 90, 0, + 0, 3, 0, 96, 16, 0, + 0, 0, 0, 0, 88, 64, + 0, 4, 0, 112, 16, 0, + 0, 0, 0, 0, 85, 85, + 0, 0, 100, 8, 0, 4, + 18, 16, 16, 0, 1, 0, + 0, 0, 4, 0, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, + 0, 0, 0, 0, 6, 0, + 0, 0, 4, 0, 0, 0, + 86, 0, 0, 5, 66, 0, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 2, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 34, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 66, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 18, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h new file mode 100644 index 00000000000..3439e7cd521 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h @@ -0,0 +1,257 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF2D texture float4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 16 instruction slots used +#endif + +const BYTE g_PS_SwizzleF2D[] = +{ + 68, 88, 66, 67, 162, 151, + 82, 12, 22, 214, 143, 216, + 57, 84, 12, 76, 109, 120, + 162, 201, 1, 0, 0, 0, + 96, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 1, 0, 0, 188, 1, + 0, 0, 240, 1, 0, 0, + 228, 3, 0, 0, 82, 68, + 69, 70, 40, 1, 0, 0, + 1, 0, 0, 0, 164, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 244, 0, 0, 0, 124, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 132, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 4, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 143, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 83, 97, + 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, + 101, 70, 50, 68, 0, 83, + 119, 105, 122, 122, 108, 101, + 80, 114, 111, 112, 101, 114, + 116, 105, 101, 115, 0, 171, + 171, 171, 143, 0, 0, 0, + 1, 0, 0, 0, 188, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 212, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 228, 0, 0, 0, 0, 0, + 0, 0, 83, 119, 105, 122, + 122, 108, 101, 73, 110, 100, + 105, 99, 101, 115, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 3, 3, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 171, 171, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 65, 82, 71, 69, + 84, 0, 171, 171, 83, 72, + 68, 82, 236, 1, 0, 0, + 64, 0, 0, 0, 123, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 90, 0, 0, 3, 0, 96, + 16, 0, 0, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 98, 16, + 0, 3, 50, 16, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 105, 0, 0, 4, 0, 0, + 0, 0, 6, 0, 0, 0, + 4, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 34, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 66, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 16, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h new file mode 100644 index 00000000000..4985c3cc54c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h @@ -0,0 +1,266 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF3D texture float4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_sampler s0, mode_default +dcl_resource_texture3d (float,float,float,float) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +sample r0.xyzw, v2.xyzx, t0.xyzw, s0 +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1.000000) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 16 instruction slots used +#endif + +const BYTE g_PS_SwizzleF3D[] = +{ + 68, 88, 66, 67, 112, 23, + 39, 219, 141, 10, 170, 22, + 165, 204, 123, 149, 248, 84, + 184, 117, 1, 0, 0, 0, + 144, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 1, 0, 0, 236, 1, + 0, 0, 32, 2, 0, 0, + 20, 4, 0, 0, 82, 68, + 69, 70, 40, 1, 0, 0, + 1, 0, 0, 0, 164, 0, + 0, 0, 3, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 244, 0, 0, 0, 124, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 132, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 13, 0, + 0, 0, 143, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 83, 97, + 109, 112, 108, 101, 114, 0, + 84, 101, 120, 116, 117, 114, + 101, 70, 51, 68, 0, 83, + 119, 105, 122, 122, 108, 101, + 80, 114, 111, 112, 101, 114, + 116, 105, 101, 115, 0, 171, + 171, 171, 143, 0, 0, 0, + 1, 0, 0, 0, 188, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 212, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 228, 0, 0, 0, 0, 0, + 0, 0, 83, 119, 105, 122, + 122, 108, 101, 73, 110, 100, + 105, 99, 101, 115, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 128, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 7, 7, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 83, 86, 95, 82, 69, 78, + 68, 69, 82, 84, 65, 82, + 71, 69, 84, 65, 82, 82, + 65, 89, 73, 78, 68, 69, + 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 65, 82, 71, 69, + 84, 0, 171, 171, 83, 72, + 68, 82, 236, 1, 0, 0, + 64, 0, 0, 0, 123, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 90, 0, 0, 3, 0, 96, + 16, 0, 0, 0, 0, 0, + 88, 40, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 98, 16, + 0, 3, 114, 16, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 105, 0, 0, 4, 0, 0, + 0, 0, 6, 0, 0, 0, + 4, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 18, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 34, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 66, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 16, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h new file mode 100644 index 00000000000..6f2fa45fc5e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h @@ -0,0 +1,287 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI2DArray texture sint4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture2darray (sint,sint,sint,sint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 22 instruction slots used +#endif + +const BYTE g_PS_SwizzleI2DArray[] = +{ + 68, 88, 66, 67, 75, 76, + 4, 200, 179, 192, 148, 142, + 191, 41, 209, 141, 122, 203, + 184, 74, 1, 0, 0, 0, + 240, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 64, 1, 0, 0, 200, 1, + 0, 0, 252, 1, 0, 0, + 116, 4, 0, 0, 82, 68, + 69, 70, 4, 1, 0, 0, + 1, 0, 0, 0, 128, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 208, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 5, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 108, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 73, 50, 68, + 65, 114, 114, 97, 121, 0, + 83, 119, 105, 122, 122, 108, + 101, 80, 114, 111, 112, 101, + 114, 116, 105, 101, 115, 0, + 171, 171, 108, 0, 0, 0, + 1, 0, 0, 0, 152, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 176, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 192, 0, 0, 0, 0, 0, + 0, 0, 83, 119, 105, 122, + 122, 108, 101, 73, 110, 100, + 105, 99, 101, 115, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 128, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 7, 3, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 83, 86, 95, 82, 69, 78, + 68, 69, 82, 84, 65, 82, + 71, 69, 84, 65, 82, 82, + 65, 89, 73, 78, 68, 69, + 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 65, 82, 71, 69, + 84, 0, 171, 171, 83, 72, + 68, 82, 112, 2, 0, 0, + 64, 0, 0, 0, 156, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 88, 64, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 51, 51, 0, 0, 100, 8, + 0, 4, 18, 16, 16, 0, + 1, 0, 0, 0, 4, 0, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 105, 0, + 0, 4, 0, 0, 0, 0, + 6, 0, 0, 0, 4, 0, + 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 2, 0, 0, 0, + 27, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 34, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 66, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 22, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h new file mode 100644 index 00000000000..f7d4540112c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h @@ -0,0 +1,271 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI2D texture sint4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture2d (sint,sint,sint,sint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleI2D[] = +{ + 68, 88, 66, 67, 137, 89, + 210, 142, 141, 7, 14, 194, + 111, 71, 23, 167, 232, 166, + 154, 59, 1, 0, 0, 0, + 164, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 148, 1, + 0, 0, 200, 1, 0, 0, + 40, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 0, 0, + 1, 0, 0, 0, 124, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 204, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 103, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 73, 50, 68, + 0, 83, 119, 105, 122, 122, + 108, 101, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, + 0, 171, 171, 171, 103, 0, + 0, 0, 1, 0, 0, 0, + 148, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 0, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, + 105, 122, 122, 108, 101, 73, + 110, 100, 105, 99, 101, 115, + 0, 171, 1, 0, 19, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 51, 48, 46, 57, 50, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 88, 2, + 0, 0, 64, 0, 0, 0, + 150, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 88, 24, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 51, 51, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, + 0, 0, 0, 0, 6, 0, + 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 34, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 66, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 21, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h new file mode 100644 index 00000000000..064c2760449 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h @@ -0,0 +1,278 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI3D texture sint4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET int xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture3d (sint,sint,sint,sint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleI3D[] = +{ + 68, 88, 66, 67, 101, 41, + 194, 229, 103, 175, 204, 102, + 192, 43, 200, 161, 117, 114, + 19, 252, 1, 0, 0, 0, + 200, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 196, 1, + 0, 0, 248, 1, 0, 0, + 76, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 0, 0, + 1, 0, 0, 0, 124, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 204, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 103, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 73, 51, 68, + 0, 83, 119, 105, 122, 122, + 108, 101, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, + 0, 171, 171, 171, 103, 0, + 0, 0, 1, 0, 0, 0, + 148, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 0, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, + 105, 122, 122, 108, 101, 73, + 110, 100, 105, 99, 101, 115, + 0, 171, 1, 0, 19, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 51, 48, 46, 57, 50, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 76, 2, + 0, 0, 64, 0, 0, 0, + 147, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 51, 51, 0, 0, + 98, 16, 0, 3, 114, 16, + 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, + 0, 0, 0, 0, 6, 0, + 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 34, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 66, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 21, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h new file mode 100644 index 00000000000..5fa9a54cd21 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h @@ -0,0 +1,287 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI2DArray texture uint4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x +// TEXCOORD 0 xyz 2 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture2darray (uint,uint,uint,uint) t0 +dcl_input_ps_siv constant v1.x, rendertarget_array_index +dcl_input_ps linear v2.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v2.xyxx +ftoi r0.xy, r0.xyxx +mov r0.z, v1.x +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 22 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI2DArray[] = +{ + 68, 88, 66, 67, 239, 117, + 221, 64, 238, 147, 130, 15, + 39, 48, 171, 143, 66, 71, + 242, 70, 1, 0, 0, 0, + 240, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 64, 1, 0, 0, 200, 1, + 0, 0, 252, 1, 0, 0, + 116, 4, 0, 0, 82, 68, + 69, 70, 4, 1, 0, 0, + 1, 0, 0, 0, 128, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 208, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 5, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 109, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 85, 73, 50, + 68, 65, 114, 114, 97, 121, + 0, 83, 119, 105, 122, 122, + 108, 101, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, + 0, 171, 109, 0, 0, 0, + 1, 0, 0, 0, 152, 0, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 176, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 192, 0, 0, 0, 0, 0, + 0, 0, 83, 119, 105, 122, + 122, 108, 101, 73, 110, 100, + 105, 99, 101, 115, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 171, 73, 83, 71, 78, + 128, 0, 0, 0, 3, 0, + 0, 0, 8, 0, 0, 0, + 80, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 7, 3, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 83, 86, 95, 82, 69, 78, + 68, 69, 82, 84, 65, 82, + 71, 69, 84, 65, 82, 82, + 65, 89, 73, 78, 68, 69, + 88, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 79, 83, 71, 78, 44, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 65, 82, 71, 69, + 84, 0, 171, 171, 83, 72, + 68, 82, 112, 2, 0, 0, + 64, 0, 0, 0, 156, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 88, 64, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, + 68, 68, 0, 0, 100, 8, + 0, 4, 18, 16, 16, 0, + 1, 0, 0, 0, 4, 0, + 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 2, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 105, 0, + 0, 4, 0, 0, 0, 0, + 6, 0, 0, 0, 4, 0, + 0, 0, 61, 16, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 50, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 2, 0, 0, 0, + 27, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 45, 0, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 48, 32, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 18, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 34, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 66, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 130, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, + 0, 0, 22, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h new file mode 100644 index 00000000000..9b5b73a00b7 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h @@ -0,0 +1,271 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI2D texture uint4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture2d (uint,uint,uint,uint) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftoi r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI2D[] = +{ + 68, 88, 66, 67, 255, 167, + 19, 151, 79, 137, 69, 230, + 159, 28, 107, 211, 13, 155, + 249, 151, 1, 0, 0, 0, + 164, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 148, 1, + 0, 0, 200, 1, 0, 0, + 40, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 0, 0, + 1, 0, 0, 0, 124, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 204, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 85, 73, 50, + 68, 0, 83, 119, 105, 122, + 122, 108, 101, 80, 114, 111, + 112, 101, 114, 116, 105, 101, + 115, 0, 171, 171, 104, 0, + 0, 0, 1, 0, 0, 0, + 148, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 0, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, + 105, 122, 122, 108, 101, 73, + 110, 100, 105, 99, 101, 115, + 0, 171, 1, 0, 19, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 51, 48, 46, 57, 50, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 88, 2, + 0, 0, 64, 0, 0, 0, + 150, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 88, 24, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 68, 68, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, + 0, 0, 0, 0, 6, 0, + 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 27, 0, + 0, 5, 50, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 34, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 66, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 21, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h new file mode 100644 index 00000000000..87d4c5419a5 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h @@ -0,0 +1,278 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +// +/// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI3D texture uint4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint +// TEXCOORD 0 xyz 2 NONE float xyz +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET uint xyzw +// +ps_4_0 +dcl_constantbuffer cb0[1], immediateIndexed +dcl_resource_texture3d (uint,uint,uint,uint) t0 +dcl_input_ps linear v2.xyz +dcl_output o0.xyzw +dcl_temps 1 +dcl_indexableTemp x0[6], 4 +resinfo_uint r0.xyzw, l(0), t0.xyzw +utof r0.xyz, r0.xyzx +mul r0.xyz, r0.xyzx, v2.xyzx +ftoi r0.xyz, r0.xyzx +mov r0.w, l(0) +ld r0.xyzw, r0.xyzw, t0.xyzw +mov x0[0].x, r0.x +mov x0[1].x, r0.y +mov x0[2].x, r0.z +mov x0[3].x, r0.w +mov x0[4].x, l(0) +mov x0[5].x, l(1) +mov r0.x, cb0[0].x +mov o0.x, x0[r0.x + 0].x +mov r0.x, cb0[0].y +mov o0.y, x0[r0.x + 0].x +mov r0.x, cb0[0].z +mov o0.z, x0[r0.x + 0].x +mov r0.x, cb0[0].w +mov o0.w, x0[r0.x + 0].x +ret +// Approximately 21 instruction slots used +#endif + +const BYTE g_PS_SwizzleUI3D[] = +{ + 68, 88, 66, 67, 49, 1, + 112, 225, 163, 227, 102, 82, + 218, 3, 161, 60, 179, 27, + 12, 252, 1, 0, 0, 0, + 200, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 196, 1, + 0, 0, 248, 1, 0, 0, + 76, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 0, 0, + 1, 0, 0, 0, 124, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 204, 0, 0, 0, 92, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 8, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 84, 101, 120, 116, + 117, 114, 101, 85, 73, 51, + 68, 0, 83, 119, 105, 122, + 122, 108, 101, 80, 114, 111, + 112, 101, 114, 116, 105, 101, + 115, 0, 171, 171, 104, 0, + 0, 0, 1, 0, 0, 0, + 148, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 0, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 188, 0, 0, 0, + 0, 0, 0, 0, 83, 119, + 105, 122, 122, 108, 101, 73, + 110, 100, 105, 99, 101, 115, + 0, 171, 1, 0, 19, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 51, 48, 46, 57, 50, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 171, 73, 83, + 71, 78, 128, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 118, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 7, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 83, 86, 95, 82, + 69, 78, 68, 69, 82, 84, + 65, 82, 71, 69, 84, 65, + 82, 82, 65, 89, 73, 78, + 68, 69, 88, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 76, 2, + 0, 0, 64, 0, 0, 0, + 147, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 88, 40, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 68, 68, 0, 0, + 98, 16, 0, 3, 114, 16, + 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 105, 0, 0, 4, + 0, 0, 0, 0, 6, 0, + 0, 0, 4, 0, 0, 0, + 61, 16, 0, 7, 242, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 86, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 114, 0, + 16, 0, 0, 0, 0, 0, + 70, 2, 16, 0, 0, 0, + 0, 0, 70, 18, 16, 0, + 2, 0, 0, 0, 27, 0, + 0, 5, 114, 0, 16, 0, + 0, 0, 0, 0, 70, 2, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 7, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 48, + 32, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 7, 34, 32, 16, 0, + 0, 0, 0, 0, 10, 48, + 32, 4, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 6, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 7, + 66, 32, 16, 0, 0, 0, + 0, 0, 10, 48, 32, 4, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 54, 0, 0, 6, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 7, 130, 32, + 16, 0, 0, 0, 0, 0, + 10, 48, 32, 4, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 21, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat new file mode 100644 index 00000000000..739c9457641 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat @@ -0,0 +1,119 @@ +@ECHO OFF +REM +REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +REM Use of this source code is governed by a BSD-style license that can be +REM found in the LICENSE file. +REM + +PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.0\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 + +setlocal +set errorCount=0 +set successCount=0 +set debug=0 + +if "%1" == "debug" ( + set debug=1 +) +if "%1" == "release" ( + set debug=0 +) + +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0 compiled\passthrough2d11vs.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughDepth2D ps_4_0 compiled\passthroughdepth2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0 compiled\passthroughrgba2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DUI ps_4_0 compiled\passthroughrgba2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DI ps_4_0 compiled\passthroughrgba2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0 compiled\passthroughrgb2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DUI ps_4_0 compiled\passthroughrgb2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DI ps_4_0 compiled\passthroughrgb2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D ps_4_0 compiled\passthroughrg2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DUI ps_4_0 compiled\passthroughrg2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DI ps_4_0 compiled\passthroughrg2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0 compiled\passthroughr2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DUI ps_4_0 compiled\passthroughr2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DI ps_4_0 compiled\passthroughr2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D ps_4_0 compiled\passthroughlum2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0 compiled\passthroughlumalpha2d11ps.h %debug% + + +call:BuildShader Passthrough3D11.hlsl VS_Passthrough3D vs_4_0 compiled\passthrough3d11vs.h %debug% +call:BuildShader Passthrough3D11.hlsl GS_Passthrough3D gs_4_0 compiled\passthrough3d11gs.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3D ps_4_0 compiled\passthroughrgba3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DUI ps_4_0 compiled\passthroughrgba3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DI ps_4_0 compiled\passthroughrgba3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3D ps_4_0 compiled\passthroughrgb3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DUI ps_4_0 compiled\passthroughrgb3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DI ps_4_0 compiled\passthroughrgb3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3D ps_4_0 compiled\passthroughrg3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DUI ps_4_0 compiled\passthroughrg3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DI ps_4_0 compiled\passthroughrg3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3D ps_4_0 compiled\passthroughr3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DUI ps_4_0 compiled\passthroughr3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DI ps_4_0 compiled\passthroughr3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLum3D ps_4_0 compiled\passthroughlum3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLumAlpha3D ps_4_0 compiled\passthroughlumalpha3d11ps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2D ps_4_0 compiled\swizzlef2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2D ps_4_0 compiled\swizzlei2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2D ps_4_0 compiled\swizzleui2dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF3D ps_4_0 compiled\swizzlef3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI3D ps_4_0 compiled\swizzlei3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI3D ps_4_0 compiled\swizzleui3dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2DArray ps_4_0 compiled\swizzlef2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2DArray ps_4_0 compiled\swizzlei2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2DArray ps_4_0 compiled\swizzleui2darrayps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearFloat vs_4_0 compiled\clearfloat11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearFloat ps_4_0 compiled\clearfloat11ps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearUint vs_4_0 compiled\clearuint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearUint ps_4_0 compiled\clearuint11ps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearSint vs_4_0 compiled\clearsint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearSint ps_4_0 compiled\clearsint11ps.h %debug% + +call:BuildShader BufferToTexture11.hlsl VS_BufferToTexture vs_4_0 compiled/buffertotexture11_vs.h %debug% +call:BuildShader BufferToTexture11.hlsl GS_BufferToTexture gs_4_0 compiled/buffertotexture11_gs.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4F ps_4_0 compiled/buffertotexture11_ps_4f.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4I ps_4_0 compiled/buffertotexture11_ps_4i.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4UI ps_4_0 compiled/buffertotexture11_ps_4ui.h %debug% + +echo. + +if %successCount% GTR 0 ( + echo %successCount% shaders compiled successfully. +) +if %errorCount% GTR 0 ( + echo There were %errorCount% shader compilation errors. +) + +endlocal +exit /b + +:BuildShader +set input=%~1 +set entry=%~2 +set type=%~3 +set output=%~4 +set debug=%~5 + +if %debug% == 0 ( + set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" +) else ( + set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" +) + +set error=0 +%buildCMD% || set error=1 + +if %error% == 0 ( + set /a successCount=%successCount%+1 +) else ( + set /a errorCount=%errorCount%+1 +) + +exit /b diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Blit.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Blit9.cpp index 2a3ce39c632..80a4375ccd7 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Blit.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Blit9.cpp @@ -5,25 +5,26 @@ // found in the LICENSE file. // -// Blit.cpp: Surface copy utility class. +// Blit9.cpp: Surface copy utility class. -#include "libGLESv2/renderer/Blit.h" +#include "libGLESv2/renderer/d3d9/Blit9.h" #include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/Renderer9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/Renderbuffer.h" namespace { -#include "libGLESv2/renderer/shaders/compiled/standardvs.h" -#include "libGLESv2/renderer/shaders/compiled/flipyvs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughps.h" -#include "libGLESv2/renderer/shaders/compiled/luminanceps.h" -#include "libGLESv2/renderer/shaders/compiled/componentmaskps.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h" const BYTE* const g_shaderCode[] = { @@ -46,29 +47,26 @@ const size_t g_shaderSize[] = namespace rx { -Blit::Blit(rx::Renderer9 *renderer) +Blit9::Blit9(rx::Renderer9 *renderer) : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL) { initGeometry(); memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); } -Blit::~Blit() +Blit9::~Blit9() { - if (mSavedStateBlock) mSavedStateBlock->Release(); - if (mQuadVertexBuffer) mQuadVertexBuffer->Release(); - if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release(); + SafeRelease(mSavedStateBlock); + SafeRelease(mQuadVertexBuffer); + SafeRelease(mQuadVertexDeclaration); for (int i = 0; i < SHADER_COUNT; i++) { - if (mCompiledShaders[i]) - { - mCompiledShaders[i]->Release(); - } + SafeRelease(mCompiledShaders[i]); } } -void Blit::initGeometry() +void Blit9::initGeometry() { static const float quad[] = { @@ -116,7 +114,7 @@ void Blit::initGeometry() } template <class D3DShaderType> -bool Blit::setShader(ShaderId source, const char *profile, +bool Blit9::setShader(ShaderId source, const char *profile, D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length), HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) { @@ -154,17 +152,17 @@ bool Blit::setShader(ShaderId source, const char *profile, return true; } -bool Blit::setVertexShader(ShaderId shader) +bool Blit9::setVertexShader(ShaderId shader) { return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); } -bool Blit::setPixelShader(ShaderId shader) +bool Blit9::setPixelShader(ShaderId shader) { return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); } -RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const +RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const { D3DSURFACE_DESC desc; surface->GetDesc(&desc); @@ -178,7 +176,7 @@ RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const return rect; } -bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); if (!texture) @@ -204,18 +202,18 @@ bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) render(); - texture->Release(); + SafeRelease(texture); restoreState(); return true; } -bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); if (colorbuffer) { @@ -240,18 +238,18 @@ bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum des if (destSurface) { result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - destSurface->Release(); + SafeRelease(destSurface); } - source->Release(); + SafeRelease(source); return result; } -bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); if (colorbuffer) { @@ -276,14 +274,14 @@ bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum des if (destSurface) { result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - destSurface->Release(); + SafeRelease(destSurface); } - source->Release(); + SafeRelease(source); return result; } -bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) { if (!dest) { @@ -298,7 +296,7 @@ bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFo dest->GetDesc(&destDesc); if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET && - d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect + d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat, mRenderer->getCurrentClientVersion())) // Can use StretchRect { RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)}; HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); @@ -316,7 +314,7 @@ bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFo return true; } -bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) { IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); if (!texture) @@ -339,14 +337,14 @@ bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLen render(); } - texture->Release(); + SafeRelease(texture); restoreState(); return true; } -bool Blit::setFormatConvertShaders(GLenum destFormat) +bool Blit9::setFormatConvertShaders(GLenum destFormat) { bool okay = setVertexShader(SHADER_VS_STANDARD); @@ -356,6 +354,8 @@ bool Blit::setFormatConvertShaders(GLenum destFormat) case GL_RGBA: case GL_BGRA_EXT: case GL_RGB: + case GL_RG_EXT: + case GL_RED_EXT: case GL_ALPHA: okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); break; @@ -375,41 +375,99 @@ bool Blit::setFormatConvertShaders(GLenum destFormat) // The meaning of this constant depends on the shader that was selected. // See the shader assembly code above for details. - float psConst0[4] = { 0, 0, 0, 0 }; + // Allocate one array for both registers and split it into two float4's. + float psConst[8] = { 0 }; + float *multConst = &psConst[0]; + float *addConst = &psConst[4]; switch (destFormat) { default: UNREACHABLE(); case GL_RGBA: case GL_BGRA_EXT: - psConst0[X] = 1; - psConst0[Z] = 1; + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 1; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; break; case GL_RGB: - psConst0[X] = 1; - psConst0[W] = 1; + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 1; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_RG_EXT: + multConst[X] = 1; + multConst[Y] = 1; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; + break; + + case GL_RED_EXT: + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; break; case GL_ALPHA: - psConst0[Z] = 1; + multConst[X] = 0; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; break; case GL_LUMINANCE: - psConst0[Y] = 1; + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 0; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 1; break; case GL_LUMINANCE_ALPHA: - psConst0[X] = 1; + multConst[X] = 1; + multConst[Y] = 0; + multConst[Z] = 0; + multConst[W] = 1; + addConst[X] = 0; + addConst[Y] = 0; + addConst[Z] = 0; + addConst[W] = 0; break; } - mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1); + mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2); return true; } -IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) +IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) { if (!surface) { @@ -437,26 +495,26 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - texture->Release(); + SafeRelease(texture); return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); } mRenderer->endScene(); result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); - textureSurface->Release(); + SafeRelease(textureSurface); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - texture->Release(); + SafeRelease(texture); return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); } return texture; } -void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) +void Blit9::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) { IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -473,7 +531,7 @@ void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) device->SetVertexShaderConstantF(0, halfPixelAdjust, 1); } -void Blit::setCommonBlitState() +void Blit9::setCommonBlitState() { IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -503,7 +561,7 @@ void Blit::setCommonBlitState() } } -void Blit::render() +void Blit9::render() { IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -514,7 +572,7 @@ void Blit::render() hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } -void Blit::saveState() +void Blit9::saveState() { IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -530,12 +588,12 @@ void Blit::saveState() setCommonBlitState(); - static const float dummyConst[4] = { 0, 0, 0, 0 }; + static const float dummyConst[8] = { 0 }; device->SetVertexShader(NULL); - device->SetVertexShaderConstantF(0, dummyConst, 1); + device->SetVertexShaderConstantF(0, dummyConst, 2); device->SetPixelShader(NULL); - device->SetPixelShaderConstantF(0, dummyConst, 1); + device->SetPixelShaderConstantF(0, dummyConst, 2); D3DVIEWPORT9 dummyVp; dummyVp.X = 0; @@ -566,23 +624,15 @@ void Blit::saveState() } } -void Blit::restoreState() +void Blit9::restoreState() { IDirect3DDevice9 *device = mRenderer->getDevice(); device->SetDepthStencilSurface(mSavedDepthStencil); - if (mSavedDepthStencil != NULL) - { - mSavedDepthStencil->Release(); - mSavedDepthStencil = NULL; - } + SafeRelease(mSavedDepthStencil); device->SetRenderTarget(0, mSavedRenderTarget); - if (mSavedRenderTarget != NULL) - { - mSavedRenderTarget->Release(); - mSavedRenderTarget = NULL; - } + SafeRelease(mSavedRenderTarget); ASSERT(mSavedStateBlock != NULL); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Blit.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Blit9.h index 3718028e662..3635bca932b 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Blit.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Blit9.h @@ -4,10 +4,10 @@ // found in the LICENSE file. // -// Blit.cpp: Surface copy utility class. +// Blit9.cpp: Surface copy utility class. -#ifndef LIBGLESV2_BLIT_H_ -#define LIBGLESV2_BLIT_H_ +#ifndef LIBGLESV2_BLIT9_H_ +#define LIBGLESV2_BLIT9_H_ #include "common/angleutils.h" @@ -22,11 +22,11 @@ class Renderer9; class TextureStorageInterface2D; class TextureStorageInterfaceCube; -class Blit +class Blit9 { public: - explicit Blit(Renderer9 *renderer); - ~Blit(); + explicit Blit9(Renderer9 *renderer); + ~Blit9(); // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) @@ -87,8 +87,8 @@ class Blit IDirect3DSurface9 *mSavedRenderTarget; IDirect3DSurface9 *mSavedDepthStencil; - DISALLOW_COPY_AND_ASSIGN(Blit); + DISALLOW_COPY_AND_ASSIGN(Blit9); }; } -#endif // LIBGLESV2_BLIT_H_ +#endif // LIBGLESV2_BLIT9_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp new file mode 100644 index 00000000000..489a0401cb6 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp @@ -0,0 +1,98 @@ +#include "precompiled.h" +// +// Copyright (c) 2013-2014 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. +// + +// BufferStorage9.cpp Defines the BufferStorage9 class. + +#include "libGLESv2/renderer/d3d9/BufferStorage9.h" +#include "common/debug.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +BufferStorage9::BufferStorage9() + : mSize(0) +{ +} + +BufferStorage9::~BufferStorage9() +{ +} + +BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage) +{ + ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage)); + return static_cast<BufferStorage9*>(bufferStorage); +} + +void *BufferStorage9::getData() +{ + return mMemory.data(); +} + +void BufferStorage9::setData(const void* data, size_t size, size_t offset) +{ + if (offset + size > mMemory.size()) + { + mMemory.resize(offset + size); + } + + mSize = std::max(mSize, offset + size); + if (data) + { + memcpy(mMemory.data() + offset, data, size); + } +} + +void BufferStorage9::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset) +{ + BufferStorage9* source = makeBufferStorage9(sourceStorage); + if (source) + { + memcpy(mMemory.data() + destOffset, source->mMemory.data() + sourceOffset, size); + } +} + +void BufferStorage9::clear() +{ + mSize = 0; +} + +void BufferStorage9::markTransformFeedbackUsage() +{ + UNREACHABLE(); +} + +size_t BufferStorage9::getSize() const +{ + return mSize; +} + +bool BufferStorage9::supportsDirectBinding() const +{ + return false; +} + +// We do not suppot buffer mapping facility in D3D9 +bool BufferStorage9::isMapped() const +{ + UNREACHABLE(); + return false; +} + +void *BufferStorage9::map(GLbitfield access) +{ + UNREACHABLE(); + return NULL; +} + +void BufferStorage9::unmap() +{ + UNREACHABLE(); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h index 3e803969bc3..dd61624c285 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/BufferStorage9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2013-2014 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. // @@ -23,18 +23,22 @@ class BufferStorage9 : public BufferStorage static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage); virtual void *getData(); - virtual void setData(const void* data, unsigned int size, unsigned int offset); + virtual void setData(const void* data, size_t size, size_t offset); + virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset); virtual void clear(); - virtual unsigned int getSize() const; + virtual void markTransformFeedbackUsage(); + virtual size_t getSize() const; virtual bool supportsDirectBinding() const; + virtual bool isMapped() const; + virtual void *map(GLbitfield access); + virtual void unmap(); + private: DISALLOW_COPY_AND_ASSIGN(BufferStorage9); - void *mMemory; - unsigned int mAllocatedSize; - - unsigned int mSize; + std::vector<char> mMemory; + size_t mSize; }; } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp new file mode 100644 index 00000000000..372a8a45a5e --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp @@ -0,0 +1,73 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Fence9.cpp: Defines the rx::Fence9 class. + +#include "libGLESv2/renderer/d3d9/Fence9.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +namespace rx +{ + +Fence9::Fence9(rx::Renderer9 *renderer) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Fence9::~Fence9() +{ + SafeRelease(mQuery); +} + +bool Fence9::isSet() const +{ + return mQuery != NULL; +} + +void Fence9::set() +{ + if (!mQuery) + { + mQuery = mRenderer->allocateEventQuery(); + if (!mQuery) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + HRESULT result = mQuery->Issue(D3DISSUE_END); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(SUCCEEDED(result)); +} + +bool Fence9::test(bool flushCommandBuffer) +{ + ASSERT(mQuery); + + DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0); + HRESULT result = mQuery->GetData(NULL, 0, getDataFlags); + + if (d3d9::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::error(GL_OUT_OF_MEMORY, true); + } + + ASSERT(result == S_OK || result == S_FALSE); + + return (result == S_OK); +} + +bool Fence9::hasError() const +{ + return mRenderer->isDeviceLost(); +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Fence9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Fence9.h index 9f17641e519..e923a2178cf 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Fence9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Fence9.h @@ -21,11 +21,10 @@ class Fence9 : public FenceImpl explicit Fence9(rx::Renderer9 *renderer); virtual ~Fence9(); - GLboolean isFence(); - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - void getFenceiv(GLenum pname, GLint *params); + bool isSet() const; + void set(); + bool test(bool flushCommandBuffer); + bool hasError() const; private: DISALLOW_COPY_AND_ASSIGN(Fence9); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Image9.cpp index b3dcc59b6bd..001858e90a9 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Image9.cpp @@ -8,17 +8,17 @@ // Image9.cpp: Implements the rx::Image9 class, which acts as the interface to // the actual underlying surfaces of a Texture. -#include "libGLESv2/renderer/Image9.h" +#include "libGLESv2/renderer/d3d9/Image9.h" #include "libGLESv2/main.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/generatemip.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" namespace rx { @@ -34,10 +34,7 @@ Image9::Image9() Image9::~Image9() { - if (mSurface) - { - mSurface->Release(); - } + SafeRelease(mSurface); } void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface) @@ -54,6 +51,9 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); + MipGenerationFunction mipFunction = d3d9::GetMipGenerationFunction(sourceDesc.Format); + ASSERT(mipFunction != NULL); + D3DLOCKED_RECT sourceLocked = {0}; result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); ASSERT(SUCCEEDED(result)); @@ -67,32 +67,12 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour if (sourceData && destData) { - switch (sourceDesc.Format) - { - case D3DFMT_L8: - GenerateMip<L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A8L8: - GenerateMip<A8L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - GenerateMip<A8R8G8B8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A16B16G16R16F: - GenerateMip<A16B16G16R16F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A32B32G32R32F: - GenerateMip<A32B32G32R32F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - default: - UNREACHABLE(); - break; - } - - destSurface->UnlockRect(); - sourceSurface->UnlockRect(); + mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, + destData, destLocked.Pitch, 0); } + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); } Image9 *Image9::makeImage9(Image *img) @@ -126,8 +106,10 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so D3DSURFACE_DESC desc; source->GetDesc(&desc); - int rows = d3d9::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height; - int bytes = d3d9::ComputeRowSize(desc.Format, desc.Width); + int blockHeight = d3d9::GetBlockHeight(desc.Format); + int rows = desc.Height / blockHeight; + + int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight); ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); for(int i = 0; i < rows; i++) @@ -141,10 +123,17 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so else UNREACHABLE(); } -bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) +bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) { + // 3D textures are not supported by the D3D9 backend. + ASSERT(depth <= 1); + + // Only 2D and cube texture are supported by the D3D9 backend. + ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP); + if (mWidth != width || mHeight != height || + mDepth != depth || mInternalFormat != internalformat || forceRelease) { @@ -152,16 +141,16 @@ bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei widt mWidth = width; mHeight = height; + mDepth = depth; mInternalFormat = internalformat; + // compute the d3d format that will be used - mD3DFormat = mRenderer->ConvertTextureInternalFormat(internalformat); - mActualFormat = d3d9_gl::GetEquivalentFormat(mD3DFormat); + mD3DFormat = gl_d3d9::GetTextureFormat(internalformat, mRenderer); + mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat); + mRenderable = gl_d3d9::GetRenderFormat(internalformat, mRenderer) != D3DFMT_UNKNOWN; - if (mSurface) - { - mSurface->Release(); - mSurface = NULL; - } + SafeRelease(mSurface); + mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat); return true; } @@ -180,14 +169,13 @@ void Image9::createSurface() IDirect3DSurface9 *newSurface = NULL; const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; const D3DFORMAT d3dFormat = getD3DFormat(); - ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures if (mWidth != 0 && mHeight != 0) { int levelToFetch = 0; GLsizei requestWidth = mWidth; GLsizei requestHeight = mHeight; - gl::MakeValidSize(true, gl::IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch); + d3d9::MakeValidSize(true, d3dFormat, &requestWidth, &requestHeight, &levelToFetch); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -202,7 +190,27 @@ void Image9::createSurface() } newTexture->GetSurfaceLevel(levelToFetch, &newSurface); - newTexture->Release(); + SafeRelease(newTexture); + + if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) + { + InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat); + + RECT entireRect; + entireRect.left = 0; + entireRect.right = mWidth; + entireRect.top = 0; + entireRect.bottom = mHeight; + + D3DLOCKED_RECT lockedRect; + result = newSurface->LockRect(&lockedRect, &entireRect, 0); + ASSERT(SUCCEEDED(result)); + + initializeFunc(mWidth, mHeight, 1, lockedRect.pBits, lockedRect.Pitch, 0); + + result = newSurface->UnlockRect(); + ASSERT(SUCCEEDED(result)); + } } mSurface = newSurface; @@ -232,15 +240,11 @@ void Image9::unlock() if (mSurface) { HRESULT result = mSurface->UnlockRect(); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } } -bool Image9::isRenderableFormat() const -{ - return TextureStorage9::IsTextureFormatRenderable(getD3DFormat()); -} - D3DFORMAT Image9::getD3DFormat() const { // this should only happen if the image hasn't been redefined first @@ -250,6 +254,13 @@ D3DFORMAT Image9::getD3DFormat() const return mD3DFormat; } +bool Image9::isDirty() const +{ + // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet + // if initialization is required before use. + return (mSurface || gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) && mDirty; +} + IDirect3DSurface9 *Image9::getSurface() { createSurface(); @@ -280,7 +291,7 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) if (mSurface) { copyLockableSurfaces(surface, mSurface); - mSurface->Release(); + SafeRelease(mSurface); } mSurface = surface; @@ -288,22 +299,38 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) } } -bool Image9::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { ASSERT(getSurface() != NULL); TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); - return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); + return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); } -bool Image9::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { ASSERT(getSurface() != NULL); TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); - return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); + return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); +} + +bool Image9::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +{ + // 3D textures are not supported by the D3D9 backend. + UNREACHABLE(); + return false; +} + +bool Image9::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) +{ + // 2D array textures are not supported by the D3D9 backend. + UNREACHABLE(); + return false; } -bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { + ASSERT(width > 0 && height > 0); + if (!destSurface) return false; @@ -334,26 +361,36 @@ bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint copyLockableSurfaces(surf, sourceSurface); result = device->UpdateSurface(surf, &rect, destSurface, &point); ASSERT(SUCCEEDED(result)); - surf->Release(); + SafeRelease(surf); } } else { // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } } - destSurface->Release(); + SafeRelease(destSurface); return true; } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input) +void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) { + // 3D textures are not supported by the D3D9 backend. + ASSERT(zoffset == 0 && depth == 1); + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, clientVersion, width, unpackAlignment); + + LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat, mRenderer); + ASSERT(loadFunction != NULL); + RECT lockRect = { xoffset, yoffset, @@ -367,96 +404,29 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heigh return; } - - GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); - - switch (mInternalFormat) - { - case GL_ALPHA8_EXT: - if (gl::supportsSSE2()) - { - loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - else - { - loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - break; - case GL_LUMINANCE8_EXT: - loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8); - break; - case GL_ALPHA32F_EXT: - loadAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE32F_EXT: - loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_ALPHA16F_EXT: - loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE16F_EXT: - loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE8_ALPHA8_EXT: - loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8); - break; - case GL_LUMINANCE_ALPHA32F_EXT: - loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE_ALPHA16F_EXT: - loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB8_OES: - loadRGBUByteDataToBGRX(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB565: - loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA8_OES: - if (gl::supportsSSE2()) - { - loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - else - { - loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - break; - case GL_RGBA4: - loadRGBA4444DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB5_A1: - loadRGBA5551DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_BGRA8_EXT: - loadBGRADataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D - case GL_RGB32F_EXT: - loadRGBFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB16F_EXT: - loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA32F_EXT: - loadRGBAFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA16F_EXT: - loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - default: UNREACHABLE(); - } + loadFunction(width, height, depth, input, inputRowPitch, 0, locked.pBits, locked.Pitch, 0); unlock(); } -void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input) { - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); + // 3D textures are not supported by the D3D9 backend. + ASSERT(zoffset == 0 && depth == 1); - RECT lockRect = { + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, 1); + GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, clientVersion, width, height, 1); + + ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0); + ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0); + + LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat, mRenderer); + ASSERT(loadFunction != NULL); + + RECT lockRect = + { xoffset, yoffset, xoffset + width, yoffset + height }; @@ -468,23 +438,21 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLs return; } - GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); - GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); - int rows = inputSize / inputPitch; - for (int i = 0; i < rows; ++i) - { - memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); - } + loadFunction(width, height, depth, input, inputRowPitch, inputDepthPitch, + locked.pBits, locked.Pitch, 0); unlock(); } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures -void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { + // ES3.0 only behaviour to copy into a 3d texture + ASSERT(zoffset == 0); + RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *surface = NULL; - gl::Renderbuffer *colorbuffer = source->getColorbuffer(0); + gl::FramebufferAttachment *colorbuffer = source->getColorbuffer(0); if (colorbuffer) { @@ -513,7 +481,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, if (FAILED(result)) { ERR("Could not create matching destination surface."); - surface->Release(); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } @@ -522,8 +490,8 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, if (FAILED(result)) { ERR("GetRenderTargetData unexpectedly failed."); - renderTargetData->Release(); - surface->Release(); + SafeRelease(renderTargetData); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } @@ -536,8 +504,8 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, if (FAILED(result)) { ERR("Failed to lock the source surface (rectangle might be invalid)."); - renderTargetData->Release(); - surface->Release(); + SafeRelease(renderTargetData); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } @@ -548,8 +516,8 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, { ERR("Failed to lock the destination surface (rectangle might be invalid)."); renderTargetData->UnlockRect(); - renderTargetData->Release(); - surface->Release(); + SafeRelease(renderTargetData); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } @@ -723,10 +691,10 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, unlock(); renderTargetData->UnlockRect(); - renderTargetData->Release(); - surface->Release(); + SafeRelease(renderTargetData); + SafeRelease(surface); mDirty = true; } -}
\ No newline at end of file +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Image9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Image9.h index 2fbbca31243..8b5ba89ff24 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Image9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Image9.h @@ -37,32 +37,33 @@ class Image9 : public Image static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); - virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); + virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); - virtual bool isRenderableFormat() const; D3DFORMAT getD3DFormat() const; - virtual bool isDirty() const {return mSurface && mDirty;} + virtual bool isDirty() const; IDirect3DSurface9 *getSurface(); virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level); - virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + virtual bool copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height); + + virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input); + virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input); - virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset,GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); private: DISALLOW_COPY_AND_ASSIGN(Image9); void createSurface(); void setManagedSurface(IDirect3DSurface9 *surface); - bool updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + bool copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); void unlock(); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp index c6d83c5dca7..bc2e6a8002c 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp @@ -7,8 +7,8 @@ // Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation. -#include "libGLESv2/renderer/IndexBuffer9.h" -#include "libGLESv2/renderer/Renderer9.h" +#include "libGLESv2/renderer/d3d9/IndexBuffer9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" namespace rx { @@ -23,20 +23,12 @@ IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) IndexBuffer9::~IndexBuffer9() { - if (mIndexBuffer) - { - mIndexBuffer->Release(); - mIndexBuffer = NULL; - } + SafeRelease(mIndexBuffer); } bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { - if (mIndexBuffer) - { - mIndexBuffer->Release(); - mIndexBuffer = NULL; - } + SafeRelease(mIndexBuffer); updateSerial(); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h index 68018675324..68018675324 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/IndexBuffer9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Query9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Query9.cpp index ef694267dd1..bc3f58fb7bd 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Query9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Query9.cpp @@ -8,10 +8,10 @@ // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. -#include "libGLESv2/renderer/Query9.h" +#include "libGLESv2/renderer/d3d9/Query9.h" #include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" namespace rx { @@ -24,11 +24,7 @@ Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) Query9::~Query9() { - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } + SafeRelease(mQuery); } void Query9::begin() @@ -42,17 +38,16 @@ void Query9::begin() } HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } void Query9::end() { - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } + ASSERT(mQuery); HRESULT result = mQuery->Issue(D3DISSUE_END); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); mStatus = GL_FALSE; @@ -122,4 +117,9 @@ GLboolean Query9::testQuery() return GL_TRUE; // prevent blocking when query is null } +bool Query9::isStarted() const +{ + return (mQuery != NULL); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Query9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Query9.h index 47eef89336e..62906230c47 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Query9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Query9.h @@ -21,10 +21,11 @@ class Query9 : public QueryImpl Query9(rx::Renderer9 *renderer, GLenum type); virtual ~Query9(); - void begin(); - void end(); - GLuint getResult(); - GLboolean isResultAvailable(); + virtual void begin(); + virtual void end(); + virtual GLuint getResult(); + virtual GLboolean isResultAvailable(); + virtual bool isStarted() const; private: DISALLOW_COPY_AND_ASSIGN(Query9); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp new file mode 100644 index 00000000000..a3f2e709d3a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp @@ -0,0 +1,141 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9 +// pointers retained by renderbuffers. + +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. +RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) +{ + mRenderer = Renderer9::makeRenderer9(renderer); + mRenderTarget = surface; + + if (mRenderTarget) + { + D3DSURFACE_DESC description; + mRenderTarget->GetDesc(&description); + + mWidth = description.Width; + mHeight = description.Height; + mDepth = 1; + + mInternalFormat = d3d9_gl::GetInternalFormat(description.Format); + mActualFormat = d3d9_gl::GetInternalFormat(description.Format); + mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType); + } +} + +RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) +{ + mRenderer = Renderer9::makeRenderer9(renderer); + mRenderTarget = NULL; + + D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat, mRenderer); + int supportedSamples = mRenderer->getNearestSupportedSamples(renderFormat, samples); + + if (supportedSamples == -1) + { + gl::error(GL_OUT_OF_MEMORY); + + return; + } + + HRESULT result = D3DERR_INVALIDCALL; + + GLuint clientVersion = mRenderer->getCurrentClientVersion(); + + if (width > 0 && height > 0) + { + IDirect3DDevice9 *device = mRenderer->getDevice(); + + bool requiresInitialization = false; + + if (gl::GetDepthBits(internalFormat, clientVersion) > 0 || + gl::GetStencilBits(internalFormat, clientVersion) > 0) + { + result = device->CreateDepthStencilSurface(width, height, renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &mRenderTarget, NULL); + } + else + { + requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat); + + result = device->CreateRenderTarget(width, height, renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &mRenderTarget, NULL); + } + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + + return; + } + + ASSERT(SUCCEEDED(result)); + + if (requiresInitialization) + { + // This format requires that the data be initialized before the render target can be used + // Unfortunately this requires a Get call on the d3d device but it is far better than having + // to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = NULL; + device->GetRenderTarget(0, &prevRenderTarget); + device->SetRenderTarget(0, mRenderTarget); + device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + device->SetRenderTarget(0, prevRenderTarget); + } + } + + mWidth = width; + mHeight = height; + mDepth = 1; + mInternalFormat = internalFormat; + mSamples = supportedSamples; + mActualFormat = d3d9_gl::GetInternalFormat(renderFormat); +} + +RenderTarget9::~RenderTarget9() +{ + SafeRelease(mRenderTarget); +} + +RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target)); + return static_cast<rx::RenderTarget9*>(target); +} + +void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) +{ + // Currently a no-op +} + +IDirect3DSurface9 *RenderTarget9::getSurface() +{ + // Caller is responsible for releasing the returned surface reference. + // TODO: remove the AddRef to match RenderTarget11 + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + return mRenderTarget; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h index faf8ad1c6d2..68d7adb49ef 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/RenderTarget9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h @@ -21,10 +21,13 @@ class RenderTarget9 : public RenderTarget { public: RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface); - RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples); + RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples); virtual ~RenderTarget9(); static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget); + + virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height); + IDirect3DSurface9 *getSurface(); private: diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp index c46d82b335a..7d6dd7a6703 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp @@ -1,12 +1,14 @@ #include "precompiled.h" // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // // Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer. +#include "common/utilities.h" + #include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Texture.h" @@ -14,23 +16,26 @@ #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/renderer/IndexDataManager.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/ShaderExecutable9.h" -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/Image9.h" -#include "libGLESv2/renderer/Blit.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/IndexBuffer9.h" -#include "libGLESv2/renderer/BufferStorage9.h" -#include "libGLESv2/renderer/Query9.h" -#include "libGLESv2/renderer/Fence9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h" +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/Image9.h" +#include "libGLESv2/renderer/d3d9/Blit9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d9/IndexBuffer9.h" +#include "libGLESv2/renderer/d3d9/BufferStorage9.h" +#include "libGLESv2/renderer/d3d9/Query9.h" +#include "libGLESv2/renderer/d3d9/Fence9.h" +#include "libGLESv2/angletypes.h" #include "libEGL/Display.h" #include "third_party/trace_event/trace_event.h" +#include "third_party/systeminfo/SystemInfo.h" // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 @@ -43,6 +48,13 @@ #define ANGLE_ENABLE_D3D9EX 1 #endif // !defined(ANGLE_ENABLE_D3D9EX) +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + +const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); +const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); + namespace rx { static const D3DFORMAT RenderTargetFormats[] = @@ -80,7 +92,7 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice) +Renderer9::Renderer9(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc) { mD3d9Module = NULL; @@ -117,6 +129,10 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend mNullColorbufferCache[i].height = 0; mNullColorbufferCache[i].buffer = NULL; } + + mAppliedVertexShader = NULL; + mAppliedPixelShader = NULL; + mAppliedProgramSerial = 0; } Renderer9::~Renderer9() @@ -142,22 +158,15 @@ void Renderer9::deinitialize() SafeRelease(mD3d9); SafeRelease(mD3d9Ex); + mCompiler.release(); + if (mDeviceWindow) { DestroyWindow(mDeviceWindow); mDeviceWindow = NULL; } - if (mD3d9Module) - { - mD3d9Module = NULL; - } - - while (!mMultiSampleSupport.empty()) - { - delete [] mMultiSampleSupport.begin()->second; - mMultiSampleSupport.erase(mMultiSampleSupport.begin()); - } + mD3d9Module = NULL; } Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) @@ -168,21 +177,13 @@ Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) EGLint Renderer9::initialize() { - if (!initializeCompiler()) + if (!mCompiler.initialize()) { return EGL_NOT_INITIALIZED; } - if (mSoftwareDevice) - { - TRACE_EVENT0("gpu", "GetModuleHandle_swiftshader"); - mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); - } - else - { - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); - mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); - } + TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); + mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) { @@ -200,7 +201,7 @@ EGLint Renderer9::initialize() { TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); - mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); + mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else @@ -251,7 +252,7 @@ EGLint Renderer9::initialize() } // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported. - // This is required by Texture2D::convertToRenderTarget. + // This is required by Texture2D::ensureRenderTarget. if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) { ERR("Renderer does not support stretctrect from textures!\n"); @@ -267,7 +268,7 @@ EGLint Renderer9::initialize() mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && - !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD); + !(!isWindowsVistaOrGreater() && mAdapterIdentifier.VendorId == VENDOR_ID_AMD); // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2)); @@ -301,48 +302,17 @@ EGLint Renderer9::initialize() mMaxSwapInterval = std::max(mMaxSwapInterval, 4); } - int max = 0; - { - TRACE_EVENT0("gpu", "getMultiSampleSupport"); - for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i) - { - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(RenderTargetFormats[i], multisampleArray); - mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray; - - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) - { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) - { - max = j; - } - } - } - } + mMaxSupportedSamples = 0; + const d3d9::D3DFormatSet &d3d9Formats = d3d9::GetAllUsedD3DFormats(); + for (d3d9::D3DFormatSet::const_iterator i = d3d9Formats.begin(); i != d3d9Formats.end(); ++i) { - TRACE_EVENT0("gpu", "getMultiSampleSupport2"); - for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i) - { - if (DepthStencilFormats[i] == D3DFMT_UNKNOWN) - continue; - - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(DepthStencilFormats[i], multisampleArray); - mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray; - - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) - { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) - { - max = j; - } - } - } + TRACE_EVENT0("gpu", "getMultiSampleSupport"); + MultisampleSupportInfo support = getMultiSampleSupport(*i); + mMultiSampleSupport[*i] = support; + mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples); } - mMaxSupportedSamples = max; - static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); @@ -378,7 +348,7 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { TRACE_EVENT0("gpu", "mDevice_QueryInterface"); - result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); + result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void**)&mDeviceEx); ASSERT(SUCCEEDED(result)); } @@ -394,7 +364,7 @@ EGLint Renderer9::initialize() TRACE_EVENT0("gpu", "device_CreateQuery"); if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery) { - occlusionQuery->Release(); + SafeRelease(occlusionQuery); mOcclusionQuerySupport = true; } else @@ -409,7 +379,7 @@ EGLint Renderer9::initialize() TRACE_EVENT0("gpu", "device_CreateQuery2"); if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery) { - eventQuery->Release(); + SafeRelease(eventQuery); mEventQuerySupport = true; } else @@ -428,6 +398,10 @@ EGLint Renderer9::initialize() SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); + // Check RGB565 texture support + mRGB565TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5)); + // Check depth texture support // we use INTZ for depth textures in Direct3D9 // we also want NULL texture support to ensure the we can make depth-only FBOs @@ -483,6 +457,25 @@ EGLint Renderer9::initialize() mFloat16TextureSupport = true; } + D3DFORMAT rgTextureFormats[] = + { + D3DFMT_R16F, + D3DFMT_G16R16F, + D3DFMT_R32F, + D3DFMT_G32R32F, + }; + + mRGTextureSupport = true; + for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++) + { + D3DFORMAT fmt = rgTextureFormats[i]; + mRGTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, fmt)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, D3DRTYPE_CUBETEXTURE, fmt)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, fmt)); + } + + // Check DXT texture support mDXT1TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); mDXT3TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3)); @@ -494,6 +487,8 @@ EGLint Renderer9::initialize() initializeDevice(); + d3d9::InitializeVertexTranslations(this); + return EGL_SUCCESS; } @@ -520,7 +515,7 @@ void Renderer9::initializeDevice() mSceneStarted = false; ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager); - mBlit = new Blit(this); + mBlit = new Blit9(this); mVertexDataManager = new rx::VertexDataManager(this); mIndexDataManager = new rx::IndexDataManager(this); } @@ -585,10 +580,11 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList) if (SUCCEEDED(result)) { ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d9_gl::ConvertBackBufferFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d9_gl::ConvertDepthStencilFormat(depthStencilFormat); + newConfig.renderTargetFormat = d3d9_gl::GetInternalFormat(renderTargetFormat); + newConfig.depthStencilFormat = d3d9_gl::GetInternalFormat(depthStencilFormat); newConfig.multiSample = 0; // FIXME: enumerate multi-sampling newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat); + newConfig.es3Capable = false; (*configDescList)[numConfigs++] = newConfig; } @@ -681,6 +677,7 @@ IDirect3DQuery9* Renderer9::allocateEventQuery() if (mEventQueryPool.empty()) { HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } else @@ -696,7 +693,7 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query) { if (mEventQueryPool.size() > 1000) { - query->Release(); + SafeRelease(query); } else { @@ -751,6 +748,26 @@ FenceImpl *Renderer9::createFence() return new Fence9(this); } +bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const +{ + // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. + return false; +} + +bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +{ + // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. + UNREACHABLE(); + return false; +} + +void Renderer9::generateSwizzle(gl::Texture *texture) +{ + // Swizzled textures are not available in ES2 or D3D9 + UNREACHABLE(); +} + void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; @@ -769,7 +786,7 @@ void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::Sampl gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel); if (mSupportsTextureFilterAnisotropy) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); @@ -814,6 +831,12 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture appliedSerials[index] = serial; } +bool Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[]) +{ + // No effect in ES2/D3D9 + return true; +} + void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) { bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; @@ -852,10 +875,11 @@ void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) mForceSetRasterState = false; } -void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, unsigned int sampleMask) +void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) { bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; - bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0; + bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; if (blendStateChanged || blendColorChanged) @@ -906,6 +930,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::Color FIXME("Sample alpha to coverage is unimplemented."); } + gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); + GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; + GLuint clientVersion = getCurrentClientVersion(); + // Set the color mask bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD; // Apparently some ATI cards have a bug where a draw with a zero color @@ -914,8 +942,10 @@ void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::Color // drawing is done. // http://code.google.com/p/angleproject/issues/detail?id=169 - DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, - blendState.colorMaskBlue, blendState.colorMaskAlpha); + DWORD colorMask = gl_d3d9::ConvertColorMask(gl::GetRedBits(internalFormat, clientVersion) > 0 && blendState.colorMaskRed, + gl::GetGreenBits(internalFormat, clientVersion) > 0 && blendState.colorMaskGreen, + gl::GetBlueBits(internalFormat, clientVersion) > 0 && blendState.colorMaskBlue, + gl::GetAlphaBits(internalFormat, clientVersion) > 0 && blendState.colorMaskAlpha); if (colorMask == 0 && !zeroColorMaskAllowed) { // Enable green channel, but set blending so nothing will be drawn. @@ -1195,7 +1225,7 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) } -gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer) +gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer) { if (!depthbuffer) { @@ -1218,7 +1248,7 @@ gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer) } } - gl::Renderbuffer *nullbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); + gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1243,7 +1273,7 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) { // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. - gl::Renderbuffer *renderbufferObject = NULL; + gl::FramebufferAttachment *renderbufferObject = NULL; if (framebuffer->getColorbufferType(0) != GL_NONE) { renderbufferObject = framebuffer->getColorbuffer(0); @@ -1278,13 +1308,13 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) } mDevice->SetRenderTarget(0, renderTargetSurface); - renderTargetSurface->Release(); + SafeRelease(renderTargetSurface); mAppliedRenderTargetSerial = renderTargetSerial; renderTargetChanged = true; } - gl::Renderbuffer *depthStencil = NULL; + gl::FramebufferAttachment *depthStencil = NULL; unsigned int depthbufferSerial = 0; unsigned int stencilbufferSerial = 0; if (framebuffer->getDepthbufferType() != GL_NONE) @@ -1335,7 +1365,7 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) } mDevice->SetDepthStencilSurface(depthStencilSurface); - depthStencilSurface->Release(); + SafeRelease(depthStencilSurface); depthSize = depthStencil->getDepthSize(); stencilSize = depthStencil->getStencilSize(); @@ -1366,6 +1396,7 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) { mForceSetScissor = true; mForceSetViewport = true; + mForceSetBlendState = true; mRenderTargetDesc.width = renderbufferObject->getWidth(); mRenderTargetDesc.height = renderbufferObject->getHeight(); @@ -1376,15 +1407,16 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) return true; } -GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) +GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); + GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); if (err != GL_NO_ERROR) { return err; } - + return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); } @@ -1410,10 +1442,17 @@ GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArr return err; } -void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) +void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) { + UNREACHABLE(); +} + +void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +{ + ASSERT(!transformFeedbackActive); + startScene(); - + if (mode == GL_LINE_LOOP) { drawLineLoop(count, GL_NONE, NULL, 0, NULL); @@ -1448,13 +1487,14 @@ void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) } } -void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) { startScene(); if (mode == GL_POINTS) { - drawIndexedPoints(count, type, indices, elementArrayBuffer); + drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer); } else if (mode == GL_LINE_LOOP) { @@ -1498,15 +1538,15 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int))) { ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); return gl::error(GL_OUT_OF_MEMORY); } - // Checked by Renderer9::applyPrimitiveType - ASSERT(count >= 0); - const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { @@ -1658,16 +1698,16 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } template <typename T> -static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices) +static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) { for (int i = 0; i < count; i++) { - unsigned int indexValue = static_cast<unsigned int>(static_cast<const T*>(indices)[i]); + unsigned int indexValue = static_cast<unsigned int>(static_cast<const T*>(indices)[i]) - minIndex; device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); } } -void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer) +void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call // for each individual point. This call is not expected to happen often. @@ -1681,41 +1721,57 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi switch (type) { - case GL_UNSIGNED_BYTE: drawPoints<GLubyte>(mDevice, count, indices); break; - case GL_UNSIGNED_SHORT: drawPoints<GLushort>(mDevice, count, indices); break; - case GL_UNSIGNED_INT: drawPoints<GLuint>(mDevice, count, indices); break; + case GL_UNSIGNED_BYTE: drawPoints<GLubyte>(mDevice, count, indices, minIndex); break; + case GL_UNSIGNED_SHORT: drawPoints<GLushort>(mDevice, count, indices, minIndex); break; + case GL_UNSIGNED_INT: drawPoints<GLuint>(mDevice, count, indices, minIndex); break; default: UNREACHABLE(); } } -void Renderer9::applyShaders(gl::ProgramBinary *programBinary) +void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]) { - unsigned int programBinarySerial = programBinary->getSerial(); - if (programBinarySerial != mAppliedProgramBinarySerial) - { - ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); - ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); + ASSERT(!transformFeedbackActive); + ASSERT(!rasterizerDiscard); - IDirect3DVertexShader9 *vertexShader = NULL; - if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader(); + ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); + ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); - IDirect3DPixelShader9 *pixelShader = NULL; - if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader(); + IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); + IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); - mDevice->SetPixelShader(pixelShader); + if (vertexShader != mAppliedVertexShader) + { mDevice->SetVertexShader(vertexShader); + mAppliedVertexShader = vertexShader; + } + + if (pixelShader != mAppliedPixelShader) + { + mDevice->SetPixelShader(pixelShader); + mAppliedPixelShader = pixelShader; + } + + // D3D9 has a quirk where creating multiple shaders with the same content + // can return the same shader pointer. Because GL programs store different data + // per-program, checking the program serial guarantees we upload fresh + // uniform data even if our shader pointers are the same. + // https://code.google.com/p/angleproject/issues/detail?id=661 + unsigned int programSerial = programBinary->getSerial(); + if (programSerial != mAppliedProgramSerial) + { programBinary->dirtyAllUniforms(); mDxUniformsDirty = true; - - mAppliedProgramBinarySerial = programBinarySerial; + mAppliedProgramSerial = programSerial; } } -void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) +void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) { - for (std::vector<gl::Uniform*>::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub) + const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); + + for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) { - gl::Uniform *targetUniform = *ub; + gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; if (targetUniform->dirty) { @@ -1751,8 +1807,6 @@ void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray default: UNREACHABLE(); } - - targetUniform->dirty = false; } } @@ -1765,20 +1819,20 @@ void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray } } -void Renderer9::applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v) +void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) { - if (targetUniform->psRegisterIndex >= 0) + if (targetUniform->isReferencedByFragmentShader()) { mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount); } - if (targetUniform->vsRegisterIndex >= 0) + if (targetUniform->isReferencedByVertexShader()) { mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount); } } -void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v) +void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -1794,7 +1848,7 @@ void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v) applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v) +void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v) { ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; @@ -1812,27 +1866,70 @@ void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v) void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { - D3DCOLOR color = D3DCOLOR_ARGB(gl::unorm<8>(clearParams.colorClearValue.alpha), - gl::unorm<8>(clearParams.colorClearValue.red), - gl::unorm<8>(clearParams.colorClearValue.green), - gl::unorm<8>(clearParams.colorClearValue.blue)); + if (clearParams.colorClearType != GL_FLOAT) + { + // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 + UNREACHABLE(); + return; + } + + bool clearColor = clearParams.clearColor[0]; + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + if (clearParams.clearColor[i] != clearColor) + { + // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 + UNREACHABLE(); + return; + } + } + float depth = gl::clamp01(clearParams.depthClearValue); - int stencil = clearParams.stencilClearValue & 0x000000FF; + DWORD stencil = clearParams.stencilClearValue & 0x000000FF; unsigned int stencilUnmasked = 0x0; - if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil()) + if (clearParams.clearStencil && frameBuffer->hasStencil()) { - unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); + unsigned int stencilSize = gl::GetStencilBits(frameBuffer->getStencilbuffer()->getActualFormat(), + getCurrentClientVersion()); stencilUnmasked = (0x1 << stencilSize) - 1; } - bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha; - - const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && + const bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; - const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && - !(clearParams.colorMaskRed && clearParams.colorMaskGreen && - clearParams.colorMaskBlue && alphaUnmasked); + + bool needMaskedColorClear = false; + D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); + if (clearColor) + { + gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); + GLenum internalFormat = attachment->getInternalFormat(); + GLenum actualFormat = attachment->getActualFormat(); + + GLuint clientVersion = getCurrentClientVersion(); + GLuint internalRedBits = gl::GetRedBits(internalFormat, clientVersion); + GLuint internalGreenBits = gl::GetGreenBits(internalFormat, clientVersion); + GLuint internalBlueBits = gl::GetBlueBits(internalFormat, clientVersion); + GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat, clientVersion); + + GLuint actualRedBits = gl::GetRedBits(actualFormat, clientVersion); + GLuint actualGreenBits = gl::GetGreenBits(actualFormat, clientVersion); + GLuint actualBlueBits = gl::GetBlueBits(actualFormat, clientVersion); + GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat, clientVersion); + + color = D3DCOLOR_ARGB(gl::unorm<8>((internalAlphaBits == 0 && actualAlphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + gl::unorm<8>((internalRedBits == 0 && actualRedBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + gl::unorm<8>((internalGreenBits == 0 && actualGreenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + gl::unorm<8>((internalBlueBits == 0 && actualBlueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); + + if ((internalRedBits > 0 && !clearParams.colorMaskRed) || + (internalGreenBits > 0 && !clearParams.colorMaskGreen) || + (internalBlueBits > 0 && !clearParams.colorMaskBlue) || + (internalAlphaBits > 0 && !clearParams.colorMaskAlpha)) + { + needMaskedColorClear = true; + } + } if (needMaskedColorClear || needMaskedStencilClear) { @@ -1893,7 +1990,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - if (clearParams.mask & GL_COLOR_BUFFER_BIT) + if (clearColor) { mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, @@ -1906,7 +2003,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); } - if (stencilUnmasked != 0x0 && (clearParams.mask & GL_STENCIL_BUFFER_BIT)) + if (stencilUnmasked != 0x0 && clearParams.clearStencil) { mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); @@ -1962,7 +2059,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f startScene(); mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4])); - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) + if (clearParams.clearDepth) { mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); @@ -1974,18 +2071,18 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f mMaskedClearSavedState->Apply(); } } - else if (clearParams.mask) + else if (clearColor || clearParams.clearDepth || clearParams.clearStencil) { DWORD dxClearFlags = 0; - if (clearParams.mask & GL_COLOR_BUFFER_BIT) + if (clearColor) { dxClearFlags |= D3DCLEAR_TARGET; } - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) + if (clearParams.clearDepth) { dxClearFlags |= D3DCLEAR_ZBUFFER; } - if (clearParams.mask & GL_STENCIL_BUFFER_BIT) + if (clearParams.clearStencil) { dxClearFlags |= D3DCLEAR_STENCIL; } @@ -2020,7 +2117,9 @@ void Renderer9::markAllStateDirty() } mAppliedIBSerial = 0; - mAppliedProgramBinarySerial = 0; + mAppliedVertexShader = NULL; + mAppliedPixelShader = NULL; + mAppliedProgramSerial = 0; mDxUniformsDirty = true; mVertexDeclarationCache.markStateDirty(); @@ -2028,11 +2127,11 @@ void Renderer9::markAllStateDirty() void Renderer9::releaseDeviceResources() { - while (!mEventQueryPool.empty()) + for (size_t i = 0; i < mEventQueryPool.size(); i++) { - mEventQueryPool.back()->Release(); - mEventQueryPool.pop_back(); + SafeRelease(mEventQueryPool[i]); } + mEventQueryPool.clear(); SafeRelease(mMaskedClearSavedState); @@ -2048,10 +2147,8 @@ void Renderer9::releaseDeviceResources() { SafeDelete(mNullColorbufferCache[i].buffer); } - } - void Renderer9::notifyDeviceLost() { mDeviceLost = true; @@ -2067,7 +2164,7 @@ bool Renderer9::isDeviceLost() bool Renderer9::testDeviceLost(bool notify) { HRESULT status = getDeviceStatusCode(); - bool isLost = (FAILED(status) || d3d9::isDeviceLostError(status)); + bool isLost = FAILED(status); if (isLost) { @@ -2255,15 +2352,30 @@ GUID Renderer9::getAdapterIdentifier() const return mAdapterIdentifier.DeviceIdentifier; } -void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) +Renderer9::MultisampleSupportInfo Renderer9::getMultiSampleSupport(D3DFORMAT format) { - for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) + MultisampleSupportInfo support = { 0 }; + + for (unsigned int multiSampleIndex = 0; multiSampleIndex < ArraySize(support.supportedSamples); multiSampleIndex++) { - HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, - TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); + HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, TRUE, + (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); - multiSampleArray[multiSampleIndex] = SUCCEEDED(result); + if (SUCCEEDED(result)) + { + support.supportedSamples[multiSampleIndex] = true; + if (multiSampleIndex != D3DMULTISAMPLE_NONMASKABLE) + { + support.maxSupportedSamples = std::max(support.maxSupportedSamples, multiSampleIndex); + } + } + else + { + support.supportedSamples[multiSampleIndex] = false; + } } + + return support; } bool Renderer9::getBGRATextureSupport() const @@ -2272,17 +2384,17 @@ bool Renderer9::getBGRATextureSupport() const return true; } -bool Renderer9::getDXT1TextureSupport() +bool Renderer9::getDXT1TextureSupport() const { return mDXT1TextureSupport; } -bool Renderer9::getDXT3TextureSupport() +bool Renderer9::getDXT3TextureSupport() const { return mDXT3TextureSupport; } -bool Renderer9::getDXT5TextureSupport() +bool Renderer9::getDXT5TextureSupport() const { return mDXT5TextureSupport; } @@ -2292,35 +2404,67 @@ bool Renderer9::getDepthTextureSupport() const return mDepthTextureSupport; } -bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable) +bool Renderer9::getFloat32TextureSupport() const { - *filtering = mFloat32FilterSupport; - *renderable = mFloat32RenderSupport; return mFloat32TextureSupport; } -bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable) +bool Renderer9::getFloat32TextureFilteringSupport() const +{ + return mFloat32FilterSupport; +} + +bool Renderer9::getFloat32TextureRenderingSupport() const +{ + return mFloat32RenderSupport; +} + +bool Renderer9::getFloat16TextureSupport() const { - *filtering = mFloat16FilterSupport; - *renderable = mFloat16RenderSupport; return mFloat16TextureSupport; } -bool Renderer9::getLuminanceTextureSupport() +bool Renderer9::getFloat16TextureFilteringSupport() const +{ + return mFloat16FilterSupport; +} + +bool Renderer9::getFloat16TextureRenderingSupport() const +{ + return mFloat16RenderSupport; +} + +bool Renderer9::getRGB565TextureSupport() const +{ + return mRGB565TextureSupport; +} + +bool Renderer9::getLuminanceTextureSupport() const { return mLuminanceTextureSupport; } -bool Renderer9::getLuminanceAlphaTextureSupport() +bool Renderer9::getLuminanceAlphaTextureSupport() const { return mLuminanceAlphaTextureSupport; } +bool Renderer9::getRGTextureSupport() const +{ + return mRGTextureSupport; +} + bool Renderer9::getTextureFilterAnisotropySupport() const { return mSupportsTextureFilterAnisotropy; } +bool Renderer9::getPBOSupport() const +{ + // D3D9 cannot support PBOs + return false; +} + float Renderer9::getTextureMaxAnisotropy() const { if (mSupportsTextureFilterAnisotropy) @@ -2330,7 +2474,7 @@ float Renderer9::getTextureMaxAnisotropy() const return 1.0f; } -bool Renderer9::getEventQuerySupport() +bool Renderer9::getEventQuerySupport() const { return mEventQuerySupport; } @@ -2373,6 +2517,46 @@ unsigned int Renderer9::getMaxVaryingVectors() const return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2; } +unsigned int Renderer9::getMaxVertexShaderUniformBuffers() const +{ + return 0; +} + +unsigned int Renderer9::getMaxFragmentShaderUniformBuffers() const +{ + return 0; +} + +unsigned int Renderer9::getReservedVertexUniformBuffers() const +{ + return 0; +} + +unsigned int Renderer9::getReservedFragmentUniformBuffers() const +{ + return 0; +} + +unsigned int Renderer9::getMaxTransformFeedbackBuffers() const +{ + return 0; +} + +unsigned int Renderer9::getMaxTransformFeedbackSeparateComponents() const +{ + return 0; +} + +unsigned int Renderer9::getMaxTransformFeedbackInterleavedComponents() const +{ + return 0; +} + +unsigned int Renderer9::getMaxUniformBufferSize() const +{ + return 0; +} + bool Renderer9::getNonPower2TextureSupport() const { return mSupportsNonPower2Textures; @@ -2404,6 +2588,20 @@ bool Renderer9::getPostSubBufferSupport() const return true; } +int Renderer9::getMaxRecommendedElementsIndices() const +{ + // ES3 only + UNREACHABLE(); + return 0; +} + +int Renderer9::getMaxRecommendedElementsVertices() const +{ + // ES3 only + UNREACHABLE(); + return 0; +} + int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2418,7 +2616,7 @@ float Renderer9::getMaxPointSize() const int Renderer9::getMaxViewportDimension() const { int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()), - (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE); + (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE); return maxTextureDimension; } @@ -2432,6 +2630,18 @@ int Renderer9::getMaxTextureHeight() const return (int)mDeviceCaps.MaxTextureHeight; } +int Renderer9::getMaxTextureDepth() const +{ + // 3D textures are not available in the D3D9 backend. + return 1; +} + +int Renderer9::getMaxTextureArrayLayers() const +{ + // 2D array textures are not available in the D3D9 backend. + return 1; +} + bool Renderer9::get32BitIndexSupport() const { return mDeviceCaps.MaxVertexIndex >= (1 << 16); @@ -2457,6 +2667,53 @@ int Renderer9::getMaxSupportedSamples() const return mMaxSupportedSamples; } +GLsizei Renderer9::getMaxSupportedFormatSamples(GLenum internalFormat) const +{ + D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this); + MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format); + return (itr != mMultiSampleSupport.end()) ? mMaxSupportedSamples : 0; +} + +GLsizei Renderer9::getNumSampleCounts(GLenum internalFormat) const +{ + D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this); + MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format); + + unsigned int numCounts = 0; + if (iter != mMultiSampleSupport.end()) + { + const MultisampleSupportInfo& info = iter->second; + for (int i = 0; i < D3DMULTISAMPLE_16_SAMPLES; i++) + { + if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i]) + { + numCounts++; + } + } + } + + return numCounts; +} + +void Renderer9::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const +{ + D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat, this); + MultisampleSupportMap::const_iterator iter = mMultiSampleSupport.find(format); + + if (iter != mMultiSampleSupport.end()) + { + const MultisampleSupportInfo& info = iter->second; + int bufPos = 0; + for (int i = D3DMULTISAMPLE_16_SAMPLES; i >= 0 && bufPos < bufSize; i--) + { + if (i != D3DMULTISAMPLE_NONMASKABLE && info.supportedSamples[i]) + { + params[bufPos++] = i; + } + } + } +} + int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const { if (requested == 0) @@ -2464,7 +2721,7 @@ int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const return requested; } - std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format); + MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format); if (itr == mMultiSampleSupport.end()) { if (format == D3DFMT_UNKNOWN) @@ -2472,9 +2729,9 @@ int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const return -1; } - for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i) + for (unsigned int i = requested; i < ArraySize(itr->second.supportedSamples); ++i) { - if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE) + if (itr->second.supportedSamples[i] && i != D3DMULTISAMPLE_NONMASKABLE) { return i; } @@ -2489,7 +2746,7 @@ unsigned int Renderer9::getMaxRenderTargets() const return 1; } -D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLint internalformat) +D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLenum internalformat) { switch (internalformat) { @@ -2545,19 +2802,21 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStora TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance()); TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance()); - int levels = source9->levelCount(); + int levels = source9->getLevelCount(); for (int i = 0; i < levels; ++i) { IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false); IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false); - + result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - if (srcSurf) srcSurf->Release(); - if (dstSurf) dstSurf->Release(); + SafeRelease(srcSurf); + SafeRelease(dstSurf); if (!result) + { return false; + } } } @@ -2572,7 +2831,7 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSto { TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance()); TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance()); - int levels = source9->levelCount(); + int levels = source9->getLevelCount(); for (int f = 0; f < 6; f++) { for (int i = 0; i < levels; i++) @@ -2582,11 +2841,13 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSto result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - if (srcSurf) srcSurf->Release(); - if (dstSurf) dstSurf->Release(); + SafeRelease(srcSurf); + SafeRelease(dstSurf); if (!result) + { return false; + } } } } @@ -2594,6 +2855,20 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSto return result; } +bool Renderer9::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +{ + // 3D textures are not available in the D3D9 backend. + UNREACHABLE(); + return false; +} + +bool Renderer9::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +{ + // 2D array textures are not supported by the D3D9 backend. + UNREACHABLE(); + return false; +} + D3DPOOL Renderer9::getBufferPool(DWORD usage) const { if (mD3d9Ex != NULL) @@ -2635,15 +2910,33 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); } +bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) +{ + // 3D textures are not available in the D3D9 backend. + UNREACHABLE(); + return false; +} + +bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) +{ + // 2D array textures are not available in the D3D9 backend. + UNREACHABLE(); + return false; +} + bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil) + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) { + ASSERT(filter == GL_NEAREST); + endScene(); if (blitRenderTarget) { - gl::Renderbuffer *readBuffer = readFramebuffer->getColorbuffer(0); - gl::Renderbuffer *drawBuffer = drawFramebuffer->getColorbuffer(0); + gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0); + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0); RenderTarget9 *readRenderTarget = NULL; RenderTarget9 *drawRenderTarget = NULL; IDirect3DSurface9* readSurface = NULL; @@ -2673,6 +2966,9 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & return gl::error(GL_OUT_OF_MEMORY, false); } + gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); + gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); + RECT srcRect; srcRect.left = readRect.x; srcRect.right = readRect.x + readRect.width; @@ -2685,10 +2981,79 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & dstRect.top = drawRect.y; dstRect.bottom = drawRect.y + drawRect.height; + // Clip the rectangles to the scissor rectangle + if (scissor) + { + if (dstRect.left < scissor->x) + { + srcRect.left += (scissor->x - dstRect.left); + dstRect.left = scissor->x; + } + if (dstRect.top < scissor->y) + { + srcRect.top += (scissor->y - dstRect.top); + dstRect.top = scissor->y; + } + if (dstRect.right > scissor->x + scissor->width) + { + srcRect.right -= (dstRect.right - (scissor->x + scissor->width)); + dstRect.right = scissor->x + scissor->width; + } + if (dstRect.bottom > scissor->y + scissor->height) + { + srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height)); + dstRect.bottom = scissor->y + scissor->height; + } + } + + // Clip the rectangles to the destination size + if (dstRect.left < 0) + { + srcRect.left += -dstRect.left; + dstRect.left = 0; + } + if (dstRect.right > dstSize.width) + { + srcRect.right -= (dstRect.right - dstSize.width); + dstRect.right = dstSize.width; + } + if (dstRect.top < 0) + { + srcRect.top += -dstRect.top; + dstRect.top = 0; + } + if (dstRect.bottom > dstSize.height) + { + srcRect.bottom -= (dstRect.bottom - dstSize.height); + dstRect.bottom = dstSize.height; + } + + // Clip the rectangles to the source size + if (srcRect.left < 0) + { + dstRect.left += -srcRect.left; + srcRect.left = 0; + } + if (srcRect.right > srcSize.width) + { + dstRect.right -= (srcRect.right - srcSize.width); + srcRect.right = srcSize.width; + } + if (srcRect.top < 0) + { + dstRect.top += -srcRect.top; + srcRect.top = 0; + } + if (srcRect.bottom > srcSize.height) + { + dstRect.bottom -= (srcRect.bottom - srcSize.height); + srcRect.bottom = srcSize.height; + } + HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE); - readSurface->Release(); - drawSurface->Release(); + SafeRelease(readSurface); + SafeRelease(drawSurface); if (FAILED(result)) { @@ -2697,10 +3062,10 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & } } - if (blitDepthStencil) + if (blitDepth || blitStencil) { - gl::Renderbuffer *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); - gl::Renderbuffer *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); RenderTarget9 *readDepthStencil = NULL; RenderTarget9 *drawDepthStencil = NULL; IDirect3DSurface9* readSurface = NULL; @@ -2732,8 +3097,8 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); - readSurface->Release(); - drawSurface->Release(); + SafeRelease(readSurface); + SafeRelease(drawSurface); if (FAILED(result)) { @@ -2745,18 +3110,20 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & return true; } -void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) +void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) { + ASSERT(pack.pixelBuffer.get() == NULL); + RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *surface = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); if (colorbuffer) { renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); } - + if (renderTarget) { surface = renderTarget->getSurface(); @@ -2774,13 +3141,13 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) { UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target - surface->Release(); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } HRESULT result; IDirect3DSurface9 *systemSurface = NULL; - bool directToPixels = !packReverseRowOrder && packAlignment <= 4 && getShareHandleSupport() && + bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && getShareHandleSupport() && x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; if (directToPixels) @@ -2802,18 +3169,17 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - surface->Release(); + SafeRelease(surface); return gl::error(GL_OUT_OF_MEMORY); } } result = mDevice->GetRenderTargetData(surface, systemSurface); - surface->Release(); - surface = NULL; + SafeRelease(surface); if (FAILED(result)) { - systemSurface->Release(); + SafeRelease(systemSurface); // It turns out that D3D will sometimes produce more error // codes than those documented. @@ -2832,7 +3198,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (directToPixels) { - systemSurface->Release(); + SafeRelease(systemSurface); return; } @@ -2848,17 +3214,14 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (FAILED(result)) { UNREACHABLE(); - systemSurface->Release(); + SafeRelease(systemSurface); return; // No sensible error to generate } - unsigned char *dest = (unsigned char*)pixels; - unsigned short *dest16 = (unsigned short*)pixels; - unsigned char *source; int inputPitch; - if (packReverseRowOrder) + if (pack.reverseRowOrder) { source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); inputPitch = -lock.Pitch; @@ -2869,231 +3232,69 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz inputPitch = lock.Pitch; } - unsigned int fastPixelSize = 0; + GLuint clientVersion = getCurrentClientVersion(); - if (desc.Format == D3DFMT_A8R8G8B8 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_BYTE) - { - fastPixelSize = 4; - } - else if ((desc.Format == D3DFMT_A4R4G4B4 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) || - (desc.Format == D3DFMT_A1R5G5B5 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)) - { - fastPixelSize = 2; - } - else if (desc.Format == D3DFMT_A16B16G16R16F && - format == GL_RGBA && - type == GL_HALF_FLOAT_OES) - { - fastPixelSize = 8; - } - else if (desc.Format == D3DFMT_A32B32G32R32F && - format == GL_RGBA && - type == GL_FLOAT) - { - fastPixelSize = 16; - } + GLenum sourceInternalFormat = d3d9_gl::GetInternalFormat(desc.Format); + GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion); + GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion); - for (int j = 0; j < rect.bottom - rect.top; j++) + GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion); + + if (sourceFormat == format && sourceType == type) { - if (fastPixelSize != 0) - { - // Fast path for formats which require no translation: - // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE - // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT - // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT - // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES - // D3DFMT_A32B32G32R32F to RGBA/FLOAT - // - // Note that buffers with no alpha go through the slow path below. - memcpy(dest + j * outputPitch, - source + j * inputPitch, - (rect.right - rect.left) * fastPixelSize); - continue; - } - else if (desc.Format == D3DFMT_A8R8G8B8 && - format == GL_RGBA && - type == GL_UNSIGNED_BYTE) + // Direct copy possible + unsigned char *dest = static_cast<unsigned char*>(pixels); + for (int y = 0; y < rect.bottom - rect.top; y++) { - // Fast path for swapping red with blue - for (int i = 0; i < rect.right - rect.left; i++) - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - *(unsigned int*)(dest + 4 * i + j * outputPitch) = - (argb & 0xFF00FF00) | // Keep alpha and green - (argb & 0x00FF0000) >> 16 | // Move red to blue - (argb & 0x000000FF) << 16; // Move blue to red - } - continue; + memcpy(dest + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourcePixelSize); } + } + else + { + GLenum destInternalFormat = gl::GetSizedInternalFormat(format, type, clientVersion); + GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion); + GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion); - for (int i = 0; i < rect.right - rect.left; i++) + ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type, getCurrentClientVersion()); + if (fastCopyFunc) { - float r; - float g; - float b; - float a; - - switch (desc.Format) + // Fast copy is possible through some special function + for (int y = 0; y < rect.bottom - rect.top; y++) { - case D3DFMT_R5G6B5: + for (int x = 0; x < rect.right - rect.left; x++) { - unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); + void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; + void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; - a = 1.0f; - b = (rgb & 0x001F) * (1.0f / 0x001F); - g = (rgb & 0x07E0) * (1.0f / 0x07E0); - r = (rgb & 0xF800) * (1.0f / 0xF800); + fastCopyFunc(src, dest); } - break; - case D3DFMT_A1R5G5B5: - { - unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); - - a = (argb & 0x8000) ? 1.0f : 0.0f; - b = (argb & 0x001F) * (1.0f / 0x001F); - g = (argb & 0x03E0) * (1.0f / 0x03E0); - r = (argb & 0x7C00) * (1.0f / 0x7C00); - } - break; - case D3DFMT_A8R8G8B8: - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + } + } + else + { + ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format); + ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type, clientVersion); - a = (argb & 0xFF000000) * (1.0f / 0xFF000000); - b = (argb & 0x000000FF) * (1.0f / 0x000000FF); - g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); - r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); - } - break; - case D3DFMT_X8R8G8B8: - { - unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); + gl::ColorF temp; - a = 1.0f; - b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); - g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); - r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); - } - break; - case D3DFMT_A2R10G10B10: + for (int y = 0; y < rect.bottom - rect.top; y++) + { + for (int x = 0; x < rect.right - rect.left; x++) { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + void *dest = reinterpret_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; + void *src = source + y * inputPitch + x * sourcePixelSize; - a = (argb & 0xC0000000) * (1.0f / 0xC0000000); - b = (argb & 0x000003FF) * (1.0f / 0x000003FF); - g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); - r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); - } - break; - case D3DFMT_A32B32G32R32F: - { - // float formats in D3D are stored rgba, rather than the other way round - r = *((float*)(source + 16 * i + j * inputPitch) + 0); - g = *((float*)(source + 16 * i + j * inputPitch) + 1); - b = *((float*)(source + 16 * i + j * inputPitch) + 2); - a = *((float*)(source + 16 * i + j * inputPitch) + 3); + // readFunc and writeFunc will be using the same type of color, CopyTexImage + // will not allow the copy otherwise. + readFunc(src, &temp); + writeFunc(&temp, dest); } - break; - case D3DFMT_A16B16G16R16F: - { - // float formats in D3D are stored rgba, rather than the other way round - r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0)); - g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1)); - b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2)); - a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3)); - } - break; - default: - UNIMPLEMENTED(); // FIXME - UNREACHABLE(); - return; - } - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); - dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); - dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); - break; - default: UNREACHABLE(); - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); - dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); - dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)(15 * a + 0.5f) << 12)| - ((unsigned short)(15 * r + 0.5f) << 8) | - ((unsigned short)(15 * g + 0.5f) << 4) | - ((unsigned short)(15 * b + 0.5f) << 0); - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)( a + 0.5f) << 15) | - ((unsigned short)(31 * r + 0.5f) << 10) | - ((unsigned short)(31 * g + 0.5f) << 5) | - ((unsigned short)(31 * b + 0.5f) << 0); - break; - default: UNREACHABLE(); - } - break; - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_SHORT_5_6_5: - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)(31 * b + 0.5f) << 0) | - ((unsigned short)(63 * g + 0.5f) << 5) | - ((unsigned short)(31 * r + 0.5f) << 11); - break; - case GL_UNSIGNED_BYTE: - dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); - dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); - break; - default: UNREACHABLE(); - } - break; - default: UNREACHABLE(); } } } systemSurface->UnlockRect(); - - systemSurface->Release(); + SafeRelease(systemSurface); } RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) @@ -3114,14 +3315,19 @@ RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) return renderTarget; } -RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) +RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples) { RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples); return renderTarget; } -ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type) +ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers) { + // Transform feedback is not supported in ES2 or D3D9 + ASSERT(transformFeedbackVaryings.size() == 0); + ShaderExecutable9 *executable = NULL; switch (type) @@ -3152,8 +3358,13 @@ ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, return executable; } -ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) +ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround) { + // Transform feedback is not supported in ES2 or D3D9 + ASSERT(transformFeedbackVaryings.size() == 0); + const char *profile = NULL; switch (type) @@ -3169,20 +3380,67 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha return NULL; } - // ANGLE issue 486: - // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization - UINT optimizationFlags = (workaround == ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ? D3DCOMPILE_SKIP_OPTIMIZATION : ANGLE_COMPILE_OPTIMIZATION_LEVEL); + UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; + + if (workaround == ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION) + { + flags = D3DCOMPILE_SKIP_OPTIMIZATION; + } + else if (workaround == ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION) + { + flags = D3DCOMPILE_OPTIMIZATION_LEVEL3; + } + else ASSERT(workaround == ANGLE_D3D_WORKAROUND_NONE); + + if (gl::perfActive()) + { +#ifndef NDEBUG + flags = D3DCOMPILE_SKIP_OPTIMIZATION; +#endif + + flags |= D3DCOMPILE_DEBUG; + + std::string sourcePath = getTempPath(); + std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); + } + + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. + // Try the default flags first and if compilation fails, try some alternatives. + const UINT extraFlags[] = + { + flags, + flags | D3DCOMPILE_AVOID_FLOW_CONTROL, + flags | D3DCOMPILE_PREFER_FLOW_CONTROL + }; + + const static char *extraFlagNames[] = + { + "default", + "avoid flow control", + "prefer flow control" + }; + + int attempts = ArraySize(extraFlags); - ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true); + ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); if (!binary) + { return NULL; + } - ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type); - binary->Release(); + ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers); + SafeRelease(binary); return executable; } +rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize) +{ + return new UniformStorage(storageSize); +} + bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { return mBlit->boxFilter(source, dest); @@ -3223,7 +3481,7 @@ bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *s { Image9::copyLockableSurfaces(surf, source); result = mDevice->UpdateSurface(surf, NULL, dest, NULL); - surf->Release(); + SafeRelease(surf); } } else @@ -3260,14 +3518,30 @@ TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain) return new TextureStorage9_2D(this, swapChain9); } -TextureStorage *Renderer9::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) +TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) +{ + return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); +} + +TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) +{ + return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels); +} + +TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) { - return new TextureStorage9_2D(this, levels, internalformat, usage, forceRenderable, width, height); + // 3D textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return NULL; } -TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) +TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) { - return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size); + // 2D array textures are not supported by the D3D9 backend. + UNREACHABLE(); + + return NULL; } bool Renderer9::getLUID(LUID *adapterLuid) const @@ -3284,4 +3558,20 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } +GLenum Renderer9::getNativeTextureFormat(GLenum internalFormat) const +{ + return d3d9_gl::GetInternalFormat(gl_d3d9::GetTextureFormat(internalFormat, this)); +} + +rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +{ + return d3d9::GetVertexConversionType(vertexFormat); +} + +GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +{ + D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat); + return d3d9::GetDeclTypeComponentType(declType); +} + } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Renderer9.h index 1fac9b7fac6..d3ea314f1a6 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/Renderer9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/Renderer9.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2014 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. // @@ -10,15 +10,16 @@ #define LIBGLESV2_RENDERER_RENDERER9_H_ #include "common/angleutils.h" -#include "libGLESv2/mathutil.h" -#include "libGLESv2/renderer/ShaderCache.h" -#include "libGLESv2/renderer/VertexDeclarationCache.h" +#include "common/mathutil.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/renderer/d3d9/ShaderCache.h" +#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/RenderTarget.h" namespace gl { -class Renderbuffer; +class FramebufferAttachment; } namespace rx @@ -27,11 +28,12 @@ class VertexDataManager; class IndexDataManager; class StreamingIndexBufferInterface; struct TranslatedAttribute; +class Blit9; class Renderer9 : public Renderer { public: - Renderer9(egl::Display *display, HDC hDc, bool softwareDevice); + Renderer9(egl::Display *display, HDC hDc); virtual ~Renderer9(); static Renderer9 *makeRenderer9(Renderer *renderer); @@ -57,22 +59,14 @@ class Renderer9 : public Renderer IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); -#if 0 - void *createTexture2D(); - void *createTextureCube(); - void *createQuery(); - void *createIndexBuffer(); - void *createVertexbuffer(); - - // state setup - void applyShaders(); - void applyConstants(); -#endif + virtual void generateSwizzle(gl::Texture *texture); virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask); virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW); @@ -82,14 +76,18 @@ class Renderer9 : public Renderer bool ignoreViewport); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary); - virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); + virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]); + virtual void applyUniforms(const gl::ProgramBinary &programBinary); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); + virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); + + virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); @@ -108,14 +106,20 @@ class Renderer9 : public Renderer virtual GUID getAdapterIdentifier() const; virtual bool getBGRATextureSupport() const; - virtual bool getDXT1TextureSupport(); - virtual bool getDXT3TextureSupport(); - virtual bool getDXT5TextureSupport(); - virtual bool getEventQuerySupport(); - virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); - virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); - virtual bool getLuminanceTextureSupport(); - virtual bool getLuminanceAlphaTextureSupport(); + virtual bool getDXT1TextureSupport() const; + virtual bool getDXT3TextureSupport() const; + virtual bool getDXT5TextureSupport() const; + virtual bool getEventQuerySupport() const; + virtual bool getFloat32TextureSupport() const; + virtual bool getFloat32TextureFilteringSupport() const; + virtual bool getFloat32TextureRenderingSupport() const; + virtual bool getFloat16TextureSupport() const; + virtual bool getFloat16TextureFilteringSupport() const; + virtual bool getFloat16TextureRenderingSupport() const; + virtual bool getRGB565TextureSupport() const; + virtual bool getLuminanceTextureSupport() const; + virtual bool getLuminanceAlphaTextureSupport() const; + virtual bool getRGTextureSupport() const; virtual unsigned int getMaxVertexTextureImageUnits() const; virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; @@ -123,61 +127,90 @@ class Renderer9 : public Renderer virtual unsigned int getMaxVertexUniformVectors() const; virtual unsigned int getMaxFragmentUniformVectors() const; virtual unsigned int getMaxVaryingVectors() const; + virtual unsigned int getMaxVertexShaderUniformBuffers() const; + virtual unsigned int getMaxFragmentShaderUniformBuffers() const; + virtual unsigned int getReservedVertexUniformBuffers() const; + virtual unsigned int getReservedFragmentUniformBuffers() const; + virtual unsigned int getMaxTransformFeedbackBuffers() const; + virtual unsigned int getMaxTransformFeedbackSeparateComponents() const; + virtual unsigned int getMaxTransformFeedbackInterleavedComponents() const; + virtual unsigned int getMaxUniformBufferSize() const; virtual bool getNonPower2TextureSupport() const; virtual bool getDepthTextureSupport() const; virtual bool getOcclusionQuerySupport() const; virtual bool getInstancingSupport() const; virtual bool getTextureFilterAnisotropySupport() const; + virtual bool getPBOSupport() const; virtual float getTextureMaxAnisotropy() const; virtual bool getShareHandleSupport() const; virtual bool getDerivativeInstructionSupport() const; virtual bool getPostSubBufferSupport() const; + virtual int getMaxRecommendedElementsIndices() const; + virtual int getMaxRecommendedElementsVertices() const; virtual int getMajorShaderModel() const; virtual float getMaxPointSize() const; virtual int getMaxViewportDimension() const; virtual int getMaxTextureWidth() const; virtual int getMaxTextureHeight() const; + virtual int getMaxTextureDepth() const; + virtual int getMaxTextureArrayLayers() const; virtual bool get32BitIndexSupport() const; DWORD getCapsDeclTypes() const; virtual int getMinSwapInterval() const; virtual int getMaxSwapInterval() const; virtual GLsizei getMaxSupportedSamples() const; + virtual GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const; + virtual GLsizei getNumSampleCounts(GLenum internalFormat) const; + virtual void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const; int getNearestSupportedSamples(D3DFORMAT format, int requested) const; virtual unsigned int getMaxRenderTargets() const; - D3DFORMAT ConvertTextureInternalFormat(GLint internalformat); + D3DFORMAT ConvertTextureInternalFormat(GLenum internalformat); // Pixel operations virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); + virtual bool copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source); + virtual bool copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source); virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); + virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); + virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); // Shader operations - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround); + virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers); + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, + const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround); + virtual UniformStorage *createUniformStorage(size_t storageSize); // Image operations virtual Image *createImage(); virtual void generateMipmap(Image *dest, Image *source); virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); - virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels); + virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); + virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Buffer creation virtual VertexBuffer *createVertexBuffer(); @@ -188,28 +221,35 @@ class Renderer9 : public Renderer virtual QueryImpl *createQuery(GLenum type); virtual FenceImpl *createFence(); + // Buffer-to-texture and Texture-to-buffer copies + virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; + virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + // D3D9-renderer specific methods bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); D3DPOOL getTexturePool(DWORD usage) const; virtual bool getLUID(LUID *adapterLuid) const; + virtual GLenum getNativeTextureFormat(GLenum internalFormat) const; + virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; + virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; private: DISALLOW_COPY_AND_ASSIGN(Renderer9); void deinitialize(); - void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v); - void applyUniformniv(gl::Uniform *targetUniform, const GLint *v); - void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v); + void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v); + void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v); + void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v); void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer); + void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); - gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer); + gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer); D3DPOOL getBufferPool(DWORD usage) const; @@ -226,13 +266,14 @@ class Renderer9 : public Renderer UINT mAdapter; D3DDEVTYPE mDeviceType; - bool mSoftwareDevice; // FIXME: Deprecate IDirect3D9 *mD3d9; // Always valid after successful initialization. IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3DDevice9 *mDevice; IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. - Blit *mBlit; + HLSLCompiler mCompiler; + + Blit9 *mBlit; HWND mDeviceWindow; @@ -256,6 +297,8 @@ class Renderer9 : public Renderer bool mDepthTextureSupport; + bool mRGB565TextureSupport; + bool mFloat32TextureSupport; bool mFloat32FilterSupport; bool mFloat32RenderSupport; @@ -271,8 +314,18 @@ class Renderer9 : public Renderer bool mLuminanceTextureSupport; bool mLuminanceAlphaTextureSupport; - std::map<D3DFORMAT, bool *> mMultiSampleSupport; - GLsizei mMaxSupportedSamples; + bool mRGTextureSupport; + + struct MultisampleSupportInfo + { + bool supportedSamples[D3DMULTISAMPLE_16_SAMPLES + 1]; + unsigned int maxSupportedSamples; + }; + typedef std::map<D3DFORMAT, MultisampleSupportInfo> MultisampleSupportMap; + MultisampleSupportMap mMultiSampleSupport; + unsigned int mMaxSupportedSamples; + + MultisampleSupportInfo getMultiSampleSupport(D3DFORMAT format); // current render target states unsigned int mAppliedRenderTargetSerial; @@ -308,7 +361,7 @@ class Renderer9 : public Renderer bool mForceSetBlendState; gl::BlendState mCurBlendState; - gl::Color mCurBlendColor; + gl::ColorF mCurBlendColor; GLuint mCurSampleMask; // Currently applied sampler states @@ -323,8 +376,10 @@ class Renderer9 : public Renderer unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; unsigned int mAppliedIBSerial; - unsigned int mAppliedProgramBinarySerial; - + IDirect3DVertexShader9 *mAppliedVertexShader; + IDirect3DPixelShader9 *mAppliedPixelShader; + unsigned int mAppliedProgramSerial; + rx::dx_VertexConstants mVertexConstants; rx::dx_PixelConstants mPixelConstants; bool mDxUniformsDirty; @@ -346,7 +401,7 @@ class Renderer9 : public Renderer UINT lruCount; int width; int height; - gl::Renderbuffer *buffer; + gl::FramebufferAttachment *buffer; } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; UINT mMaxNullColorbufferLRU; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderCache.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderCache.h index 4391ac271a3..a03528c9b55 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderCache.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderCache.h @@ -53,7 +53,7 @@ class ShaderCache // Random eviction policy. if (mMap.size() >= kMaxMapSize) { - mMap.begin()->second->Release(); + SafeRelease(mMap.begin()->second); mMap.erase(mMap.begin()); } @@ -67,7 +67,7 @@ class ShaderCache { for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it) { - it->second->Release(); + SafeRelease(it->second); } mMap.clear(); @@ -88,15 +88,7 @@ class ShaderCache return mDevice->CreatePixelShader(function, shader); } -#ifndef HASH_MAP -# ifdef _MSC_VER -# define HASH_MAP stdext::hash_map -# else -# define HASH_MAP std::unordered_map -# endif -#endif - - typedef HASH_MAP<std::string, ShaderObject*> Map; + typedef std::unordered_map<std::string, ShaderObject*> Map; Map mMap; IDirect3DDevice9 *mDevice; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp index 98868a3fbf3..115ed0823c7 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp @@ -8,7 +8,7 @@ // ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader // executable implementation details. -#include "libGLESv2/renderer/ShaderExecutable9.h" +#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h" #include "common/debug.h" @@ -31,14 +31,8 @@ ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirec ShaderExecutable9::~ShaderExecutable9() { - if (mVertexExecutable) - { - mVertexExecutable->Release(); - } - if (mPixelExecutable) - { - mPixelExecutable->Release(); - } + SafeRelease(mVertexExecutable); + SafeRelease(mPixelExecutable); } ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable) diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h index fa1e6c2844a..fa1e6c2844a 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/ShaderExecutable9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp index 7b9b32b412f..bfb34594c52 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp @@ -7,9 +7,10 @@ // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" namespace rx { @@ -35,38 +36,16 @@ SwapChain9::~SwapChain9() void SwapChain9::release() { - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } - - if (mRenderTarget) - { - mRenderTarget->Release(); - mRenderTarget = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } + SafeRelease(mSwapChain); + SafeRelease(mBackBuffer); + SafeRelease(mDepthStencil); + SafeRelease(mRenderTarget); + SafeRelease(mOffscreenTexture); if (mWindow) + { mShareHandle = NULL; + } } static DWORD convertInterval(EGLint interval) @@ -111,29 +90,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI // Release specific resources to free up memory for the new render target, while the // old render target still exists for the purpose of preserving its contents. - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } + SafeRelease(mSwapChain); + SafeRelease(mBackBuffer); + SafeRelease(mOffscreenTexture); + SafeRelease(mDepthStencil); HANDLE *pShareHandle = NULL; if (!mWindow && mRenderer->getShareHandleSupport()) @@ -142,8 +102,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI } result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT, - &mOffscreenTexture, pShareHandle); + gl_d3d9::GetTextureFormat(mBackBufferFormat, mRenderer), + D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); @@ -187,15 +147,15 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); ASSERT(SUCCEEDED(result)); - oldRenderTarget->Release(); + SafeRelease(oldRenderTarget); } if (mWindow) { D3DPRESENT_PARAMETERS presentParameters = {0}; - presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat); + presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat, mRenderer); presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat); + presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat, mRenderer); presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = mWindow; @@ -247,7 +207,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI if (mDepthBufferFormat != GL_NONE) { result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat), + gl_d3d9::GetRenderFormat(mDepthBufferFormat, mRenderer), D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); if (FAILED(result)) @@ -351,23 +311,34 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) mRenderer->markAllStateDirty(); - if (d3d9::isDeviceLostError(result)) + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) { - return EGL_CONTEXT_LOST; + return EGL_BAD_ALLOC; } - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) + // On Windows 8 systems, IDirect3DSwapChain9::Present sometimes returns 0x88760873 when the windows is + // in the process of entering/exiting fullscreen. This code doesn't seem to have any documentation. The + // device appears to be ok after emitting this error so simply return a failure to swap. + if (result == 0x88760873) { - return EGL_BAD_ALLOC; + return EGL_BAD_MATCH; } - ASSERT(SUCCEEDED(result)); + // http://crbug.com/313210 + // If our swap failed, trigger a device lost event. Resetting will work around an AMD-specific + // device removed bug with lost contexts when reinstalling drivers. + if (FAILED(result)) + { + mRenderer->notifyDeviceLost(); + return EGL_CONTEXT_LOST; + } return EGL_SUCCESS; } // Increments refcount on surface. // caller must Release() the returned surface +// TODO: remove the AddRef to match SwapChain11 IDirect3DSurface9 *SwapChain9::getRenderTarget() { if (mRenderTarget) @@ -380,6 +351,7 @@ IDirect3DSurface9 *SwapChain9::getRenderTarget() // Increments refcount on surface. // caller must Release() the returned surface +// TODO: remove the AddRef to match SwapChain11 IDirect3DSurface9 *SwapChain9::getDepthStencil() { if (mDepthStencil) @@ -392,6 +364,7 @@ IDirect3DSurface9 *SwapChain9::getDepthStencil() // Increments refcount on texture. // caller must Release() the returned texture +// TODO: remove the AddRef to match SwapChain11 IDirect3DTexture9 *SwapChain9::getOffscreenTexture() { if (mOffscreenTexture) @@ -432,10 +405,10 @@ void SwapChain9::recreate() return; } - mSwapChain->Release(); + SafeRelease(mSwapChain); mSwapChain = newSwapChain; - mBackBuffer->Release(); + SafeRelease(mBackBuffer); result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); ASSERT(SUCCEEDED(result)); } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h index 16a62bd86f6..16a62bd86f6 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/SwapChain9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp index 8aa74a7cba1..a8efca7fb4b 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage9.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp @@ -1,6 +1,6 @@ #include "precompiled.h" // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 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. // @@ -10,17 +10,18 @@ // D3D9 texture. #include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" #include "libGLESv2/Texture.h" namespace rx { TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage) - : mLodOffset(0), + : mTopLevel(0), mRenderer(Renderer9::makeRenderer9(renderer)), mD3DUsage(usage), mD3DPool(mRenderer->getTexturePool(usage)) @@ -37,46 +38,25 @@ TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage) return static_cast<TextureStorage9*>(storage); } -DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable) +DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, Renderer9 *renderer, bool renderTarget) { + GLuint clientVersion = renderer->getCurrentClientVersion(); + DWORD d3dusage = 0; - if (d3dfmt == D3DFMT_INTZ) + if (gl::GetDepthBits(internalformat, clientVersion) > 0 || + gl::GetStencilBits(internalformat, clientVersion) > 0) { d3dusage |= D3DUSAGE_DEPTHSTENCIL; } - else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) + else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat, renderer) != D3DFMT_UNKNOWN)) { d3dusage |= D3DUSAGE_RENDERTARGET; } + return d3dusage; } -bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return true; - } - switch(format) - { - case D3DFMT_L8: - case D3DFMT_A8L8: - case D3DFMT_DXT1: - case D3DFMT_DXT3: - case D3DFMT_DXT5: - return false; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - case D3DFMT_A16B16G16R16F: - case D3DFMT_A32B32G32R32F: - return true; - default: - UNREACHABLE(); - } - - return false; -} bool TextureStorage9::isRenderTarget() const { @@ -98,17 +78,18 @@ DWORD TextureStorage9::getUsage() const return mD3DUsage; } -int TextureStorage9::getLodOffset() const +int TextureStorage9::getTopLevel() const { - return mLodOffset; + return mTopLevel; } -int TextureStorage9::levelCount() +int TextureStorage9::getLevelCount() const { - return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0; + return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0; } -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) +TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) + : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) { IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); mTexture = surfaceTexture; @@ -117,8 +98,8 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain initializeRenderTarget(); } -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) - : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) +TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) + : TextureStorage9(renderer, GetTextureUsage(internalformat, Renderer9::makeRenderer9(renderer), renderTarget)) { mTexture = NULL; mRenderTarget = NULL; @@ -127,9 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum in if (width > 0 && height > 0) { IDirect3DDevice9 *device = mRenderer->getDevice(); - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); - HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), - mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); + D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat, mRenderer); + d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel); + UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; + + HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -143,12 +126,8 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum in TextureStorage9_2D::~TextureStorage9_2D() { - if (mTexture) - { - mTexture->Release(); - } - - delete mRenderTarget; + SafeRelease(mTexture); + SafeDelete(mRenderTarget); } TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage) @@ -165,11 +144,12 @@ IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) if (mTexture) { - HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface); + HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); // With managed textures the driver needs to be informed of updates to the lower mipmap levels - if (level + mLodOffset != 0 && isManaged() && dirty) + if (level + mTopLevel != 0 && isManaged() && dirty) { mTexture->AddDirtyRect(NULL); } @@ -178,7 +158,7 @@ IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) return surface; } -RenderTarget *TextureStorage9_2D::getRenderTarget() +RenderTarget *TextureStorage9_2D::getRenderTarget(int level) { return mRenderTarget; } @@ -193,8 +173,8 @@ void TextureStorage9_2D::generateMipmap(int level) mRenderer->boxFilter(upper, lower); } - if (upper != NULL) upper->Release(); - if (lower != NULL) lower->Release(); + SafeRelease(upper); + SafeRelease(lower); } IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const @@ -214,8 +194,8 @@ void TextureStorage9_2D::initializeRenderTarget() } } -TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) - : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) +TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) + : TextureStorage9(renderer, GetTextureUsage(internalformat, Renderer9::makeRenderer9(renderer), renderTarget)) { mTexture = NULL; for (int i = 0; i < 6; ++i) @@ -229,9 +209,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenu { IDirect3DDevice9 *device = mRenderer->getDevice(); int height = size; - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); - HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(), - mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); + D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat, mRenderer); + d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel); + UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; + + HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -245,14 +227,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenu TextureStorage9_Cube::~TextureStorage9_Cube() { - if (mTexture) - { - mTexture->Release(); - } + SafeRelease(mTexture); for (int i = 0; i < 6; ++i) { - delete mRenderTarget[i]; + SafeDelete(mRenderTarget[i]); } } @@ -271,7 +250,8 @@ IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, in if (mTexture) { D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); - HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface); + HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface); + UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); // With managed textures the driver needs to be informed of updates to the lower mipmap levels @@ -284,23 +264,23 @@ IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, in return surface; } -RenderTarget *TextureStorage9_Cube::getRenderTarget(GLenum faceTarget) +RenderTarget *TextureStorage9_Cube::getRenderTargetFace(GLenum faceTarget, int level) { - return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)]; + return mRenderTarget[gl::TextureCubeMap::targetToIndex(faceTarget)]; } -void TextureStorage9_Cube::generateMipmap(int face, int level) +void TextureStorage9_Cube::generateMipmap(int faceIndex, int level) { - IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false); - IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true); + IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false); + IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true); if (upper != NULL && lower != NULL) { mRenderer->boxFilter(upper, lower); } - if (upper != NULL) upper->Release(); - if (lower != NULL) lower->Release(); + SafeRelease(upper); + SafeRelease(lower); } IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h index 86f551a1315..1f4975f48e5 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/TextureStorage9.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012-2013 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. // @@ -20,37 +20,37 @@ class Renderer9; class SwapChain9; class RenderTarget; class RenderTarget9; -class Blit; class TextureStorage9 : public TextureStorage { public: - TextureStorage9(Renderer *renderer, DWORD usage); virtual ~TextureStorage9(); static TextureStorage9 *makeTextureStorage9(TextureStorage *storage); - static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable); - static bool IsTextureFormatRenderable(D3DFORMAT format); + static DWORD GetTextureUsage(GLenum internalformat, Renderer9 *renderer, bool renderTarget); D3DPOOL getPool() const; DWORD getUsage() const; virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; - virtual RenderTarget *getRenderTarget() { return NULL; } - virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return NULL; } + virtual RenderTarget *getRenderTarget(int level) { return NULL; } + virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level) { return NULL; } + virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer) { return NULL; } virtual void generateMipmap(int level) {}; virtual void generateMipmap(int face, int level) {}; - virtual int getLodOffset() const; + virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; - virtual int levelCount(); + virtual int getLevelCount() const; protected: - int mLodOffset; + int mTopLevel; Renderer9 *mRenderer; + TextureStorage9(Renderer *renderer, DWORD usage); + private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9); @@ -62,13 +62,13 @@ class TextureStorage9_2D : public TextureStorage9 { public: TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain); - TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage9_2D(); static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); - virtual RenderTarget *getRenderTarget(); + virtual RenderTarget *getRenderTarget(int level); virtual IDirect3DBaseTexture9 *getBaseTexture() const; virtual void generateMipmap(int level); @@ -84,15 +84,15 @@ class TextureStorage9_2D : public TextureStorage9 class TextureStorage9_Cube : public TextureStorage9 { public: - TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); virtual ~TextureStorage9_Cube(); static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); - virtual RenderTarget *getRenderTarget(GLenum faceTarget); + virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int face, int level); + virtual void generateMipmap(int faceIndex, int level); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp new file mode 100644 index 00000000000..42ddfcae1cb --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp @@ -0,0 +1,252 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. + +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/vertexconversion.h" +#include "libGLESv2/renderer/BufferStorage.h" +#include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" + +#include "libGLESv2/Buffer.h" + +namespace rx +{ + +VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) +{ + mVertexBuffer = NULL; + mBufferSize = 0; + mDynamicUsage = false; +} + +VertexBuffer9::~VertexBuffer9() +{ + SafeRelease(mVertexBuffer); +} + +bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) +{ + SafeRelease(mVertexBuffer); + + updateSerial(); + + if (size > 0) + { + DWORD flags = D3DUSAGE_WRITEONLY; + if (dynamicUsage) + { + flags |= D3DUSAGE_DYNAMIC; + } + + HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", size); + return false; + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + return true; +} + +VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer)); + return static_cast<VertexBuffer9*>(vertexBuffer); +} + +bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) +{ + if (mVertexBuffer) + { + gl::Buffer *buffer = attrib.mBoundBuffer.get(); + + int inputStride = attrib.stride(); + int elementSize = attrib.typeSize(); + + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + + void *mapPtr = NULL; + + unsigned int mapSize; + if (!spaceRequired(attrib, count, instances, &mapSize)) + { + return false; + } + + HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); + + if (FAILED(result)) + { + ERR("Lock failed with error 0x%08x", result); + return false; + } + + const char *input = NULL; + if (attrib.mArrayEnabled) + { + if (buffer) + { + BufferStorage *storage = buffer->getStorage(); + input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset); + } + else + { + input = static_cast<const char*>(attrib.mPointer); + } + } + else + { + input = reinterpret_cast<const char*>(currentValue.FloatValues); + } + + if (instances == 0 || attrib.mDivisor == 0) + { + input += inputStride * start; + } + + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + bool needsConversion = (d3d9::GetVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) > 0; + + if (!needsConversion && inputStride == elementSize) + { + size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride); + memcpy(mapPtr, input, copySize); + } + else + { + VertexCopyFunction copyFunction = d3d9::GetVertexCopyFunction(vertexFormat); + copyFunction(input, inputStride, count, mapPtr); + } + + mVertexBuffer->Unlock(); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const +{ + return spaceRequired(attrib, count, instances, outSpaceRequired); +} + +unsigned int VertexBuffer9::getBufferSize() const +{ + return mBufferSize; +} + +bool VertexBuffer9::setBufferSize(unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(size, mDynamicUsage); + } + else + { + return true; + } +} + +bool VertexBuffer9::discard() +{ + if (mVertexBuffer) + { + void *dummy; + HRESULT result; + + result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + ERR("Discard lock failed with error 0x%08x", result); + return false; + } + + result = mVertexBuffer->Unlock(); + if (FAILED(result)) + { + ERR("Discard unlock failed with error 0x%08x", result); + return false; + } + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const +{ + return mVertexBuffer; +} + +bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) +{ + gl::VertexFormat vertexFormat(attrib, GL_FLOAT); + unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat); + + if (attrib.mArrayEnabled) + { + unsigned int elementCount = 0; + if (instances == 0 || attrib.mDivisor == 0) + { + elementCount = count; + } + else + { + if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; + } + else + { + elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor; + } + } + + if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; + } + } + else + { + const unsigned int elementSize = 4; + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * 4; + } + return true; + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h new file mode 100644 index 00000000000..2fb5a36b37b --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h @@ -0,0 +1,54 @@ +// +// Copyright (c) 2002-2012 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. +// + +// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation. + +#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ +#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ + +#include "libGLESv2/renderer/VertexBuffer.h" + +namespace rx +{ +class Renderer9; + +class VertexBuffer9 : public VertexBuffer +{ + public: + explicit VertexBuffer9(rx::Renderer9 *const renderer); + virtual ~VertexBuffer9(); + + virtual bool initialize(unsigned int size, bool dynamicUsage); + + static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); + + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset); + + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; + + virtual unsigned int getBufferSize() const; + virtual bool setBufferSize(unsigned int size); + virtual bool discard(); + + IDirect3DVertexBuffer9 *getBuffer() const; + + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); + + rx::Renderer9 *const mRenderer; + + IDirect3DVertexBuffer9 *mVertexBuffer; + unsigned int mBufferSize; + bool mDynamicUsage; + + static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired); +}; + +} + +#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp index 9b83a6476eb..30c023378a1 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp @@ -8,9 +8,10 @@ // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. #include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Context.h" -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/VertexDeclarationCache.h" +#include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h" +#include "libGLESv2/renderer/d3d9/formatutils9.h" namespace rx { @@ -36,10 +37,7 @@ VertexDeclarationCache::~VertexDeclarationCache() { for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) { - if (mVertexDeclCache[i].vertexDeclaration) - { - mVertexDeclCache[i].vertexDeclaration->Release(); - } + SafeRelease(mVertexDeclCache[i].vertexDeclaration); } } @@ -134,9 +132,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl mAppliedVBs[stream].offset = attributes[i].offset; } + gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); + element->Stream = stream; element->Offset = 0; - element->Type = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDeclType(*attributes[i].attribute) : D3DDECLTYPE_FLOAT4; + element->Type = d3d9::GetNativeVertexFormat(vertexFormat); element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; element->UsageIndex = programBinary->getSemanticIndex(i); @@ -188,8 +188,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl if (lastCache->vertexDeclaration != NULL) { - lastCache->vertexDeclaration->Release(); - lastCache->vertexDeclaration = NULL; + SafeRelease(lastCache->vertexDeclaration); // mLastSetVDecl is set to the replacement, so we don't have to worry // about it. } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDeclarationCache.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h index 3fc024a9bab..3fc024a9bab 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/VertexDeclarationCache.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.cpp new file mode 100644 index 00000000000..141bcc7c958 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.cpp @@ -0,0 +1,864 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// formatutils9.cpp: Queries for GL image formats and their translations to D3D9 +// formats. + +#include "libGLESv2/renderer/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/generatemip.h" +#include "libGLESv2/renderer/loadimage.h" +#include "libGLESv2/renderer/copyimage.h" +#include "libGLESv2/renderer/vertexconversion.h" + +namespace rx +{ + +// Each GL internal format corresponds to one D3D format and data loading function. +// Due to not all formats being available all the time, some of the function/format types are wrapped +// in templates that perform format support queries on a Renderer9 object which is supplied +// when requesting the function or format. + +typedef bool ((Renderer9::*Renderer9FormatCheckFunction)(void) const); +typedef LoadImageFunction (*RendererCheckLoadFunction)(const Renderer9 *renderer); + +template <Renderer9FormatCheckFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> +LoadImageFunction RendererCheckLoad(const Renderer9 *renderer) +{ + return ((renderer->*pred)()) ? prefered : fallback; +} + +template <LoadImageFunction loadFunc> +LoadImageFunction SimpleLoad(const Renderer9 *renderer) +{ + return loadFunc; +} + +LoadImageFunction UnreachableLoad(const Renderer9 *renderer) +{ + UNREACHABLE(); + return NULL; +} + +typedef bool (*FallbackPredicateFunction)(void); + +template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> +LoadImageFunction FallbackLoadFunction(const Renderer9 *renderer) +{ + return pred() ? prefered : fallback; +} + +typedef D3DFORMAT (*FormatQueryFunction)(const rx::Renderer9 *renderer); + +template <Renderer9FormatCheckFunction pred, D3DFORMAT prefered, D3DFORMAT fallback> +D3DFORMAT CheckFormatSupport(const rx::Renderer9 *renderer) +{ + return (renderer->*pred)() ? prefered : fallback; +} + +template <D3DFORMAT format> +D3DFORMAT D3D9Format(const rx::Renderer9 *renderer) +{ + return format; +} + +struct D3D9FormatInfo +{ + FormatQueryFunction mTexFormat; + FormatQueryFunction mRenderFormat; + RendererCheckLoadFunction mLoadFunction; + + D3D9FormatInfo() + : mTexFormat(NULL), mRenderFormat(NULL), mLoadFunction(NULL) + { } + + D3D9FormatInfo(FormatQueryFunction textureFormat, FormatQueryFunction renderFormat, RendererCheckLoadFunction loadFunc) + : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc) + { } +}; + +const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); +const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); + +typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair; +typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap; + +static D3D9FormatMap BuildD3D9FormatMap() +{ + D3D9FormatMap map; + + // | Internal format | Texture format | Render format | Load function | + map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3D9Format<D3DFMT_NULL>, D3D9Format<D3DFMT_NULL>, UnreachableLoad ))); + + map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); + map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D32>, UnreachableLoad ))); + map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); + map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3D9Format<D3DFMT_UNKNOWN>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); // TODO: What's the texture format? + + map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative<GLfloat, 4> > ))); + map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative3To4<GLfloat, gl::Float32One> >))); + map.insert(D3D9FormatPair(GL_RG32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_G32R32F>, D3D9Format<D3DFMT_G32R32F>, SimpleLoad<loadToNative<GLfloat, 2> > ))); + map.insert(D3D9FormatPair(GL_R32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_R32F>, D3D9Format<D3DFMT_R32F>, SimpleLoad<loadToNative<GLfloat, 1> > ))); + map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaFloatDataToRGBA> ))); + map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceFloatDataToRGBA> ))); + map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaFloatDataToRGBA> ))); + + map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadToNative<GLhalf, 4> > ))); + map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadToNative3To4<GLhalf, gl::Float16One> >))); + map.insert(D3D9FormatPair(GL_RG16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_G16R16F>, D3D9Format<D3DFMT_G16R16F>, SimpleLoad<loadToNative<GLhalf, 2> > ))); + map.insert(D3D9FormatPair(GL_R16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_R16F>, D3D9Format<D3DFMT_R16F>, SimpleLoad<loadToNative<GLhalf, 1> > ))); + map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaHalfFloatDataToRGBA> ))); + map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceHalfFloatDataToRGBA> ))); + map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaHalfFloatDataToRGBA>))); + + map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadAlphaDataToBGRASSE2, loadAlphaDataToBGRA>))); + + map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGBUByteDataToBGRX> ))); + map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, RendererCheckLoad<&Renderer9::getRGB565TextureSupport, loadToNative<GLushort, 1>, loadRGB565DataToBGRA>))); + map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadRGBAUByteDataToBGRASSE2, loadRGBAUByteDataToBGRA>))); + map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToBGRA> ))); + map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToBGRA> ))); + map.insert(D3D9FormatPair(GL_R8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRUByteDataToBGRX> ))); + map.insert(D3D9FormatPair(GL_RG8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGUByteDataToBGRX> ))); + + map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadToNative<GLubyte, 4> > ))); + map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToRGBA> ))); + map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToRGBA> ))); + + map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >))); + map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >))); + map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT3>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >))); + map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT5>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >))); + + // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and + // then changing the format and loading function appropriately. + map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceTextureSupport, D3DFMT_L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 1>, loadLuminanceDataToBGRA>))); + map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceAlphaTextureSupport, D3DFMT_A8L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 2>, loadLuminanceAlphaDataToBGRA>))); + + return map; +} + +static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo) +{ + static const D3D9FormatMap formatMap = BuildD3D9FormatMap(); + D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} + +// A map to determine the pixel size and mip generation function of a given D3D format +struct D3DFormatInfo +{ + GLuint mPixelBits; + GLuint mBlockWidth; + GLuint mBlockHeight; + GLenum mInternalFormat; + + MipGenerationFunction mMipGenerationFunction; + ColorReadFunction mColorReadFunction; + + D3DFormatInfo() + : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL), + mColorReadFunction(NULL) + { } + + D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum internalFormat, + MipGenerationFunction mipFunc, ColorReadFunction readFunc) + : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat), + mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) + { } +}; + +typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair; +typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap; + +static D3D9FormatInfoMap BuildD3D9FormatInfoMap() +{ + D3D9FormatInfoMap map; + + // | D3DFORMAT | | S |W |H | Internal format | Mip generation function | Color read function | + map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); + + map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_R16F, D3DFormatInfo( 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_G16R16F, D3DFormatInfo( 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>))); + map.insert(D3D9FormatInfoPair(D3DFMT_R32F, D3DFormatInfo( 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F, D3DFormatInfo( 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ))); + map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>))); + + map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ))); + + map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); + + map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ))); + map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ))); + + return map; +} + +static const D3D9FormatInfoMap &GetD3D9FormatInfoMap() +{ + static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); + return infoMap; +} + +static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo) +{ + const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); + D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); + if (iter != infoMap.end()) + { + if (outFormatInfo) + { + *outFormatInfo = iter->second; + } + return true; + } + else + { + return false; + } +} +static d3d9::D3DFormatSet BuildAllD3DFormatSet() +{ + d3d9::D3DFormatSet set; + + const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); + for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i) + { + set.insert(i->first); + } + + return set; +} + +struct D3D9FastCopyFormat +{ + D3DFORMAT mSourceFormat; + GLenum mDestFormat; + GLenum mDestType; + + D3D9FastCopyFormat(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) + : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType) + { } + + bool operator<(const D3D9FastCopyFormat& other) const + { + return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; + } +}; + +typedef std::map<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyMap; +typedef std::pair<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyPair; + +static D3D9FastCopyMap BuildFastCopyMap() +{ + D3D9FastCopyMap map; + + map.insert(D3D9FastCopyPair(D3D9FastCopyFormat(D3DFMT_A8R8G8B8, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte)); + + return map; +} + +typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair; +typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap; + +static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() +{ + InternalFormatInitialzerMap map; + + map.insert(InternalFormatInitialzerPair(GL_RGB16F, initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); + map.insert(InternalFormatInitialzerPair(GL_RGB32F, initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); + + return map; +} + +static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap() +{ + static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap(); + return map; +} + +namespace d3d9 +{ + +MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + return d3dFormatInfo.mMipGenerationFunction; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +LoadImageFunction GetImageLoadFunction(GLenum internalFormat, const Renderer9 *renderer) +{ + if (!renderer) + { + return NULL; + } + + ASSERT(renderer->getCurrentClientVersion() == 2); + + D3D9FormatInfo d3d9FormatInfo; + if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) + { + return d3d9FormatInfo.mLoadFunction(renderer); + } + else + { + UNREACHABLE(); + return NULL; + } +} + +GLuint GetFormatPixelBytes(D3DFORMAT format) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + return d3dFormatInfo.mPixelBits / 8; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlockWidth(D3DFORMAT format) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + return d3dFormatInfo.mBlockWidth; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlockHeight(D3DFORMAT format) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + return d3dFormatInfo.mBlockHeight; + } + else + { + UNREACHABLE(); + return 0; + } +} + +GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth; + GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight; + + return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; + } + else + { + UNREACHABLE(); + return 0; + } +} + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + int upsampleCount = 0; + + GLsizei blockWidth = d3dFormatInfo.mBlockWidth; + GLsizei blockHeight = d3dFormatInfo.mBlockHeight; + + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) + { + while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; + } +} + +const D3DFormatSet &GetAllUsedD3DFormats() +{ + static const D3DFormatSet formatSet = BuildAllD3DFormatSet(); + return formatSet; +} + +ColorReadFunction GetColorReadFunction(D3DFORMAT format) +{ + D3DFormatInfo d3dFormatInfo; + if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + { + return d3dFormatInfo.mColorReadFunction; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion) +{ + static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); + D3D9FastCopyMap::const_iterator iter = fastCopyMap.find(D3D9FastCopyFormat(sourceFormat, destFormat, destType)); + return (iter != fastCopyMap.end()) ? iter->second : NULL; +} + +GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) +{ + switch (declType) + { + case D3DDECLTYPE_FLOAT1: return GL_FLOAT; + case D3DDECLTYPE_FLOAT2: return GL_FLOAT; + case D3DDECLTYPE_FLOAT3: return GL_FLOAT; + case D3DDECLTYPE_FLOAT4: return GL_FLOAT; + case D3DDECLTYPE_UBYTE4: return GL_UNSIGNED_INT; + case D3DDECLTYPE_SHORT2: return GL_INT; + case D3DDECLTYPE_SHORT4: return GL_INT; + case D3DDECLTYPE_UBYTE4N: return GL_UNSIGNED_NORMALIZED; + case D3DDECLTYPE_SHORT4N: return GL_SIGNED_NORMALIZED; + case D3DDECLTYPE_USHORT4N: return GL_UNSIGNED_NORMALIZED; + case D3DDECLTYPE_SHORT2N: return GL_SIGNED_NORMALIZED; + case D3DDECLTYPE_USHORT2N: return GL_UNSIGNED_NORMALIZED; + default: UNREACHABLE(); return GL_NONE; + } +} + +// Attribute format conversion +enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; + +struct FormatConverter +{ + bool identity; + std::size_t outputElementSize; + void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); + D3DDECLTYPE d3dDeclType; +}; + +struct TranslationDescription +{ + DWORD capsFlag; + FormatConverter preferredConversion; + FormatConverter fallbackConversion; +}; + +static unsigned int typeIndex(GLenum type); +static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); + +bool mTranslationsInitialized = false; +FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + +// Mapping from OpenGL-ES vertex attrib type to D3D decl type: +// +// BYTE SHORT (Cast) +// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) +// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) +// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) +// SHORT SHORT (Identity) +// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) +// UNSIGNED_SHORT FLOAT (Cast) +// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) +// FIXED (not in WebGL) FLOAT (FixedToFloat) +// FLOAT FLOAT (Identity) + +// GLToCType maps from GL type (as GLenum) to the C typedef. +template <GLenum GLType> struct GLToCType { }; + +template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; }; +template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; }; +template <> struct GLToCType<GL_SHORT> { typedef GLshort type; }; +template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; }; +template <> struct GLToCType<GL_FIXED> { typedef GLuint type; }; +template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; }; + +// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) +enum D3DVertexType +{ + D3DVT_FLOAT, + D3DVT_SHORT, + D3DVT_SHORT_NORM, + D3DVT_UBYTE, + D3DVT_UBYTE_NORM, + D3DVT_USHORT_NORM +}; + +// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. +template <unsigned int D3DType> struct D3DToCType { }; + +template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; }; +template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; }; +template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; }; +template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; }; +template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; }; +template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; }; + +// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. +template <unsigned int type, int size> struct WidenRule { }; + +template <int size> struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size> { }; +template <int size> struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size> { }; +template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size> { }; +template <int size> struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size> { }; +template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size> { }; +template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size> { }; + +// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. +template <unsigned int d3dtype, int size> struct VertexTypeFlags { }; + +template <unsigned int _capflag, unsigned int _declflag> +struct VertexTypeFlagsHelper +{ + enum { capflag = _capflag }; + enum { declflag = _declflag }; +}; + +template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { }; +template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { }; +template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { }; +template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { }; +template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { }; + + +// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). +template <GLenum GLtype, bool normalized> struct VertexTypeMapping { }; + +template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred> +struct VertexTypeMappingBase +{ + enum { preferred = Preferred }; + enum { fallback = Fallback }; +}; + +template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast +template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize +template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast +template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize +template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity +template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize +template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast +template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize +template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat +template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity + + +// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). +// The conversion rules themselves are defined in vertexconversion.h. + +// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping). +template <GLenum fromType, bool normalized, unsigned int toType> +struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { }; + +// All conversions from normalized types to float use the Normalize operator. +template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { }; + +// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules. +template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; +template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; + +// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) +// whether it is normalized or not. +template <class T, bool normalized> struct DefaultVertexValuesStage2 { }; + +template <class T> struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T> { }; +template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { }; + +// Work out the default value rule for a D3D type (expressed as the C type) and +template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { }; +template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { }; + +// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion. +// The fallback conversion produces an output that all D3D9 devices must support. +template <class T> struct UsePreferred { enum { type = T::preferred }; }; +template <class T> struct UseFallback { enum { type = T::fallback }; }; + +// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion, +// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag +// and the D3DDECLTYPE member needed for the vertex declaration in declflag. +template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule> +struct Converter + : VertexDataConverter<typename GLToCType<fromType>::type, + WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>, + ConversionRule<fromType, + normalized, + PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>, + DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > > +{ +private: + enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type }; + enum { d3dsize = WidenRule<d3dtype, size>::finalWidth }; + +public: + enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag }; + enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; +}; + +// Initialize a TranslationInfo +#define TRANSLATION(type, norm, size, preferred) \ + { \ + Converter<type, norm, size, preferred>::identity, \ + Converter<type, norm, size, preferred>::finalSize, \ + Converter<type, norm, size, preferred>::convertArray, \ + static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \ + } + +#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ + { \ + Converter<type, norm, size, UsePreferred>::capflag, \ + TRANSLATION(type, norm, size, UsePreferred), \ + TRANSLATION(type, norm, size, UseFallback) \ + } + +#define TRANSLATIONS_FOR_TYPE(type) \ + { \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \ + } + +#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ + { \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + } + +const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] +{ + TRANSLATIONS_FOR_TYPE(GL_BYTE), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), + TRANSLATIONS_FOR_TYPE(GL_SHORT), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) +}; + +void InitializeVertexTranslations(const rx::Renderer9 *renderer) +{ + DWORD declTypes = renderer->getCapsDeclTypes(); + + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 4; k++) + { + if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) + { + mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; + } + else + { + mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; + } + } + } + } +} + +unsigned int typeIndex(GLenum type) +{ + switch (type) + { + case GL_BYTE: return 0; + case GL_UNSIGNED_BYTE: return 1; + case GL_SHORT: return 2; + case GL_UNSIGNED_SHORT: return 3; + case GL_FIXED: return 4; + case GL_FLOAT: return 5; + + default: UNREACHABLE(); return 5; + } +} + +const FormatConverter &formatConverter(const gl::VertexFormat &vertexFormat) +{ + // Pure integer attributes only supported in ES3.0 + ASSERT(!vertexFormat.mPureInteger); + return mFormatConverters[typeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; +} + +VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat) +{ + return formatConverter(vertexFormat).convertArray; +} + +size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat) +{ + return formatConverter(vertexFormat).outputElementSize; +} + +VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat) +{ + return (formatConverter(vertexFormat).identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU); +} + +D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat) +{ + return formatConverter(vertexFormat).d3dDeclType; +} + +} + +namespace gl_d3d9 +{ + +D3DFORMAT GetTextureFormat(GLenum internalFormat, const Renderer9 *renderer) +{ + if (!renderer) + { + UNREACHABLE(); + return D3DFMT_UNKNOWN; + } + + ASSERT(renderer->getCurrentClientVersion() == 2); + + D3D9FormatInfo d3d9FormatInfo; + if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) + { + return d3d9FormatInfo.mTexFormat(renderer); + } + else + { + UNREACHABLE(); + return D3DFMT_UNKNOWN; + } +} + +D3DFORMAT GetRenderFormat(GLenum internalFormat, const Renderer9 *renderer) +{ + if (!renderer) + { + UNREACHABLE(); + return D3DFMT_UNKNOWN; + } + + ASSERT(renderer->getCurrentClientVersion() == 2); + + D3D9FormatInfo d3d9FormatInfo; + if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) + { + return d3d9FormatInfo.mRenderFormat(renderer); + } + else + { + UNREACHABLE(); + return D3DFMT_UNKNOWN; + } +} + +D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples) +{ + return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE; +} + +bool RequiresTextureDataInitialization(GLint internalFormat) +{ + const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); + return map.find(internalFormat) != map.end(); +} + +InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) +{ + const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); + InternalFormatInitialzerMap::const_iterator iter = map.find(internalFormat); + if (iter != map.end()) + { + return iter->second; + } + else + { + UNREACHABLE(); + return NULL; + } +} + +} + +namespace d3d9_gl +{ + +GLenum GetInternalFormat(D3DFORMAT format) +{ + static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); + D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); + if (iter != infoMap.end()) + { + return iter->second.mInternalFormat; + } + else + { + UNREACHABLE(); + return GL_NONE; + } +} + +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) +{ + return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; +} + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion) +{ + GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat); + GLenum convertedFormat = gl::GetFormat(internalFormat, clientVersion); + return convertedFormat == format; +} + +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.h new file mode 100644 index 00000000000..5b40c105443 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/formatutils9.h @@ -0,0 +1,77 @@ +// +// Copyright (c) 2013 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. +// + +// formatutils9.h: Queries for GL image formats and their translations to D3D9 +// formats. + +#ifndef LIBGLESV2_RENDERER_FORMATUTILS9_H_ +#define LIBGLESV2_RENDERER_FORMATUTILS9_H_ + +#include "libGLESv2/formatutils.h" + +namespace rx +{ + +class Renderer9; + +namespace d3d9 +{ + +typedef std::set<D3DFORMAT> D3DFormatSet; + +MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format); +LoadImageFunction GetImageLoadFunction(GLenum internalFormat, const Renderer9 *renderer); + +GLuint GetFormatPixelBytes(D3DFORMAT format); +GLuint GetBlockWidth(D3DFORMAT format); +GLuint GetBlockHeight(D3DFORMAT format); +GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height); + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + +const D3DFormatSet &GetAllUsedD3DFormats(); + +ColorReadFunction GetColorReadFunction(D3DFORMAT format); +ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion); + +VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat); +size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat); +VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat); +D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat); + +GLenum GetDeclTypeComponentType(D3DDECLTYPE declType); +int GetDeclTypeComponentCount(D3DDECLTYPE declType); +bool IsDeclTypeNormalized(D3DDECLTYPE declType); + +void InitializeVertexTranslations(const rx::Renderer9 *renderer); + +} + +namespace gl_d3d9 +{ + +D3DFORMAT GetTextureFormat(GLenum internalFormat, const Renderer9 *renderer); +D3DFORMAT GetRenderFormat(GLenum internalFormat, const Renderer9 *renderer); + +D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples); + +bool RequiresTextureDataInitialization(GLint internalFormat); +InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + +} + +namespace d3d9_gl +{ + +GLenum GetInternalFormat(D3DFORMAT format); +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion); + +} + +} + +#endif // LIBGLESV2_RENDERER_FORMATUTILS9_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/renderer9_utils.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp index da75d465e3c..48c378838d6 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/renderer9_utils.cpp +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp @@ -8,12 +8,15 @@ // renderer9_utils.cpp: Conversion functions and other utility routines // specific to the D3D9 renderer. -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/mathutil.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "common/mathutil.h" #include "libGLESv2/Context.h" #include "common/debug.h" +namespace rx +{ + namespace gl_d3d9 { @@ -36,7 +39,7 @@ D3DCMPFUNC ConvertComparison(GLenum comparison) return d3dComp; } -D3DCOLOR ConvertColor(gl::Color color) +D3DCOLOR ConvertColor(gl::ColorF color) { return D3DCOLOR_RGBA(gl::unorm<8>(color.red), gl::unorm<8>(color.green), @@ -80,6 +83,8 @@ D3DBLENDOP ConvertBlendOp(GLenum blendOp) case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break; case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break; case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break; + case GL_MIN_EXT: d3dBlendOp = D3DBLENDOP_MIN; break; + case GL_MAX_EXT: d3dBlendOp = D3DBLENDOP_MAX; break; default: UNREACHABLE(); } @@ -237,264 +242,6 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } -D3DFORMAT ConvertRenderbufferFormat(GLenum format) -{ - switch (format) - { - case GL_NONE: return D3DFMT_NULL; - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; - case GL_RGB565: return D3DFMT_R5G6B5; - case GL_RGB8_OES: return D3DFMT_X8R8G8B8; - case GL_DEPTH_COMPONENT16: - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; - default: UNREACHABLE(); return D3DFMT_A8R8G8B8; - } -} - -D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) -{ - if (samples <= 1) - return D3DMULTISAMPLE_NONE; - else - return (D3DMULTISAMPLE_TYPE)samples; -} - -} - -namespace d3d9_gl -{ - -unsigned int GetStencilSize(D3DFORMAT stencilFormat) -{ - if (stencilFormat == D3DFMT_INTZ) - { - return 8; - } - switch(stencilFormat) - { - case D3DFMT_D24FS8: - case D3DFMT_D24S8: - return 8; - case D3DFMT_D24X4S4: - return 4; - case D3DFMT_D15S1: - return 1; - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D32: - case D3DFMT_D24X8: - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_D16: - return 0; - //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only - //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only - default: - return 0; - } -} - -unsigned int GetAlphaSize(D3DFORMAT colorFormat) -{ - switch (colorFormat) - { - case D3DFMT_A16B16G16R16F: - return 16; - case D3DFMT_A32B32G32R32F: - return 32; - case D3DFMT_A2R10G10B10: - return 2; - case D3DFMT_A8R8G8B8: - return 8; - case D3DFMT_A1R5G5B5: - return 1; - case D3DFMT_X8R8G8B8: - case D3DFMT_R5G6B5: - return 0; - default: - return 0; - } -} - -GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) -{ - if (type == D3DMULTISAMPLE_NONMASKABLE) - return 0; - else - return type; -} - -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) -{ - switch (d3dformat) - { - case D3DFMT_L8: - return (format == GL_LUMINANCE); - case D3DFMT_A8L8: - return (format == GL_LUMINANCE_ALPHA); - case D3DFMT_DXT1: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT); - case D3DFMT_DXT3: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - case D3DFMT_DXT5: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - case D3DFMT_A8R8G8B8: - case D3DFMT_A16B16G16R16F: - case D3DFMT_A32B32G32R32F: - return (format == GL_RGBA || format == GL_BGRA_EXT); - case D3DFMT_X8R8G8B8: - return (format == GL_RGB); - default: - if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format)) - return true; - return false; - } -} - -GLenum ConvertBackBufferFormat(D3DFORMAT format) -{ - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - default: - UNREACHABLE(); - } - - return GL_RGBA4; -} - -GLenum ConvertDepthStencilFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return GL_DEPTH24_STENCIL8_OES; - } - switch (format) - { - case D3DFMT_D16: - case D3DFMT_D24X8: - return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: - return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_DEPTH24_STENCIL8_OES; -} - -GLenum ConvertRenderTargetFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return GL_DEPTH24_STENCIL8_OES; - } - - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - case D3DFMT_D16: - case D3DFMT_D24X8: - return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: - return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_RGBA4; -} - -GLenum GetEquivalentFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - return GL_DEPTH24_STENCIL8_OES; - if (format == D3DFMT_NULL) - return GL_NONE; - - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - case D3DFMT_D16: return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: return GL_NONE; - case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; - case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; - case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT; - case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT; - case D3DFMT_L8: return GL_LUMINANCE8_EXT; - case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT; - default: UNREACHABLE(); - return GL_NONE; - } -} - -} - -namespace d3d9 -{ - -bool IsCompressedFormat(D3DFORMAT surfaceFormat) -{ - switch(surfaceFormat) - { - case D3DFMT_DXT1: - case D3DFMT_DXT2: - case D3DFMT_DXT3: - case D3DFMT_DXT4: - case D3DFMT_DXT5: - return true; - default: - return false; - } -} - -size_t ComputeRowSize(D3DFORMAT format, unsigned int width) -{ - if (format == D3DFMT_INTZ) - { - return 4 * width; - } - switch (format) - { - case D3DFMT_L8: - return 1 * width; - case D3DFMT_A8L8: - return 2 * width; - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - return 4 * width; - case D3DFMT_A16B16G16R16F: - return 8 * width; - case D3DFMT_A32B32G32R32F: - return 16 * width; - case D3DFMT_DXT1: - return 8 * ((width + 3) / 4); - case D3DFMT_DXT3: - case D3DFMT_DXT5: - return 16 * ((width + 3) / 4); - default: - UNREACHABLE(); - return 0; - } } } diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/renderer9_utils.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h index bf6cdf1ea65..a115f9e3b9c 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/renderer9_utils.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h @@ -10,16 +10,16 @@ #ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H #define LIBGLESV2_RENDERER_RENDERER9_UTILS_H -#include "libGLESv2/utilities.h" +#include "libGLESv2/angletypes.h" -const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); -const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); +namespace rx +{ namespace gl_d3d9 { D3DCMPFUNC ConvertComparison(GLenum comparison); -D3DCOLOR ConvertColor(gl::Color color); +D3DCOLOR ConvertColor(gl::ColorF color); D3DBLEND ConvertBlendFunc(GLenum blend); D3DBLENDOP ConvertBlendOp(GLenum blendOp); D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); @@ -29,31 +29,11 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy); -D3DFORMAT ConvertRenderbufferFormat(GLenum format); -D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples); - -} - -namespace d3d9_gl -{ - -GLuint GetAlphaSize(D3DFORMAT colorFormat); -GLuint GetStencilSize(D3DFORMAT stencilFormat); - -GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); - -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); -GLenum ConvertBackBufferFormat(D3DFORMAT format); -GLenum ConvertDepthStencilFormat(D3DFORMAT format); -GLenum ConvertRenderTargetFormat(D3DFORMAT format); -GLenum GetEquivalentFormat(D3DFORMAT format); } namespace d3d9 { -bool IsCompressedFormat(D3DFORMAT format); -size_t ComputeRowSize(D3DFORMAT format, unsigned int width); inline bool isDeviceLostError(HRESULT errorCode) { @@ -71,4 +51,6 @@ inline bool isDeviceLostError(HRESULT errorCode) } +} + #endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps new file mode 100644 index 00000000000..dc357d0fa6a --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps @@ -0,0 +1,33 @@ +// +// Copyright (c) 2012 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. +// + +sampler2D tex : s0; + +uniform float4 mult : c0; +uniform float4 add : c1; + +// Passthrough Pixel Shader +// Outputs texture 0 sampled at texcoord 0. +float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR +{ + return tex2D(tex, texcoord.xy); +}; + +// Luminance Conversion Pixel Shader +// Performs a mad operation using the LA data from the texture with mult.xw and add.xw. +// Returns data in the form of llla +float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR +{ + return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy; +}; + +// RGB/A Component Mask Pixel Shader +// Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw. +// Returns data in the form of rgba +float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR +{ + return tex2D(tex, texcoord.xy) * mult + add; +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Blit.vs b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs index 3a36980b935..3a36980b935 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Blit.vs +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/luminanceps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h index f32d3f2f290..f370c47ebbb 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/luminanceps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h @@ -5,7 +5,8 @@ /// // Parameters: // -// float4 mode; +// float4 add; +// float4 mult; // sampler2D tex; // // @@ -13,7 +14,8 @@ // // Name Reg Size // ------------ ----- ---- -// mode c0 1 +// mult c0 1 +// add c1 1 // tex s0 1 // @@ -21,33 +23,37 @@ dcl t0.xy dcl_2d s0 texld r0, t0, s0 - mad r1.w, r0.w, c0.x, c0.y - mov r1.xyz, r0.x - mov oC0, r1 + mov r1, c0 + mad r0, r0, r1, c1 + mov oC0, r0 // approximately 4 instruction slots used (1 texture, 3 arithmetic) #endif -const BYTE g_ps20_luminanceps[] = +const BYTE g_ps20_componentmaskps[] = { 0, 2, 255, 255, 254, 255, - 44, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 119, 0, + 50, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 143, 0, 0, 0, 0, 2, 255, 255, - 2, 0, 0, 0, 28, 0, + 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, - 112, 0, 0, 0, 68, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 76, 0, + 136, 0, 0, 0, 88, 0, + 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, - 92, 0, 0, 0, 3, 0, + 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, - 96, 0, 0, 0, 0, 0, - 0, 0, 109, 111, 100, 101, - 0, 171, 171, 171, 1, 0, - 3, 0, 1, 0, 4, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 116, 101, 120, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 113, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 120, 0, 0, 0, + 0, 0, 0, 0, 97, 100, + 100, 0, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 109, 117, 108, 116, 0, 116, + 101, 120, 0, 171, 171, 171, 4, 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, @@ -67,13 +73,13 @@ const BYTE g_ps20_luminanceps[] = 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, + 228, 160, 1, 0, 0, 2, + 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, - 1, 0, 8, 128, 0, 0, - 255, 128, 0, 0, 0, 160, - 0, 0, 85, 160, 1, 0, - 0, 2, 1, 0, 7, 128, - 0, 0, 0, 128, 1, 0, + 0, 0, 15, 128, 0, 0, + 228, 128, 1, 0, 228, 128, + 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, - 1, 0, 228, 128, 255, 255, + 0, 0, 228, 128, 255, 255, 0, 0 }; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/flipyvs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h index 27d84c9f346..27d84c9f346 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/flipyvs.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h new file mode 100644 index 00000000000..0c9a14edf66 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h @@ -0,0 +1,95 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 +// +/// +// Parameters: +// +// float4 add; +// float4 mult; +// sampler2D tex; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// mult c0 1 +// add c1 1 +// tex s0 1 +// + + ps_2_0 + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mov r1.xw, c0 + mad r0.x, r0.x, r1.x, c1.x + mad r0.y, r0.w, r1.w, c1.w + mov r1.xyz, r0.x + mov r1.w, r0.y + mov oC0, r1 + +// approximately 7 instruction slots used (1 texture, 6 arithmetic) +#endif + +const BYTE g_ps20_luminanceps[] = +{ + 0, 2, 255, 255, 254, 255, + 50, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 143, 0, + 0, 0, 0, 2, 255, 255, + 3, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 136, 0, 0, 0, 88, 0, + 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 92, 0, + 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 113, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 120, 0, 0, 0, + 0, 0, 0, 0, 97, 100, + 100, 0, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 109, 117, 108, 116, 0, 116, + 101, 120, 0, 171, 171, 171, + 4, 0, 12, 0, 1, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 112, 115, + 95, 50, 95, 48, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 51, 48, 46, 57, 50, 48, + 48, 46, 49, 54, 51, 56, + 52, 0, 171, 171, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 3, 176, 31, 0, + 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 66, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 176, 0, 8, + 228, 160, 1, 0, 0, 2, + 1, 0, 9, 128, 0, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 1, 128, 0, 0, + 0, 128, 1, 0, 0, 128, + 1, 0, 0, 160, 4, 0, + 0, 4, 0, 0, 2, 128, + 0, 0, 255, 128, 1, 0, + 255, 128, 1, 0, 255, 160, + 1, 0, 0, 2, 1, 0, + 7, 128, 0, 0, 0, 128, + 1, 0, 0, 2, 1, 0, + 8, 128, 0, 0, 85, 128, + 1, 0, 0, 2, 0, 8, + 15, 128, 1, 0, 228, 128, + 255, 255, 0, 0 +}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughps.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h index 66059b84c37..66059b84c37 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/passthroughps.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/standardvs.h b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h index 0841cfb32e4..0841cfb32e4 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/standardvs.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat new file mode 100644 index 00000000000..d9c4ec1167f --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat @@ -0,0 +1,63 @@ +@ECHO OFF +REM +REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +REM Use of this source code is governed by a BSD-style license that can be +REM found in the LICENSE file. +REM + +PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.0\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 + +setlocal +set errorCount=0 +set successCount=0 +set debug=0 + +if "%1" == "debug" ( + set debug=1 +) +if "%1" == "release" ( + set debug=0 +) + +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Blit.vs standardvs vs_2_0 compiled\standardvs.h %debug% +call:BuildShader Blit.vs flipyvs vs_2_0 compiled\flipyvs.h %debug% +call:BuildShader Blit.ps passthroughps ps_2_0 compiled\passthroughps.h %debug% +call:BuildShader Blit.ps luminanceps ps_2_0 compiled\luminanceps.h %debug% +call:BuildShader Blit.ps componentmaskps ps_2_0 compiled\componentmaskps.h %debug% + +echo. + +if %successCount% GTR 0 ( + echo %successCount% shaders compiled successfully. +) +if %errorCount% GTR 0 ( + echo There were %errorCount% shader compilation errors. +) + +endlocal +exit /b + +:BuildShader +set input=%~1 +set entry=%~2 +set type=%~3 +set output=%~4 +set debug=%~5 + +if %debug% == 0 ( + set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" +) else ( + set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" +) + +set error=0 +%buildCMD% || set error=1 + +if %error% == 0 ( + set /a successCount=%successCount%+1 +) else ( + set /a errorCount=%errorCount%+1 +) + +exit /b diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/generatemip.h b/chromium/third_party/angle/src/libGLESv2/renderer/generatemip.h index 8e1973605b8..3177a2b1f39 100644 --- a/chromium/third_party/angle/src/libGLESv2/renderer/generatemip.h +++ b/chromium/third_party/angle/src/libGLESv2/renderer/generatemip.h @@ -10,194 +10,260 @@ #ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_ #define LIBGLESV2_RENDERER_GENERATEMIP_H_ -#include "libGLESv2/mathutil.h" +#include "common/mathutil.h" +#include "imageformats.h" namespace rx { -struct L8 + +namespace priv { - unsigned char L; - static void average(L8 *dst, const L8 *src1, const L8 *src2) - { - dst->L = ((src1->L ^ src2->L) >> 1) + (src1->L & src2->L); - } -}; +template <typename T> +static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch) +{ + return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch)); +} -typedef L8 R8; // R8 type is functionally equivalent for mip purposes -typedef L8 A8; // A8 type is functionally equivalent for mip purposes +template <typename T> +static inline const T *GetPixel(const void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch) +{ + return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch)); +} -struct A8L8 +template <typename T> +static void GenerateMip_Y(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - unsigned char L; - unsigned char A; + ASSERT(sourceWidth == 1); + ASSERT(sourceHeight > 1); + ASSERT(sourceDepth == 1); - static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) + for (unsigned int y = 0; y < destHeight; y++) { - *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); - } -}; + const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch); -typedef A8L8 R8G8; // R8G8 type is functionally equivalent for mip purposes + T::average(dst, src0, src1); + } +} -struct A8R8G8B8 +template <typename T> +static void GenerateMip_X(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - unsigned char B; - unsigned char G; - unsigned char R; - unsigned char A; + ASSERT(sourceWidth > 1); + ASSERT(sourceHeight == 1); + ASSERT(sourceDepth == 1); - static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) + for (unsigned int x = 0; x < destWidth; x++) { - *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); - } -}; + const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch); -typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes + T::average(dst, src0, src1); + } +} -struct A16B16G16R16F +template <typename T> +static void GenerateMip_Z(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - unsigned short R; - unsigned short G; - unsigned short B; - unsigned short A; + ASSERT(sourceWidth == 1); + ASSERT(sourceHeight == 1); + ASSERT(sourceDepth > 1); - static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2) + for (unsigned int z = 0; z < destDepth; z++) { - dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); - dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f); - dst->B = gl::float32ToFloat16((gl::float16ToFloat32(src1->B) + gl::float16ToFloat32(src2->B)) * 0.5f); - dst->A = gl::float32ToFloat16((gl::float16ToFloat32(src1->A) + gl::float16ToFloat32(src2->A)) * 0.5f); + const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch); + + T::average(dst, src0, src1); } -}; +} -struct R16F +template <typename T> +static void GenerateMip_XY(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - unsigned short R; + ASSERT(sourceWidth > 1); + ASSERT(sourceHeight > 1); + ASSERT(sourceDepth == 1); - static void average(R16F *dst, const R16F *src1, const R16F *src2) + for (unsigned int y = 0; y < destHeight; y++) { - dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); - } -}; + for (unsigned int x = 0; x < destWidth; x++) + { + const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch); + const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch); + const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch); -struct R16G16F -{ - unsigned short R; - unsigned short G; + T tmp0, tmp1; - static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) - { - dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f); - dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f); + T::average(&tmp0, src0, src1); + T::average(&tmp1, src2, src3); + T::average(dst, &tmp0, &tmp1); + } } -}; +} -struct A32B32G32R32F +template <typename T> +static void GenerateMip_YZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - float R; - float G; - float B; - float A; + ASSERT(sourceWidth == 1); + ASSERT(sourceHeight > 1); + ASSERT(sourceDepth > 1); - static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2) + for (unsigned int z = 0; z < destDepth; z++) { - dst->R = (src1->R + src2->R) * 0.5f; - dst->G = (src1->G + src2->G) * 0.5f; - dst->B = (src1->B + src2->B) * 0.5f; - dst->A = (src1->A + src2->A) * 0.5f; - } -}; + for (unsigned int y = 0; y < destHeight; y++) + { + const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch); -struct R32F -{ - float R; + T tmp0, tmp1; - static void average(R32F *dst, const R32F *src1, const R32F *src2) - { - dst->R = (src1->R + src2->R) * 0.5f; + T::average(&tmp0, src0, src1); + T::average(&tmp1, src2, src3); + T::average(dst, &tmp0, &tmp1); + } } -}; +} -struct R32G32F +template <typename T> +static void GenerateMip_XZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - float R; - float G; + ASSERT(sourceWidth > 1); + ASSERT(sourceHeight == 1); + ASSERT(sourceDepth > 1); - static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) + for (unsigned int z = 0; z < destDepth; z++) { - dst->R = (src1->R + src2->R) * 0.5f; - dst->G = (src1->G + src2->G) * 0.5f; - } -}; + for (unsigned int x = 0; x < destWidth; x++) + { + const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch); -struct R32G32B32F -{ - float R; - float G; - float B; + T tmp0, tmp1; - static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) - { - dst->R = (src1->R + src2->R) * 0.5f; - dst->G = (src1->G + src2->G) * 0.5f; - dst->B = (src1->B + src2->B) * 0.5f; + T::average(&tmp0, src0, src1); + T::average(&tmp1, src2, src3); + T::average(dst, &tmp0, &tmp1); + } } -}; +} template <typename T> -static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, - const unsigned char *sourceData, int sourcePitch, - unsigned char *destData, int destPitch) +static void GenerateMip_XYZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch) { - unsigned int mipWidth = std::max(1U, sourceWidth >> 1); - unsigned int mipHeight = std::max(1U, sourceHeight >> 1); + ASSERT(sourceWidth > 1); + ASSERT(sourceHeight > 1); + ASSERT(sourceDepth > 1); - if (sourceHeight == 1) + for (unsigned int z = 0; z < destDepth; z++) { - ASSERT(sourceWidth != 1); - - const T *src = (const T*)sourceData; - T *dst = (T*)destData; - - for (unsigned int x = 0; x < mipWidth; x++) + for (unsigned int y = 0; y < destHeight; y++) { - T::average(&dst[x], &src[x * 2], &src[x * 2 + 1]); + for (unsigned int x = 0; x < destWidth; x++) + { + const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch); + const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch); + T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch); + + T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + + T::average(&tmp0, src0, src1); + T::average(&tmp1, src2, src3); + T::average(&tmp2, src4, src5); + T::average(&tmp3, src6, src7); + + T::average(&tmp4, &tmp0, &tmp1); + T::average(&tmp5, &tmp2, &tmp3); + + T::average(dst, &tmp4, &tmp5); + } } } - else if (sourceWidth == 1) - { - ASSERT(sourceHeight != 1); +} - for (unsigned int y = 0; y < mipHeight; y++) - { - const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch); - const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch); - T *dst = (T*)(destData + y * destPitch); - T::average(dst, src0, src1); - } - } - else - { - for (unsigned int y = 0; y < mipHeight; y++) - { - const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch); - const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch); - T *dst = (T*)(destData + y * destPitch); +typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, + unsigned char *destData, int destRowPitch, int destDepthPitch); - for (unsigned int x = 0; x < mipWidth; x++) - { - T tmp0; - T tmp1; +template <typename T> +static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth) +{ + unsigned char index = ((sourceWidth > 1) ? 1 : 0) | + ((sourceHeight > 1) ? 2 : 0) | + ((sourceDepth > 1) ? 4 : 0); - T::average(&tmp0, &src0[x * 2], &src0[x * 2 + 1]); - T::average(&tmp1, &src1[x * 2], &src1[x * 2 + 1]); - T::average(&dst[x], &tmp0, &tmp1); - } - } + switch (index) + { + case 1: return GenerateMip_X<T>; // W x 1 x 1 + case 2: return GenerateMip_Y<T>; // 1 x H x 1 + case 3: return GenerateMip_XY<T>; // W x H x 1 + case 4: return GenerateMip_Z<T>; // 1 x 1 x D + case 5: return GenerateMip_XZ<T>; // W x 1 x D + case 6: return GenerateMip_YZ<T>; // 1 x H x D + case 7: return GenerateMip_XYZ<T>; // W x H x D + default: return NULL; } } + +} + +template <typename T> +static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, + const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, + unsigned char *destData, int destRowPitch, int destDepthPitch) +{ + unsigned int mipWidth = std::max(1U, sourceWidth >> 1); + unsigned int mipHeight = std::max(1U, sourceHeight >> 1); + unsigned int mipDepth = std::max(1U, sourceDepth >> 1); + + priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth); + ASSERT(generationFunction != NULL); + + generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch, + mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch); +} + } #endif // LIBGLESV2_RENDERER_GENERATEMIP_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/imageformats.h b/chromium/third_party/angle/src/libGLESv2/renderer/imageformats.h new file mode 100644 index 00000000000..1fd93fe56e1 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/imageformats.h @@ -0,0 +1,2029 @@ +// +// Copyright (c) 2013 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. +// + +// imageformats.h: Defines image format types with functions for mip generation +// and copying. + +#ifndef LIBGLESV2_RENDERER_IMAGEFORMATS_H_ +#define LIBGLESV2_RENDERER_IMAGEFORMATS_H_ + +#include "libGLESv2/angletypes.h" + +namespace rx +{ + +// Several structures share functionality for reading, writing or mipmapping but the layout +// must match the texture format which the structure represents. If collapsing or typedefing +// structs in this header, make sure the functionality and memory layout is exactly the same. + +struct L8 +{ + unsigned char L; + + static void readColor(gl::ColorF *dst, const L8 *src) + { + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; + } + + static void writeColor(L8 *dst, const gl::ColorF *src) + { + dst->L = gl::floatToNormalized<unsigned char>((src->red + src->green + src->blue) / 3.0f); + } + + static void average(L8 *dst, const L8 *src1, const L8 *src2) + { + dst->L = gl::average(src1->L, src2->L); + } +}; + +struct R8 +{ + unsigned char R; + + static void readColor(gl::ColorF *dst, const R8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R8 *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + } + + static void writeColor(R8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + } + + static void average(R8 *dst, const R8 *src1, const R8 *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct A8 +{ + unsigned char A; + + static void readColor(gl::ColorF *dst, const A8 *src) + { + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void writeColor(A8 *dst, const gl::ColorF *src) + { + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void average(A8 *dst, const A8 *src1, const A8 *src2) + { + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct L8A8 +{ + unsigned char L; + unsigned char A; + + static void readColor(gl::ColorF *dst, const L8A8 *src) + { + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void writeColor(L8A8 *dst, const gl::ColorF *src) + { + dst->L = gl::floatToNormalized<unsigned char>((src->red + src->green + src->blue) / 3.0f); + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) + { + *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); + } +}; + +struct A8L8 +{ + unsigned char A; + unsigned char L; + + static void readColor(gl::ColorF *dst, const A8L8 *src) + { + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void writeColor(A8L8 *dst, const gl::ColorF *src) + { + dst->L = gl::floatToNormalized<unsigned char>((src->red + src->green + src->blue) / 3.0f); + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) + { + *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); + } +}; + +struct R8G8 +{ + unsigned char R; + unsigned char G; + + static void readColor(gl::ColorF *dst, const R8G8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R8G8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R8G8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + } + + static void writeColor(R8G8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + } + + static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) + { + *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); + } +}; + +struct R8G8B8 +{ + unsigned char R; + unsigned char G; + unsigned char B; + + static void readColor(gl::ColorF *dst, const R8G8B8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R8G8B8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; + } + + static void writeColor(R8G8B8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + } + + static void writeColor(R8G8B8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + } + + static void average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct B8G8R8 +{ + unsigned char B; + unsigned char G; + unsigned char R; + + static void readColor(gl::ColorF *dst, const B8G8R8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const B8G8R8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; + } + + static void writeColor(B8G8R8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + } + + static void writeColor(B8G8R8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + } + + static void average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R5G6B5 +{ + unsigned short RGB; + + static void readColor(gl::ColorF *dst, const R5G6B5 *src) + { + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); + dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); + dst->alpha = 1.0f; + } + + static void writeColor(R5G6B5 *dst, const gl::ColorF *src) + { + dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | + gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); + } + + static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) + { + dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), gl::getShiftedData<5, 11>(src2->RGB))) | + gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), gl::getShiftedData<6, 5>(src2->RGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), gl::getShiftedData<5, 0>(src2->RGB))); + } +}; + +struct A8R8G8B8 +{ + unsigned char A; + unsigned char R; + unsigned char G; + unsigned char B; + + static void readColor(gl::ColorF *dst, const A8R8G8B8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorUI *dst, const A8R8G8B8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(A8R8G8B8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void writeColor(A8R8G8B8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + dst->A = static_cast<unsigned char>(src->alpha); + } + + static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) + { + *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); + } +}; + +struct R8G8B8A8 +{ + unsigned char R; + unsigned char G; + unsigned char B; + unsigned char A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorUI *dst, const R8G8B8A8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R8G8B8A8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void writeColor(R8G8B8A8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + dst->A = static_cast<unsigned char>(src->alpha); + } + + static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) + { + *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); + } +}; + +struct B8G8R8A8 +{ + unsigned char B; + unsigned char G; + unsigned char R; + unsigned char A; + + static void readColor(gl::ColorF *dst, const B8G8R8A8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorUI *dst, const B8G8R8A8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(B8G8R8A8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + dst->A = gl::floatToNormalized<unsigned char>(src->alpha); + } + + static void writeColor(B8G8R8A8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + dst->A = static_cast<unsigned char>(src->alpha); + } + + static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) + { + *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); + } +}; + +struct B8G8R8X8 +{ + unsigned char B; + unsigned char G; + unsigned char R; + unsigned char X; + + static void readColor(gl::ColorF *dst, const B8G8R8X8 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(B8G8R8X8 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned char>(src->red); + dst->G = gl::floatToNormalized<unsigned char>(src->green); + dst->B = gl::floatToNormalized<unsigned char>(src->blue); + dst->X = 255; + } + + static void writeColor(B8G8R8X8 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned char>(src->red); + dst->G = static_cast<unsigned char>(src->green); + dst->B = static_cast<unsigned char>(src->blue); + dst->X = 255; + } + + static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) + { + *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); + dst->X = 255; + } +}; + +struct B5G5R5A1 +{ + unsigned short BGRA; + + static void readColor(gl::ColorF *dst, const B5G5R5A1 *src) + { + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->BGRA)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->BGRA)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->BGRA)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->BGRA)); + } + + static void writeColor(B5G5R5A1 *dst, const gl::ColorF *src) + { + dst->BGRA = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | + gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) | + gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); + } + + static void average(B5G5R5A1 *dst, const B5G5R5A1 *src1, const B5G5R5A1 *src2) + { + dst->BGRA = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->BGRA), gl::getShiftedData<1, 15>(src2->BGRA))) | + gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->BGRA), gl::getShiftedData<5, 10>(src2->BGRA))) | + gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->BGRA), gl::getShiftedData<5, 5>(src2->BGRA))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->BGRA), gl::getShiftedData<5, 0>(src2->BGRA))); + } +}; + +struct R5G5B5A1 +{ + unsigned short RGBA; + + static void readColor(gl::ColorF *dst, const R5G5B5A1 *src) + { + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->RGBA)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->RGBA)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->RGBA)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGBA)); + } + + static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src) + { + dst->RGBA = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | + gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->blue)) | + gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->red)); + } + + static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) + { + dst->RGBA = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->RGBA), gl::getShiftedData<1, 15>(src2->RGBA))) | + gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->RGBA), gl::getShiftedData<5, 10>(src2->RGBA))) | + gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->RGBA), gl::getShiftedData<5, 5>(src2->RGBA))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGBA), gl::getShiftedData<5, 0>(src2->RGBA))); + } +}; + +struct R4G4B4A4 +{ + unsigned char R : 4; + unsigned char G : 4; + unsigned char B : 4; + unsigned char A : 4; + + static void readColor(gl::ColorF *dst, const R4G4B4A4 *src) + { + dst->red = gl::normalizedToFloat<4>(src->R); + dst->green = gl::normalizedToFloat<4>(src->G); + dst->blue = gl::normalizedToFloat<4>(src->B); + dst->alpha = gl::normalizedToFloat<4>(src->A); + } + + static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<4, unsigned char>(src->red); + dst->G = gl::floatToNormalized<4, unsigned char>(src->green); + dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); + dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); + } + + static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct A4R4G4B4 +{ + unsigned char A : 4; + unsigned char R : 4; + unsigned char G : 4; + unsigned char B : 4; + + static void readColor(gl::ColorF *dst, const A4R4G4B4 *src) + { + dst->red = gl::normalizedToFloat<4>(src->R); + dst->green = gl::normalizedToFloat<4>(src->G); + dst->blue = gl::normalizedToFloat<4>(src->B); + dst->alpha = gl::normalizedToFloat<4>(src->A); + } + + static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<4, unsigned char>(src->red); + dst->G = gl::floatToNormalized<4, unsigned char>(src->green); + dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); + dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); + } + + static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct B4G4R4A4 +{ + unsigned char B : 4; + unsigned char G : 4; + unsigned char R : 4; + unsigned char A : 4; + + static void readColor(gl::ColorF *dst, const B4G4R4A4 *src) + { + dst->red = gl::normalizedToFloat<4>(src->R); + dst->green = gl::normalizedToFloat<4>(src->G); + dst->blue = gl::normalizedToFloat<4>(src->B); + dst->alpha = gl::normalizedToFloat<4>(src->A); + } + + static void writeColor(B4G4R4A4 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<4, unsigned char>(src->red); + dst->G = gl::floatToNormalized<4, unsigned char>(src->green); + dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); + dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); + } + + static void average(B4G4R4A4 *dst, const B4G4R4A4 *src1, const B4G4R4A4 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R16 +{ + unsigned short R; + + static void readColor(gl::ColorF *dst, const R16 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R16 *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R16 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned short>(src->red); + } + + static void writeColor(R16 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned short>(src->red); + } + + static void average(R16 *dst, const R16 *src1, const R16 *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct R16G16 +{ + unsigned short R; + unsigned short G; + + static void readColor(gl::ColorF *dst, const R16G16 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R16G16 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R16G16 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned short>(src->red); + dst->G = gl::floatToNormalized<unsigned short>(src->green); + } + + static void writeColor(R16G16 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned short>(src->red); + dst->G = static_cast<unsigned short>(src->green); + } + + static void average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R16G16B16 +{ + unsigned short R; + unsigned short G; + unsigned short B; + + static void readColor(gl::ColorF *dst, const R16G16B16 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R16G16B16 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(R16G16B16 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned short>(src->red); + dst->G = gl::floatToNormalized<unsigned short>(src->green); + dst->B = gl::floatToNormalized<unsigned short>(src->blue); + } + + static void writeColor(R16G16B16 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned short>(src->red); + dst->G = static_cast<unsigned short>(src->green); + dst->B = static_cast<unsigned short>(src->blue); + } + + static void average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R16G16B16A16 +{ + unsigned short R; + unsigned short G; + unsigned short B; + unsigned short A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorUI *dst, const R16G16B16A16 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R16G16B16A16 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned short>(src->red); + dst->G = gl::floatToNormalized<unsigned short>(src->green); + dst->B = gl::floatToNormalized<unsigned short>(src->blue); + dst->A = gl::floatToNormalized<unsigned short>(src->alpha); + } + + static void writeColor(R16G16B16A16 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned short>(src->red); + dst->G = static_cast<unsigned short>(src->green); + dst->B = static_cast<unsigned short>(src->blue); + dst->A = static_cast<unsigned short>(src->alpha); + } + + static void average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R32 +{ + unsigned int R; + + static void readColor(gl::ColorF *dst, const R32 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R32 *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R32 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned int>(src->red); + } + + static void writeColor(R32 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned int>(src->red); + } + + static void average(R32 *dst, const R32 *src1, const R32 *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct R32G32 +{ + unsigned int R; + unsigned int G; + + static void readColor(gl::ColorF *dst, const R32G32 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R32G32 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R32G32 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned int>(src->red); + dst->G = gl::floatToNormalized<unsigned int>(src->green); + } + + static void writeColor(R32G32 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned int>(src->red); + dst->G = static_cast<unsigned int>(src->green); + } + + static void average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R32G32B32 +{ + unsigned int R; + unsigned int G; + unsigned int B; + + static void readColor(gl::ColorF *dst, const R32G32B32 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorUI *dst, const R32G32B32 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(R32G32B32 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned int>(src->red); + dst->G = gl::floatToNormalized<unsigned int>(src->green); + dst->B = gl::floatToNormalized<unsigned int>(src->blue); + } + + static void writeColor(R32G32B32 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned int>(src->red); + dst->G = static_cast<unsigned int>(src->green); + dst->B = static_cast<unsigned int>(src->blue); + } + + static void average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R32G32B32A32 +{ + unsigned int R; + unsigned int G; + unsigned int B; + unsigned int A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32 *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorUI *dst, const R32G32B32A32 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R32G32B32A32 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<unsigned int>(src->red); + dst->G = gl::floatToNormalized<unsigned int>(src->green); + dst->B = gl::floatToNormalized<unsigned int>(src->blue); + dst->A = gl::floatToNormalized<unsigned int>(src->alpha); + } + + static void writeColor(R32G32B32A32 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned int>(src->red); + dst->G = static_cast<unsigned int>(src->green); + dst->B = static_cast<unsigned int>(src->blue); + dst->A = static_cast<unsigned int>(src->alpha); + } + + static void average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R8S +{ + char R; + + static void readColor(gl::ColorF *dst, const R8S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R8S *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R8S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<char>(src->red); + } + + static void writeColor(R8S *dst, const gl::ColorI *src) + { + dst->R = static_cast<char>(src->red); + } + + static void average(R8S *dst, const R8S *src1, const R8S *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct R8G8S +{ + char R; + char G; + + static void readColor(gl::ColorF *dst, const R8G8S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R8G8S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R8G8S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<char>(src->red); + dst->G = gl::floatToNormalized<char>(src->green); + } + + static void writeColor(R8G8S *dst, const gl::ColorI *src) + { + dst->R = static_cast<char>(src->red); + dst->G = static_cast<char>(src->green); + } + + static void average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R8G8B8S +{ + char R; + char G; + char B; + + static void readColor(gl::ColorF *dst, const R8G8B8S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R8G8B8S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(R8G8B8S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<char>(src->red); + dst->G = gl::floatToNormalized<char>(src->green); + dst->B = gl::floatToNormalized<char>(src->blue); + } + + static void writeColor(R8G8B8S *dst, const gl::ColorI *src) + { + dst->R = static_cast<char>(src->red); + dst->G = static_cast<char>(src->green); + dst->B = static_cast<char>(src->blue); + } + + static void average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R8G8B8A8S +{ + char R; + char G; + char B; + char A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorI *dst, const R8G8B8A8S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R8G8B8A8S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<char>(src->red); + dst->G = gl::floatToNormalized<char>(src->green); + dst->B = gl::floatToNormalized<char>(src->blue); + dst->A = gl::floatToNormalized<char>(src->alpha); + } + + static void writeColor(R8G8B8A8S *dst, const gl::ColorI *src) + { + dst->R = static_cast<char>(src->red); + dst->G = static_cast<char>(src->green); + dst->B = static_cast<char>(src->blue); + dst->A = static_cast<char>(src->alpha); + } + + static void average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R16S +{ + short R; + + static void readColor(gl::ColorF *dst, const R16S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R16S *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R16S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<short>(src->red); + } + + static void writeColor(R16S *dst, const gl::ColorI *src) + { + dst->R = static_cast<short>(src->red); + } + + static void average(R16S *dst, const R16S *src1, const R16S *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct R16G16S +{ + short R; + short G; + + static void readColor(gl::ColorF *dst, const R16G16S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R16G16S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R16G16S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<short>(src->red); + dst->G = gl::floatToNormalized<short>(src->green); + } + + static void writeColor(R16G16S *dst, const gl::ColorI *src) + { + dst->R = static_cast<short>(src->red); + dst->G = static_cast<short>(src->green); + } + + static void average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R16G16B16S +{ + short R; + short G; + short B; + + static void readColor(gl::ColorF *dst, const R16G16B16S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R16G16B16S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(R16G16B16S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<short>(src->red); + dst->G = gl::floatToNormalized<short>(src->green); + dst->B = gl::floatToNormalized<short>(src->blue); + } + + static void writeColor(R16G16B16S *dst, const gl::ColorI *src) + { + dst->R = static_cast<short>(src->red); + dst->G = static_cast<short>(src->green); + dst->B = static_cast<short>(src->blue); + } + + static void average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R16G16B16A16S +{ + short R; + short G; + short B; + short A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorI *dst, const R16G16B16A16S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R16G16B16A16S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<short>(src->red); + dst->G = gl::floatToNormalized<short>(src->green); + dst->B = gl::floatToNormalized<short>(src->blue); + dst->A = gl::floatToNormalized<short>(src->alpha); + } + + static void writeColor(R16G16B16A16S *dst, const gl::ColorI *src) + { + dst->R = static_cast<short>(src->red); + dst->G = static_cast<short>(src->green); + dst->B = static_cast<short>(src->blue); + dst->A = static_cast<short>(src->alpha); + } + + static void average(R16G16B16A16S *dst, const R16G16B16A16S *src1, const R16G16B16A16S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R32S +{ + int R; + + static void readColor(gl::ColorF *dst, const R32S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R32S *src) + { + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R32S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<int>(src->red); + } + + static void writeColor(R32S *dst, const gl::ColorI *src) + { + dst->R = static_cast<int>(src->red); + } + + static void average(R32S *dst, const R32S *src1, const R32S *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct R32G32S +{ + int R; + int G; + + static void readColor(gl::ColorF *dst, const R32G32S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R32G32S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; + } + + static void writeColor(R32G32S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<int>(src->red); + dst->G = gl::floatToNormalized<int>(src->green); + } + + static void writeColor(R32G32S *dst, const gl::ColorI *src) + { + dst->R = static_cast<int>(src->red); + dst->G = static_cast<int>(src->green); + } + + static void average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R32G32B32S +{ + int R; + int G; + int B; + + static void readColor(gl::ColorF *dst, const R32G32B32S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; + } + + static void readColor(gl::ColorI *dst, const R32G32B32S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; + } + + static void writeColor(R32G32B32S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<int>(src->red); + dst->G = gl::floatToNormalized<int>(src->green); + dst->B = gl::floatToNormalized<int>(src->blue); + } + + static void writeColor(R32G32B32S *dst, const gl::ColorI *src) + { + dst->R = static_cast<int>(src->red); + dst->G = static_cast<int>(src->green); + dst->B = static_cast<int>(src->blue); + } + + static void average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R32G32B32A32S +{ + int R; + int G; + int B; + int A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32S *src) + { + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); + } + + static void readColor(gl::ColorI *dst, const R32G32B32A32S *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R32G32B32A32S *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<int>(src->red); + dst->G = gl::floatToNormalized<int>(src->green); + dst->B = gl::floatToNormalized<int>(src->blue); + dst->A = gl::floatToNormalized<int>(src->alpha); + } + + static void writeColor(R32G32B32A32S *dst, const gl::ColorI *src) + { + dst->R = static_cast<int>(src->red); + dst->G = static_cast<int>(src->green); + dst->B = static_cast<int>(src->blue); + dst->A = static_cast<int>(src->alpha); + } + + static void average(R32G32B32A32S *dst, const R32G32B32A32S *src1, const R32G32B32A32S *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct A16B16G16R16F +{ + unsigned short A; + unsigned short R; + unsigned short G; + unsigned short B; + + static void readColor(gl::ColorF *dst, const A16B16G16R16F *src) + { + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); + } + + static void writeColor(A16B16G16R16F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); + } + + static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2) + { + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); + } +}; + +struct R16G16B16A16F +{ + unsigned short R; + unsigned short G; + unsigned short B; + unsigned short A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16F *src) + { + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); + } + + static void writeColor(R16G16B16A16F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); + } + + static void average(R16G16B16A16F *dst, const R16G16B16A16F *src1, const R16G16B16A16F *src2) + { + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); + } +}; + +struct R16F +{ + unsigned short R; + + static void readColor(gl::ColorF *dst, const R16F *src) + { + dst->red = gl::float16ToFloat32(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void writeColor(R16F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat16(src->red); + } + + static void average(R16F *dst, const R16F *src1, const R16F *src2) + { + dst->R = gl::averageHalfFloat(src1->R, src2->R); + } +}; + +struct A16F +{ + unsigned short A; + + static void readColor(gl::ColorF *dst, const A16F *src) + { + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::float16ToFloat32(src->A); + } + + static void writeColor(A16F *dst, const gl::ColorF *src) + { + dst->A = gl::float32ToFloat16(src->alpha); + } + + static void average(A16F *dst, const A16F *src1, const A16F *src2) + { + dst->A = gl::averageHalfFloat(src1->A, src2->A); + } +}; + +struct L16F +{ + unsigned short L; + + static void readColor(gl::ColorF *dst, const L16F *src) + { + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; + } + + static void writeColor(L16F *dst, const gl::ColorF *src) + { + dst->L = gl::float32ToFloat16((src->red + src->green + src->blue) / 3.0f); + } + + static void average(L16F *dst, const L16F *src1, const L16F *src2) + { + dst->L = gl::averageHalfFloat(src1->L, src2->L); + } +}; + +struct L16A16F +{ + unsigned short L; + unsigned short A; + + static void readColor(gl::ColorF *dst, const L16A16F *src) + { + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::float16ToFloat32(src->A); + } + + static void writeColor(L16A16F *dst, const gl::ColorF *src) + { + dst->L = gl::float32ToFloat16((src->red + src->green + src->blue) / 3.0f); + dst->A = gl::float32ToFloat16(src->alpha); + } + + static void average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2) + { + dst->L = gl::averageHalfFloat(src1->L, src2->L); + dst->A = gl::averageHalfFloat(src1->A, src2->A); + } +}; + +struct R16G16F +{ + unsigned short R; + unsigned short G; + + static void readColor(gl::ColorF *dst, const R16G16F *src) + { + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void writeColor(R16G16F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + } + + static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) + { + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + } +}; + +struct R16G16B16F +{ + unsigned short R; + unsigned short G; + unsigned short B; + + static void readColor(gl::ColorF *dst, const R16G16B16F *src) + { + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = 1.0f; + } + + static void writeColor(R16G16B16F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + } + + static void average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2) + { + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + } +}; + +struct A32B32G32R32F +{ + float A; + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const A32B32G32R32F *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(A32B32G32R32F *dst, const gl::ColorF *src) + { + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; + } + + static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R32G32B32A32F +{ + float R; + float G; + float B; + float A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32F *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R32G32B32A32F *dst, const gl::ColorF *src) + { + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; + } + + static void average(R32G32B32A32F *dst, const R32G32B32A32F *src1, const R32G32B32A32F *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R32F +{ + float R; + + static void readColor(gl::ColorF *dst, const R32F *src) + { + dst->red = src->R; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void writeColor(R32F *dst, const gl::ColorF *src) + { + dst->R = src->red; + } + + static void average(R32F *dst, const R32F *src1, const R32F *src2) + { + dst->R = gl::average(src1->R, src2->R); + } +}; + +struct A32F +{ + float A; + + static void readColor(gl::ColorF *dst, const A32F *src) + { + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = src->A; + } + + static void writeColor(A32F *dst, const gl::ColorF *src) + { + dst->A = src->alpha; + } + + static void average(A32F *dst, const A32F *src1, const A32F *src2) + { + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct L32F +{ + float L; + + static void readColor(gl::ColorF *dst, const L32F *src) + { + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = 1.0f; + } + + static void writeColor(L32F *dst, const gl::ColorF *src) + { + dst->L = (src->red + src->green + src->blue) / 3.0f; + } + + static void average(L32F *dst, const L32F *src1, const L32F *src2) + { + dst->L = gl::average(src1->L, src2->L); + } +}; + +struct L32A32F +{ + float L; + float A; + + static void readColor(gl::ColorF *dst, const L32A32F *src) + { + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = src->A; + } + + static void writeColor(L32A32F *dst, const gl::ColorF *src) + { + dst->L = (src->red + src->green + src->blue) / 3.0f; + dst->A = src->alpha; + } + + static void average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2) + { + dst->L = gl::average(src1->L, src2->L); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R32G32F +{ + float R; + float G; + + static void readColor(gl::ColorF *dst, const R32G32F *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = 0.0f; + dst->alpha = 1.0f; + } + + static void writeColor(R32G32F *dst, const gl::ColorF *src) + { + dst->R = src->red; + dst->G = src->green; + } + + static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + } +}; + +struct R32G32B32F +{ + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const R32G32B32F *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1.0f; + } + + static void writeColor(R32G32B32F *dst, const gl::ColorF *src) + { + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + } + + static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + } +}; + +struct R10G10B10A2 +{ + unsigned int R : 10; + unsigned int G : 10; + unsigned int B : 10; + unsigned int A : 2; + + static void readColor(gl::ColorF *dst, const R10G10B10A2 *src) + { + dst->red = gl::normalizedToFloat<10>(src->R); + dst->green = gl::normalizedToFloat<10>(src->G); + dst->blue = gl::normalizedToFloat<10>(src->B); + dst->alpha = gl::normalizedToFloat< 2>(src->A); + } + + static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src) + { + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; + } + + static void writeColor(R10G10B10A2 *dst, const gl::ColorF *src) + { + dst->R = gl::floatToNormalized<10, unsigned int>(src->red); + dst->G = gl::floatToNormalized<10, unsigned int>(src->green); + dst->B = gl::floatToNormalized<10, unsigned int>(src->blue); + dst->A = gl::floatToNormalized< 2, unsigned int>(src->alpha); + } + + static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) + { + dst->R = static_cast<unsigned int>(src->red); + dst->G = static_cast<unsigned int>(src->green); + dst->B = static_cast<unsigned int>(src->blue); + dst->A = static_cast<unsigned int>(src->alpha); + } + + static void average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2) + { + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); + } +}; + +struct R9G9B9E5 +{ + unsigned int R : 9; + unsigned int G : 9; + unsigned int B : 9; + unsigned int E : 5; + + static void readColor(gl::ColorF *dst, const R9G9B9E5 *src) + { + gl::convert999E5toRGBFloats(gl::bitCast<unsigned int>(*src), &dst->red, &dst->green, &dst->blue); + dst->alpha = 1.0f; + } + + static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src) + { + *reinterpret_cast<unsigned int*>(dst) = gl::convertRGBFloatsTo999E5(src->red, + src->green, + src->blue); + } + + static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) + { + float r1, g1, b1; + gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int*>(src1), &r1, &g1, &b1); + + float r2, g2, b2; + gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int*>(src2), &r2, &g2, &b2); + + *reinterpret_cast<unsigned int*>(dst) = gl::convertRGBFloatsTo999E5(gl::average(r1, r2), + gl::average(g1, g2), + gl::average(b1, b2)); + } +}; + +struct R11G11B10F +{ + unsigned int R : 11; + unsigned int G : 11; + unsigned int B : 10; + + static void readColor(gl::ColorF *dst, const R11G11B10F *src) + { + dst->red = gl::float11ToFloat32(src->R); + dst->green = gl::float11ToFloat32(src->G); + dst->blue = gl::float10ToFloat32(src->B); + dst->alpha = 1.0f; + } + + static void writeColor(R11G11B10F *dst, const gl::ColorF *src) + { + dst->R = gl::float32ToFloat11(src->red); + dst->G = gl::float32ToFloat11(src->green); + dst->B = gl::float32ToFloat10(src->blue); + } + + static void average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2) + { + dst->R = gl::averageFloat11(src1->R, src2->R); + dst->G = gl::averageFloat11(src1->G, src2->G); + dst->B = gl::averageFloat10(src1->B, src2->B); + } +}; + +} + +#endif // LIBGLESV2_RENDERER_IMAGEFORMATS_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.cpp new file mode 100644 index 00000000000..6e2d2460a52 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.cpp @@ -0,0 +1,951 @@ +#include "precompiled.h" +// +// Copyright (c) 0013 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. +// + +// loadimage.cpp: Defines image loading functions. + +#include "libGLESv2/renderer/loadimage.h" + +namespace rx +{ + +void loadAlphaDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = 0; + dest[4 * x + 1] = 0; + dest[4 * x + 2] = 0; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void loadAlphaDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width); + } + } +} + +void loadAlphaFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = 0; + dest[4 * x + 1] = 0; + dest[4 * x + 2] = 0; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = 0; + dest[4 * x + 1] = 0; + dest[4 * x + 2] = 0; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void loadLuminanceDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width); + } + } +} + +void loadLuminanceDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadLuminanceFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 1.0f; + } + } + } +} + +void loadLuminanceFloatDataToRGB(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[3 * x + 0] = source[x]; + dest[3 * x + 1] = source[x]; + dest[3 * x + 2] = source[x]; + } + } + } +} + +void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = gl::Float16One; + } + } + } +} + +void loadLuminanceAlphaDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + + memcpy(dest, source, width * 2); + } + } +} + +void loadLuminanceAlphaDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2*x+0]; + dest[4 * x + 1] = source[2*x+0]; + dest[4 * x + 2] = source[2*x+0]; + dest[4 * x + 3] = source[2*x+1]; + } + } + } +} + +void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2*x+0]; + dest[4 * x + 1] = source[2*x+0]; + dest[4 * x + 2] = source[2*x+0]; + dest[4 * x + 3] = source[2*x+1]; + } + } + } +} + +void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2*x+0]; + dest[4 * x + 1] = source[2*x+0]; + dest[4 * x + 2] = source[2*x+0]; + dest[4 * x + 3] = source[2*x+1]; + } + } + } +} + +void loadRGBUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 2]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRGUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = source[x * 2 + 1]; + dest[4 * x + 2] = source[x * 2 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = 0x00; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRGBUByteDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 0]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 2]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRGBSByteDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const char *source = NULL; + char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 0]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 2]; + dest[4 * x + 3] = 0x7F; + } + } + } +} + +void loadRGB565DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2); + dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9); + dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRGB565DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); + dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9); + dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void loadRGBFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 0]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 2]; + dest[4 * x + 3] = 1.0f; + } + } + } +} + +void loadRGBFloatDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width * 12); + } + } +} + +void loadRGBHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 0]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 2]; + dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1 + } + } + } +} + +void loadRGBAUByteDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } +} + +void loadRGBAUByteDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + memcpy(dest, source, width * 4); + } + } +} + +void loadRGBA4444DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); + dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); + dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); + dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); + } + } + } +} + +void loadRGBA4444DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12); + dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8); + dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4); + dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0); + } + } + } +} + +void loadRGBA5551DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); + dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); + dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); + dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0; + } + } + } +} +void loadRGBA5551DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + for (int x = 0; x < width; x++) + { + unsigned short rgba = source[x]; + dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13); + dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8); + dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3); + dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0; + } + } + } +} + +void loadRGBAFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + float *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width * 16); + } + } +} + +void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width * 8); + } + } +} + +void loadBGRADataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned char *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width*4); + } + } +} + +void loadRGBA2101010ToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width * sizeof(unsigned int)); + } + } +} + +void loadRGBA2101010ToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned char *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + unsigned int rgba = source[x]; + dest[4 * x + 0] = (rgba & 0x000003FF) >> 2; + dest[4 * x + 1] = (rgba & 0x000FFC00) >> 12; + dest[4 * x + 2] = (rgba & 0x3FF00000) >> 22; + dest[4 * x + 3] = ((rgba & 0xC0000000) >> 30) * 0x55; + } + } + } +} + +void loadRGBHalfFloatDataTo999E5(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]), + gl::float16ToFloat32(source[x * 3 + 1]), + gl::float16ToFloat32(source[x * 3 + 2])); + } + } + } +} + +void loadRGBFloatDataTo999E5(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]); + } + } + } +} + +void loadRGBHalfFloatDataTo111110Float(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned short *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) | + (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) | + (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22); + } + } + } +} + +void loadRGBFloatDataTo111110Float(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) | + (gl::float32ToFloat11(source[x * 3 + 1]) << 11) | + (gl::float32ToFloat10(source[x * 3 + 2]) << 22); + } + } + } +} + + +void loadG8R24DataToR24G8(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned int *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<const unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + unsigned int d = source[x] >> 8; + unsigned int s = source[x] & 0xFF; + dest[x] = d | (s << 24); + } + } + } +} + +void loadFloatRGBDataToHalfFloatRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]); + dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]); + dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]); + dest[x * 4 + 3] = gl::Float16One; + } + } + } +} + +void loadUintDataToUshort(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int *source = NULL; + unsigned short *dest = NULL; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x] = source[x] >> 16; + } + } + } +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.h b/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.h new file mode 100644 index 00000000000..537a5e4c170 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/loadimage.h @@ -0,0 +1,343 @@ +// +// Copyright (c) 2013 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. +// + +// loadimage.h: Defines image loading functions + +#ifndef LIBGLESV2_RENDERER_LOADIMAGE_H_ +#define LIBGLESV2_RENDERER_LOADIMAGE_H_ + +#include "common/mathutil.h" + +namespace rx +{ + +template <typename T> +inline static T *offsetDataPointer(void *data, int y, int z, int rowPitch, int depthPitch) +{ + return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (y * rowPitch) + (z * depthPitch)); +} + +template <typename T> +inline static const T *offsetDataPointer(const void *data, int y, int z, int rowPitch, int depthPitch) +{ + return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (y * rowPitch) + (z * depthPitch)); +} + +void loadAlphaDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadAlphaDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadAlphaDataToBGRASSE2(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadAlphaFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceFloatDataToRGB(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceAlphaDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceAlphaDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRUByteDataToBGRX(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBUByteDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBSByteDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGB565DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGB565DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBFloatDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBAUByteDataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBAUByteDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA4444DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA4444DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA5551DataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA5551DataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBAFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadBGRADataToBGRA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA2101010ToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBA2101010ToRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBHalfFloatDataTo999E5(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBFloatDataTo999E5(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBHalfFloatDataTo111110Float(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadRGBFloatDataTo111110Float(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +void loadG8R24DataToR24G8(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +template <typename type, unsigned int componentCount> +void loadToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const unsigned int rowSize = width * sizeof(type) * componentCount; + const unsigned int layerSize = rowSize * height; + const unsigned int imageSize = layerSize * depth; + + if (layerSize == inputDepthPitch && layerSize == outputDepthPitch) + { + ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch); + memcpy(output, input, imageSize); + } + else if (rowSize == inputRowPitch && rowSize == outputRowPitch) + { + for (int z = 0; z < depth; z++) + { + const type *source = offsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch); + type *dest = offsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch); + + memcpy(dest, source, layerSize); + } + } + else + { + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + const type *source = offsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); + type *dest = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + memcpy(dest, source, width * sizeof(type) * componentCount); + } + } + } +} + +template <typename type, unsigned int fourthComponentBits> +void loadToNative3To4(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const type *source = NULL; + type *dest = NULL; + + const unsigned int fourthBits = fourthComponentBits; + const type fourthValue = *reinterpret_cast<const type*>(&fourthBits); + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + dest[x * 4 + 0] = source[x * 3 + 0]; + dest[x * 4 + 1] = source[x * 3 + 1]; + dest[x * 4 + 2] = source[x * 3 + 2]; + dest[x * 4 + 3] = fourthValue; + } + } + } +} + +template <unsigned int componentCount> +void loadFloatDataToHalfFloat(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + const float *source = NULL; + unsigned short *dest = NULL; + + const int elementWidth = componentCount * width; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < elementWidth; x++) + { + dest[x] = gl::float32ToFloat16(source[x]); + } + } + } +} + +void loadFloatRGBDataToHalfFloatRGBA(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +template <unsigned int blockWidth, unsigned int blockHeight, unsigned int blockSize> +void loadCompressedBlockDataToNative(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + int columns = (width + (blockWidth - 1)) / blockWidth; + int rows = (height + (blockHeight - 1)) / blockHeight; + + for (int z = 0; z < depth; ++z) + { + for (int y = 0; y < rows; ++y) + { + void *source = (void*)((char*)input + y * inputRowPitch + z * inputDepthPitch); + void *dest = (void*)((char*)output + y * outputRowPitch + z * outputDepthPitch); + + memcpy(dest, source, columns * blockSize); + } + } +} + +void loadUintDataToUshort(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch); + +template <typename type, unsigned int firstBits, unsigned int secondBits, unsigned int thirdBits, unsigned int fourthBits> +void initialize4ComponentData(int width, int height, int depth, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) +{ + unsigned int writeBits[4] = { firstBits, secondBits, thirdBits, fourthBits }; + type writeValues[4] = { *reinterpret_cast<const type*>(&writeBits[0]), + *reinterpret_cast<const type*>(&writeBits[1]), + *reinterpret_cast<const type*>(&writeBits[2]), + *reinterpret_cast<const type*>(&writeBits[3]) }; + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + type* destRow = offsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + + for (int x = 0; x < width; x++) + { + type* destPixel = destRow + x * 4; + + // This could potentially be optimized by generating an entire row of initialization + // data and copying row by row instead of pixel by pixel. + memcpy(destPixel, writeValues, sizeof(type) * 4); + } + } + } +} + +} + +#endif // LIBGLESV2_RENDERER_LOADIMAGE_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/loadimageSSE2.cpp new file mode 100644 index 00000000000..129e39bbe20 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/renderer/loadimageSSE2.cpp @@ -0,0 +1,107 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// loadimage.cpp: Defines image loading functions. It's +// in a separated file for GCC, which can enable SSE usage only per-file, +// not for code blocks that use SSE2 explicitly. + +#include "libGLESv2/renderer/loadimage.h" + +namespace rx +{ + + void loadAlphaDataToBGRASSE2(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) + { + const unsigned char *source = NULL; + unsigned int *dest = NULL; + __m128i zeroWide = _mm_setzero_si128(); + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch; + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch); + + int x; + // Make output writes aligned + for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++) + { + dest[x] = static_cast<unsigned int>(source[x]) << 24; + } + + for (; x + 7 < width; x += 8) + { + __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x])); + // Interleave each byte to 16bit, make the lower byte to zero + sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); + // Interleave each 16bit to 32bit, make the lower 16bit to zero + __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); + __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); + + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi); + } + + // Handle the remainder + for (; x < width; x++) + { + dest[x] = static_cast<unsigned int>(source[x]) << 24; + } + } + } + } + + void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth, + const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch, + void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch) + { + const unsigned int *source = NULL; + unsigned int *dest = NULL; + __m128i brMask = _mm_set1_epi32(0x00ff00ff); + + for (int z = 0; z < depth; z++) + { + for (int y = 0; y < height; y++) + { + source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch); + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch); + int x = 0; + + // Make output writes aligned + for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++) + { + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + + for (; x + 3 < width; x += 4) + { + __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x])); + // Mask out g and a, which don't change + __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); + // Mask out b and r + __m128i brComponents = _mm_and_si128(sourceData, brMask); + // Swap b and r + __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); + __m128i result = _mm_or_si128(gaComponents, brSwapped); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result); + } + + // Perform leftover writes + for (; x < width; x++) + { + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } + } + +} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.cpp deleted file mode 100644 index 13800da258c..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.cpp +++ /dev/null @@ -1,688 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// renderer11_utils.cpp: Conversion functions and other utility routines -// specific to the D3D11 renderer. - -#include "libGLESv2/renderer/renderer11_utils.h" - -#include "common/debug.h" - -namespace gl_d3d11 -{ - -D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) -{ - D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; - - switch (glBlend) - { - case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; - case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; - case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; - case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; - case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; - case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; - case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; - case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; - case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; - case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; - default: UNREACHABLE(); - } - - return d3dBlend; -} - -D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) -{ - D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; - - switch (glBlendOp) - { - case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; - case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; - case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; - default: UNREACHABLE(); - } - - return d3dBlendOp; -} - -UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) -{ - UINT8 mask = 0; - if (red) - { - mask |= D3D11_COLOR_WRITE_ENABLE_RED; - } - if (green) - { - mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; - } - if (blue) - { - mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; - } - if (alpha) - { - mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; - } - return mask; -} - -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) -{ - D3D11_CULL_MODE cull = D3D11_CULL_NONE; - - if (cullEnabled) - { - switch (cullMode) - { - case GL_FRONT: cull = D3D11_CULL_FRONT; break; - case GL_BACK: cull = D3D11_CULL_BACK; break; - case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; - default: UNREACHABLE(); - } - } - else - { - cull = D3D11_CULL_NONE; - } - - return cull; -} - -D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) -{ - D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; - switch (comparison) - { - case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; - case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; - case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; - case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; - case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; - case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; - case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; - case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; - default: UNREACHABLE(); - } - - return d3dComp; -} - -D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) -{ - return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; -} - -UINT8 ConvertStencilMask(GLuint stencilmask) -{ - return static_cast<UINT8>(stencilmask); -} - -D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) -{ - D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; - - switch (stencilOp) - { - case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; - case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; - case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; - case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; - case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; - case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; - case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; - case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; - default: UNREACHABLE(); - } - - return d3dStencilOp; -} - -D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) -{ - if (maxAnisotropy > 1.0f) - { - return D3D11_ENCODE_ANISOTROPIC_FILTER(false); - } - else - { - D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; - D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; - switch (minFilter) - { - case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; - switch (magFilter) - { - case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false); - } -} - -D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) -{ - switch (wrap) - { - case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; - case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; - case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; - default: UNREACHABLE(); - } - - return D3D11_TEXTURE_ADDRESS_WRAP; -} - -FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset) -{ - return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : -FLT_MAX; -} - -FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset) -{ - return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : FLT_MAX; -} - -} - -namespace d3d11_gl -{ - -GLenum ConvertBackBufferFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES; - case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -GLenum ConvertDepthStencilFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_UNKNOWN: return GL_NONE; - case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES; - default: - UNREACHABLE(); - } - - return GL_DEPTH24_STENCIL8_OES; -} - -GLenum ConvertRenderbufferFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_B8G8R8A8_UNORM: - return GL_BGRA8_EXT; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return GL_RGBA8_OES; - case DXGI_FORMAT_D16_UNORM: - return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return GL_DEPTH24_STENCIL8_OES; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -GLenum ConvertTextureInternalFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - return GL_RGBA8_OES; - case DXGI_FORMAT_A8_UNORM: - return GL_ALPHA8_EXT; - case DXGI_FORMAT_BC1_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case DXGI_FORMAT_BC2_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; - case DXGI_FORMAT_BC3_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return GL_RGBA32F_EXT; - case DXGI_FORMAT_R32G32B32_FLOAT: - return GL_RGB32F_EXT; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return GL_RGBA16F_EXT; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return GL_BGRA8_EXT; - case DXGI_FORMAT_R8_UNORM: - return GL_R8_EXT; - case DXGI_FORMAT_R8G8_UNORM: - return GL_RG8_EXT; - case DXGI_FORMAT_R16_FLOAT: - return GL_R16F_EXT; - case DXGI_FORMAT_R16G16_FLOAT: - return GL_RG16F_EXT; - case DXGI_FORMAT_D16_UNORM: - return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return GL_DEPTH24_STENCIL8_OES; - case DXGI_FORMAT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -} - -namespace gl_d3d11 -{ - -DXGI_FORMAT ConvertRenderbufferFormat(GLenum format) -{ - switch (format) - { - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8_OES: - case GL_RGB565: - case GL_RGB8_OES: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case GL_BGRA8_EXT: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case GL_DEPTH_COMPONENT16: - return DXGI_FORMAT_D16_UNORM; - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - default: - UNREACHABLE(); - } - - return DXGI_FORMAT_R8G8B8A8_UNORM; -} - -DXGI_FORMAT ConvertTextureFormat(GLenum internalformat) -{ - switch (internalformat) - { - case GL_RGB565: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB8_OES: - case GL_RGBA8_OES: - case GL_LUMINANCE8_EXT: - case GL_LUMINANCE8_ALPHA8_EXT: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case GL_ALPHA8_EXT: - return DXGI_FORMAT_A8_UNORM; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return DXGI_FORMAT_BC1_UNORM; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - return DXGI_FORMAT_BC2_UNORM; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return DXGI_FORMAT_BC3_UNORM; - case GL_RGBA32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case GL_RGB32F_EXT: - case GL_LUMINANCE32F_EXT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case GL_RGBA16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - case GL_RGB16F_EXT: - case GL_LUMINANCE16F_EXT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case GL_BGRA8_EXT: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case GL_R8_EXT: - return DXGI_FORMAT_R8_UNORM; - case GL_RG8_EXT: - return DXGI_FORMAT_R8G8_UNORM; - case GL_R16F_EXT: - return DXGI_FORMAT_R16_FLOAT; - case GL_RG16F_EXT: - return DXGI_FORMAT_R16G16_FLOAT; - case GL_DEPTH_COMPONENT16: - return DXGI_FORMAT_D16_UNORM; - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH24_STENCIL8_OES: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - case GL_NONE: - return DXGI_FORMAT_UNKNOWN; - default: - UNREACHABLE(); - } - - return DXGI_FORMAT_R8G8B8A8_UNORM; -} - -} - -namespace d3d11 -{ - -void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) -{ - vertex->x = x; - vertex->y = y; - vertex->u = u; - vertex->v = v; -} - -void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, - const gl::Color &color) -{ - vertex->x = x; - vertex->y = y; - vertex->z = z; - vertex->r = color.red; - vertex->g = color.green; - vertex->b = color.blue; - vertex->a = color.alpha; -} - -size_t ComputePixelSizeBits(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R1_UNORM: - return 1; - - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_UNORM: - return 8; - - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_UNORM: - return 16; - - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - return 32; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - return 64; - - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_UINT: - return 96; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_UINT: - return 128; - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - return 4; - - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 8; - - default: - return 0; - } -} - -size_t ComputeBlockSizeBits(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return ComputePixelSizeBits(format) * 16; - default: - UNREACHABLE(); - return 0; - } -} - -bool IsCompressed(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return true; - case DXGI_FORMAT_UNKNOWN: - UNREACHABLE(); - return false; - default: - return false; - } -} - -unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 4; - case DXGI_FORMAT_UNKNOWN: - UNREACHABLE(); - return 1; - default: - return 1; - } -} - -bool IsDepthStencilFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D16_UNORM: - return true; - default: - return false; - } -} - -DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS; - case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24G8_TYPELESS; - case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS; - default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; - } -} - -DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_UINT; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_UNORM; - default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; - } -} - -HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) -{ -#if defined(_DEBUG) - return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); -#else - return S_OK; -#endif -} - -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.h b/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.h deleted file mode 100644 index 1bc48c1a135..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/renderer11_utils.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// renderer11_utils.h: Conversion functions and other utility routines -// specific to the D3D11 renderer. - -#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H -#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H - -#include "libGLESv2/angletypes.h" - -namespace gl_d3d11 -{ - -D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); -D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); -UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); - -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode); - -D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); -D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); -UINT8 ConvertStencilMask(GLuint stencilmask); -D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); - -D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy); -D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); -FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset); -FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset); - -DXGI_FORMAT ConvertRenderbufferFormat(GLenum format); -DXGI_FORMAT ConvertTextureFormat(GLenum format); -} - -namespace d3d11_gl -{ - -GLenum ConvertBackBufferFormat(DXGI_FORMAT format); -GLenum ConvertDepthStencilFormat(DXGI_FORMAT format); -GLenum ConvertRenderbufferFormat(DXGI_FORMAT format); -GLenum ConvertTextureInternalFormat(DXGI_FORMAT format); - -} - -namespace d3d11 -{ - -struct PositionTexCoordVertex -{ - float x, y; - float u, v; -}; -void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v); - -struct PositionDepthColorVertex -{ - float x, y, z; - float r, g, b, a; -}; -void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, - const gl::Color &color); - -size_t ComputePixelSizeBits(DXGI_FORMAT format); -size_t ComputeBlockSizeBits(DXGI_FORMAT format); - -bool IsCompressed(DXGI_FORMAT format); -unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format); - -bool IsDepthStencilFormat(DXGI_FORMAT format); -DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format); -DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format); - -HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); - -inline bool isDeviceLostError(HRESULT errorCode) -{ - switch (errorCode) - { - case DXGI_ERROR_DEVICE_HUNG: - case DXGI_ERROR_DEVICE_REMOVED: - case DXGI_ERROR_DEVICE_RESET: - case DXGI_ERROR_DRIVER_INTERNAL_ERROR: - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: - return true; - default: - return false; - } -} - -} - -#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Blit.ps b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Blit.ps deleted file mode 100644 index dcb3bd0e76b..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Blit.ps +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -sampler2D tex : s0; - -uniform float4 mode : c0; - -// Passthrough Pixel Shader -// Outputs texture 0 sampled at texcoord 0. -float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR -{ - return tex2D(tex, texcoord.xy); -}; - -// Luminance Conversion Pixel Shader -// Outputs sample(tex0, tc0).rrra. -// For LA output (pass A) set C0.X = 1, C0.Y = 0. -// For L output (A = 1) set C0.X = 0, C0.Y = 1. -float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR -{ - float4 tmp = tex2D(tex, texcoord.xy); - tmp.w = tmp.w * mode.x + mode.y; - return tmp.xxxw; -}; - -// RGB/A Component Mask Pixel Shader -// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1. -// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1. -// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0. -float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR -{ - float4 tmp = tex2D(tex, texcoord.xy); - tmp.xyz = tmp.xyz * mode.x; - tmp.w = tmp.w * mode.z + mode.w; - return tmp; -}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl deleted file mode 100644 index 042ac699b66..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl +++ /dev/null @@ -1,38 +0,0 @@ -void VS_Clear( in float3 inPosition : POSITION, in float4 inColor : COLOR, - out float4 outPosition : SV_POSITION, out float4 outColor : COLOR) -{ - outPosition = float4(inPosition, 1.0f); - outColor = inColor; -} - -// Assume we are in SM4+, which has 8 color outputs -struct PS_OutputMultiple -{ - float4 color0 : SV_TARGET0; - float4 color1 : SV_TARGET1; - float4 color2 : SV_TARGET2; - float4 color3 : SV_TARGET3; - float4 color4 : SV_TARGET4; - float4 color5 : SV_TARGET5; - float4 color6 : SV_TARGET6; - float4 color7 : SV_TARGET7; -}; - -PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) -{ - PS_OutputMultiple outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; - outColor.color4 = inColor; - outColor.color5 = inColor; - outColor.color6 = inColor; - outColor.color7 = inColor; - return outColor; -} - -float4 PS_ClearSingle(in float4 inPosition : SV_Position, in float4 inColor : COLOR) : SV_Target0 -{ - return inColor; -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl deleted file mode 100644 index 43b7801efc1..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl +++ /dev/null @@ -1,29 +0,0 @@ -Texture2D Texture : register(t0); -SamplerState Sampler : register(s0); - -void VS_Passthrough( in float2 inPosition : POSITION, in float2 inTexCoord : TEXCOORD0, - out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0) -{ - outPosition = float4(inPosition, 0.0f, 1.0f); - outTexCoord = inTexCoord; -} - -float4 PS_PassthroughRGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return Texture.Sample(Sampler, inTexCoord).rgba; -} - -float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f); -} - -float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f); -} - -float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return Texture.Sample(Sampler, inTexCoord).rrra; -} diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clearsingle11ps.h b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clearsingle11ps.h deleted file mode 100644 index dde816a0e85..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/clearsingle11ps.h +++ /dev/null @@ -1,110 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 -// -// -/// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Position 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE float xyzw -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Target 0 xyzw 0 TARGET float xyzw -// -ps_4_0 -dcl_input_ps linear v1.xyzw -dcl_output o0.xyzw -mov o0.xyzw, v1.xyzw -ret -// Approximately 2 instruction slots used -#endif - -const BYTE g_PS_ClearSingle[] = -{ - 68, 88, 66, 67, 13, 152, - 32, 49, 222, 236, 92, 20, - 188, 71, 88, 46, 163, 241, - 188, 238, 1, 0, 0, 0, - 208, 1, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 224, 0, - 0, 0, 20, 1, 0, 0, - 84, 1, 0, 0, 82, 68, - 69, 70, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 28, 0, 0, 0, 0, 4, - 255, 255, 0, 1, 0, 0, - 28, 0, 0, 0, 77, 105, - 99, 114, 111, 115, 111, 102, - 116, 32, 40, 82, 41, 32, - 72, 76, 83, 76, 32, 83, - 104, 97, 100, 101, 114, 32, - 67, 111, 109, 112, 105, 108, - 101, 114, 32, 57, 46, 51, - 48, 46, 57, 50, 48, 48, - 46, 49, 54, 51, 56, 52, - 0, 171, 73, 83, 71, 78, - 76, 0, 0, 0, 2, 0, - 0, 0, 8, 0, 0, 0, - 56, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 83, 86, 95, 80, 111, 115, - 105, 116, 105, 111, 110, 0, - 67, 79, 76, 79, 82, 0, - 171, 171, 79, 83, 71, 78, - 44, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 83, 86, 95, 84, 97, 114, - 103, 101, 116, 0, 171, 171, - 83, 72, 68, 82, 56, 0, - 0, 0, 64, 0, 0, 0, - 14, 0, 0, 0, 98, 16, - 0, 3, 242, 16, 16, 0, - 1, 0, 0, 0, 101, 0, - 0, 3, 242, 32, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 62, 0, 0, 1, 83, 84, - 65, 84, 116, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0 -}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/componentmaskps.h b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/componentmaskps.h deleted file mode 100644 index a6ec1d99d2b..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/compiled/componentmaskps.h +++ /dev/null @@ -1,79 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384 -// -/// -// Parameters: -// -// float4 mode; -// sampler2D tex; -// -// -// Registers: -// -// Name Reg Size -// ------------ ----- ---- -// mode c0 1 -// tex s0 1 -// - - ps_2_0 - dcl t0.xy - dcl_2d s0 - texld r0, t0, s0 - mul r1.xyz, r0, c0.x - mad r1.w, r0.w, c0.z, c0.w - mov oC0, r1 - -// approximately 4 instruction slots used (1 texture, 3 arithmetic) -#endif - -const BYTE g_ps20_componentmaskps[] = -{ - 0, 2, 255, 255, 254, 255, - 44, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 119, 0, - 0, 0, 0, 2, 255, 255, - 2, 0, 0, 0, 28, 0, - 0, 0, 0, 1, 0, 0, - 112, 0, 0, 0, 68, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 76, 0, - 0, 0, 0, 0, 0, 0, - 92, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 96, 0, 0, 0, 0, 0, - 0, 0, 109, 111, 100, 101, - 0, 171, 171, 171, 1, 0, - 3, 0, 1, 0, 4, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 116, 101, 120, 0, - 4, 0, 12, 0, 1, 0, - 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 112, 115, - 95, 50, 95, 48, 0, 77, - 105, 99, 114, 111, 115, 111, - 102, 116, 32, 40, 82, 41, - 32, 72, 76, 83, 76, 32, - 83, 104, 97, 100, 101, 114, - 32, 67, 111, 109, 112, 105, - 108, 101, 114, 32, 57, 46, - 51, 48, 46, 57, 50, 48, - 48, 46, 49, 54, 51, 56, - 52, 0, 171, 171, 31, 0, - 0, 2, 0, 0, 0, 128, - 0, 0, 3, 176, 31, 0, - 0, 2, 0, 0, 0, 144, - 0, 8, 15, 160, 66, 0, - 0, 3, 0, 0, 15, 128, - 0, 0, 228, 176, 0, 8, - 228, 160, 5, 0, 0, 3, - 1, 0, 7, 128, 0, 0, - 228, 128, 0, 0, 0, 160, - 4, 0, 0, 4, 1, 0, - 8, 128, 0, 0, 255, 128, - 0, 0, 170, 160, 0, 0, - 255, 160, 1, 0, 0, 2, - 0, 8, 15, 128, 1, 0, - 228, 128, 255, 255, 0, 0 -}; diff --git a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/generate_shaders.bat b/chromium/third_party/angle/src/libGLESv2/renderer/shaders/generate_shaders.bat deleted file mode 100644 index 48fd7ee1835..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/renderer/shaders/generate_shaders.bat +++ /dev/null @@ -1,24 +0,0 @@ -@ECHO OFF -REM -REM Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -REM Use of this source code is governed by a BSD-style license that can be -REM found in the LICENSE file. -REM - -PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.0\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 - -fxc /E standardvs /T vs_2_0 /Fh compiled/standardvs.h Blit.vs -fxc /E flipyvs /T vs_2_0 /Fh compiled/flipyvs.h Blit.vs -fxc /E passthroughps /T ps_2_0 /Fh compiled/passthroughps.h Blit.ps -fxc /E luminanceps /T ps_2_0 /Fh compiled/luminanceps.h Blit.ps -fxc /E componentmaskps /T ps_2_0 /Fh compiled/componentmaskps.h Blit.ps - -fxc /E VS_Passthrough /T vs_4_0 /Fh compiled/passthrough11vs.h Passthrough11.hlsl -fxc /E PS_PassthroughRGBA /T ps_4_0 /Fh compiled/passthroughrgba11ps.h Passthrough11.hlsl -fxc /E PS_PassthroughRGB /T ps_4_0 /Fh compiled/passthroughrgb11ps.h Passthrough11.hlsl -fxc /E PS_PassthroughLum /T ps_4_0 /Fh compiled/passthroughlum11ps.h Passthrough11.hlsl -fxc /E PS_PassthroughLumAlpha /T ps_4_0 /Fh compiled/passthroughlumalpha11ps.h Passthrough11.hlsl - -fxc /E VS_Clear /T vs_4_0 /Fh compiled/clear11vs.h Clear11.hlsl -fxc /E PS_ClearSingle /T ps_4_0 /Fh compiled/clearsingle11ps.h Clear11.hlsl -fxc /E PS_ClearMultiple /T ps_4_0 /Fh compiled/clearmultiple11ps.h Clear11.hlsl diff --git a/chromium/third_party/angle/src/libGLESv2/utilities.cpp b/chromium/third_party/angle/src/libGLESv2/utilities.cpp deleted file mode 100644 index 32df49e672b..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/utilities.cpp +++ /dev/null @@ -1,769 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2013 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. -// - -// utilities.cpp: Conversion functions and other utility routines. - -#include "libGLESv2/utilities.h" -#include "libGLESv2/mathutil.h" - -namespace gl -{ - -int UniformComponentCount(GLenum type) -{ - switch (type) - { - case GL_BOOL: - case GL_FLOAT: - case GL_INT: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - return 1; - case GL_BOOL_VEC2: - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - return 2; - case GL_INT_VEC3: - case GL_FLOAT_VEC3: - case GL_BOOL_VEC3: - return 3; - case GL_BOOL_VEC4: - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_FLOAT_MAT2: - return 4; - case GL_FLOAT_MAT3: - return 9; - case GL_FLOAT_MAT4: - return 16; - default: - UNREACHABLE(); - } - - return 0; -} - -GLenum UniformComponentType(GLenum type) -{ - switch(type) - { - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: - return GL_BOOL; - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: - return GL_FLOAT; - case GL_INT: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - return GL_INT; - default: - UNREACHABLE(); - } - - return GL_NONE; -} - -size_t UniformComponentSize(GLenum type) -{ - switch(type) - { - case GL_BOOL: return sizeof(GLint); - case GL_FLOAT: return sizeof(GLfloat); - case GL_INT: return sizeof(GLint); - default: UNREACHABLE(); - } - - return 0; -} - -size_t UniformInternalSize(GLenum type) -{ - // Expanded to 4-element vectors - return UniformComponentSize(UniformComponentType(type)) * VariableRowCount(type) * 4; -} - -size_t UniformExternalSize(GLenum type) -{ - return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type); -} - -int VariableRowCount(GLenum type) -{ - switch (type) - { - case GL_NONE: - return 0; - case GL_BOOL: - case GL_FLOAT: - case GL_INT: - case GL_BOOL_VEC2: - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_FLOAT_VEC3: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - return 1; - case GL_FLOAT_MAT2: - return 2; - case GL_FLOAT_MAT3: - return 3; - case GL_FLOAT_MAT4: - return 4; - default: - UNREACHABLE(); - } - - return 0; -} - -int VariableColumnCount(GLenum type) -{ - switch (type) - { - case GL_NONE: - return 0; - case GL_BOOL: - case GL_FLOAT: - case GL_INT: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - return 1; - case GL_BOOL_VEC2: - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_FLOAT_MAT2: - return 2; - case GL_INT_VEC3: - case GL_FLOAT_VEC3: - case GL_BOOL_VEC3: - case GL_FLOAT_MAT3: - return 3; - case GL_BOOL_VEC4: - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_FLOAT_MAT4: - return 4; - default: - UNREACHABLE(); - } - - return 0; -} - -int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize) -{ - ASSERT(allocationSize <= bitsSize); - - unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize); - - for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++) - { - if ((*bits & mask) == 0) - { - *bits |= mask; - return i; - } - - mask <<= 1; - } - - return -1; -} - -GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment) -{ - ASSERT(alignment > 0 && isPow2(alignment)); - - GLsizei rawPitch = ComputePixelSize(internalformat) * width; - return (rawPitch + alignment - 1) & ~(alignment - 1); -} - -GLsizei ComputeCompressedPitch(GLsizei width, GLenum internalformat) -{ - return ComputeCompressedSize(width, 1, internalformat); -} - -GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum internalformat) -{ - switch (internalformat) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return 8 * ((width + 3) / 4) * ((height + 3) / 4); - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return 16 * ((width + 3) / 4) * ((height + 3) / 4); - default: - return 0; - } -} - -GLsizei ComputeTypeSize(GLenum type) -{ - switch (type) - { - case GL_BYTE: return 1; - case GL_UNSIGNED_BYTE: return 1; - case GL_SHORT: return 2; - case GL_UNSIGNED_SHORT: return 2; - case GL_INT: return 4; - case GL_UNSIGNED_INT: return 4; - case GL_FLOAT: return 4; - case GL_HALF_FLOAT_OES: return 2; - case GL_UNSIGNED_SHORT_5_6_5: return 2; - case GL_UNSIGNED_SHORT_4_4_4_4: return 2; - case GL_UNSIGNED_SHORT_5_5_5_1: return 2; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return 2; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return 2; - case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return 4; - case GL_UNSIGNED_INT_24_8_OES: return 4; - default: UNREACHABLE(); return 0; - } -} - -bool IsCompressed(GLenum format) -{ - if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || - format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE || - format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE) - { - return true; - } - else - { - return false; - } -} - -bool IsDepthTexture(GLenum format) -{ - if (format == GL_DEPTH_COMPONENT || - format == GL_DEPTH_STENCIL_OES || - format == GL_DEPTH_COMPONENT16 || - format == GL_DEPTH_COMPONENT32_OES || - format == GL_DEPTH24_STENCIL8_OES) - { - return true; - } - - return false; -} - -bool IsStencilTexture(GLenum format) -{ - if (format == GL_DEPTH_STENCIL_OES || - format == GL_DEPTH24_STENCIL8_OES) - { - return true; - } - - return false; -} - -void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) -{ - int upsampleCount = 0; - - if (isCompressed) - { - // Don't expand the size of full textures that are at least 4x4 - // already. - if (isImage || *requestWidth < 4 || *requestHeight < 4) - { - while (*requestWidth % 4 != 0 || *requestHeight % 4 != 0) - { - *requestWidth <<= 1; - *requestHeight <<= 1; - upsampleCount++; - } - } - } - *levelOffset = upsampleCount; -} - -// Returns the size, in bytes, of a single texel in an Image -int ComputePixelSize(GLint internalformat) -{ - switch (internalformat) - { - case GL_ALPHA8_EXT: return sizeof(unsigned char); - case GL_LUMINANCE8_EXT: return sizeof(unsigned char); - case GL_ALPHA32F_EXT: return sizeof(float); - case GL_LUMINANCE32F_EXT: return sizeof(float); - case GL_ALPHA16F_EXT: return sizeof(unsigned short); - case GL_LUMINANCE16F_EXT: return sizeof(unsigned short); - case GL_LUMINANCE8_ALPHA8_EXT: return sizeof(unsigned char) * 2; - case GL_LUMINANCE_ALPHA32F_EXT: return sizeof(float) * 2; - case GL_LUMINANCE_ALPHA16F_EXT: return sizeof(unsigned short) * 2; - case GL_RGB8_OES: return sizeof(unsigned char) * 3; - case GL_RGB565: return sizeof(unsigned short); - case GL_RGB32F_EXT: return sizeof(float) * 3; - case GL_RGB16F_EXT: return sizeof(unsigned short) * 3; - case GL_RGBA8_OES: return sizeof(unsigned char) * 4; - case GL_RGBA4: return sizeof(unsigned short); - case GL_RGB5_A1: return sizeof(unsigned short); - case GL_RGBA32F_EXT: return sizeof(float) * 4; - case GL_RGBA16F_EXT: return sizeof(unsigned short) * 4; - case GL_BGRA8_EXT: return sizeof(unsigned char) * 4; - case GL_BGRA4_ANGLEX: return sizeof(unsigned short); - case GL_BGR5_A1_ANGLEX: return sizeof(unsigned short); - default: UNREACHABLE(); - } - - return 0; -} - -bool IsCubemapTextureTarget(GLenum target) -{ - return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); -} - -bool IsInternalTextureTarget(GLenum target) -{ - return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); -} - -GLint ConvertSizedInternalFormat(GLenum format, GLenum type) -{ - switch (format) - { - case GL_ALPHA: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_ALPHA8_EXT; - case GL_FLOAT: return GL_ALPHA32F_EXT; - case GL_HALF_FLOAT_OES: return GL_ALPHA16F_EXT; - default: UNIMPLEMENTED(); - } - break; - case GL_LUMINANCE: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_EXT; - case GL_FLOAT: return GL_LUMINANCE32F_EXT; - case GL_HALF_FLOAT_OES: return GL_LUMINANCE16F_EXT; - default: UNIMPLEMENTED(); - } - break; - case GL_LUMINANCE_ALPHA: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_ALPHA8_EXT; - case GL_FLOAT: return GL_LUMINANCE_ALPHA32F_EXT; - case GL_HALF_FLOAT_OES: return GL_LUMINANCE_ALPHA16F_EXT; - default: UNIMPLEMENTED(); - } - break; - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_RGB8_OES; - case GL_UNSIGNED_SHORT_5_6_5: return GL_RGB565; - case GL_FLOAT: return GL_RGB32F_EXT; - case GL_HALF_FLOAT_OES: return GL_RGB16F_EXT; - default: UNIMPLEMENTED(); - } - break; - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_RGBA8_OES; - case GL_UNSIGNED_SHORT_4_4_4_4: return GL_RGBA4; - case GL_UNSIGNED_SHORT_5_5_5_1: return GL_RGB5_A1; - case GL_FLOAT: return GL_RGBA32F_EXT; - case GL_HALF_FLOAT_OES: return GL_RGBA16F_EXT; - break; - default: UNIMPLEMENTED(); - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: return GL_BGRA8_EXT; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return GL_BGRA4_ANGLEX; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return GL_BGR5_A1_ANGLEX; - default: UNIMPLEMENTED(); - } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return format; - case GL_DEPTH_COMPONENT: - switch (type) - { - case GL_UNSIGNED_SHORT: return GL_DEPTH_COMPONENT16; - case GL_UNSIGNED_INT: return GL_DEPTH_COMPONENT32_OES; - default: UNIMPLEMENTED(); - } - break; - case GL_DEPTH_STENCIL_OES: - switch (type) - { - case GL_UNSIGNED_INT_24_8_OES: return GL_DEPTH24_STENCIL8_OES; - default: UNIMPLEMENTED(); - } - break; - default: - UNIMPLEMENTED(); - } - - return GL_NONE; -} - -GLenum ExtractFormat(GLenum internalformat) -{ - switch (internalformat) - { - case GL_RGB565: return GL_RGB; - case GL_RGBA4: return GL_RGBA; - case GL_RGB5_A1: return GL_RGBA; - case GL_RGB8_OES: return GL_RGB; - case GL_RGBA8_OES: return GL_RGBA; - case GL_LUMINANCE8_ALPHA8_EXT: return GL_LUMINANCE_ALPHA; - case GL_LUMINANCE8_EXT: return GL_LUMINANCE; - case GL_ALPHA8_EXT: return GL_ALPHA; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; - case GL_RGBA32F_EXT: return GL_RGBA; - case GL_RGB32F_EXT: return GL_RGB; - case GL_ALPHA32F_EXT: return GL_ALPHA; - case GL_LUMINANCE32F_EXT: return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA32F_EXT: return GL_LUMINANCE_ALPHA; - case GL_RGBA16F_EXT: return GL_RGBA; - case GL_RGB16F_EXT: return GL_RGB; - case GL_ALPHA16F_EXT: return GL_ALPHA; - case GL_LUMINANCE16F_EXT: return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA; - case GL_BGRA8_EXT: return GL_BGRA_EXT; - case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT; - case GL_DEPTH_COMPONENT32_OES: return GL_DEPTH_COMPONENT; - case GL_DEPTH24_STENCIL8_OES: return GL_DEPTH_STENCIL_OES; - default: return GL_NONE; // Unsupported - } -} - -GLenum ExtractType(GLenum internalformat) -{ - switch (internalformat) - { - case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5; - case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4; - case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1; - case GL_RGB8_OES: return GL_UNSIGNED_BYTE; - case GL_RGBA8_OES: return GL_UNSIGNED_BYTE; - case GL_LUMINANCE8_ALPHA8_EXT: return GL_UNSIGNED_BYTE; - case GL_LUMINANCE8_EXT: return GL_UNSIGNED_BYTE; - case GL_ALPHA8_EXT: return GL_UNSIGNED_BYTE; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_UNSIGNED_BYTE; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_UNSIGNED_BYTE; - case GL_RGBA32F_EXT: return GL_FLOAT; - case GL_RGB32F_EXT: return GL_FLOAT; - case GL_ALPHA32F_EXT: return GL_FLOAT; - case GL_LUMINANCE32F_EXT: return GL_FLOAT; - case GL_LUMINANCE_ALPHA32F_EXT: return GL_FLOAT; - case GL_RGBA16F_EXT: return GL_HALF_FLOAT_OES; - case GL_RGB16F_EXT: return GL_HALF_FLOAT_OES; - case GL_ALPHA16F_EXT: return GL_HALF_FLOAT_OES; - case GL_LUMINANCE16F_EXT: return GL_HALF_FLOAT_OES; - case GL_LUMINANCE_ALPHA16F_EXT: return GL_HALF_FLOAT_OES; - case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; - case GL_DEPTH_COMPONENT16: return GL_UNSIGNED_SHORT; - case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT; - case GL_DEPTH24_STENCIL8_OES: return GL_UNSIGNED_INT_24_8_OES; - default: return GL_NONE; // Unsupported - } -} - -bool IsColorRenderable(GLenum internalformat) -{ - switch (internalformat) - { - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB565: - case GL_RGB8_OES: - case GL_RGBA8_OES: - return true; - case GL_DEPTH_COMPONENT16: - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: - return false; - case GL_BGRA8_EXT: - return true; - default: - UNIMPLEMENTED(); - } - - return false; -} - -bool IsDepthRenderable(GLenum internalformat) -{ - switch (internalformat) - { - case GL_DEPTH_COMPONENT16: - case GL_DEPTH24_STENCIL8_OES: - return true; - case GL_STENCIL_INDEX8: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB565: - case GL_RGB8_OES: - case GL_RGBA8_OES: - return false; - default: - UNIMPLEMENTED(); - } - - return false; -} - -bool IsStencilRenderable(GLenum internalformat) -{ - switch (internalformat) - { - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: - return true; - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB565: - case GL_RGB8_OES: - case GL_RGBA8_OES: - case GL_DEPTH_COMPONENT16: - return false; - default: - UNIMPLEMENTED(); - } - - return false; -} - -bool IsFloat32Format(GLint internalformat) -{ - switch (internalformat) - { - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - return true; - default: - return false; - } -} - -bool IsFloat16Format(GLint internalformat) -{ - switch (internalformat) - { - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - return true; - default: - return false; - } -} - -unsigned int GetAlphaSize(GLenum colorFormat) -{ - switch (colorFormat) - { - case GL_RGBA16F_EXT: - return 16; - case GL_RGBA32F_EXT: - return 32; - case GL_RGBA4: - return 4; - case GL_RGBA8_OES: - case GL_BGRA8_EXT: - return 8; - case GL_RGB5_A1: - return 1; - case GL_RGB8_OES: - case GL_RGB565: - case GL_RGB32F_EXT: - case GL_RGB16F_EXT: - return 0; - default: - return 0; - } -} - -unsigned int GetRedSize(GLenum colorFormat) -{ - switch (colorFormat) - { - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - return 16; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - return 32; - case GL_RGBA4: - return 4; - case GL_RGBA8_OES: - case GL_BGRA8_EXT: - case GL_RGB8_OES: - return 8; - case GL_RGB5_A1: - case GL_RGB565: - return 5; - default: - return 0; - } -} - -unsigned int GetGreenSize(GLenum colorFormat) -{ - switch (colorFormat) - { - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - return 16; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - return 32; - case GL_RGBA4: - return 4; - case GL_RGBA8_OES: - case GL_BGRA8_EXT: - case GL_RGB8_OES: - return 8; - case GL_RGB5_A1: - return 5; - case GL_RGB565: - return 6; - default: - return 0; - } -} - -unsigned int GetBlueSize(GLenum colorFormat) -{ - switch (colorFormat) - { - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - return 16; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - return 32; - case GL_RGBA4: - return 4; - case GL_RGBA8_OES: - case GL_BGRA8_EXT: - case GL_RGB8_OES: - return 8; - case GL_RGB5_A1: - case GL_RGB565: - return 5; - default: - return 0; - } -} - -unsigned int GetDepthSize(GLenum depthFormat) -{ - switch (depthFormat) - { - case GL_DEPTH_COMPONENT16: return 16; - case GL_DEPTH_COMPONENT32_OES: return 32; - case GL_DEPTH24_STENCIL8_OES: return 24; - default: return 0; - } -} - -unsigned int GetStencilSize(GLenum stencilFormat) -{ - switch (stencilFormat) - { - case GL_DEPTH24_STENCIL8_OES: return 8; - default: return 0; - } -} - -bool IsTriangleMode(GLenum drawMode) -{ - switch (drawMode) - { - case GL_TRIANGLES: - case GL_TRIANGLE_FAN: - case GL_TRIANGLE_STRIP: - return true; - case GL_POINTS: - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - return false; - default: UNREACHABLE(); - } - - return false; -} - -} - -std::string getTempPath() -{ - char path[MAX_PATH]; - DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); - if (pathLen == 0) - { - UNREACHABLE(); - return std::string(); - } - - UINT unique = GetTempFileNameA(path, "sh", 0, path); - if (unique == 0) - { - UNREACHABLE(); - return std::string(); - } - - return path; -} - -void writeFile(const char* path, const void* content, size_t size) -{ - FILE* file = fopen(path, "w"); - if (!file) - { - UNREACHABLE(); - return; - } - - fwrite(content, sizeof(char), size, file); - fclose(file); -} diff --git a/chromium/third_party/angle/src/libGLESv2/utilities.h b/chromium/third_party/angle/src/libGLESv2/utilities.h deleted file mode 100644 index ed663ebca20..00000000000 --- a/chromium/third_party/angle/src/libGLESv2/utilities.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) 2002-2013 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. -// - -// utilities.h: Conversion functions and other utility routines. - -#ifndef LIBGLESV2_UTILITIES_H -#define LIBGLESV2_UTILITIES_H - -#define GL_APICALL -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - -#include <string> - -namespace gl -{ - -struct Color; - -int UniformComponentCount(GLenum type); -GLenum UniformComponentType(GLenum type); -size_t UniformInternalSize(GLenum type); -size_t UniformExternalSize(GLenum type); -int VariableRowCount(GLenum type); -int VariableColumnCount(GLenum type); - -int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); - -void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); -int ComputePixelSize(GLint internalformat); -GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment); -GLsizei ComputeCompressedPitch(GLsizei width, GLenum format); -GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format); -GLsizei ComputeTypeSize(GLenum type); -bool IsCompressed(GLenum format); -bool IsDepthTexture(GLenum format); -bool IsStencilTexture(GLenum format); -bool IsCubemapTextureTarget(GLenum target); -bool IsInternalTextureTarget(GLenum target); -GLint ConvertSizedInternalFormat(GLenum format, GLenum type); -GLenum ExtractFormat(GLenum internalformat); -GLenum ExtractType(GLenum internalformat); - -bool IsColorRenderable(GLenum internalformat); -bool IsDepthRenderable(GLenum internalformat); -bool IsStencilRenderable(GLenum internalformat); - -bool IsFloat32Format(GLint internalformat); -bool IsFloat16Format(GLint internalformat); - -GLuint GetAlphaSize(GLenum colorFormat); -GLuint GetRedSize(GLenum colorFormat); -GLuint GetGreenSize(GLenum colorFormat); -GLuint GetBlueSize(GLenum colorFormat); -GLuint GetDepthSize(GLenum depthFormat); -GLuint GetStencilSize(GLenum stencilFormat); -bool IsTriangleMode(GLenum drawMode); - -} - -std::string getTempPath(); -void writeFile(const char* path, const void* data, size_t size); - -#endif // LIBGLESV2_UTILITIES_H diff --git a/chromium/third_party/angle/src/libGLESv2/validationES.cpp b/chromium/third_party/angle/src/libGLESv2/validationES.cpp new file mode 100644 index 00000000000..03b8f71b53d --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES.cpp @@ -0,0 +1,1293 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// validationES.h: Validation functions for generic OpenGL ES entry point parameters + +#include "libGLESv2/validationES.h" +#include "libGLESv2/validationES2.h" +#include "libGLESv2/validationES3.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/main.h" +#include "libGLESv2/Query.h" +#include "libGLESv2/ProgramBinary.h" + +#include "common/mathutil.h" +#include "common/utilities.h" + +namespace gl +{ + +bool ValidCap(const Context *context, GLenum cap) +{ + switch (cap) + { + case GL_CULL_FACE: + case GL_POLYGON_OFFSET_FILL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + return (context->getClientVersion() >= 3); + default: + return false; + } +} + +bool ValidTextureTarget(const Context *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + return true; + + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return (context->getClientVersion() >= 3); + + default: + return false; + } +} + +// This function differs from ValidTextureTarget in that the target must be +// usable as the destination of a 2D operation-- so a cube face is valid, but +// GL_TEXTURE_CUBE_MAP is not. +// Note: duplicate of IsInternalTextureTarget +bool ValidTexture2DDestinationTarget(const Context *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return true; + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_3D: + return (context->getClientVersion() >= 3); + default: + return false; + } +} + +bool ValidFramebufferTarget(GLenum target) +{ + META_ASSERT(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER); + + switch (target) + { + case GL_FRAMEBUFFER: return true; + case GL_READ_FRAMEBUFFER: return true; + case GL_DRAW_FRAMEBUFFER: return true; + default: return false; + } +} + +bool ValidBufferTarget(const Context *context, GLenum target) +{ + switch (target) + { + case GL_ARRAY_BUFFER: + case GL_ELEMENT_ARRAY_BUFFER: + return true; + + case GL_PIXEL_PACK_BUFFER: + case GL_PIXEL_UNPACK_BUFFER: + return context->supportsPBOs(); + + case GL_COPY_READ_BUFFER: + case GL_COPY_WRITE_BUFFER: + case GL_TRANSFORM_FEEDBACK_BUFFER: + case GL_UNIFORM_BUFFER: + return (context->getClientVersion() >= 3); + + default: + return false; + } +} + +bool ValidBufferParameter(const Context *context, GLenum pname) +{ + switch (pname) + { + case GL_BUFFER_USAGE: + case GL_BUFFER_SIZE: + return true; + + // GL_BUFFER_MAP_POINTER is a special case, and may only be + // queried with GetBufferPointerv + case GL_BUFFER_ACCESS_FLAGS: + case GL_BUFFER_MAPPED: + case GL_BUFFER_MAP_OFFSET: + case GL_BUFFER_MAP_LENGTH: + return (context->getClientVersion() >= 3); + + default: + return false; + } +} + +bool ValidMipLevel(const Context *context, GLenum target, GLint level) +{ + int maxLevel = 0; + switch (target) + { + case GL_TEXTURE_2D: maxLevel = context->getMaximum2DTextureLevel(); break; + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: maxLevel = context->getMaximumCubeTextureLevel(); break; + case GL_TEXTURE_3D: maxLevel = context->getMaximum3DTextureLevel(); break; + case GL_TEXTURE_2D_ARRAY: maxLevel = context->getMaximum2DArrayTextureLevel(); break; + default: UNREACHABLE(); + } + + return level < maxLevel; +} + +bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, + GLsizei width, GLsizei height, GLsizei depth) +{ + if (level < 0 || width < 0 || height < 0 || depth < 0) + { + return false; + } + + if (!context->supportsNonPower2Texture() && + (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth)))) + { + return false; + } + + if (!ValidMipLevel(context, target, level)) + { + return false; + } + + return true; +} + +bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height) +{ + GLuint clientVersion = context->getClientVersion(); + if (!IsFormatCompressed(internalFormat, clientVersion)) + { + return false; + } + + GLint blockWidth = GetCompressedBlockWidth(internalFormat, clientVersion); + GLint blockHeight = GetCompressedBlockHeight(internalFormat, clientVersion); + if (width < 0 || (width > blockWidth && width % blockWidth != 0) || + height < 0 || (height > blockHeight && height % blockHeight != 0)) + { + return false; + } + + return true; +} + +bool ValidQueryType(const Context *context, GLenum queryType) +{ + META_ASSERT(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT); + META_ASSERT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); + + switch (queryType) + { + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return true; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return (context->getClientVersion() >= 3); + default: + return false; + } +} + +bool ValidProgram(const Context *context, GLuint id) +{ + // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the + // error INVALID_VALUE if the provided name is not the name of either a shader or program object and + // INVALID_OPERATION if the provided name identifies an object that is not the expected type." + + if (context->getProgram(id) != NULL) + { + return true; + } + else if (context->getShader(id) != NULL) + { + // ID is the wrong type + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + // No shader/program object has this ID + return gl::error(GL_INVALID_VALUE, false); + } +} + +bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + bool angleExtension) +{ + switch (target) + { + case GL_RENDERBUFFER: + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (width < 0 || height < 0 || samples < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (!gl::IsValidInternalFormat(internalformat, context)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be + // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains + // only sized internal formats. The ES3 spec (section 4.4.2) does, however, state that the + // internal format must be sized and not an integer format if samples is greater than zero. + if (!gl::IsSizedInternalFormat(internalformat, context->getClientVersion())) + { + return gl::error(GL_INVALID_ENUM, false); + } + + GLenum componentType = gl::GetComponentType(internalformat, context->getClientVersion()); + if ((componentType == GL_UNSIGNED_INT || componentType == GL_INT) && samples > 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!gl::IsColorRenderingSupported(internalformat, context) && + !gl::IsDepthRenderingSupported(internalformat, context) && + !gl::IsStencilRenderingSupported(internalformat, context)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (std::max(width, height) > context->getMaximumRenderbufferDimension()) + { + return gl::error(GL_INVALID_VALUE, false); + } + + // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal + // to MAX_SAMPLES_ANGLE (Context::getMaxSupportedSamples) while the ES3.0 spec (section 4.4.2) + // states that samples must be less than or equal to the maximum samples for the specified + // internal format. + if (angleExtension) + { + if (samples > context->getMaxSupportedSamples()) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + else + { + if (samples > context->getMaxSupportedFormatSamples(internalformat)) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + + GLuint handle = context->getRenderbufferHandle(); + if (handle == 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) +{ + gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); + GLuint framebufferHandle = context->getTargetFramebufferHandle(target); + + if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + + if (colorAttachment >= context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + break; + case GL_STENCIL_ATTACHMENT: + break; + case GL_DEPTH_STENCIL_ATTACHMENT: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + + // [OpenGL ES 2.0.25] Section 4.4.3 page 112 + // [OpenGL ES 3.0.2] Section 4.4.2 page 201 + // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of + // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated. + if (renderbuffer != 0) + { + if (!context->getRenderbuffer(renderbuffer)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + return true; +} + +static bool IsPartialBlit(gl::Context *context, gl::FramebufferAttachment *readBuffer, gl::FramebufferAttachment *writeBuffer, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) +{ + if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || + dstX1 != writeBuffer->getWidth() || dstY1 != writeBuffer->getHeight() || + srcX1 != readBuffer->getWidth() || srcY1 != readBuffer->getHeight()) + { + return true; + } + else if (context->isScissorTestEnabled()) + { + int scissorX, scissorY, scissorWidth, scissorHeight; + context->getScissorParams(&scissorX, &scissorY, &scissorWidth, &scissorHeight); + + return scissorX > 0 || scissorY > 0 || + scissorWidth < writeBuffer->getWidth() || + scissorHeight < writeBuffer->getHeight(); + } + else + { + return false; + } +} + +bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, + GLenum filter, bool fromAngleExtension) +{ + switch (filter) + { + case GL_NEAREST: + break; + case GL_LINEAR: + if (fromAngleExtension) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (mask == 0) + { + // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no + // buffers are copied. + return false; + } + + if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)) + { + ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."); + return gl::error(GL_INVALID_OPERATION, false); + } + + // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the + // color buffer, leaving only nearest being unfiltered from above + if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle()) + { + if (fromAngleExtension) + { + ERR("Blits with the same source and destination framebuffer are not supported by this " + "implementation."); + } + return gl::error(GL_INVALID_OPERATION, false); + } + + gl::Framebuffer *readFramebuffer = context->getReadFramebuffer(); + gl::Framebuffer *drawFramebuffer = context->getDrawFramebuffer(); + if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE || + !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); + } + + if (drawFramebuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1; + + GLuint clientVersion = context->getClientVersion(); + + if (mask & GL_COLOR_BUFFER_BIT) + { + gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer(); + gl::FramebufferAttachment *drawColorBuffer = drawFramebuffer->getFirstColorbuffer(); + + if (readColorBuffer && drawColorBuffer) + { + GLenum readInternalFormat = readColorBuffer->getActualFormat(); + GLenum readComponentType = gl::GetComponentType(readInternalFormat, clientVersion); + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) + { + if (drawFramebuffer->isEnabledColorAttachment(i)) + { + GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat(); + GLenum drawComponentType = gl::GetComponentType(drawInternalFormat, clientVersion); + + // The GL ES 3.0.2 spec (pg 193) states that: + // 1) If the read buffer is fixed point format, the draw buffer must be as well + // 2) If the read buffer is an unsigned integer format, the draw buffer must be as well + // 3) If the read buffer is a signed integer format, the draw buffer must be as well + if ( (readComponentType == GL_UNSIGNED_NORMALIZED || readComponentType == GL_SIGNED_NORMALIZED) && + !(drawComponentType == GL_UNSIGNED_NORMALIZED || drawComponentType == GL_SIGNED_NORMALIZED)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (readComponentType == GL_UNSIGNED_INT && drawComponentType != GL_UNSIGNED_INT) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (readComponentType == GL_INT && drawComponentType != GL_INT) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + + if ((readComponentType == GL_INT || readComponentType == GL_UNSIGNED_INT) && filter == GL_LINEAR) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (fromAngleExtension) + { + const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType(); + if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + if (drawFramebuffer->isEnabledColorAttachment(colorAttachment)) + { + if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D && + drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + } + + if (mask & GL_DEPTH_BUFFER_BIT) + { + gl::FramebufferAttachment *readDepthBuffer = readFramebuffer->getDepthbuffer(); + gl::FramebufferAttachment *drawDepthBuffer = drawFramebuffer->getDepthbuffer(); + + if (readDepthBuffer && drawDepthBuffer) + { + if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (readDepthBuffer->getSamples() > 0 && !sameBounds) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (fromAngleExtension) + { + if (IsPartialBlit(context, readDepthBuffer, drawDepthBuffer, + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) + { + ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); + return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted + } + + if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + } + + if (mask & GL_STENCIL_BUFFER_BIT) + { + gl::FramebufferAttachment *readStencilBuffer = readFramebuffer->getStencilbuffer(); + gl::FramebufferAttachment *drawStencilBuffer = drawFramebuffer->getStencilbuffer(); + + if (readStencilBuffer && drawStencilBuffer) + { + if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (readStencilBuffer->getSamples() > 0 && !sameBounds) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (fromAngleExtension) + { + if (IsPartialBlit(context, readStencilBuffer, drawStencilBuffer, + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) + { + ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); + return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted + } + + if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + } + + return true; +} + +bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion) +{ + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + case GL_CURRENT_VERTEX_ATTRIB: + return true; + + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses + // the same constant. + META_ASSERT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE); + return true; + + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + return ((clientVersion >= 3) ? true : gl::error(GL_INVALID_ENUM, false)); + + default: + return gl::error(GL_INVALID_ENUM, false); + } +} + +bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) +{ + switch (pname) + { + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + if (context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + + default: break; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + switch (param) + { + case GL_REPEAT: + case GL_CLAMP_TO_EDGE: + case GL_MIRRORED_REPEAT: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + case GL_TEXTURE_MIN_FILTER: + switch (param) + { + case GL_NEAREST: + case GL_LINEAR: + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_MAG_FILTER: + switch (param) + { + case GL_NEAREST: + case GL_LINEAR: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_USAGE_ANGLE: + switch (param) + { + case GL_NONE: + case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!context->supportsTextureFilterAnisotropy()) + { + return gl::error(GL_INVALID_ENUM, false); + } + + // we assume the parameter passed to this validation method is truncated, not rounded + if (param < 1) + { + return gl::error(GL_INVALID_VALUE, false); + } + return true; + + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + // any value is permissible + return true; + + case GL_TEXTURE_COMPARE_MODE: + // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17 + switch (param) + { + case GL_NONE: + case GL_COMPARE_REF_TO_TEXTURE: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_COMPARE_FUNC: + // Acceptable function parameters from GLES 3.0.2 spec, table 3.17 + switch (param) + { + case GL_LEQUAL: + case GL_GEQUAL: + case GL_LESS: + case GL_GREATER: + case GL_EQUAL: + case GL_NOTEQUAL: + case GL_ALWAYS: + case GL_NEVER: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + switch (param) + { + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_ZERO: + case GL_ONE: + return true; + default: + return gl::error(GL_INVALID_ENUM, false); + } + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + if (param < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + return true; + + default: + return gl::error(GL_INVALID_ENUM, false); + } +} + +bool ValidateSamplerObjectParameter(GLenum pname) +{ + switch (pname) + { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + return true; + + default: + return gl::error(GL_INVALID_ENUM, false); + } +} + +bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels) +{ + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + ASSERT(framebuffer); + + if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); + } + + if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!framebuffer->getReadColorbuffer()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + GLenum currentInternalFormat, currentFormat, currentType; + int clientVersion = context->getClientVersion(); + + context->getCurrentReadFormatType(¤tInternalFormat, ¤tFormat, ¤tType); + + bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) : + ValidES3ReadFormatType(context, currentInternalFormat, format, type); + + if (!(currentFormat == format && currentType == type) && !validReadFormat) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format : + GetSizedInternalFormat(format, type, clientVersion); + + GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, clientVersion, width, context->getPackAlignment()); + // sized query sanity check + if (bufSize) + { + int requiredSize = outputPitch * height; + if (requiredSize > *bufSize) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + return true; +} + +bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) +{ + if (!ValidQueryType(context, target)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (id == 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> + // of zero, if the active query object name for <target> is non-zero (for the + // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if + // the active query for either target is non-zero), if <id> is the name of an + // existing query object whose type does not match <target>, or if <id> is the + // active query object name for any query type, the error INVALID_OPERATION is + // generated. + + // Ensure no other queries are active + // NOTE: If other queries than occlusion are supported, we will need to check + // separately that: + // a) The query ID passed is not the current active query for any target/type + // b) There are no active queries for the requested target (and in the case + // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, + // no query may be active for either if glBeginQuery targets either. + if (context->isQueryActive()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + Query *queryObject = context->getQuery(id, true, target); + + // check that name was obtained with glGenQueries + if (!queryObject) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + // check for type mismatch + if (queryObject->getType() != target) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidateEndQuery(gl::Context *context, GLenum target) +{ + if (!ValidQueryType(context, target)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + const Query *queryObject = context->getActiveQuery(target); + + if (queryObject == NULL) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!queryObject->isStarted()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniformType, + GLint location, GLsizei count, LinkedUniform **uniformOut) +{ + if (count < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); + if (!programBinary) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (location == -1) + { + // Silently ignore the uniform command + return false; + } + + if (!programBinary->isValidUniformLocation(location)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + LinkedUniform *uniform = programBinary->getUniformByLocation(location); + + // attempting to write an array to a non-array uniform is an INVALID_OPERATION + if (uniform->elementCount() == 1 && count > 1) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + *uniformOut = uniform; + return true; +} + +bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count) +{ + // Check for ES3 uniform entry points + if (UniformComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + LinkedUniform *uniform = NULL; + if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform)) + { + return false; + } + + GLenum targetBoolType = UniformBoolVectorType(uniformType); + bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT); + if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose) +{ + // Check for ES3 uniform entry points + int rows = VariableRowCount(matrixType); + int cols = VariableColumnCount(matrixType); + if (rows != cols && context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (transpose != GL_FALSE && context->getClientVersion() < 3) + { + return gl::error(GL_INVALID_VALUE, false); + } + + LinkedUniform *uniform = NULL; + if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform)) + { + return false; + } + + if (uniform->type != matrixType) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams) +{ + if (!context->getQueryParameterInfo(pname, nativeType, numParams)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15) + { + unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0); + + if (colorAttachment >= context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + switch (pname) + { + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + if (context->getActiveSampler() >= context->getMaximumCombinedTextureImageUnits()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + { + Framebuffer *framebuffer = context->getReadFramebuffer(); + ASSERT(framebuffer); + if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); + if (!attachment) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + break; + + default: + break; + } + + // pname is valid, but there are no parameters to return + if (numParams == 0) + { + return false; + } + + return true; +} + +bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, + GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, + GLint border, GLenum *textureFormatOut) +{ + + if (!ValidTexture2DDestinationTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (border != 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (!ValidMipLevel(context, target, level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); + } + + if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + gl::Texture *texture = NULL; + GLenum textureInternalFormat = GL_NONE; + bool textureCompressed = false; + bool textureIsDepth = false; + GLint textureLevelWidth = 0; + GLint textureLevelHeight = 0; + GLint textureLevelDepth = 0; + int maxDimension = 0; + + switch (target) + { + case GL_TEXTURE_2D: + { + gl::Texture2D *texture2d = context->getTexture2D(); + if (texture2d) + { + textureInternalFormat = texture2d->getInternalFormat(level); + textureCompressed = texture2d->isCompressed(level); + textureIsDepth = texture2d->isDepth(level); + textureLevelWidth = texture2d->getWidth(level); + textureLevelHeight = texture2d->getHeight(level); + textureLevelDepth = 1; + texture = texture2d; + maxDimension = context->getMaximum2DTextureDimension(); + } + } + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); + if (textureCube) + { + textureInternalFormat = textureCube->getInternalFormat(target, level); + textureCompressed = textureCube->isCompressed(target, level); + textureIsDepth = false; + textureLevelWidth = textureCube->getWidth(target, level); + textureLevelHeight = textureCube->getHeight(target, level); + textureLevelDepth = 1; + texture = textureCube; + maxDimension = context->getMaximumCubeTextureDimension(); + } + } + break; + + case GL_TEXTURE_2D_ARRAY: + { + gl::Texture2DArray *texture2dArray = context->getTexture2DArray(); + if (texture2dArray) + { + textureInternalFormat = texture2dArray->getInternalFormat(level); + textureCompressed = texture2dArray->isCompressed(level); + textureIsDepth = texture2dArray->isDepth(level); + textureLevelWidth = texture2dArray->getWidth(level); + textureLevelHeight = texture2dArray->getHeight(level); + textureLevelDepth = texture2dArray->getLayers(level); + texture = texture2dArray; + maxDimension = context->getMaximum2DTextureDimension(); + } + } + break; + + case GL_TEXTURE_3D: + { + gl::Texture3D *texture3d = context->getTexture3D(); + if (texture3d) + { + textureInternalFormat = texture3d->getInternalFormat(level); + textureCompressed = texture3d->isCompressed(level); + textureIsDepth = texture3d->isDepth(level); + textureLevelWidth = texture3d->getWidth(level); + textureLevelHeight = texture3d->getHeight(level); + textureLevelDepth = texture3d->getDepth(level); + texture = texture3d; + maxDimension = context->getMaximum3DTextureDimension(); + } + } + break; + + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (!texture) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (texture->isImmutable() && !isSubImage) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (textureIsDepth) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (textureCompressed) + { + int clientVersion = context->getClientVersion(); + GLint blockWidth = GetCompressedBlockWidth(textureInternalFormat, clientVersion); + GLint blockHeight = GetCompressedBlockHeight(textureInternalFormat, clientVersion); + + if (((width % blockWidth) != 0 && width != textureLevelWidth) || + ((height % blockHeight) != 0 && height != textureLevelHeight)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (isSubImage) + { + if (xoffset + width > textureLevelWidth || + yoffset + height > textureLevelHeight || + zoffset >= textureLevelDepth) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + else + { + if (IsCubemapTextureTarget(target) && width != height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (!IsValidInternalFormat(internalformat, context)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + int maxLevelDimension = (maxDimension >> level); + if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + + *textureFormatOut = textureInternalFormat; + return true; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/validationES.h b/chromium/third_party/angle/src/libGLESv2/validationES.h new file mode 100644 index 00000000000..2bce2d75efd --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES.h @@ -0,0 +1,63 @@ +// +// Copyright (c) 2013 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. +// + +// validationES.h: Validation functions for generic OpenGL ES entry point parameters + +#ifndef LIBGLESV2_VALIDATION_ES_H +#define LIBGLESV2_VALIDATION_ES_H + +namespace gl +{ + +class Context; + +bool ValidCap(const Context *context, GLenum cap); +bool ValidTextureTarget(const Context *context, GLenum target); +bool ValidTexture2DDestinationTarget(const Context *context, GLenum target); +bool ValidFramebufferTarget(GLenum target); +bool ValidBufferTarget(const Context *context, GLenum target); +bool ValidBufferParameter(const Context *context, GLenum pname); +bool ValidMipLevel(const Context *context, GLenum target, GLint level); +bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth); +bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height); +bool ValidQueryType(const gl::Context *context, GLenum queryType); +bool ValidProgram(const gl::Context *context, GLuint id); + +bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + bool angleExtension); +bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer); + +bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, + GLenum filter, bool fromAngleExtension); + +bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion); + +bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param); + +bool ValidateSamplerObjectParameter(GLenum pname); + +bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels); + +bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id); +bool ValidateEndQuery(gl::Context *context, GLenum target); + +bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count); +bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose); + +bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams); + +bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, + GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, + GLint border, GLenum *textureInternalFormatOut); + +} + +#endif // LIBGLESV2_VALIDATION_ES_H diff --git a/chromium/third_party/angle/src/libGLESv2/validationES2.cpp b/chromium/third_party/angle/src/libGLESv2/validationES2.cpp new file mode 100644 index 00000000000..a0ef855e327 --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES2.cpp @@ -0,0 +1,992 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters + +#include "libGLESv2/validationES2.h" +#include "libGLESv2/validationES.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/main.h" + +#include "common/mathutil.h" +#include "common/utilities.h" + +namespace gl +{ + +static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, + GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type, + gl::Texture2D *texture) +{ + if (!texture) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (compressed != texture->isCompressed(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (format != GL_NONE) + { + GLenum internalformat = gl::GetSizedInternalFormat(format, type, 2); + if (internalformat != texture->getInternalFormat(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (compressed) + { + if ((width % 4 != 0 && width != texture->getWidth(level)) || + (height % 4 != 0 && height != texture->getHeight(level))) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (xoffset + width > texture->getWidth(level) || + yoffset + height > texture->getHeight(level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + return true; +} + +static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, + GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type, + gl::TextureCubeMap *texture) +{ + if (!texture) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (compressed != texture->isCompressed(target, level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (format != GL_NONE) + { + GLenum internalformat = gl::GetSizedInternalFormat(format, type, 2); + if (internalformat != texture->getInternalFormat(target, level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (compressed) + { + if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || + (height % 4 != 0 && height != texture->getHeight(target, 0))) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (xoffset + width > texture->getWidth(target, level) || + yoffset + height > texture->getHeight(target, level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + return true; +} + +bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (!ValidImageSize(context, target, level, width, height, 1)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (level < 0 || xoffset < 0 || + std::numeric_limits<GLsizei>::max() - xoffset < width || + std::numeric_limits<GLsizei>::max() - yoffset < height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (!isSubImage && !isCompressed && internalformat != format) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + gl::Texture *texture = NULL; + bool textureCompressed = false; + GLenum textureInternalFormat = GL_NONE; + GLint textureLevelWidth = 0; + GLint textureLevelHeight = 0; + switch (target) + { + case GL_TEXTURE_2D: + { + if (width > (context->getMaximum2DTextureDimension() >> level) || + height > (context->getMaximum2DTextureDimension() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture2D *tex2d = context->getTexture2D(); + if (tex2d) + { + textureCompressed = tex2d->isCompressed(level); + textureInternalFormat = tex2d->getInternalFormat(level); + textureLevelWidth = tex2d->getWidth(level); + textureLevelHeight = tex2d->getHeight(level); + texture = tex2d; + } + + if (isSubImage && !validateSubImageParams2D(isCompressed, width, height, xoffset, yoffset, + level, format, type, tex2d)) + { + return false; + } + + texture = tex2d; + } + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (!isSubImage && width != height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (width > (context->getMaximumCubeTextureDimension() >> level) || + height > (context->getMaximumCubeTextureDimension() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::TextureCubeMap *texCube = context->getTextureCubeMap(); + if (texCube) + { + textureCompressed = texCube->isCompressed(target, level); + textureInternalFormat = texCube->getInternalFormat(target, level); + textureLevelWidth = texCube->getWidth(target, level); + textureLevelHeight = texCube->getHeight(target, level); + texture = texCube; + } + + if (isSubImage && !validateSubImageParamsCube(isCompressed, width, height, xoffset, yoffset, + target, level, format, type, texCube)) + { + return false; + } + } + break; + + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (!texture) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!isSubImage && texture->isImmutable()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + // Verify zero border + if (border != 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat; + if (isCompressed) + { + if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + switch (actualInternalFormat) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->supportsDXT1Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->supportsDXT3Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->supportsDXT5Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + else + { + // validate <type> by itself (used as secondary key below) + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_OES: + case GL_HALF_FLOAT_OES: + case GL_FLOAT: + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + // validate <format> + <type> combinations + // - invalid <format> -> sets INVALID_ENUM + // - invalid <format>+<type> combination -> sets INVALID_OPERATION + switch (format) + { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RED: + if (!context->supportsRGTextures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RG: + if (!context->supportsRGTextures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + break; + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_DEPTH_STENCIL_OES: + switch (type) + { + case GL_UNSIGNED_INT_24_8_OES: + break; + default: + return gl::error(GL_INVALID_OPERATION, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + switch (format) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (context->supportsDXT1Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->supportsDXT3Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->supportsDXT5Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + if (!context->supportsDepthTextures()) + { + return gl::error(GL_INVALID_VALUE, false); + } + if (target != GL_TEXTURE_2D) + { + return gl::error(GL_INVALID_OPERATION, false); + } + // OES_depth_texture supports loading depth data and multiple levels, + // but ANGLE_depth_texture does not + if (pixels != NULL || level != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + default: + break; + } + + if (type == GL_FLOAT) + { + if (!context->supportsFloat32Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + } + else if (type == GL_HALF_FLOAT_OES) + { + if (!context->supportsFloat16Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + } + } + + return true; +} + + + +bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + GLenum textureInternalFormat = GL_NONE; + + if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, + xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat)) + { + return false; + } + + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat(); + GLenum textureFormat = gl::GetFormat(textureInternalFormat, context->getClientVersion()); + + // [OpenGL ES 2.0.24] table 3.9 + if (isSubImage) + { + switch (textureFormat) + { + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_LUMINANCE: + if (colorbufferFormat != GL_R8_EXT && + colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && + colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return gl::error(GL_INVALID_OPERATION, false); + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + return gl::error(GL_INVALID_OPERATION, false); + default: + return gl::error(GL_INVALID_OPERATION, false); + } + } + else + { + switch (internalformat) + { + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_LUMINANCE: + if (colorbufferFormat != GL_R8_EXT && + colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && + colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (context->supportsDXT1Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->supportsDXT3Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->supportsDXT5Textures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH_STENCIL_OES: + case GL_DEPTH24_STENCIL8_OES: + if (context->supportsDepthTextures()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + else + { + return gl::error(GL_INVALID_ENUM, false); + } + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + + // If width or height is zero, it is a no-op. Return false without setting an error. + return (width > 0 && height > 0); +} + +bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height) +{ + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (width < 1 || height < 1 || levels < 1) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (target == GL_TEXTURE_CUBE_MAP && width != height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + GLenum format = gl::GetFormat(internalformat, context->getClientVersion()); + GLenum type = gl::GetType(internalformat, context->getClientVersion()); + + if (format == GL_NONE || type == GL_NONE) + { + return gl::error(GL_INVALID_ENUM, false); + } + + switch (target) + { + case GL_TEXTURE_2D: + if (width > context->getMaximum2DTextureDimension() || + height > context->getMaximum2DTextureDimension()) + { + return gl::error(GL_INVALID_VALUE, false); + } + break; + case GL_TEXTURE_CUBE_MAP: + if (width > context->getMaximumCubeTextureDimension() || + height > context->getMaximumCubeTextureDimension()) + { + return gl::error(GL_INVALID_VALUE, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (levels != 1 && !context->supportsNonPower2Texture()) + { + if (!gl::isPow2(width) || !gl::isPow2(height)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + switch (internalformat) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->supportsDXT1Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->supportsDXT3Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->supportsDXT5Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_RGBA32F_EXT: + case GL_RGB32F_EXT: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + if (!context->supportsFloat32Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_RGBA16F_EXT: + case GL_RGB16F_EXT: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + if (!context->supportsFloat16Textures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_R8_EXT: + case GL_RG8_EXT: + case GL_R16F_EXT: + case GL_RG16F_EXT: + case GL_R32F_EXT: + case GL_RG32F_EXT: + if (!context->supportsRGTextures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH24_STENCIL8_OES: + if (!context->supportsDepthTextures()) + { + return gl::error(GL_INVALID_ENUM, false); + } + if (target != GL_TEXTURE_2D) + { + return gl::error(GL_INVALID_OPERATION, false); + } + // ANGLE_depth_texture only supports 1-level textures + if (levels != 1) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + default: + break; + } + + gl::Texture *texture = NULL; + switch(target) + { + case GL_TEXTURE_2D: + texture = context->getTexture2D(); + break; + case GL_TEXTURE_CUBE_MAP: + texture = context->getTextureCubeMap(); + break; + default: + UNREACHABLE(); + } + + if (!texture || texture->id() == 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (texture->isImmutable()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidateES2FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) +{ + META_ASSERT(GL_DRAW_FRAMEBUFFER == GL_DRAW_FRAMEBUFFER_ANGLE && GL_READ_FRAMEBUFFER == GL_READ_FRAMEBUFFER_ANGLE); + + if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) + { + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0); + if (colorAttachment >= context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + + if (texture != 0) + { + gl::Texture *tex = context->getTexture(texture); + + if (tex == NULL) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + switch (textarget) + { + case GL_TEXTURE_2D: + { + if (tex->getTarget() != GL_TEXTURE_2D) + { + return gl::error(GL_INVALID_OPERATION, false); + } + gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); + if (tex2d->isCompressed(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + } + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) + { + return gl::error(GL_INVALID_OPERATION, false); + } + gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); + if (texcube->isCompressed(textarget, level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + } + + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (level != 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + + gl::Framebuffer *framebuffer = NULL; + GLuint framebufferHandle = 0; + if (target == GL_READ_FRAMEBUFFER) + { + framebuffer = context->getReadFramebuffer(); + framebufferHandle = context->getReadFramebufferHandle(); + } + else + { + framebuffer = context->getDrawFramebuffer(); + framebufferHandle = context->getDrawFramebufferHandle(); + } + + if (framebufferHandle == 0 || !framebuffer) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +// check for combinations of format and type that are valid for ReadPixels +bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type) +{ + switch (format) + { + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + return false; + } + break; + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + break; + default: + return false; + } + break; + case GL_RG_EXT: + case GL_RED_EXT: + if (!context->supportsRGTextures()) + { + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + return false; + } + break; + + default: + return false; + } + return true; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/validationES2.h b/chromium/third_party/angle/src/libGLESv2/validationES2.h new file mode 100644 index 00000000000..02775ff012b --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES2.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2013 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. +// + +// validationES2.h: Validation functions for OpenGL ES 2.0 entry point parameters + +#ifndef LIBGLESV2_VALIDATION_ES2_H +#define LIBGLESV2_VALIDATION_ES2_H + +namespace gl +{ + +class Context; + +bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, const GLvoid *pixels); + +bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height); + +bool ValidateES2FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level); + +bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type); + +} + +#endif // LIBGLESV2_VALIDATION_ES2_H diff --git a/chromium/third_party/angle/src/libGLESv2/validationES3.cpp b/chromium/third_party/angle/src/libGLESv2/validationES3.cpp new file mode 100644 index 00000000000..a45a5a31d3f --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES3.cpp @@ -0,0 +1,760 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters + +#include "libGLESv2/validationES3.h" +#include "libGLESv2/validationES.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/main.h" + +#include "common/mathutil.h" + +namespace gl +{ + +bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, + GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + // Validate image size + if (!ValidImageSize(context, target, level, width, height, depth)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + // Verify zero border + if (border != 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0 || + std::numeric_limits<GLsizei>::max() - xoffset < width || + std::numeric_limits<GLsizei>::max() - yoffset < height || + std::numeric_limits<GLsizei>::max() - zoffset < depth) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture *texture = NULL; + bool textureCompressed = false; + GLenum textureInternalFormat = GL_NONE; + GLint textureLevelWidth = 0; + GLint textureLevelHeight = 0; + GLint textureLevelDepth = 0; + switch (target) + { + case GL_TEXTURE_2D: + { + if (width > (context->getMaximum2DTextureDimension() >> level) || + height > (context->getMaximum2DTextureDimension() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture2D *texture2d = context->getTexture2D(); + if (texture2d) + { + textureCompressed = texture2d->isCompressed(level); + textureInternalFormat = texture2d->getInternalFormat(level); + textureLevelWidth = texture2d->getWidth(level); + textureLevelHeight = texture2d->getHeight(level); + textureLevelDepth = 1; + texture = texture2d; + } + } + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (!isSubImage && width != height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (width > (context->getMaximumCubeTextureDimension() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); + if (textureCube) + { + textureCompressed = textureCube->isCompressed(target, level); + textureInternalFormat = textureCube->getInternalFormat(target, level); + textureLevelWidth = textureCube->getWidth(target, level); + textureLevelHeight = textureCube->getHeight(target, level); + textureLevelDepth = 1; + texture = textureCube; + } + } + break; + + case GL_TEXTURE_3D: + { + if (width > (context->getMaximum3DTextureDimension() >> level) || + height > (context->getMaximum3DTextureDimension() >> level) || + depth > (context->getMaximum3DTextureDimension() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture3D *texture3d = context->getTexture3D(); + if (texture3d) + { + textureCompressed = texture3d->isCompressed(level); + textureInternalFormat = texture3d->getInternalFormat(level); + textureLevelWidth = texture3d->getWidth(level); + textureLevelHeight = texture3d->getHeight(level); + textureLevelDepth = texture3d->getDepth(level); + texture = texture3d; + } + } + break; + + case GL_TEXTURE_2D_ARRAY: + { + if (width > (context->getMaximum2DTextureDimension() >> level) || + height > (context->getMaximum2DTextureDimension() >> level) || + depth > (context->getMaximum2DArrayTextureLayers() >> level)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture2DArray *texture2darray = context->getTexture2DArray(); + if (texture2darray) + { + textureCompressed = texture2darray->isCompressed(level); + textureInternalFormat = texture2darray->getInternalFormat(level); + textureLevelWidth = texture2darray->getWidth(level); + textureLevelHeight = texture2darray->getHeight(level); + textureLevelDepth = texture2darray->getLayers(level); + texture = texture2darray; + } + } + break; + + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (!texture) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (texture->isImmutable() && !isSubImage) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + // Validate texture formats + GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat; + int clientVersion = context->getClientVersion(); + if (isCompressed) + { + if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!gl::IsFormatCompressed(actualInternalFormat, clientVersion)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (target == GL_TEXTURE_3D) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + else + { + // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid + // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d) + if (!gl::IsValidInternalFormat(actualInternalFormat, context) || + !gl::IsValidFormat(format, clientVersion) || + !gl::IsValidType(type, clientVersion)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, clientVersion)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + // Validate sub image parameters + if (isSubImage) + { + if (isCompressed != textureCompressed) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (isCompressed) + { + if ((width % 4 != 0 && width != textureLevelWidth) || + (height % 4 != 0 && height != textureLevelHeight)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + if (width == 0 || height == 0 || depth == 0) + { + return false; + } + + if (xoffset < 0 || yoffset < 0 || zoffset < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (std::numeric_limits<GLsizei>::max() - xoffset < width || + std::numeric_limits<GLsizei>::max() - yoffset < height || + std::numeric_limits<GLsizei>::max() - zoffset < depth) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (xoffset + width > textureLevelWidth || + yoffset + height > textureLevelHeight || + zoffset + depth > textureLevelDepth) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + + // Check for pixel unpack buffer related API errors + gl::Buffer *pixelUnpackBuffer = context->getPixelUnpackBuffer(); + if (pixelUnpackBuffer != NULL) + { + // ...the data would be unpacked from the buffer object such that the memory reads required + // would exceed the data store size. + size_t widthSize = static_cast<size_t>(width); + size_t heightSize = static_cast<size_t>(height); + size_t depthSize = static_cast<size_t>(depth); + GLenum sizedFormat = gl::IsSizedInternalFormat(actualInternalFormat, clientVersion) ? + actualInternalFormat : + gl::GetSizedInternalFormat(actualInternalFormat, type, clientVersion); + + size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(sizedFormat, clientVersion)); + + if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) || + !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) || + !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes)) + { + // Overflow past the end of the buffer + return gl::error(GL_INVALID_OPERATION, false); + } + + size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes; + size_t offset = reinterpret_cast<size_t>(pixels); + + if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) || + ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size()))) + { + // Overflow past the end of the buffer + return gl::error(GL_INVALID_OPERATION, false); + } + + // ...data is not evenly divisible into the number of bytes needed to store in memory a datum + // indicated by type. + size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeBytes(type)); + + if ((offset % dataBytesPerPixel) != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + // ...the buffer object's data store is currently mapped. + if (pixelUnpackBuffer->mapped()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + return true; +} + +bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, + bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + GLenum textureInternalFormat; + if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, + xoffset, yoffset, zoffset, x, y, width, height, + border, &textureInternalFormat)) + { + return false; + } + + gl::Framebuffer *framebuffer = context->getReadFramebuffer(); + + if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + { + return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false); + } + + if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer(); + GLenum colorbufferInternalFormat = source->getInternalFormat(); + + if (isSubImage) + { + if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, + context->getReadFramebufferHandle(), + context->getClientVersion())) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + else + { + if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat, + context->getReadFramebufferHandle(), + context->getClientVersion())) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + + // If width or height is zero, it is a no-op. Return false without setting an error. + return (width > 0 && height > 0); +} + +bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + if (width < 1 || height < 1 || depth < 1 || levels < 1) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + gl::Texture *texture = NULL; + switch (target) + { + case GL_TEXTURE_2D: + { + texture = context->getTexture2D(); + + if (width > (context->getMaximum2DTextureDimension()) || + height > (context->getMaximum2DTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + break; + + case GL_TEXTURE_CUBE_MAP: + { + texture = context->getTextureCubeMap(); + + if (width != height) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (width > (context->getMaximumCubeTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + break; + + case GL_TEXTURE_3D: + { + texture = context->getTexture3D(); + + if (width > (context->getMaximum3DTextureDimension()) || + height > (context->getMaximum3DTextureDimension()) || + depth > (context->getMaximum3DTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + break; + + case GL_TEXTURE_2D_ARRAY: + { + texture = context->getTexture2DArray(); + + if (width > (context->getMaximum2DTextureDimension()) || + height > (context->getMaximum2DTextureDimension()) || + depth > (context->getMaximum2DArrayTextureLayers())) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + break; + + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (!texture || texture->id() == 0) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (texture->isImmutable()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (!gl::IsValidInternalFormat(internalformat, context)) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (!gl::IsSizedInternalFormat(internalformat, context->getClientVersion())) + { + return gl::error(GL_INVALID_ENUM, false); + } + + return true; +} + +bool ValidateES3FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level, GLint layer, + bool layerCall) +{ + if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) + { + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0); + if (colorAttachment >= context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_VALUE, false); + } + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + + if (texture != 0) + { + gl::Texture *tex = context->getTexture(texture); + + if (tex == NULL) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + if (level < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (layer < 0) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (!layerCall) + { + switch (textarget) + { + case GL_TEXTURE_2D: + { + if (level > gl::log2(context->getMaximum2DTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + if (tex->getTarget() != GL_TEXTURE_2D) + { + return gl::error(GL_INVALID_OPERATION, false); + } + gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); + if (tex2d->isCompressed(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + } + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (level > gl::log2(context->getMaximumCubeTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) + { + return gl::error(GL_INVALID_OPERATION, false); + } + gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); + if (texcube->isCompressed(textarget, level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + break; + } + + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + else + { + switch (tex->getTarget()) + { + case GL_TEXTURE_2D_ARRAY: + { + if (level > gl::log2(context->getMaximum2DTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (layer >= context->getMaximum2DArrayTextureLayers()) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex); + if (texArray->isCompressed(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + break; + } + + case GL_TEXTURE_3D: + { + if (level > gl::log2(context->getMaximum3DTextureDimension())) + { + return gl::error(GL_INVALID_VALUE, false); + } + + if (layer >= context->getMaximum3DTextureDimension()) + { + return gl::error(GL_INVALID_VALUE, false); + } + + gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex); + if (tex3d->isCompressed(level)) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + break; + } + + default: + return gl::error(GL_INVALID_OPERATION, false); + } + } + } + + gl::Framebuffer *framebuffer = NULL; + GLuint framebufferHandle = 0; + if (target == GL_READ_FRAMEBUFFER) + { + framebuffer = context->getReadFramebuffer(); + framebufferHandle = context->getReadFramebufferHandle(); + } + else + { + framebuffer = context->getDrawFramebuffer(); + framebufferHandle = context->getDrawFramebufferHandle(); + } + + if (framebufferHandle == 0 || !framebuffer) + { + return gl::error(GL_INVALID_OPERATION, false); + } + + return true; +} + +bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type) +{ + switch (format) + { + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (internalFormat != GL_RGB10_A2) + { + return false; + } + break; + case GL_FLOAT: + if (gl::GetComponentType(internalFormat, 3) != GL_FLOAT) + { + return false; + } + break; + default: + return false; + } + break; + case GL_RGBA_INTEGER: + switch (type) + { + case GL_INT: + if (gl::GetComponentType(internalFormat, 3) != GL_INT) + { + return false; + } + break; + case GL_UNSIGNED_INT: + if (gl::GetComponentType(internalFormat, 3) != GL_UNSIGNED_INT) + { + return false; + } + break; + default: + return false; + } + break; + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + break; + default: + return false; + } + break; + case GL_RG_EXT: + case GL_RED_EXT: + if (!context->supportsRGTextures()) + { + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + return false; + } + break; + default: + return false; + } + return true; +} + +bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments, + const GLenum* attachments) +{ + bool defaultFramebuffer = false; + + switch (target) + { + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + defaultFramebuffer = context->getDrawFramebufferHandle() == 0; + break; + case GL_READ_FRAMEBUFFER: + defaultFramebuffer = context->getReadFramebufferHandle() == 0; + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + for (int i = 0; i < numAttachments; ++i) + { + if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) + { + if (defaultFramebuffer) + { + return gl::error(GL_INVALID_ENUM, false); + } + + if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getMaximumRenderTargets()) + { + return gl::error(GL_INVALID_OPERATION, false); + } + } + else + { + switch (attachments[i]) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (defaultFramebuffer) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + case GL_COLOR: + case GL_DEPTH: + case GL_STENCIL: + if (!defaultFramebuffer) + { + return gl::error(GL_INVALID_ENUM, false); + } + break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + } + } + + return true; +} + +} diff --git a/chromium/third_party/angle/src/libGLESv2/validationES3.h b/chromium/third_party/angle/src/libGLESv2/validationES3.h new file mode 100644 index 00000000000..93917c26bae --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/validationES3.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2013 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. +// + +// validationES3.h: Validation functions for OpenGL ES 3.0 entry point parameters + +#ifndef LIBGLESV2_VALIDATION_ES3_H +#define LIBGLESV2_VALIDATION_ES3_H + +namespace gl +{ + +class Context; + +bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, + GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, const GLvoid *pixels); + +bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, + bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border); + +bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth); + +bool ValidateES3FramebufferTextureParameters(gl::Context *context, GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level, GLint layer, + bool layerCall); + +bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type); + +bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments, + const GLenum* attachments); + +} + +#endif // LIBGLESV2_VALIDATION_ES3_H |