diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer')
108 files changed, 8114 insertions, 6212 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h index bea689b956..f0b5f02227 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h @@ -20,12 +20,12 @@ class BufferImpl public: virtual ~BufferImpl() { } - virtual void setData(const void* data, size_t size, GLenum usage) = 0; + virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; virtual void *getData() = 0; - virtual void setSubData(const void* data, size_t size, size_t offset) = 0; - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access) = 0; - virtual void unmap() = 0; + virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0; + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; + virtual gl::Error unmap() = 0; virtual void markTransformFeedbackUsage() = 0; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp index 5963534e03..370b086233 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp @@ -1,4 +1,3 @@ -#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 diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h index 8fcffa4309..3bfc663762 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h @@ -13,6 +13,8 @@ #include "common/debug.h" +#include <GLES2/gl2.h> + namespace gl { class Framebuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp index e957d96270..f68ac383de 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -1,4 +1,3 @@ -#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 @@ -10,16 +9,49 @@ #include "libGLESv2/renderer/IndexRangeCache.h" #include "libGLESv2/formatutils.h" + #include "common/debug.h" + #include <tuple> namespace rx { -void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx, +template <class IndexType> +static RangeUI ComputeTypedRange(const IndexType *indices, GLsizei count) +{ + unsigned int minIndex = indices[0]; + unsigned int maxIndex = indices[0]; + + for (GLsizei i = 1; i < count; i++) + { + if (minIndex > indices[i]) minIndex = indices[i]; + if (maxIndex < indices[i]) maxIndex = indices[i]; + } + + return RangeUI(minIndex, maxIndex); +} + +RangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsizei count) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return ComputeTypedRange(static_cast<const GLubyte*>(indices), count); + case GL_UNSIGNED_INT: + return ComputeTypedRange(static_cast<const GLuint*>(indices), count); + case GL_UNSIGNED_SHORT: + return ComputeTypedRange(static_cast<const GLushort*>(indices), count); + default: + UNREACHABLE(); + return RangeUI(); + } +} + +void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range, unsigned int streamOffset) { - mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(minIdx, maxIdx, streamOffset); + mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset); } void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size) @@ -31,7 +63,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::GetTypeBytes(i->first.type) * i->first.count); + unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count); if (invalidateEnd < rangeStart || invalidateStart > rangeEnd) { @@ -44,21 +76,19 @@ void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size) } } -bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex, - unsigned int *outMaxIndex, unsigned int *outStreamOffset) const +bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, + RangeUI *outRange, unsigned int *outStreamOffset) const { IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count)); if (i != mIndexRangeCache.end()) { - if (outMinIndex) *outMinIndex = i->second.minIndex; - if (outMaxIndex) *outMaxIndex = i->second.maxIndex; + if (outRange) *outRange = i->second.range; if (outStreamOffset) *outStreamOffset = i->second.streamOffset; return true; } else { - if (outMinIndex) *outMinIndex = 0; - if (outMaxIndex) *outMaxIndex = 0; + if (outRange) *outRange = RangeUI(0, 0); if (outStreamOffset) *outStreamOffset = 0; return false; } @@ -89,12 +119,13 @@ bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const } IndexRangeCache::IndexBounds::IndexBounds() - : minIndex(0), maxIndex(0), streamOffset(0) + : range(0, 0), + streamOffset(0) { } -IndexRangeCache::IndexBounds::IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset) - : minIndex(minIdx), maxIndex(maxIdx), streamOffset(offset) +IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset) + : range(rangeIn), streamOffset(offset) { } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h index 837a44acd3..a7d91e035b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h @@ -11,6 +11,10 @@ #define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_ #include "common/angleutils.h" +#include "common/mathutil.h" + +#include "angle_gl.h" + #include <map> namespace rx @@ -19,14 +23,16 @@ namespace rx class IndexRangeCache { public: - void addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx, + void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range, unsigned int streamOffset); - bool findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex, - unsigned int *outMaxIndex, unsigned int *outStreamOffset) const; + bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut, + unsigned int *outStreamOffset) const; void invalidateRange(unsigned int offset, unsigned int size); void clear(); + static RangeUI ComputeRange(GLenum type, const GLvoid *indices, GLsizei count); + private: struct IndexRange { @@ -42,12 +48,11 @@ class IndexRangeCache struct IndexBounds { - unsigned int minIndex; - unsigned int maxIndex; + RangeUI range; unsigned int streamOffset; IndexBounds(); - IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset); + IndexBounds(const RangeUI &range, unsigned int offset); }; typedef std::map<IndexRange, IndexBounds> IndexRangeMap; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h new file mode 100644 index 0000000000..ba0955fdf8 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h @@ -0,0 +1,58 @@ +// +// Copyright 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. +// + +// ProgramImpl.h: Defines the abstract rx::ProgramImpl class. + +#ifndef LIBGLESV2_RENDERER_PROGRAMIMPL_H_ +#define LIBGLESV2_RENDERER_PROGRAMIMPL_H_ + +#include "common/angleutils.h" +#include "libGLESv2/BinaryStream.h" +#include "libGLESv2/Constants.h" +#include "libGLESv2/ProgramBinary.h" + +namespace rx +{ + +class DynamicHLSL; +class Renderer; + +class ProgramImpl +{ +public: + virtual ~ProgramImpl() { } + + // TODO: Temporary interfaces to ease migration. Remove soon! + virtual Renderer *getRenderer() = 0; + virtual DynamicHLSL *getDynamicHLSL() = 0; + virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0; + + virtual GLenum getBinaryFormat() = 0; + virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; + virtual bool save(gl::BinaryOutputStream *stream) = 0; + + virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers) = 0; + virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, + const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], + const sh::Attribute shaderAttributes[], + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers) = 0; + + virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, int *registers, + std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, + gl::VariableLocation> *outputVariables) = 0; + + virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0; + + virtual void reset() = 0; +}; + +} + +#endif // LIBGLESV2_RENDERER_PROGRAMIMPL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h index a6750a204b..6b45810a3b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h @@ -9,28 +9,27 @@ #ifndef LIBGLESV2_RENDERER_QUERYIMPL_H_ #define LIBGLESV2_RENDERER_QUERYIMPL_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" +#include <GLES2/gl2.h> + namespace rx { class QueryImpl { public: - explicit QueryImpl(GLenum type) : mType(type), mStatus(GL_FALSE), mResult(0) { } + explicit QueryImpl(GLenum type) { mType = type; } virtual ~QueryImpl() { } - virtual void begin() = 0; - virtual void end() = 0; - virtual GLuint getResult() = 0; - virtual GLboolean isResultAvailable() = 0; - virtual bool isStarted() const = 0; - - GLenum getType() const { return mType; } + virtual gl::Error begin() = 0; + virtual gl::Error end() = 0; + virtual gl::Error getResult(GLuint *params) = 0; + virtual gl::Error isResultAvailable(GLuint *available) = 0; - protected: - GLuint mResult; - GLboolean mStatus; + GLenum getType() const { return mType; } private: DISALLOW_COPY_AND_ASSIGN(QueryImpl); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp index 590004ac9b..910d0285f1 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -7,12 +6,10 @@ // Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. -#include <EGL/eglext.h> #include "libGLESv2/main.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" #include "common/utilities.h" -#include "third_party/trace_event/trace_event.h" #include "libGLESv2/Shader.h" #if defined (ANGLE_ENABLE_D3D9) @@ -23,11 +20,17 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #endif // ANGLE_ENABLE_D3D11 +#if defined (ANGLE_TEST_CONFIG) +#define ANGLE_DEFAULT_D3D11 1 +#endif + #if !defined(ANGLE_DEFAULT_D3D11) // Enables use of the Direct3D 11 API for a default display, when available #define ANGLE_DEFAULT_D3D11 0 #endif +#include <EGL/eglext.h> + namespace rx { @@ -40,7 +43,6 @@ Renderer::Renderer(egl::Display *display) Renderer::~Renderer() { - gl::Shader::releaseCompiler(); } const gl::Caps &Renderer::getRendererCaps() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index f1e0fd2d99..b2249741ab 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -13,9 +13,13 @@ #include "libGLESv2/Uniform.h" #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Error.h" + +#include <cstdint> + +#include <EGL/egl.h> #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) -#include <d3dcompiler.h> // 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 @@ -40,10 +44,7 @@ struct VertexAttribCurrentValueData; namespace rx { -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; -class TextureStorageInterface3D; -class TextureStorageInterface2DArray; +class TextureStorage; class VertexBuffer; class IndexBuffer; class QueryImpl; @@ -52,16 +53,16 @@ class BufferImpl; class VertexArrayImpl; class BufferStorage; struct TranslatedIndexData; +class ShaderImpl; +class ProgramImpl; class ShaderExecutable; class SwapChain; class RenderTarget; class Image; class TextureStorage; class UniformStorage; -class Texture2DImpl; -class TextureCubeImpl; -class Texture3DImpl; -class Texture2DArrayImpl; +class TextureImpl; +class TransformFeedbackImpl; struct ConfigDesc { @@ -108,37 +109,37 @@ class Renderer virtual SwapChain *createSwapChain(EGLNativeWindowType 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 gl::Error generateSwizzle(gl::Texture *texture) = 0; + virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; - virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; - virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0; - 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; + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0; + virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) = 0; + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) = 0; virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0; - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) = 0; - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; - virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) = 0; - virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0; + virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) = 0; + virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const 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 gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) = 0; + virtual gl::Error 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, 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 gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; + virtual gl::Error 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; + virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0; virtual void markAllStateDirty() = 0; @@ -157,62 +158,48 @@ class Renderer virtual std::string getRendererDescription() const = 0; virtual GUID getAdapterIdentifier() const = 0; - bool getVertexTextureSupport() const { return getMaxVertexTextureImageUnits() > 0; } - virtual unsigned int getMaxVertexTextureImageUnits() const = 0; - virtual unsigned int getMaxCombinedTextureImageUnits() const = 0; virtual unsigned int getReservedVertexUniformVectors() const = 0; virtual unsigned int getReservedFragmentUniformVectors() const = 0; - 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 getShareHandleSupport() const = 0; virtual bool getPostSubBufferSupport() const = 0; - virtual int getMaxRecommendedElementsIndices() const = 0; - virtual int getMaxRecommendedElementsVertices() const = 0; - virtual bool getSRGBTextureSupport() const = 0; virtual int getMajorShaderModel() 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; - // 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 copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) = 0; + virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) = 0; + virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) = 0; + virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) = 0; + + virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0; + virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0; + virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; + virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, 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; + + virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0; // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0; virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0; + // Shader creation + virtual ShaderImpl *createShader(GLenum type) = 0; + virtual ProgramImpl *createProgram() = 0; + // Shader operations + virtual void releaseShaderCompiler() = 0; virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers) = 0; @@ -231,10 +218,7 @@ class Renderer virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; // Texture creation - virtual Texture2DImpl *createTexture2D() = 0; - virtual TextureCubeImpl *createTextureCube() = 0; - virtual Texture3DImpl *createTexture3D() = 0; - virtual Texture2DArrayImpl *createTexture2DArray() = 0; + virtual TextureImpl *createTexture(GLenum target) = 0; // Buffer creation virtual BufferImpl *createBuffer() = 0; @@ -248,6 +232,9 @@ class Renderer virtual QueryImpl *createQuery(GLenum type) = 0; virtual FenceImpl *createFence() = 0; + // Transform Feedback creation + virtual TransformFeedbackImpl* createTransformFeedback() = 0; + // Current GLES client version void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; } int getCurrentClientVersion() const { return mCurrentClientVersion; } @@ -258,7 +245,6 @@ class Renderer 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; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h index 054d00a712..f17195673d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h @@ -13,6 +13,9 @@ #include "common/angleutils.h" #include "common/debug.h" +#include <vector> +#include <cstdint> + namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h new file mode 100644 index 0000000000..de5d30e6fe --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h @@ -0,0 +1,54 @@ +// +// Copyright 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. +// + +// ShaderImpl.h: Defines the abstract rx::ShaderImpl class. + +#ifndef LIBGLESV2_RENDERER_SHADERIMPL_H_ +#define LIBGLESV2_RENDERER_SHADERIMPL_H_ + +#include <vector> + +#include "common/angleutils.h" +#include "libGLESv2/Shader.h" + +namespace rx +{ + +class ShaderImpl +{ + public: + ShaderImpl() { } + virtual ~ShaderImpl() { } + + virtual bool compile(const std::string &source) = 0; + virtual const std::string &getInfoLog() const = 0; + virtual const std::string &getTranslatedSource() const = 0; + + const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; } + const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; } + const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; } + const std::vector<sh::Attribute> &getActiveAttributes() const { return mActiveAttributes; } + const std::vector<sh::Attribute> &getActiveOutputVariables() const { return mActiveOutputVariables; } + + std::vector<gl::PackedVarying> &getVaryings() { return mVaryings; } + std::vector<sh::Uniform> &getUniforms() { return mUniforms; } + std::vector<sh::InterfaceBlock> &getInterfaceBlocks() { return mInterfaceBlocks; } + std::vector<sh::Attribute> &getActiveAttributes() { return mActiveAttributes; } + std::vector<sh::Attribute> &getActiveOutputVariables() { return mActiveOutputVariables; } + + protected: + DISALLOW_COPY_AND_ASSIGN(ShaderImpl); + + std::vector<gl::PackedVarying> mVaryings; + std::vector<sh::Uniform> mUniforms; + std::vector<sh::InterfaceBlock> mInterfaceBlocks; + std::vector<sh::Attribute> mActiveAttributes; + std::vector<sh::Attribute> mActiveOutputVariables; +}; + +} + +#endif // LIBGLESV2_RENDERER_SHADERIMPL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h index 77546f81e7..1ec702f299 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h @@ -10,12 +10,12 @@ #ifndef LIBGLESV2_RENDERER_SWAPCHAIN_H_ #define LIBGLESV2_RENDERER_SWAPCHAIN_H_ -#include <EGL/eglplatform.h> #include "common/angleutils.h" +#include "common/platform.h" -#if !defined(ANGLE_FORCE_VSYNC_OFF) -#define ANGLE_FORCE_VSYNC_OFF 0 -#endif +#include <GLES2/gl2.h> +#include <EGL/egl.h> +#include <EGL/eglplatform.h> namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h index 35c9166023..e3cc50d680 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h @@ -11,6 +11,10 @@ #include "common/angleutils.h" +#include "angle_gl.h" + +#include "libGLESv2/ImageIndex.h" + namespace egl { class Surface; @@ -27,138 +31,38 @@ namespace rx { class Image; -class RenderTarget; class Renderer; -class TextureStorageInterface; +class TextureStorage; -class Texture2DImpl +class TextureImpl { public: - virtual ~Texture2DImpl() {} + virtual ~TextureImpl() {}; // TODO: If this methods could go away that would be ideal; // TextureStorage should only be necessary for the D3D backend, and as such // higher level code should not rely on it. - virtual TextureStorageInterface *getNativeTexture() = 0; - - virtual Image *getImage(int level) const = 0; - - virtual void setUsage(GLenum usage) = 0; - virtual bool hasDirtyImages() const = 0; - virtual void resetDirty() = 0; - - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0; - virtual void bindTexImage(egl::Surface *surface) = 0; - virtual void releaseTexImage() = 0; - - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) = 0; - virtual void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) = 0; - virtual void generateMipmaps() = 0; - - virtual unsigned int getRenderTargetSerial(GLint level) = 0; - - virtual RenderTarget *getRenderTarget(GLint level) = 0; - virtual RenderTarget *getDepthSencil(GLint level) = 0; - - virtual void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height) = 0; -}; - -class TextureCubeImpl -{ - public: - virtual ~TextureCubeImpl() {} - - virtual TextureStorageInterface *getNativeTexture() = 0; - - virtual Image *getImage(GLenum target, int level) const = 0; - - virtual void setUsage(GLenum usage) = 0; - virtual bool hasDirtyImages() const = 0; - virtual void resetDirty() = 0; - - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0; - virtual bool isCubeComplete() const = 0; - - virtual void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) = 0; - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei size) = 0; - virtual void generateMipmaps() = 0; - - virtual unsigned int getRenderTargetSerial(GLenum target, GLint level) = 0; - - virtual RenderTarget *getRenderTarget(GLenum target, GLint level) = 0; - virtual RenderTarget *getDepthStencil(GLenum target, GLint level) = 0; -}; - -class Texture3DImpl -{ - public: - virtual ~Texture3DImpl() {} - - virtual TextureStorageInterface *getNativeTexture() = 0; - - virtual Image *getImage(int level) const = 0; - - virtual void setUsage(GLenum usage) = 0; - virtual bool hasDirtyImages() const = 0; - virtual void resetDirty() = 0; - - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0; - virtual bool isMipmapComplete() const = 0; - - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual void generateMipmaps() = 0; - - virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0; - - virtual RenderTarget *getRenderTarget(GLint level) = 0; - virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0; - virtual RenderTarget *getDepthStencil(GLint level, GLint layer) = 0; -}; - -class Texture2DArrayImpl -{ - public: - virtual ~Texture2DArrayImpl() {} - - virtual TextureStorageInterface *getNativeTexture() = 0; + virtual TextureStorage *getNativeTexture() = 0; + // Deprecated in favour of the ImageIndex method virtual Image *getImage(int level, int layer) const = 0; + virtual Image *getImage(const gl::ImageIndex &index) const = 0; virtual GLsizei getLayerCount(int level) const = 0; virtual void setUsage(GLenum usage) = 0; - virtual bool hasDirtyImages() const = 0; - virtual void resetDirty() = 0; - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const = 0; - virtual bool isMipmapComplete() const = 0; - - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; + virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; + virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; + virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual void generateMipmaps() = 0; + virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual unsigned int getRenderTargetSerial(GLint level, GLint layer) = 0; + virtual void generateMipmaps() = 0; - virtual RenderTarget *getRenderTarget(GLint level, GLint layer) = 0; - virtual RenderTarget *getDepthStencil(GLint level, GLint layer) = 0; + virtual void bindTexImage(egl::Surface *surface) = 0; + virtual void releaseTexImage() = 0; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h new file mode 100644 index 0000000000..8425604d87 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h @@ -0,0 +1,31 @@ +// +// Copyright 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. +// + +// TransformFeedbackImpl.h: Defines the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_ +#define LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_ + +#include "common/angleutils.h" +#include "libGLESv2/TransformFeedback.h" + +namespace rx +{ + +class TransformFeedbackImpl +{ + public: + virtual ~TransformFeedbackImpl() { } + + virtual void begin(GLenum primitiveMode) = 0; + virtual void end() = 0; + virtual void pause() = 0; + virtual void resume() = 0; +}; + +} + +#endif // LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp index 765089cc96..004223d70f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp @@ -1,4 +1,3 @@ -#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 @@ -12,12 +11,12 @@ namespace rx { -void CopyBGRAUByteToRGBAUByte(const void *source, void *dest) +void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *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 + uint32_t argb = *reinterpret_cast<const uint32_t*>(source); + *reinterpret_cast<uint32_t*>(dest) = (argb & 0xFF00FF00) | // Keep alpha and green + (argb & 0x00FF0000) >> 16 | // Move red to blue + (argb & 0x000000FF) << 16; // Move blue to red } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h index 9b94404ee3..513eb5cb3d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.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. // @@ -12,31 +12,24 @@ #include "common/mathutil.h" #include "libGLESv2/angletypes.h" +#include <cstdint> + 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)); -} +void ReadColor(const uint8_t *source, uint8_t *dest); 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)); -} +void WriteColor(const uint8_t *source, uint8_t *dest); template <typename sourceType, typename destType, typename colorDataType> -void CopyPixel(const void *source, void *dest) -{ - colorDataType temp; - ReadColor<sourceType, colorDataType>(source, &temp); - WriteColor<destType, colorDataType>(&temp, dest); -} +void CopyPixel(const uint8_t *source, uint8_t *dest); -void CopyBGRAUByteToRGBAUByte(const void *source, void *dest); +void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest); } +#include "copyimage.inl" + #endif // LIBGLESV2_RENDERER_COPYIMAGE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl new file mode 100644 index 0000000000..0498cf7750 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl @@ -0,0 +1,32 @@ +// +// 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. +// + +// copyimage.inl: Defines image copying functions + +namespace rx +{ + +template <typename sourceType, typename colorDataType> +inline void ReadColor(const uint8_t *source, uint8_t *dest) +{ + sourceType::readColor(reinterpret_cast<gl::Color<colorDataType>*>(dest), reinterpret_cast<const sourceType*>(source)); +} + +template <typename destType, typename colorDataType> +inline void WriteColor(const uint8_t *source, uint8_t *dest) +{ + destType::writeColor(reinterpret_cast<destType*>(dest), reinterpret_cast<const gl::Color<colorDataType>*>(source)); +} + +template <typename sourceType, typename destType, typename colorDataType> +inline void CopyPixel(const uint8_t *source, uint8_t *dest) +{ + colorDataType temp; + ReadColor<sourceType, colorDataType>(source, &temp); + WriteColor<destType, colorDataType>(&temp, dest); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h b/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h index aca031701e..e0e8af166b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.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. // @@ -11,299 +11,25 @@ #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) +namespace rx { - 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; +// '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, size_t componentCount, uint32_t widenDefaultValueBits> +inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); - 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); +template <size_t componentCount> +inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); - offsetOutput[i] = offsetInput[i]; - } - } -} +template <typename T, size_t componentCount, bool normalized> +inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); 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; - } - } -} +inline void CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output); -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)); - } -} +#include "copyvertex.inl" #endif // LIBGLESV2_RENDERER_COPYVERTEX_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl b/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl new file mode 100644 index 0000000000..7eef17b22b --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl @@ -0,0 +1,288 @@ +// +// 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. +// + +namespace rx +{ + +template <typename T, size_t componentCount, uint32_t widenDefaultValueBits> +inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + const size_t 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 + { + size_t outputStride = widen ? 4 : componentCount; + + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast<const T*>(input + (i * stride)); + T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride; + + for (size_t j = 0; j < componentCount; j++) + { + offsetOutput[j] = offsetInput[j]; + } + + if (widen) + { + offsetOutput[3] = defaultValue; + } + } + } +} + +template <size_t componentCount> +inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + static const float divisor = 1.0f / (1 << 16); + + for (size_t i = 0; i < count; i++) + { + const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(input + (stride * i)); + float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; + + for (size_t j = 0; j < componentCount; j++) + { + offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor; + } + } +} + +template <typename T, size_t componentCount, bool normalized> +inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + typedef std::numeric_limits<T> NL; + + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast<const T*>(input + (stride * i)); + float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount; + + for (size_t 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]); + } + } + } +} + +namespace priv +{ + +template <bool isSigned, bool normalized, bool toFloat> +static inline void CopyPackedRGB(uint32_t data, uint8_t *output) +{ + const uint32_t rgbSignMask = 0x200; // 1 set at the 9 bit + const uint32_t 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 int32_t maxValue = 0x1FF; // 1 set in bits 0 through 8 + const int32_t 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 int32_t halfRange = (maxValue - minValue) >> 1; + *floatOutput = ((finalValue - minValue) / halfRange) - 1.0f; + } + else + { + *floatOutput = finalValue; + } + } + else + { + if (normalized) + { + const uint32_t 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(uint32_t data, uint8_t *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 CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output) +{ + const size_t outputComponentSize = toFloat ? 4 : 2; + const size_t componentCount = 4; + + const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9 + const size_t redShift = 0; // red is bits 0 through 9 + const size_t greenShift = 10; // green is bits 10 through 19 + const size_t blueShift = 20; // blue is bits 20 through 29 + + const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1 + const size_t alphaShift = 30; // Alpha is the 30 and 31 bits + + for (size_t i = 0; i < count; i++) + { + GLuint packedValue = *reinterpret_cast<const GLuint*>(input + (i * stride)); + uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount); + + priv::CopyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize)); + priv::CopyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize)); + priv::CopyPackedRGB<isSigned, normalized, toFloat>( (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize)); + priv::CopyPackedAlpha<isSigned, normalized, toFloat>((packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize)); + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp index 08457af76d..a34ef03fb8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,9 +7,9 @@ // BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes. #include "libGLESv2/renderer/d3d/BufferD3D.h" -#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/d3d/VertexBuffer.h" #include "libGLESv2/renderer/d3d/IndexBuffer.h" +#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/main.h" namespace rx diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h index 8e204b9139..44f14cee58 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h @@ -11,7 +11,6 @@ #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/angletypes.h" -#include "libGLESv2/renderer/IndexRangeCache.h" namespace rx { @@ -31,13 +30,11 @@ class BufferD3D : public BufferImpl unsigned int getSerial() const { return mSerial; } virtual size_t getSize() const = 0; - virtual void clear() = 0; virtual bool supportsDirectBinding() const = 0; virtual Renderer* getRenderer() = 0; rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } - rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; } void initializeStaticData(); void invalidateStaticData(); @@ -51,7 +48,6 @@ class BufferD3D : public BufferImpl rx::StaticVertexBufferInterface *mStaticVertexBuffer; rx::StaticIndexBufferInterface *mStaticIndexBuffer; - rx::IndexRangeCache mIndexRangeCache; unsigned int mUnmodifiedDataUse; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp new file mode 100644 index 0000000000..13411ebe64 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp @@ -0,0 +1,1144 @@ +// +// 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 "libGLESv2/renderer/d3d/DynamicHLSL.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/formatutils.h" + +#include "common/utilities.h" +#include "common/blocklayout.h" + +// For use with ArrayString, see angleutils.h +META_ASSERT(GL_INVALID_INDEX == UINT_MAX); + +using namespace gl; + +namespace +{ + +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::VariableComponentType(type), gl::VariableComponentCount(type)); +} + +const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOutputVariable> &outputVariables, + unsigned int location) +{ + for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) + { + if (outputVariables[variableIndex].outputIndex == location) + { + return outputVariables[variableIndex]; + } + } + + UNREACHABLE(); + return outputVariables[0]; +} + +} + +namespace rx +{ + +const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; +const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; + +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; + varying->columnIndex = 0; + + 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; + varying->columnIndex = 2; + + 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[column] < 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; + varying->columnIndex = column; + + 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, rx::ShaderD3D *fragmentShader, + rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings) +{ + // TODO (geofflang): Use context's caps + const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; + + vertexShader->resetVaryingsRegisterAssignment(); + fragmentShader->resetVaryingsRegisterAssignment(); + + std::set<std::string> packedVaryings; + + std::vector<gl::PackedVarying> &fragmentVaryings = fragmentShader->getVaryings(); + std::vector<gl::PackedVarying> &vertexVaryings = vertexShader->getVaryings(); + for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++) + { + PackedVarying *varying = &fragmentVaryings[varyingIndex]; + + // Do not assign registers to built-in or unreferenced varyings + if (varying->isBuiltIn() || !varying->staticUse) + { + continue; + } + + 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 < vertexVaryings.size(); varyingIndex++) + { + PackedVarying *varying = &vertexVaryings[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(const ShaderD3D *shader) const +{ + std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize); + std::string varyingHLSL; + + const std::vector<gl::PackedVarying> &varyings = shader->getVaryings(); + + for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++) + { + const PackedVarying &varying = varyings[varyingIndex]; + if (varying.registerAssigned()) + { + ASSERT(!varying.isBuiltIn()); + 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++) + { + // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many registers being used. + // For example, if there are N registers, and we have N vec3 varyings and 1 float varying, then D3D will pack them into N registers. + // If the float varying has the 'nointerpolation' modifier on it then we would need N + 1 registers, and D3D compilation will fail. + + switch (varying.interpolation) + { + case sh::INTERPOLATION_SMOOTH: varyingHLSL += " "; break; + case sh::INTERPOLATION_FLAT: varyingHLSL += " nointerpolation "; break; + case sh::INTERPOLATION_CENTROID: varyingHLSL += " centroid "; break; + default: UNREACHABLE(); + } + + unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + 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 = VariableComponentType(transposedType); + int columnCount = VariableColumnCount(transposedType); + typeString = HLSLComponentTypeString(componentType, columnCount); + } + varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n"; + } + } + } + } + + return varyingHLSL; +} + +std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &sourceShader, + const VertexFormat inputLayout[], + const sh::Attribute shaderAttributes[]) const +{ + std::string structHLSL, initHLSL; + + int semanticIndex = 0; + unsigned int inputIndex = 0; + + for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + const sh::Attribute &shaderAttribute = shaderAttributes[attributeIndex]; + if (!shaderAttribute.name.empty()) + { + ASSERT(inputIndex < MAX_VERTEX_ATTRIBS); + const VertexFormat &vertexFormat = inputLayout[inputIndex]; + + // HLSL code for input structure + if (IsMatrixType(shaderAttribute.type)) + { + // Matrix types are always transposed + structHLSL += " " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type)); + } + else + { + GLenum componentType = mRenderer->getVertexComponentType(vertexFormat); + structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type)); + } + + structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n"; + semanticIndex += VariableRegisterCount(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)); + } + } + + std::string replacementHLSL = "struct VS_INPUT\n" + "{\n" + + structHLSL + + "};\n" + "\n" + "void initAttributes(VS_INPUT input)\n" + "{\n" + + initHLSL + + "}\n"; + + std::string vertexHLSL(sourceShader); + + size_t copyInsertionPos = vertexHLSL.find(VERTEX_ATTRIBUTE_STUB_STRING); + vertexHLSL.replace(copyInsertionPos, VERTEX_ATTRIBUTE_STUB_STRING.length(), replacementHLSL); + + return vertexHLSL; +} + +std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables, + bool usesFragDepth, const std::vector<GLenum> &outputLayout) const +{ + const int shaderModel = mRenderer->getMajorShaderModel(); + std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; + std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + + std::string declarationHLSL; + std::string copyHLSL; + + for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex) + { + GLenum binding = outputLayout[layoutIndex]; + + if (binding != GL_NONE) + { + unsigned int location = (binding - GL_COLOR_ATTACHMENT0); + + const PixelShaderOutputVariable &outputVariable = GetOutputAtLocation(outputVariables, location); + + declarationHLSL += " " + HLSLTypeString(outputVariable.type) + " " + outputVariable.name + + " : " + targetSemantic + Str(layoutIndex) + ";\n"; + + copyHLSL += " output." + outputVariable.name + " = " + outputVariable.source + ";\n"; + } + } + + if (usesFragDepth) + { + declarationHLSL += " float gl_Depth : " + depthSemantic + ";\n"; + copyHLSL += " output.gl_Depth = gl_Depth; \n"; + } + + std::string replacementHLSL = "struct PS_OUTPUT\n" + "{\n" + + declarationHLSL + + "};\n" + "\n" + "PS_OUTPUT generateOutput()\n" + "{\n" + " PS_OUTPUT output;\n" + + copyHLSL + + " return output;\n" + "}\n"; + + std::string pixelHLSL(sourceShader); + + size_t outputInsertionPos = pixelHLSL.find(PIXEL_OUTPUT_STUB_STRING); + pixelHLSL.replace(outputInsertionPos, PIXEL_OUTPUT_STUB_STRING.length(), replacementHLSL); + + return pixelHLSL; +} + +std::string DynamicHLSL::getVaryingSemantic(bool pointSize) const +{ + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + int shaderModel = mRenderer->getMajorShaderModel(); + return ((pointSize && shaderModel < 4) ? "COLOR" : "TEXCOORD"); +} + +struct DynamicHLSL::SemanticInfo +{ + struct BuiltinInfo + { + BuiltinInfo() + : enabled(false), + index(0), + systemValue(false) + {} + + bool enabled; + std::string semantic; + unsigned int index; + bool systemValue; + + std::string str() const + { + return (systemValue ? semantic : (semantic + Str(index))); + } + + void enableSystem(const std::string &systemValueSemantic) + { + enabled = true; + semantic = systemValueSemantic; + systemValue = true; + } + + void enable(const std::string &semanticVal, unsigned int indexVal) + { + enabled = true; + semantic = semanticVal; + index = indexVal; + } + }; + + BuiltinInfo dxPosition; + BuiltinInfo glPosition; + BuiltinInfo glFragCoord; + BuiltinInfo glPointCoord; + BuiltinInfo glPointSize; +}; + +DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, + bool pointSize, bool pixelShader) const +{ + SemanticInfo info; + bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); + const std::string &varyingSemantic = getVaryingSemantic(pointSize); + + int reservedRegisterIndex = startRegisters; + + if (hlsl4) + { + info.dxPosition.enableSystem("SV_Position"); + } + else if (pixelShader) + { + info.dxPosition.enableSystem("VPOS"); + } + else + { + info.dxPosition.enableSystem("POSITION"); + } + + info.glPosition.enable(varyingSemantic, reservedRegisterIndex++); + + if (fragCoord) + { + info.glFragCoord.enable(varyingSemantic, reservedRegisterIndex++); + } + + if (pointCoord) + { + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + if (hlsl4) + { + info.glPointCoord.enable(varyingSemantic, reservedRegisterIndex++); + } + else + { + info.glPointCoord.enable("TEXCOORD", 0); + } + } + + // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders + if (pointSize && (!pixelShader || hlsl4)) + { + info.glPointSize.enableSystem("PSIZE"); + } + + return info; +} + +std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const +{ + std::string linkHLSL = "{\n"; + + ASSERT(info.dxPosition.enabled && info.glPosition.enabled); + + linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n"; + linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n"; + + if (info.glFragCoord.enabled) + { + linkHLSL += " float4 gl_FragCoord : " + info.glFragCoord.str() + ";\n"; + } + + if (info.glPointCoord.enabled) + { + linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n"; + } + + linkHLSL += varyingHLSL; + + if (info.glPointSize.enabled) + { + linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n"; + } + + linkHLSL += "};\n"; + + return linkHLSL; +} + +void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, + std::vector<LinkedVarying> *linkedVaryings) const +{ + ASSERT(info.glPosition.enabled); + + linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic, + info.glPosition.index, 1)); + + if (info.glFragCoord.enabled) + { + linkedVaryings->push_back(LinkedVarying("gl_FragCoord", GL_FLOAT_VEC4, 1, info.glFragCoord.semantic, + info.glFragCoord.index, 1)); + } + + if (info.glPointSize.enabled) + { + linkedVaryings->push_back(LinkedVarying("gl_PointSize", GL_FLOAT, 1, "PSIZE", 0, 1)); + } +} + +void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, + std::vector<LinkedVarying> *linkedVaryings) const +{ + const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize); + const std::vector<PackedVarying> &varyings = vertexShader->getVaryings(); + + for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++) + { + const PackedVarying &varying = varyings[varyingIndex]; + + if (varying.registerAssigned()) + { + ASSERT(!varying.isBuiltIn()); + GLenum transposedType = TransposeMatrixType(varying.type); + int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); + + linkedVaryings->push_back(LinkedVarying(varying.name, varying.type, varying.elementCount(), + varyingSemantic, varying.registerIndex, + variableRows * varying.elementCount())); + } + } +} + +bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing, + std::string& pixelHLSL, std::string& vertexHLSL, + rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, + std::vector<LinkedVarying> *linkedVaryings, + std::map<int, VariableLocation> *programOutputVars, + std::vector<PixelShaderOutputVariable> *outPixelShaderKey, + bool *outUsesFragDepth) const +{ + if (pixelHLSL.empty() || vertexHLSL.empty()) + { + return false; + } + + bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; + bool usesFragColor = fragmentShader->mUsesFragColor; + bool usesFragData = fragmentShader->mUsesFragData; + bool usesFragCoord = fragmentShader->mUsesFragCoord; + bool usesPointCoord = fragmentShader->mUsesPointCoord; + bool usesPointSize = vertexShader->mUsesPointSize; + + 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(); + + // TODO (geofflang): Use context's caps + const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; + + const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 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->getRendererCaps().maxDrawBuffers : 1); + + int shaderVersion = vertexShader->getShaderVersion(); + + if (registersNeeded > maxVaryingVectors) + { + infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); + return false; + } + + const std::string &varyingHLSL = generateVaryingHLSL(vertexShader); + const SemanticInfo &vertexSemantics = getSemanticInfo(registers, usesFragCoord, + false, usesPointSize, false); + + storeUserLinkedVaryings(vertexShader, linkedVaryings); + storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings); + + // Add stub string to be replaced when shader is dynamically defined by its layout + vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n" + "struct VS_OUTPUT\n" + generateVaryingLinkHLSL(vertexSemantics, varyingHLSL) + "\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 (usesPointSize && shaderModel >= 3) + { + vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; + } + + if (usesFragCoord) + { + vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; + } + + const std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings(); + for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++) + { + const PackedVarying &varying = vertexVaryings[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 + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row; + vertexHLSL += " output.v" + Str(r); + + vertexHLSL += " = _" + varying.name; + + if (varying.isArray()) + { + vertexHLSL += ArrayString(elementIndex); + } + + if (variableRows > 1) + { + vertexHLSL += ArrayString(row); + } + + vertexHLSL += ";\n"; + } + } + } + } + + vertexHLSL += "\n" + " return output;\n" + "}\n"; + + const SemanticInfo &pixelSemantics = getSemanticInfo(registers, usesFragCoord, usesPointCoord, + usesPointSize, true); + + pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n"; + + if (shaderVersion < 300) + { + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + { + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = GL_FLOAT_VEC4; + outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); + outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; + outputKeyVariable.outputIndex = renderTargetIndex; + + outPixelShaderKey->push_back(outputKeyVariable); + } + + *outUsesFragDepth = fragmentShader->mUsesFragDepth; + } + else + { + defineOutputVariables(fragmentShader, programOutputVars); + + const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables(); + for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++) + { + const VariableLocation &outputLocation = locationIt->second; + const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; + const std::string &variableName = "out_" + outputLocation.name; + const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); + + ASSERT(outputVariable.staticUse); + + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = outputVariable.type; + outputKeyVariable.name = variableName + elementString; + outputKeyVariable.source = variableName + ArrayString(outputLocation.element); + outputKeyVariable.outputIndex = locationIt->first; + + outPixelShaderKey->push_back(outputKeyVariable); + } + + *outUsesFragDepth = false; + } + + pixelHLSL += PIXEL_OUTPUT_STUB_STRING + "\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 (usesFragCoord) + { + pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; + + if (shaderModel >= 4) + { + pixelHLSL += " gl_FragCoord.x = input.dx_Position.x;\n" + " gl_FragCoord.y = input.dx_Position.y;\n"; + } + else if (shaderModel >= 3) + { + pixelHLSL += " gl_FragCoord.x = input.dx_Position.x + 0.5;\n" + " gl_FragCoord.y = input.dx_Position.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 (usesPointCoord && 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"; + } + } + + const std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings(); + for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++) + { + const PackedVarying &varying = fragmentVaryings[varyingIndex]; + if (varying.registerAssigned()) + { + ASSERT(!varying.isBuiltIn()); + 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 + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + 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 + { + ASSERT(varying.isBuiltIn() || !varying.staticUse); + } + } + + pixelHLSL += "\n" + " gl_main();\n" + "\n" + " return generateOutput();\n" + "}\n"; + + return true; +} + +void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const +{ + const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables(); + + for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); outputVariableIndex++) + { + const sh::Attribute &outputVariable = shaderOutputVars[outputVariableIndex]; + const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location; + + ASSERT(outputVariable.staticUse); + + 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, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *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, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const +{ + ASSERT(registers >= 0); + ASSERT(vertexShader->mUsesPointSize); + ASSERT(mRenderer->getMajorShaderModel() >= 4); + + std::string geomHLSL; + + const SemanticInfo &inSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, + false, true, false); + const SemanticInfo &outSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, + fragmentShader->mUsesPointCoord, true, false); + + std::string varyingHLSL = generateVaryingHLSL(vertexShader); + std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL); + std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL); + + // TODO(geofflang): use context's caps + geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n" + "\n" + "struct GS_INPUT\n" + inLinkHLSL + "\n" + + "struct GS_OUTPUT\n" + outLinkHLSL + "\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(mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n" + "static float maxPointSize = " + Str(mRenderer->getRendererCaps().maxAliasedPointSize) + ".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_Position = input[0].gl_Position;\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 dx_Position = input[0].dx_Position;\n" + " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * dx_Position.w;\n"; + + for (int corner = 0; corner < 4; corner++) + { + geomHLSL += " \n" + " output.dx_Position = dx_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) + { + return "_" + name; + } + + return name; +} + +std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const +{ + std::string attribString = "input." + decorateVariable(shaderAttrib.name); + + // Matrix + if (IsMatrixType(shaderAttrib.type)) + { + return "transpose(" + attribString + ")"; + } + + GLenum shaderComponentType = VariableComponentType(shaderAttrib.type); + int shaderComponentCount = VariableComponentCount(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/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h new file mode 100644 index 0000000000..f68ed98401 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h @@ -0,0 +1,104 @@ +// +// 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_RENDERER_DYNAMIC_HLSL_H_ +#define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_ + +#include "common/angleutils.h" +#include "libGLESv2/constants.h" + +#include "angle_gl.h" + +#include <vector> +#include <map> + +namespace rx +{ +class Renderer; +} + +namespace sh +{ +struct Attribute; +struct ShaderVariable; +} + +namespace gl +{ +class InfoLog; +struct VariableLocation; +struct LinkedVarying; +struct VertexAttribute; +struct VertexFormat; +struct PackedVarying; +} + +namespace rx +{ +class Renderer; +class ShaderD3D; + +typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4]; + +struct PixelShaderOutputVariable +{ + GLenum type; + std::string name; + std::string source; + size_t outputIndex; +}; + +class DynamicHLSL +{ + public: + explicit DynamicHLSL(rx::Renderer *const renderer); + + int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader, + rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings); + std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[], + const sh::Attribute shaderAttributes[]) const; + std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables, + bool usesFragDepth, const std::vector<GLenum> &outputLayout) const; + bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing, + std::string& pixelHLSL, std::string& vertexHLSL, + rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, + const std::vector<std::string>& transformFeedbackVaryings, + std::vector<gl::LinkedVarying> *linkedVaryings, + std::map<int, gl::VariableLocation> *programOutputVars, + std::vector<PixelShaderOutputVariable> *outPixelShaderKey, + bool *outUsesFragDepth) const; + + std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; + + private: + DISALLOW_COPY_AND_ASSIGN(DynamicHLSL); + + rx::Renderer *const mRenderer; + + struct SemanticInfo; + + std::string getVaryingSemantic(bool pointSize) const; + SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize, + bool pixelShader) const; + std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; + std::string generateVaryingHLSL(const ShaderD3D *shader) const; + void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; + void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const; + void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const; + std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + + // Prepend an underscore + static std::string decorateVariable(const std::string &name); + + std::string generateAttributeConversionHLSL(const gl::VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const; +}; + +} + +#endif // LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp index e3b88d506d..d0131974ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp @@ -1,4 +1,9 @@ -#include "precompiled.h" +// +// Copyright 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/renderer/d3d/HLSLCompiler.h" #include "libGLESv2/Program.h" #include "libGLESv2/main.h" @@ -6,10 +11,6 @@ #include "common/utilities.h" #include "common/platform.h" -#include "third_party/trace_event/trace_event.h" - -#include <d3dcompiler.h> - #if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) // Add define + typedefs for older MinGW-w64 headers (pre 5783) @@ -29,10 +30,6 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const #define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL #endif -#ifndef LoadLibrary -#define LoadLibrary(dll) LoadPackagedLibrary(dll, NULL) -#endif - namespace rx { @@ -49,7 +46,6 @@ HLSLCompiler::~HLSLCompiler() bool HLSLCompiler::initialize() { - TRACE_EVENT0("gpu", "initializeCompiler"); #if !defined(ANGLE_PLATFORM_WINRT) #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. @@ -153,14 +149,11 @@ ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); } - infoLog.append("Warning: D3D shader compilation failed with "); - infoLog.append(flagNames[i]); - infoLog.append(" flags."); + infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]); + if (i + 1 < attempts) { - infoLog.append(" Retrying with "); - infoLog.append(flagNames[i + 1]); - infoLog.append(".\n"); + infoLog.append(" Retrying with %s.\n", flagNames[i + 1]); } } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp index 615d11a1f1..0854b968da 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp @@ -1,4 +1,3 @@ -#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 diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h index 242ce5af70..60a6ffdf37 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h @@ -21,10 +21,7 @@ class Framebuffer; namespace rx { -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; -class TextureStorageInterface3D; -class TextureStorageInterface2DArray; +class TextureStorage; class ImageD3D : public Image { @@ -36,14 +33,14 @@ class ImageD3D : public Image virtual bool isDirty() const = 0; - virtual void setManagedSurface(TextureStorageInterface2D *storage, int level) {}; - virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) {}; - 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 void setManagedSurface2D(TextureStorage *storage, int level) {}; + virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {}; + virtual void setManagedSurface3D(TextureStorage *storage, int level) {}; + virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {}; + virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; + virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; + virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0; + virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0; private: DISALLOW_COPY_AND_ASSIGN(ImageD3D); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp index 13e35e09ec..1dce1270d8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp @@ -1,4 +1,3 @@ -#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 @@ -67,21 +66,22 @@ unsigned int IndexBufferInterface::getSerial() const return mIndexBuffer->getSerial(); } -bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) +gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) { // Protect against integer overflow if (mWritePosition + size < mWritePosition) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow."); } - if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory)) + gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory); + if (error.isError()) { if (outMappedMemory) { *outMappedMemory = NULL; } - return false; + return error; } if (streamOffset) @@ -90,10 +90,10 @@ bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, } mWritePosition += size; - return true; + return gl::Error(GL_NO_ERROR); } -bool IndexBufferInterface::unmapBuffer() +gl::Error IndexBufferInterface::unmapBuffer() { return mIndexBuffer->unmapBuffer(); } @@ -113,12 +113,12 @@ void IndexBufferInterface::setWritePosition(unsigned int writePosition) mWritePosition = writePosition; } -bool IndexBufferInterface::discard() +gl::Error IndexBufferInterface::discard() { return mIndexBuffer->discard(); } -bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType) +gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType) { if (mIndexBuffer->getBufferSize() == 0) { @@ -138,26 +138,30 @@ StreamingIndexBufferInterface::~StreamingIndexBufferInterface() { } -bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) +gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) { - bool result = true; unsigned int curBufferSize = getBufferSize(); unsigned int writePos = getWritePosition(); if (size > curBufferSize) { - result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); + gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType); + if (error.isError()) + { + return error; + } setWritePosition(0); } else if (writePos + size > curBufferSize || writePos + size < writePos) { - if (!discard()) + gl::Error error = discard(); + if (error.isError()) { - return false; + return error; } setWritePosition(0); } - return result; + return gl::Error(GL_NO_ERROR); } @@ -169,7 +173,7 @@ StaticIndexBufferInterface::~StaticIndexBufferInterface() { } -bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) +gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) { unsigned int curSize = getBufferSize(); if (curSize == 0) @@ -178,13 +182,12 @@ bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum in } else if (curSize >= size && indexType == getIndexType()) { - return true; + return gl::Error(GL_NO_ERROR); } else { - ERR("Static index buffers can't be resized"); UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized"); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h index 6fb885a1cd..1bb5ae2c4a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_INDEXBUFFER_H_ #include "common/angleutils.h" +#include "libGLESv2/Error.h" #include "libGLESv2/renderer/IndexRangeCache.h" namespace rx @@ -23,16 +24,16 @@ class IndexBuffer IndexBuffer(); virtual ~IndexBuffer(); - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) = 0; + virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) = 0; - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) = 0; - virtual bool unmapBuffer() = 0; + virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) = 0; + virtual gl::Error unmapBuffer() = 0; - virtual bool discard() = 0; + virtual gl::Error discard() = 0; virtual GLenum getIndexType() const = 0; virtual unsigned int getBufferSize() const = 0; - virtual bool setSize(unsigned int bufferSize, GLenum indexType) = 0; + virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType) = 0; unsigned int getSerial() const; @@ -52,15 +53,15 @@ class IndexBufferInterface IndexBufferInterface(Renderer *renderer, bool dynamic); virtual ~IndexBufferInterface(); - virtual bool reserveBufferSpace(unsigned int size, GLenum indexType) = 0; + virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0; GLenum getIndexType() const; unsigned int getBufferSize() const; unsigned int getSerial() const; - bool mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset); - bool unmapBuffer(); + gl::Error mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset); + gl::Error unmapBuffer(); IndexBuffer *getIndexBuffer() const; @@ -68,9 +69,9 @@ class IndexBufferInterface unsigned int getWritePosition() const; void setWritePosition(unsigned int writePosition); - bool discard(); + gl::Error discard(); - bool setBufferSize(unsigned int bufferSize, GLenum indexType); + gl::Error setBufferSize(unsigned int bufferSize, GLenum indexType); private: DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface); @@ -89,7 +90,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface StreamingIndexBufferInterface(Renderer *renderer); ~StreamingIndexBufferInterface(); - virtual bool reserveBufferSpace(unsigned int size, GLenum indexType); + virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); }; class StaticIndexBufferInterface : public IndexBufferInterface @@ -98,7 +99,7 @@ class StaticIndexBufferInterface : public IndexBufferInterface explicit StaticIndexBufferInterface(Renderer *renderer); ~StaticIndexBufferInterface(); - virtual bool reserveBufferSpace(unsigned int size, GLenum indexType); + virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); IndexRangeCache *getIndexRangeCache(); @@ -108,4 +109,4 @@ class StaticIndexBufferInterface : public IndexBufferInterface } -#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_
\ No newline at end of file +#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp index 932524c132..8d455b4bf3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp @@ -1,6 +1,5 @@ -#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,54 +9,20 @@ #include "libGLESv2/renderer/d3d/IndexDataManager.h" #include "libGLESv2/renderer/d3d/BufferD3D.h" - +#include "libGLESv2/renderer/d3d/IndexBuffer.h" +#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" #include "libGLESv2/formatutils.h" -#include "libGLESv2/renderer/d3d/IndexBuffer.h" namespace rx { -IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer) +static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output) { - mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer); - if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT)) - { - delete mStreamingBufferShort; - mStreamingBufferShort = NULL; - } - - mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer); - if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) - { - delete mStreamingBufferInt; - mStreamingBufferInt = NULL; - } - - if (!mStreamingBufferShort) - { - // Make sure both buffers are deleted. - delete mStreamingBufferInt; - mStreamingBufferInt = NULL; - - ERR("Failed to allocate the streaming index buffer(s)."); - } - - mCountingBuffer = NULL; -} - -IndexDataManager::~IndexDataManager() -{ - delete mStreamingBufferShort; - delete mStreamingBufferInt; - delete mCountingBuffer; -} - -static void convertIndices(GLenum type, const void *input, GLsizei count, void *output) -{ - if (type == GL_UNSIGNED_BYTE) + if (sourceType == GL_UNSIGNED_BYTE) { + ASSERT(destinationType == GL_UNSIGNED_SHORT); const GLubyte *in = static_cast<const GLubyte*>(input); GLushort *out = static_cast<GLushort*>(output); @@ -66,55 +31,51 @@ static void convertIndices(GLenum type, const void *input, GLsizei count, void * out[i] = in[i]; } } - else if (type == GL_UNSIGNED_INT) + else if (sourceType == GL_UNSIGNED_INT) { + ASSERT(destinationType == GL_UNSIGNED_INT); memcpy(output, input, count * sizeof(GLuint)); } - else if (type == GL_UNSIGNED_SHORT) + else if (sourceType == GL_UNSIGNED_SHORT) { - memcpy(output, input, count * sizeof(GLushort)); + if (destinationType == GL_UNSIGNED_SHORT) + { + memcpy(output, input, count * sizeof(GLushort)); + } + else if (destinationType == GL_UNSIGNED_INT) + { + const GLushort *in = static_cast<const GLushort*>(input); + GLuint *out = static_cast<GLuint*>(output); + + for (GLsizei i = 0; i < count; i++) + { + out[i] = in[i]; + } + } + else UNREACHABLE(); } else UNREACHABLE(); } -template <class IndexType> -static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex) +IndexDataManager::IndexDataManager(Renderer *renderer) + : mRenderer(renderer), + mStreamingBufferShort(NULL), + mStreamingBufferInt(NULL) { - *minIndex = indices[0]; - *maxIndex = indices[0]; - - for (GLsizei i = 0; i < count; i++) - { - if (*minIndex > indices[i]) *minIndex = indices[i]; - if (*maxIndex < indices[i]) *maxIndex = indices[i]; - } } -static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex) +IndexDataManager::~IndexDataManager() { - if (type == GL_UNSIGNED_BYTE) - { - computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex); - } - else if (type == GL_UNSIGNED_INT) - { - computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex); - } - else if (type == GL_UNSIGNED_SHORT) - { - computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex); - } - else UNREACHABLE(); + SafeDelete(mStreamingBufferShort); + SafeDelete(mStreamingBufferInt); } -GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated) +gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated) { - if (!mStreamingBufferShort) - { - return GL_OUT_OF_MEMORY; - } + const gl::Type &typeInfo = gl::GetTypeInfo(type); GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + unsigned int offset = 0; bool alignedOffset = false; @@ -122,10 +83,6 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer if (buffer != NULL) { - if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max()) - { - return GL_OUT_OF_MEMORY; - } offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices)); storage = BufferD3D::makeBufferD3D(buffer->getImplementation()); @@ -138,59 +95,56 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer default: UNREACHABLE(); alignedOffset = false; } - unsigned int typeSize = gl::GetTypeBytes(type); - - // check for integer overflows - if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeSize) || - typeSize * static_cast<unsigned int>(count) + offset < offset) - { - return GL_OUT_OF_MEMORY; - } - - if (typeSize * static_cast<unsigned int>(count) + offset > storage->getSize()) - { - return GL_INVALID_OPERATION; - } + ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize()); indices = static_cast<const GLubyte*>(storage->getData()) + offset; } - StreamingIndexBufferInterface *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort; - StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL; - IndexBufferInterface *indexBuffer = streamingBuffer; + IndexBufferInterface *indexBuffer = NULL; bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() && destinationIndexType == type; unsigned int streamOffset = 0; if (directStorage) { - indexBuffer = streamingBuffer; streamOffset = offset; - if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, - &translated->maxIndex, NULL)) + if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL)) { - computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); - storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, - translated->maxIndex, offset); + buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset); } } else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset) { indexBuffer = staticBuffer; - if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex, - &translated->maxIndex, &streamOffset)) + if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset)) { - 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); + streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes; + staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset); } } - else + + // Avoid D3D11's primitive restart index value + // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx + if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3) { + destinationIndexType = GL_UNSIGNED_INT; + directStorage = false; + indexBuffer = NULL; + } + + const gl::Type &destTypeInfo = gl::GetTypeInfo(destinationIndexType); + + if (!directStorage && !indexBuffer) + { + gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer); + if (error.isError()) + { + return error; + } + unsigned int convertCount = count; if (staticBuffer) @@ -198,7 +152,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer if (staticBuffer->getBufferSize() == 0 && alignedOffset) { indexBuffer = staticBuffer; - convertCount = storage->getSize() / gl::GetTypeBytes(type); + convertCount = storage->getSize() / typeInfo.bytes; } else { @@ -207,133 +161,95 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer } } - if (!indexBuffer) - { - ERR("No valid index buffer."); - return GL_INVALID_OPERATION; - } + ASSERT(indexBuffer); - unsigned int indexTypeSize = gl::GetTypeBytes(destinationIndexType); - if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize) + if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes) { - ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize); - return GL_OUT_OF_MEMORY; + return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.", + convertCount, destTypeInfo.bytes); } - unsigned int bufferSizeRequired = convertCount * indexTypeSize; - if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type)) + unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes; + error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type); + if (error.isError()) { - ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired); - return GL_OUT_OF_MEMORY; + return error; } void* output = NULL; - if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset)) + error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset); + if (error.isError()) { - ERR("Failed to map index buffer."); - return GL_OUT_OF_MEMORY; + return error; } - convertIndices(type, staticBuffer ? storage->getData() : indices, convertCount, output); + ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output); - if (!indexBuffer->unmapBuffer()) + error = indexBuffer->unmapBuffer(); + if (error.isError()) { - ERR("Failed to unmap index buffer."); - return GL_OUT_OF_MEMORY; + return error; } - computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); - if (staticBuffer) { - streamOffset = (offset / gl::GetTypeBytes(type)) * gl::GetTypeBytes(destinationIndexType); - staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex, - translated->maxIndex, streamOffset); + streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes; + staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset); } } translated->storage = directStorage ? storage : NULL; - translated->indexBuffer = indexBuffer->getIndexBuffer(); + translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL; translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial(); - translated->startIndex = streamOffset / gl::GetTypeBytes(destinationIndexType); + translated->startIndex = streamOffset / destTypeInfo.bytes; translated->startOffset = streamOffset; + translated->indexType = destinationIndexType; if (storage) { - storage->promoteStaticUsage(count * gl::GetTypeBytes(type)); + storage->promoteStaticUsage(count * typeInfo.bytes); } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } -StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count) +gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer) { - if (count <= 65536) // 16-bit indices + ASSERT(outBuffer); + if (destinationIndexType == GL_UNSIGNED_INT) { - const unsigned int spaceNeeded = count * sizeof(unsigned short); - - if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded) + if (!mStreamingBufferInt) { - delete mCountingBuffer; - mCountingBuffer = new StaticIndexBufferInterface(mRenderer); - mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); - - void* mappedMemory = NULL; - if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL)) - { - ERR("Failed to map counting buffer."); - return NULL; - } - - unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory); - for(int i = 0; i < count; i++) + mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer); + gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + if (error.isError()) { - data[i] = i; - } - - if (!mCountingBuffer->unmapBuffer()) - { - ERR("Failed to unmap counting buffer."); - return NULL; + SafeDelete(mStreamingBufferInt); + return error; } } + + *outBuffer = mStreamingBufferInt; + return gl::Error(GL_NO_ERROR); } - else if (mStreamingBufferInt) // 32-bit indices supported + else { - const unsigned int spaceNeeded = count * sizeof(unsigned int); + ASSERT(destinationIndexType == GL_UNSIGNED_SHORT); - if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded) + if (!mStreamingBufferShort) { - delete mCountingBuffer; - mCountingBuffer = new StaticIndexBufferInterface(mRenderer); - mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); - - void* mappedMemory = NULL; - if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL)) + mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer); + gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + if (error.isError()) { - ERR("Failed to map counting buffer."); - return NULL; - } - - unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); - for(int i = 0; i < count; i++) - { - data[i] = i; - } - - if (!mCountingBuffer->unmapBuffer()) - { - ERR("Failed to unmap counting buffer."); - return NULL; + SafeDelete(mStreamingBufferShort); + return error; } } - } - else - { - return NULL; - } - return mCountingBuffer; + *outBuffer = mStreamingBufferShort; + return gl::Error(GL_NO_ERROR); + } } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h index 8f981936ea..6d0b89e6d4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.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. // @@ -11,6 +11,10 @@ #define LIBGLESV2_INDEXDATAMANAGER_H_ #include "common/angleutils.h" +#include "common/mathutil.h" +#include "libGLESv2/Error.h" + +#include <GLES2/gl2.h> namespace { @@ -24,6 +28,7 @@ class Buffer; namespace rx { +class IndexBufferInterface; class StaticIndexBufferInterface; class StreamingIndexBufferInterface; class IndexBuffer; @@ -32,13 +37,13 @@ class Renderer; struct TranslatedIndexData { - unsigned int minIndex; - unsigned int maxIndex; + RangeUI indexRange; unsigned int startIndex; unsigned int startOffset; // In bytes IndexBuffer *indexBuffer; BufferD3D *storage; + GLenum indexType; unsigned int serial; }; @@ -48,17 +53,17 @@ class IndexDataManager explicit IndexDataManager(Renderer *renderer); virtual ~IndexDataManager(); - GLenum prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); - StaticIndexBufferInterface *getCountingIndices(GLsizei count); + gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); private: + gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer); + DISALLOW_COPY_AND_ASSIGN(IndexDataManager); Renderer *const mRenderer; StreamingIndexBufferInterface *mStreamingBufferShort; StreamingIndexBufferInterface *mStreamingBufferInt; - StaticIndexBufferInterface *mCountingBuffer; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp index 301bbe8d3d..2b5b09a324 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp @@ -5,6 +5,7 @@ // #include "libGLESv2/renderer/d3d/MemoryBuffer.h" +#include "common/debug.h" #include <algorithm> #include <cstdlib> @@ -66,6 +67,7 @@ const uint8_t *MemoryBuffer::data() const uint8_t *MemoryBuffer::data() { + ASSERT(mData); return mData; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h index 2484c07455..c65f79fe10 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h @@ -21,6 +21,7 @@ class MemoryBuffer bool resize(size_t size); size_t size() const; + bool empty() const { return mSize == 0; } const uint8_t *data() const; uint8_t *data(); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp new file mode 100644 index 0000000000..d7d97cc2bd --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp @@ -0,0 +1,205 @@ +// +// 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. +// + +// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#include "libGLESv2/renderer/d3d/ProgramD3D.h" + +#include "common/utilities.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/ShaderExecutable.h" +#include "libGLESv2/renderer/d3d/DynamicHLSL.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +ProgramD3D::ProgramD3D(rx::Renderer *renderer) + : ProgramImpl(), + mRenderer(renderer), + mDynamicHLSL(NULL), + mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), + mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), + mVertexUniformStorage(NULL), + mFragmentUniformStorage(NULL) +{ + mDynamicHLSL = new rx::DynamicHLSL(renderer); +} + +ProgramD3D::~ProgramD3D() +{ + reset(); + SafeDelete(mDynamicHLSL); +} + +ProgramD3D *ProgramD3D::makeProgramD3D(ProgramImpl *impl) +{ + ASSERT(HAS_DYNAMIC_TYPE(ProgramD3D*, impl)); + return static_cast<ProgramD3D*>(impl); +} + +const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl) +{ + ASSERT(HAS_DYNAMIC_TYPE(const ProgramD3D*, impl)); + return static_cast<const ProgramD3D*>(impl); +} + +bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +{ + stream->readString(&mVertexHLSL); + stream->readInt(&mVertexWorkarounds); + stream->readString(&mPixelHLSL); + stream->readInt(&mPixelWorkarounds); + stream->readBool(&mUsesFragDepth); + + const size_t pixelShaderKeySize = stream->readInt<unsigned int>(); + mPixelShaderKey.resize(pixelShaderKeySize); + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; pixelShaderKeyIndex++) + { + stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type); + stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name); + stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source); + stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); + } + + return true; +} + +bool ProgramD3D::save(gl::BinaryOutputStream *stream) +{ + stream->writeString(mVertexHLSL); + stream->writeInt(mVertexWorkarounds); + stream->writeString(mPixelHLSL); + stream->writeInt(mPixelWorkarounds); + stream->writeInt(mUsesFragDepth); + + const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey; + stream->writeInt(pixelShaderKey.size()); + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++) + { + const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; + stream->writeInt(variable.type); + stream->writeString(variable.name); + stream->writeString(variable.source); + stream->writeInt(variable.outputIndex); + } + + return true; +} + +rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers) +{ + std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth, + outputSignature); + + // Generate new pixel executable + rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL, + transformFeedbackLinkedVaryings, separatedOutputBuffers, + mPixelWorkarounds); + + return pixelExecutable; +} + +rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog, + const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], + const sh::Attribute shaderAttributes[], + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers) +{ + // Generate new dynamic layout with attribute conversions + std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes); + + // Generate new vertex executable + rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(), + rx::SHADER_VERTEX, + transformFeedbackLinkedVaryings, separatedOutputBuffers, + mVertexWorkarounds); + + return vertexExecutable; +} + +bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, int *registers, + std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables) +{ + rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); + rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + + mPixelHLSL = fragmentShaderD3D->getTranslatedSource(); + mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds(); + + mVertexHLSL = vertexShaderD3D->getTranslatedSource(); + mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds(); + + // Map the varyings to the register file + rx::VaryingPacking packing = { NULL }; + *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings); + + if (*registers < 0) + { + return false; + } + + if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader)) + { + return false; + } + + if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, + fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings, + linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth)) + { + return false; + } + + return true; +} + +void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) +{ + // Compute total default block size + unsigned int vertexRegisters = 0; + unsigned int fragmentRegisters = 0; + for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++) + { + const gl::LinkedUniform &uniform = *uniforms[uniformIndex]; + + if (!gl::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); +} + +void ProgramD3D::reset() +{ + mVertexHLSL.clear(); + mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + + mPixelHLSL.clear(); + mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + mUsesFragDepth = false; + mPixelShaderKey.clear(); + + SafeDelete(mVertexUniformStorage); + SafeDelete(mFragmentUniformStorage); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h new file mode 100644 index 0000000000..d645c57daa --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h @@ -0,0 +1,87 @@ +// +// 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. +// + +// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#ifndef LIBGLESV2_RENDERER_PROGRAMD3D_H_ +#define LIBGLESV2_RENDERER_PROGRAMD3D_H_ + +#include "libGLESv2/renderer/ProgramImpl.h" + +#include <string> +#include <vector> + +namespace gl +{ +struct LinkedUniform; +struct VariableLocation; +struct VertexFormat; +} + +namespace rx +{ + +class UniformStorage; + +class ProgramD3D : public ProgramImpl +{ + public: + ProgramD3D(rx::Renderer *renderer); + virtual ~ProgramD3D(); + + static ProgramD3D *makeProgramD3D(ProgramImpl *impl); + static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl); + + Renderer *getRenderer() { return mRenderer; } + DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; } + const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; } + + GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; } + bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); + bool save(gl::BinaryOutputStream *stream); + + ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature, + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers); + ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, + const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], + const sh::Attribute shaderAttributes[], + const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings, + bool separatedOutputBuffers); + + bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector<std::string> &transformFeedbackVaryings, int *registers, + std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables); + + // D3D only + void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms); + + const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; } + const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } + + void reset(); + + private: + DISALLOW_COPY_AND_ASSIGN(ProgramD3D); + + Renderer *mRenderer; + DynamicHLSL *mDynamicHLSL; + + std::string mVertexHLSL; + rx::D3DWorkaroundType mVertexWorkarounds; + + std::string mPixelHLSL; + rx::D3DWorkaroundType mPixelWorkarounds; + bool mUsesFragDepth; + std::vector<rx::PixelShaderOutputVariable> mPixelShaderKey; + + UniformStorage *mVertexUniformStorage; + UniformStorage *mFragmentUniformStorage; +}; + +} + +#endif // LIBGLESV2_RENDERER_PROGRAMD3D_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp new file mode 100644 index 0000000000..c472113eba --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp @@ -0,0 +1,457 @@ +// +// 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. +// + +// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. + +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/main.h" + +#include "common/utilities.h" + +namespace rx +{ + +template <typename VarT> +void FilterInactiveVariables(std::vector<VarT> *variableList) +{ + ASSERT(variableList); + + for (size_t varIndex = 0; varIndex < variableList->size();) + { + if (!(*variableList)[varIndex].staticUse) + { + variableList->erase(variableList->begin() + varIndex); + } + else + { + varIndex++; + } + } +} + +void *ShaderD3D::mFragmentCompiler = NULL; +void *ShaderD3D::mVertexCompiler = NULL; + +template <typename VarT> +const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList) +{ + ASSERT(variableList); + return variableList; +} + +ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer) + : mType(type), + mRenderer(renderer), + mShaderVersion(100) +{ + uncompile(); + initializeCompiler(); +} + +ShaderD3D::~ShaderD3D() +{ +} + +ShaderD3D *ShaderD3D::makeShaderD3D(ShaderImpl *impl) +{ + ASSERT(HAS_DYNAMIC_TYPE(ShaderD3D*, impl)); + return static_cast<ShaderD3D*>(impl); +} + +const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl) +{ + ASSERT(HAS_DYNAMIC_TYPE(const ShaderD3D*, impl)); + return static_cast<const ShaderD3D*>(impl); +} + +// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) +void ShaderD3D::initializeCompiler() +{ + if (!mFragmentCompiler) + { + int result = ShInitialize(); + + if (result) + { + ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT; + + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + + // TODO(geofflang): use context's caps + const gl::Caps &caps = mRenderer->getRendererCaps(); + const gl::Extensions &extensions = mRenderer->getRendererExtensions(); + + resources.MaxVertexAttribs = caps.maxVertexAttributes; + resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; + resources.MaxVaryingVectors = caps.maxVaryingVectors; + resources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits; + resources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; + resources.MaxTextureImageUnits = caps.maxTextureImageUnits; + resources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; + resources.MaxDrawBuffers = caps.maxDrawBuffers; + resources.OES_standard_derivatives = extensions.standardDerivatives; + resources.EXT_draw_buffers = extensions.drawBuffers; + 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 = caps.maxVertexOutputComponents / 4; + resources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; + resources.MinProgramTexelOffset = caps.minProgramTexelOffset; + resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; + + mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); + mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); + } + } +} + +void ShaderD3D::releaseCompiler() +{ + ShDestruct(mFragmentCompiler); + ShDestruct(mVertexCompiler); + + mFragmentCompiler = NULL; + mVertexCompiler = NULL; + + ShFinalize(); +} + +void ShaderD3D::parseVaryings(void *compiler) +{ + if (!mHlsl.empty()) + { + const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler); + ASSERT(varyings); + + for (size_t varyingIndex = 0; varyingIndex < varyings->size(); varyingIndex++) + { + mVaryings.push_back(gl::PackedVarying((*varyings)[varyingIndex])); + } + + 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 ShaderD3D::resetVaryingsRegisterAssignment() +{ + for (size_t varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++) + { + mVaryings[varyingIndex].resetRegisterAssignment(); + } +} + +// initialize/clean up previous state +void ShaderD3D::uncompile() +{ + // set by compileToHLSL + mHlsl.clear(); + mInfoLog.clear(); + + mUsesMultipleRenderTargets = false; + mUsesFragColor = false; + mUsesFragData = false; + mUsesFragCoord = false; + mUsesFrontFacing = false; + mUsesPointSize = false; + mUsesPointCoord = false; + mUsesDepthRange = false; + mUsesFragDepth = false; + mShaderVersion = 100; + mUsesDiscardRewriting = false; + mUsesNestedBreak = false; + + mVaryings.clear(); + mUniforms.clear(); + mInterfaceBlocks.clear(); + mActiveAttributes.clear(); + mActiveOutputVariables.clear(); +} + +void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) +{ + // ensure the compiler is loaded + initializeCompiler(); + + int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); + std::string sourcePath; + if (gl::perfActive()) + { + sourcePath = getTempPath(); + writeFile(sourcePath.c_str(), source.c_str(), source.length()); + compileOptions |= SH_LINE_DIRECTIVES; + } + + int result; + if (sourcePath.empty()) + { + const char* sourceStrings[] = + { + source.c_str(), + }; + + result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); + } + else + { + const char* sourceStrings[] = + { + sourcePath.c_str(), + source.c_str(), + }; + + result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); + } + + 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); + + 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 = source.find("\n", curPos); + size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); + + hlslStream << "// " << source.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 + + SafeDeleteArray(outputHLSL); + + mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); + + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const sh::Uniform &uniform = mUniforms[uniformIndex]; + + if (uniform.staticUse) + { + unsigned int index = -1; + bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(result); + + mUniformRegisterMap[uniform.name] = index; + } + } + + mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); + + for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) + { + const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; + + if (interfaceBlock.staticUse) + { + unsigned int index = -1; + bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index); + UNUSED_ASSERTION_VARIABLE(result); + ASSERT(result); + + mInterfaceBlockRegisterMap[interfaceBlock.name] = index; + } + } + } + else + { + size_t infoLogLen = 0; + ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); + + char* infoLog = new char[infoLogLen]; + ShGetInfoLog(compiler, infoLog); + mInfoLog = infoLog; + + TRACE("\n%s", mInfoLog.c_str()); + } +} + +rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const +{ + if (mUsesDiscardRewriting) + { + // 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; + } + + if (mUsesNestedBreak) + { + // 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; + } + + return rx::ANGLE_D3D_WORKAROUND_NONE; +} + +// true if varying x has a higher priority in packing than y +bool ShaderD3D::compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y) +{ + if (x.type == y.type) + { + return x.arraySize > y.arraySize; + } + + // Special case for handling structs: we sort these to the end of the list + if (x.type == GL_STRUCT_ANGLEX) + { + return false; + } + + if (y.type == GL_STRUCT_ANGLEX) + { + return true; + } + + return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); +} + +unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const +{ + ASSERT(mUniformRegisterMap.count(uniformName) > 0); + return mUniformRegisterMap.find(uniformName)->second; +} + +unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName) const +{ + ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0); + return mInterfaceBlockRegisterMap.find(blockName)->second; +} + +void *ShaderD3D::getCompiler() +{ + if (mType == GL_VERTEX_SHADER) + { + return mVertexCompiler; + } + else + { + ASSERT(mType == GL_FRAGMENT_SHADER); + return mFragmentCompiler; + } +} + +ShShaderOutput ShaderD3D::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); +} + +bool ShaderD3D::compile(const std::string &source) +{ + uncompile(); + + void *compiler = getCompiler(); + + compileToHLSL(compiler, source); + + if (mType == GL_VERTEX_SHADER) + { + parseAttributes(compiler); + } + + parseVaryings(compiler); + + if (mType == GL_FRAGMENT_SHADER) + { + std::sort(mVaryings.begin(), mVaryings.end(), compareVarying); + + const std::string &hlsl = getTranslatedSource(); + if (!hlsl.empty()) + { + mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler)); + FilterInactiveVariables(&mActiveOutputVariables); + } + } + + return !getTranslatedSource().empty(); +} + +void ShaderD3D::parseAttributes(void *compiler) +{ + const std::string &hlsl = getTranslatedSource(); + if (!hlsl.empty()) + { + mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler)); + FilterInactiveVariables(&mActiveAttributes); + } +} + +int ShaderD3D::getSemanticIndex(const std::string &attributeName) const +{ + if (!attributeName.empty()) + { + int semanticIndex = 0; + for (size_t attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++) + { + const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex]; + + if (attribute.name == attributeName) + { + return semanticIndex; + } + + semanticIndex += gl::VariableRegisterCount(attribute.type); + } + } + + return -1; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h new file mode 100644 index 0000000000..40e64cf36c --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h @@ -0,0 +1,94 @@ +// +// 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. +// + +// ShaderD3D.h: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. + +#ifndef LIBGLESV2_RENDERER_SHADERD3D_H_ +#define LIBGLESV2_RENDERER_SHADERD3D_H_ + +#include "libGLESv2/renderer/ShaderImpl.h" +#include "libGLESv2/Shader.h" + +#include <map> + +namespace rx +{ +class DynamicHLSL; +class Renderer; + +class ShaderD3D : public ShaderImpl +{ + friend class DynamicHLSL; + + public: + ShaderD3D(GLenum type, rx::Renderer *renderer); + virtual ~ShaderD3D(); + + static ShaderD3D *makeShaderD3D(ShaderImpl *impl); + static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl); + + // ShaderImpl implementation + const std::string &getInfoLog() const { return mInfoLog; } + const std::string &getTranslatedSource() const { return mHlsl; } + + // D3D-specific methods + virtual void uncompile(); + void resetVaryingsRegisterAssignment(); + unsigned int getUniformRegister(const std::string &uniformName) const; + unsigned int getInterfaceBlockRegister(const std::string &blockName) const; + int getSemanticIndex(const std::string &attributeName) const; + + rx::D3DWorkaroundType getD3DWorkarounds() const; + int getShaderVersion() const { return mShaderVersion; } + bool usesDepthRange() const { return mUsesDepthRange; } + bool usesPointSize() const { return mUsesPointSize; } + + static void releaseCompiler(); + static ShShaderOutput getCompilerOutputType(GLenum shader); + + virtual bool compile(const std::string &source); + + private: + DISALLOW_COPY_AND_ASSIGN(ShaderD3D); + + void compileToHLSL(void *compiler, const std::string &source); + void parseVaryings(void *compiler); + + void initializeCompiler(); + void parseAttributes(void *compiler); + void *getCompiler(); + + static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y); + + static void *mFragmentCompiler; + static void *mVertexCompiler; + + GLenum mType; + rx::Renderer *mRenderer; + + int mShaderVersion; + + bool mUsesMultipleRenderTargets; + bool mUsesFragColor; + bool mUsesFragData; + bool mUsesFragCoord; + bool mUsesFrontFacing; + bool mUsesPointSize; + bool mUsesPointCoord; + bool mUsesDepthRange; + bool mUsesFragDepth; + bool mUsesDiscardRewriting; + bool mUsesNestedBreak; + + std::string mHlsl; + std::string mInfoLog; + std::map<std::string, unsigned int> mUniformRegisterMap; + std::map<std::string, unsigned int> mInterfaceBlockRegisterMap; +}; + +} + +#endif // LIBGLESV2_RENDERER_SHADERD3D_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp index e725e2fefe..96c84977cb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -7,39 +6,25 @@ // TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends. -#include "common/mathutil.h" -#include "common/utilities.h" -#include "libEGL/Surface.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TextureStorage.h" +#include "libGLESv2/renderer/d3d/ImageD3D.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Texture.h" #include "libGLESv2/main.h" #include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/renderer/RenderTarget.h" #include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/d3d/ImageD3D.h" -#include "libGLESv2/renderer/d3d/TextureD3D.h" -#include "libGLESv2/renderer/d3d/TextureStorage.h" -namespace rx -{ +#include "libEGL/Surface.h" + +#include "common/mathutil.h" +#include "common/utilities.h" -bool IsMipmapFiltered(const gl::SamplerState &samplerState) +namespace rx { - 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) { @@ -58,6 +43,26 @@ TextureD3D::~TextureD3D() { } +TextureD3D *TextureD3D::makeTextureD3D(TextureImpl *texture) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureD3D*, texture)); + return static_cast<TextureD3D*>(texture); +} + +TextureStorage *TextureD3D::getNativeTexture() +{ + // ensure the underlying texture is created + initializeStorage(false); + + TextureStorage *storage = getBaseLevelStorage(); + if (storage) + { + updateStorage(); + } + + return storage; +} + GLint TextureD3D::getBaseLevelWidth() const { const Image *baseImage = getBaseLevelImage(); @@ -116,7 +121,7 @@ void TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const } bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image) + GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index) { const void *pixelData = pixels; @@ -124,7 +129,7 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w if (unpack.pixelBuffer.id() != 0) { gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); - unsigned int offset = reinterpret_cast<unsigned int>(pixels); + ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels); // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data. // This functionality should be moved into renderer and the getData method of BufferImpl removed. const void *bufferData = pixelBuffer->getImplementation()->getData(); @@ -133,6 +138,9 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w if (pixelData != NULL) { + Image *image = getImage(index); + ASSERT(image); + image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData); mDirtyImages = true; } @@ -178,7 +186,7 @@ bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void // to create a render target. ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat)); - unsigned int offset = reinterpret_cast<unsigned int>(pixels); + ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels); return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea); } @@ -205,7 +213,6 @@ int TextureD3D::mipLevels() const TextureD3D_2D::TextureD3D_2D(Renderer *renderer) : TextureD3D(renderer), - Texture2DImpl(), mTexStorage(NULL) { for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) @@ -216,48 +223,36 @@ TextureD3D_2D::TextureD3D_2D(Renderer *renderer) TextureD3D_2D::~TextureD3D_2D() { - SafeDelete(mTexStorage); - + // Delete the Images before the TextureStorage. + // Images might be relying on the TextureStorage for some of their data. + // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { delete mImageArray[i]; } -} - -TextureD3D_2D *TextureD3D_2D::makeTextureD3D_2D(Texture2DImpl *texture) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2D*, texture)); - return static_cast<TextureD3D_2D*>(texture); -} - -TextureStorageInterface *TextureD3D_2D::getNativeTexture() -{ - // ensure the underlying texture is created - initializeStorage(false); - - TextureStorageInterface *storage = getBaseLevelStorage(); - if (storage) - { - updateStorage(); - } - return storage; + SafeDelete(mTexStorage); } -Image *TextureD3D_2D::getImage(int level) const +Image *TextureD3D_2D::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(layer == 0); return mImageArray[level]; } -void TextureD3D_2D::setUsage(GLenum usage) +Image *TextureD3D_2D::getImage(const gl::ImageIndex &index) const { - mUsage = usage; + ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(!index.hasLayer()); + ASSERT(index.type == GL_TEXTURE_2D); + return mImageArray[index.mipIndex]; } -void TextureD3D_2D::resetDirty() +GLsizei TextureD3D_2D::getLayerCount(int level) const { - mDirtyImages = false; + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return 1; } GLsizei TextureD3D_2D::getWidth(GLint level) const @@ -294,20 +289,26 @@ GLenum TextureD3D_2D::getActualFormat(GLint level) const bool TextureD3D_2D::isDepth(GLint level) const { - return gl::GetDepthBits(getInternalFormat(level)) > 0; + return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - GLenum sizedInternalFormat = gl::IsSizedInternalFormat(internalFormat) ? internalFormat - : gl::GetSizedInternalFormat(format, type); + ASSERT(target == GL_TEXTURE_2D && depth == 1); + + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + bool fastUnpacked = false; + redefineImage(level, sizedInternalFormat, width, height); + // Attempt a fast gpu copy of the pixel data to the surface if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level)) { + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + // Will try to create RT storage if it does not exist - RenderTarget *destRenderTarget = getRenderTarget(level); + RenderTarget *destRenderTarget = getRenderTarget(index); gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1); if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) @@ -325,18 +326,26 @@ void TextureD3D_2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum } } -void TextureD3D_2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +void TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) { + ASSERT(target == GL_TEXTURE_2D && depth == 1); + + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly + redefineImage(level, format, width, height); + TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]); } -void TextureD3D_2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { + ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0); + bool fastUnpacked = false; + gl::ImageIndex index = gl::ImageIndex::Make2D(level); if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level)) { - RenderTarget *renderTarget = getRenderTarget(level); + RenderTarget *renderTarget = getRenderTarget(index); gl::Box destArea(xoffset, yoffset, 0, width, height, 1); if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget)) @@ -348,22 +357,29 @@ void TextureD3D_2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei } } - if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level])) + if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index)) { commitRect(level, xoffset, yoffset, width, height); } } -void TextureD3D_2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) { + ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0); + if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level])) { commitRect(level, xoffset, yoffset, width, height); } } -void TextureD3D_2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { + ASSERT(target == GL_TEXTURE_2D); + + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); + redefineImage(level, sizedInternalFormat, width, height); + if (!mImageArray[level]->isRenderableFormat()) { mImageArray[level]->copy(0, 0, 0, x, y, width, height, source); @@ -382,13 +398,15 @@ void TextureD3D_2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsi sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, level); + mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level); } } } void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { + ASSERT(target == GL_TEXTURE_2D && zoffset == 0); + // 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); @@ -412,15 +430,17 @@ void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, - gl::GetFormat(getBaseLevelInternalFormat()), - xoffset, yoffset, mTexStorage, level); + mRenderer->copyImage2D(source, sourceRect, + gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, mTexStorage, level); } } } -void TextureD3D_2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { + ASSERT(target == GL_TEXTURE_2D && depth == 1); + for (int level = 0; level < levels; level++) { GLsizei levelWidth = std::max(1, width >> level); @@ -435,75 +455,9 @@ void TextureD3D_2D::storage(GLsizei levels, GLenum internalformat, GLsizei width mImmutable = true; - setCompleteTexStorage(new TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels)); -} - -// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85. -bool TextureD3D_2D::isSamplerComplete(const gl::SamplerState &samplerState) const -{ - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - - if (width <= 0 || height <= 0) - { - return false; - } - - if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable) - { - if (samplerState.magFilter != GL_NEAREST || - (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) - { - return false; - } - } - - // TODO(geofflang): use context's extensions - bool npotSupport = mRenderer->getRendererExtensions().textureNPOT; - - if (!npotSupport) - { - if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) || - (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height))) - { - return false; - } - } - - if (IsMipmapFiltered(samplerState)) - { - if (!npotSupport) - { - if (!gl::isPow2(width) || !gl::isPow2(height)) - { - return false; - } - } - - if (!isMipmapComplete()) - { - return false; - } - } - - // 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)) > 0 && mRenderer->getCurrentClientVersion() > 2) - { - if (samplerState.compareMode == GL_NONE) - { - if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) || - samplerState.magFilter != GL_NEAREST) - { - return false; - } - } - } - - return true; + bool renderTarget = IsRenderTargetUsage(mUsage); + TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels); + setCompleteTexStorage(storage); } void TextureD3D_2D::bindTexImage(egl::Surface *surface) @@ -516,7 +470,8 @@ void TextureD3D_2D::bindTexImage(egl::Surface *surface) { SafeDelete(mTexStorage); } - mTexStorage = new TextureStorageInterface2D(mRenderer, surface->getSwapChain()); + + mTexStorage = mRenderer->createTextureStorage2D(surface->getSwapChain()); mDirtyImages = true; } @@ -536,14 +491,20 @@ void TextureD3D_2D::releaseTexImage() void TextureD3D_2D::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)); + } if (mTexStorage && mTexStorage->isRenderTarget()) { + mTexStorage->generateMipmaps(); for (int level = 1; level < levelCount; level++) { - mTexStorage->generateMipmap(level); - mImageArray[level]->markClean(); } } @@ -556,63 +517,24 @@ void TextureD3D_2D::generateMipmaps() } } -unsigned int TextureD3D_2D::getRenderTargetSerial(GLint level) +unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0); + ASSERT(!index.hasLayer()); + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_2D::getRenderTarget(GLint level) +RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index) { - // ensure the underlying texture is created - if (!ensureRenderTarget()) - { - return NULL; - } - - updateStorageLevel(level); + ASSERT(!index.hasLayer()); - // ensure this is NOT a depth texture - if (isDepth(level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(level); -} - -RenderTarget *TextureD3D_2D::getDepthSencil(GLint level) -{ // ensure the underlying texture is created if (!ensureRenderTarget()) { return NULL; } - updateStorageLevel(level); - - // ensure this is actually a depth texture - if (!isDepth(level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(level); -} - -// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. -bool TextureD3D_2D::isMipmapComplete() const -{ - int levelCount = mipLevels(); - - for (int level = 0; level < levelCount; level++) - { - if (!isLevelComplete(level)) - { - return false; - } - } - - return true; + updateStorageLevel(index.mipIndex); + return mTexStorage->getRenderTarget(index); } bool TextureD3D_2D::isValidLevel(int level) const @@ -688,20 +610,21 @@ void TextureD3D_2D::initializeStorage(bool renderTarget) updateStorage(); } -TextureStorageInterface2D *TextureD3D_2D::createCompleteStorage(bool renderTarget) const +TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); + GLenum internalFormat = getBaseLevelInternalFormat(); ASSERT(width > 0 && height > 0); // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); - return new TextureStorageInterface2D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, levels); + return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels); } -void TextureD3D_2D::setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage) +void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -710,7 +633,7 @@ void TextureD3D_2D::setCompleteTexStorage(TextureStorageInterface2D *newComplete { for (int level = 0; level < mTexStorage->getLevelCount(); level++) { - mImageArray[level]->setManagedSurface(mTexStorage, level); + mImageArray[level]->setManagedSurface2D(mTexStorage, level); } } @@ -739,9 +662,9 @@ bool TextureD3D_2D::ensureRenderTarget() ASSERT(mTexStorage); if (!mTexStorage->isRenderTarget()) { - TextureStorageInterface2D *newRenderTargetStorage = createCompleteStorage(true); + TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage)) { delete newRenderTargetStorage; return gl::error(GL_OUT_OF_MEMORY, false); @@ -754,7 +677,7 @@ bool TextureD3D_2D::ensureRenderTarget() return (mTexStorage && mTexStorage->isRenderTarget()); } -TextureStorageInterface *TextureD3D_2D::getBaseLevelStorage() +TextureStorage *TextureD3D_2D::getBaseLevelStorage() { return mTexStorage; } @@ -809,7 +732,7 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize if (isValidLevel(level)) { ImageD3D *image = mImageArray[level]; - if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, width, height)) + if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height)) { image->markClean(); } @@ -818,8 +741,7 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer) - : TextureCubeImpl(), - TextureD3D(renderer), + : TextureD3D(renderer), mTexStorage(NULL) { for (int i = 0; i < 6; i++) @@ -833,8 +755,9 @@ TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer) TextureD3D_Cube::~TextureD3D_Cube() { - SafeDelete(mTexStorage); - + // Delete the Images before the TextureStorage. + // Images might be relying on the TextureStorage for some of their data. + // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. for (int i = 0; i < 6; i++) { for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j) @@ -842,88 +765,86 @@ TextureD3D_Cube::~TextureD3D_Cube() SafeDelete(mImageArray[i][j]); } } -} - -TextureD3D_Cube *TextureD3D_Cube::makeTextureD3D_Cube(TextureCubeImpl *texture) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_Cube*, texture)); - return static_cast<TextureD3D_Cube*>(texture); -} - -TextureStorageInterface *TextureD3D_Cube::getNativeTexture() -{ - // ensure the underlying texture is created - initializeStorage(false); - - TextureStorageInterface *storage = getBaseLevelStorage(); - if (storage) - { - updateStorage(); - } - return storage; + SafeDelete(mTexStorage); } -Image *TextureD3D_Cube::getImage(GLenum target, int level) const +Image *TextureD3D_Cube::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - return mImageArray[targetToIndex(target)][level]; + ASSERT(layer < 6); + return mImageArray[layer][level]; } -void TextureD3D_Cube::setUsage(GLenum usage) +Image *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const { - mUsage = usage; + ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(index.layerIndex < 6); + return mImageArray[index.layerIndex][index.mipIndex]; } -void TextureD3D_Cube::resetDirty() +GLsizei TextureD3D_Cube::getLayerCount(int level) const { - mDirtyImages = false; + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return 6; } -GLenum TextureD3D_Cube::getInternalFormat(GLenum target, GLint level) const +GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const { if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[targetToIndex(target)][level]->getInternalFormat(); + return mImageArray[layer][level]->getInternalFormat(); else return GL_NONE; } -bool TextureD3D_Cube::isDepth(GLenum target, GLint level) const +bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const { - return gl::GetDepthBits(getInternalFormat(target, level)) > 0; + return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; } -void TextureD3D_Cube::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - GLenum sizedInternalFormat = gl::IsSizedInternalFormat(internalFormat) ? internalFormat - : gl::GetSizedInternalFormat(format, type); + ASSERT(depth == 1); + + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); redefineImage(faceIndex, level, sizedInternalFormat, width, height); TextureD3D::setImage(unpack, type, pixels, mImageArray[faceIndex][level]); } -void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) { + ASSERT(depth == 1); + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - int faceIndex = targetToIndex(target); + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); + redefineImage(faceIndex, level, format, width, height); TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]); } -void TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - int faceIndex = targetToIndex(target); - if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level])) + ASSERT(depth == 1 && zoffset == 0); + + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); + + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index)) { commitRect(faceIndex, level, xoffset, yoffset, width, height); } } -void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) { - int faceIndex = targetToIndex(target); + ASSERT(depth == 1 && zoffset == 0); + + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); + if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level])) { commitRect(faceIndex, level, xoffset, yoffset, width, height); @@ -932,9 +853,9 @@ void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffs void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { - int faceIndex = targetToIndex(target); - GLenum sizedInternalFormat = gl::IsSizedInternalFormat(format) ? format - : gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); + redefineImage(faceIndex, level, sizedInternalFormat, width, height); if (!mImageArray[faceIndex][level]->isRenderableFormat()) @@ -957,14 +878,14 @@ void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, target, level); + mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level); } } } void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { - int faceIndex = targetToIndex(target); + int faceIndex = gl::TextureCubeMap::targetToLayerIndex(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 @@ -990,17 +911,20 @@ void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GL sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, gl::GetFormat(getBaseLevelInternalFormat()), - xoffset, yoffset, mTexStorage, target, level); + mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, mTexStorage, target, level); } } } -void TextureD3D_Cube::storage(GLsizei levels, GLenum internalformat, GLsizei size) +void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { + ASSERT(width == height); + ASSERT(depth == 1); + for (int level = 0; level < levels; level++) { - GLsizei mipSize = std::max(1, size >> level); + GLsizei mipSize = std::max(1, width >> level); for (int faceIndex = 0; faceIndex < 6; faceIndex++) { mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true); @@ -1017,50 +941,9 @@ void TextureD3D_Cube::storage(GLsizei levels, GLenum internalformat, GLsizei siz mImmutable = true; - setCompleteTexStorage(new TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), size, levels)); -} - -bool TextureD3D_Cube::isSamplerComplete(const gl::SamplerState &samplerState) const -{ - int size = getBaseLevelWidth(); - - bool mipmapping = IsMipmapFiltered(samplerState); - - // TODO(geofflang): use context's texture caps - if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable) - { - if (samplerState.magFilter != GL_NEAREST || - (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST)) - { - return false; - } - } - - // TODO(geofflang): use context's extensions - if (!gl::isPow2(size) && !mRenderer->getRendererExtensions().textureNPOT) - { - if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping) - { - return false; - } - } - - if (!mipmapping) - { - if (!isCubeComplete()) - { - return false; - } - } - else - { - if (!isMipmapCubeComplete()) // Also tests for isCubeComplete() - { - return false; - } - } - - return true; + bool renderTarget = IsRenderTargetUsage(mUsage); + TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels); + setCompleteTexStorage(storage); } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -1090,6 +973,17 @@ bool TextureD3D_Cube::isCubeComplete() const return true; } +void TextureD3D_Cube::bindTexImage(egl::Surface *surface) +{ + UNREACHABLE(); +} + +void TextureD3D_Cube::releaseTexImage() +{ + UNREACHABLE(); +} + + void TextureD3D_Cube::generateMipmaps() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. @@ -1105,12 +999,12 @@ void TextureD3D_Cube::generateMipmaps() if (mTexStorage && mTexStorage->isRenderTarget()) { + mTexStorage->generateMipmaps(); + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { for (int level = 1; level < levelCount; level++) { - mTexStorage->generateMipmap(faceIndex, level); - mImageArray[faceIndex][level]->markClean(); } } @@ -1127,35 +1021,14 @@ void TextureD3D_Cube::generateMipmaps() } } -unsigned int TextureD3D_Cube::getRenderTargetSerial(GLenum target, GLint level) +unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0); -} - -RenderTarget *TextureD3D_Cube::getRenderTarget(GLenum target, GLint level) -{ - ASSERT(gl::IsCubemapTextureTarget(target)); - - // ensure the underlying texture is created - if (!ensureRenderTarget()) - { - return NULL; - } - - updateStorageFaceLevel(targetToIndex(target), level); - - // ensure this is NOT a depth texture - if (isDepth(target, level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(target, level); + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_Cube::getDepthStencil(GLenum target, GLint level) +RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index) { - ASSERT(gl::IsCubemapTextureTarget(target)); + ASSERT(gl::IsCubemapTextureTarget(index.type)); // ensure the underlying texture is created if (!ensureRenderTarget()) @@ -1163,26 +1036,8 @@ RenderTarget *TextureD3D_Cube::getDepthStencil(GLenum target, GLint level) return NULL; } - updateStorageFaceLevel(targetToIndex(target), level); - - // ensure this is a depth texture - if (!isDepth(target, level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(target, level); -} - -int TextureD3D_Cube::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); - META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3); - 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 target - GL_TEXTURE_CUBE_MAP_POSITIVE_X; + updateStorageFaceLevel(index.layerIndex, index.mipIndex); + return mTexStorage->getRenderTarget(index); } void TextureD3D_Cube::initializeStorage(bool renderTarget) @@ -1208,7 +1063,7 @@ void TextureD3D_Cube::initializeStorage(bool renderTarget) updateStorage(); } -TextureStorageInterfaceCube *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const +TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const { GLsizei size = getBaseLevelWidth(); @@ -1217,10 +1072,10 @@ TextureStorageInterfaceCube *TextureD3D_Cube::createCompleteStorage(bool renderT // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1)); - return new TextureStorageInterfaceCube(mRenderer, getBaseLevelInternalFormat(), renderTarget, size, levels); + return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels); } -void TextureD3D_Cube::setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage) +void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -1231,7 +1086,7 @@ void TextureD3D_Cube::setCompleteTexStorage(TextureStorageInterfaceCube *newComp { for (int level = 0; level < mTexStorage->getLevelCount(); level++) { - mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level); + mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level); } } } @@ -1264,9 +1119,9 @@ bool TextureD3D_Cube::ensureRenderTarget() ASSERT(mTexStorage); if (!mTexStorage->isRenderTarget()) { - TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true); + TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage)) { delete newRenderTargetStorage; return gl::error(GL_OUT_OF_MEMORY, false); @@ -1279,7 +1134,7 @@ bool TextureD3D_Cube::ensureRenderTarget() return (mTexStorage && mTexStorage->isRenderTarget()); } -TextureStorageInterface *TextureD3D_Cube::getBaseLevelStorage() +TextureStorage *TextureD3D_Cube::getBaseLevelStorage() { return mTexStorage; } @@ -1291,40 +1146,11 @@ const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const return mImageArray[0][0]; } -bool TextureD3D_Cube::isMipmapCubeComplete() const -{ - if (isImmutable()) - { - return true; - } - - if (!isCubeComplete()) - { - return false; - } - - int levelCount = mipLevels(); - - for (int face = 0; face < 6; face++) - { - for (int level = 1; level < levelCount; level++) - { - if (!isFaceLevelComplete(face, level)) - { - return false; - } - } - } - - return true; -} - bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const { return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0); } - bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const { ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); @@ -1414,15 +1240,14 @@ void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLin if (isValidFaceLevel(faceIndex, level)) { ImageD3D *image = mImageArray[faceIndex][level]; - if (image->copyToStorage(mTexStorage, faceIndex, level, xoffset, yoffset, width, height)) + if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height)) image->markClean(); } } TextureD3D_3D::TextureD3D_3D(Renderer *renderer) - : Texture3DImpl(), - TextureD3D(renderer), + : TextureD3D(renderer), mTexStorage(NULL) { for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) @@ -1433,48 +1258,36 @@ TextureD3D_3D::TextureD3D_3D(Renderer *renderer) TextureD3D_3D::~TextureD3D_3D() { - SafeDelete(mTexStorage); - + // Delete the Images before the TextureStorage. + // Images might be relying on the TextureStorage for some of their data. + // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { delete mImageArray[i]; } -} - -TextureD3D_3D *TextureD3D_3D::makeTextureD3D_3D(Texture3DImpl *texture) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_3D*, texture)); - return static_cast<TextureD3D_3D*>(texture); -} - -TextureStorageInterface *TextureD3D_3D::getNativeTexture() -{ - // ensure the underlying texture is created - initializeStorage(false); - TextureStorageInterface *storage = getBaseLevelStorage(); - if (storage) - { - updateStorage(); - } - - return storage; + SafeDelete(mTexStorage); } -Image *TextureD3D_3D::getImage(int level) const +Image *TextureD3D_3D::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(layer == 0); return mImageArray[level]; } -void TextureD3D_3D::setUsage(GLenum usage) +Image *TextureD3D_3D::getImage(const gl::ImageIndex &index) const { - mUsage = usage; + ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(!index.hasLayer()); + ASSERT(index.type == GL_TEXTURE_3D); + return mImageArray[index.mipIndex]; } -void TextureD3D_3D::resetDirty() +GLsizei TextureD3D_3D::getLayerCount(int level) const { - mDirtyImages = false; + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return 1; } GLsizei TextureD3D_3D::getWidth(GLint level) const @@ -1511,13 +1324,14 @@ GLenum TextureD3D_3D::getInternalFormat(GLint level) const bool TextureD3D_3D::isDepth(GLint level) const { - return gl::GetDepthBits(getInternalFormat(level)) > 0; + return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - GLenum sizedInternalFormat = gl::IsSizedInternalFormat(internalFormat) ? internalFormat - : gl::GetSizedInternalFormat(format, type); + ASSERT(target == GL_TEXTURE_3D); + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + redefineImage(level, sizedInternalFormat, width, height, depth); bool fastUnpacked = false; @@ -1526,7 +1340,8 @@ void TextureD3D_3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei if (isFastUnpackable(unpack, sizedInternalFormat)) { // Will try to create RT storage if it does not exist - RenderTarget *destRenderTarget = getRenderTarget(level); + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + RenderTarget *destRenderTarget = getRenderTarget(index); gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) @@ -1544,22 +1359,28 @@ void TextureD3D_3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei } } -void TextureD3D_3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +void TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) { + ASSERT(target == GL_TEXTURE_3D); + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, format, width, height, depth); TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]); } -void TextureD3D_3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { + ASSERT(target == GL_TEXTURE_3D); + bool fastUnpacked = false; + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer if (isFastUnpackable(unpack, getInternalFormat(level))) { - RenderTarget *destRenderTarget = getRenderTarget(level); + RenderTarget *destRenderTarget = getRenderTarget(index); gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth); if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget)) @@ -1571,22 +1392,31 @@ void TextureD3D_3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zo } } - if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level])) + if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index)) { commitRect(level, xoffset, yoffset, zoffset, width, height, depth); } } -void TextureD3D_3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) { + ASSERT(target == GL_TEXTURE_3D); + if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level])) { commitRect(level, xoffset, yoffset, zoffset, width, height, depth); } } +void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +{ + UNIMPLEMENTED(); +} + void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { + ASSERT(target == GL_TEXTURE_3D); + // 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); @@ -1610,15 +1440,17 @@ void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLin sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, - gl::GetFormat(getBaseLevelInternalFormat()), - xoffset, yoffset, zoffset, mTexStorage, level); + mRenderer->copyImage3D(source, sourceRect, + gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, zoffset, mTexStorage, level); } } } -void TextureD3D_3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { + ASSERT(target == GL_TEXTURE_3D); + for (int level = 0; level < levels; level++) { GLsizei levelWidth = std::max(1, width >> level); @@ -1634,53 +1466,22 @@ void TextureD3D_3D::storage(GLsizei levels, GLenum internalformat, GLsizei width mImmutable = true; - setCompleteTexStorage(new TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels)); + bool renderTarget = IsRenderTargetUsage(mUsage); + TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels); + setCompleteTexStorage(storage); } -bool TextureD3D_3D::isSamplerComplete(const gl::SamplerState &samplerState) const +void TextureD3D_3D::bindTexImage(egl::Surface *surface) { - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei depth = getBaseLevelDepth(); - - if (width <= 0 || height <= 0 || depth <= 0) - { - return false; - } - - // TODO(geofflang): use context's texture caps - if (!mRenderer->getRendererTextureCaps().get(getInternalFormat(0)).filterable) - { - 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; + UNREACHABLE(); } -bool TextureD3D_3D::isMipmapComplete() const +void TextureD3D_3D::releaseTexImage() { - int levelCount = mipLevels(); - - for (int level = 0; level < levelCount; level++) - { - if (!isLevelComplete(level)) - { - return false; - } - } - - return true; + UNREACHABLE(); } + void TextureD3D_3D::generateMipmaps() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. @@ -1695,10 +1496,10 @@ void TextureD3D_3D::generateMipmaps() if (mTexStorage && mTexStorage->isRenderTarget()) { + mTexStorage->generateMipmaps(); + for (int level = 1; level < levelCount; level++) { - mTexStorage->generateMipmap(level); - mImageArray[level]->markClean(); } } @@ -1711,12 +1512,12 @@ void TextureD3D_3D::generateMipmaps() } } -unsigned int TextureD3D_3D::getRenderTargetSerial(GLint level, GLint layer) +unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0); + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_3D::getRenderTarget(GLint level) +RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index) { // ensure the underlying texture is created if (!ensureRenderTarget()) @@ -1724,53 +1525,16 @@ RenderTarget *TextureD3D_3D::getRenderTarget(GLint level) return NULL; } - updateStorageLevel(level); - - // ensure this is NOT a depth texture - if (isDepth(level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(level); -} - -RenderTarget *TextureD3D_3D::getRenderTarget(GLint level, GLint layer) -{ - // ensure the underlying texture is created - if (!ensureRenderTarget()) + if (index.hasLayer()) { - return NULL; - } - - updateStorage(); - - // ensure this is NOT a depth texture - if (isDepth(level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(level, layer); -} - -RenderTarget *TextureD3D_3D::getDepthStencil(GLint level, GLint layer) -{ - // ensure the underlying texture is created - if (!ensureRenderTarget()) - { - return NULL; + updateStorage(); } - - updateStorageLevel(level); - - // ensure this is a depth texture - if (!isDepth(level)) + else { - return NULL; + updateStorageLevel(index.mipIndex); } - return mTexStorage->getRenderTarget(level, layer); + return mTexStorage->getRenderTarget(index); } void TextureD3D_3D::initializeStorage(bool renderTarget) @@ -1796,21 +1560,22 @@ void TextureD3D_3D::initializeStorage(bool renderTarget) updateStorage(); } -TextureStorageInterface3D *TextureD3D_3D::createCompleteStorage(bool renderTarget) const +TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); GLsizei depth = getBaseLevelDepth(); + GLenum internalFormat = getBaseLevelInternalFormat(); 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 TextureStorageInterface3D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels); + return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels); } -void TextureD3D_3D::setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage) +void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -1842,9 +1607,9 @@ bool TextureD3D_3D::ensureRenderTarget() ASSERT(mTexStorage); if (!mTexStorage->isRenderTarget()) { - TextureStorageInterface3D *newRenderTargetStorage = createCompleteStorage(true); + TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage)) { delete newRenderTargetStorage; return gl::error(GL_OUT_OF_MEMORY, false); @@ -1857,7 +1622,7 @@ bool TextureD3D_3D::ensureRenderTarget() return (mTexStorage && mTexStorage->isRenderTarget()); } -TextureStorageInterface *TextureD3D_3D::getBaseLevelStorage() +TextureStorage *TextureD3D_3D::getBaseLevelStorage() { return mTexStorage; } @@ -1967,7 +1732,7 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint if (isValidLevel(level)) { ImageD3D *image = mImageArray[level]; - if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth)) + if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth)) { image->markClean(); } @@ -1976,8 +1741,7 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer) - : Texture2DArrayImpl(), - TextureD3D(renderer), + : TextureD3D(renderer), mTexStorage(NULL) { for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) @@ -1989,29 +1753,11 @@ TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer) TextureD3D_2DArray::~TextureD3D_2DArray() { - SafeDelete(mTexStorage); - + // Delete the Images before the TextureStorage. + // Images might be relying on the TextureStorage for some of their data. + // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. deleteImages(); -} - -TextureD3D_2DArray *TextureD3D_2DArray::makeTextureD3D_2DArray(Texture2DArrayImpl *texture) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureD3D_2DArray*, texture)); - return static_cast<TextureD3D_2DArray*>(texture); -} - -TextureStorageInterface *TextureD3D_2DArray::getNativeTexture() -{ - // ensure the underlying texture is created - initializeStorage(false); - - TextureStorageInterface *storage = getBaseLevelStorage(); - if (storage) - { - updateStorage(); - } - - return storage; + SafeDelete(mTexStorage); } Image *TextureD3D_2DArray::getImage(int level, int layer) const @@ -2021,20 +1767,18 @@ Image *TextureD3D_2DArray::getImage(int level, int layer) const return mImageArray[level][layer]; } -GLsizei TextureD3D_2DArray::getLayerCount(int level) const -{ - ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - return mLayerCounts[level]; -} - -void TextureD3D_2DArray::setUsage(GLenum usage) +Image *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const { - mUsage = usage; + ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(index.layerIndex < mLayerCounts[index.mipIndex]); + ASSERT(index.type == GL_TEXTURE_2D_ARRAY); + return mImageArray[index.mipIndex][index.layerIndex]; } -void TextureD3D_2DArray::resetDirty() +GLsizei TextureD3D_2DArray::getLayerCount(int level) const { - mDirtyImages = false; + ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + return mLayerCounts[level]; } GLsizei TextureD3D_2DArray::getWidth(GLint level) const @@ -2059,16 +1803,19 @@ GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const bool TextureD3D_2DArray::isDepth(GLint level) const { - return gl::GetDepthBits(getInternalFormat(level)) > 0; + return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - GLenum sizedInternalFormat = gl::IsSizedInternalFormat(internalFormat) ? internalFormat - : gl::GetSizedInternalFormat(format, type); + ASSERT(target == GL_TEXTURE_2D_ARRAY); + + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + redefineImage(level, sizedInternalFormat, width, height, depth); - GLsizei inputDepthPitch = gl::GetDepthPitch(sizedInternalFormat, type, width, height, unpack.alignment); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpack.alignment); for (int i = 0; i < depth; i++) { @@ -2077,12 +1824,15 @@ void TextureD3D_2DArray::setImage(GLint level, GLsizei width, GLsizei height, GL } } -void TextureD3D_2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) { + ASSERT(target == GL_TEXTURE_2D_ARRAY); + // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, format, width, height, depth); - GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, width, height, 1); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); for (int i = 0; i < depth; i++) { @@ -2091,26 +1841,32 @@ void TextureD3D_2DArray::setCompressedImage(GLint level, GLenum format, GLsizei } } -void TextureD3D_2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) { - GLenum internalformat = getInternalFormat(level); - GLsizei inputDepthPitch = gl::GetDepthPitch(internalformat, type, width, height, unpack.alignment); + ASSERT(target == GL_TEXTURE_2D_ARRAY); + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level)); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, 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 (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer])) + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); + if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index)) { commitRect(level, xoffset, yoffset, layer, width, height); } } } -void TextureD3D_2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) { - GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, width, height, 1); + ASSERT(target == GL_TEXTURE_2D_ARRAY); + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); for (int i = 0; i < depth; i++) { @@ -2124,8 +1880,15 @@ void TextureD3D_2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yo } } +void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +{ + UNIMPLEMENTED(); +} + void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { + ASSERT(target == GL_TEXTURE_2D_ARRAY); + // 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); @@ -2149,14 +1912,16 @@ void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, sourceRect.y = y; sourceRect.height = height; - mRenderer->copyImage(source, sourceRect, gl::GetFormat(getInternalFormat(0)), - xoffset, yoffset, zoffset, mTexStorage, level); + mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format, + xoffset, yoffset, zoffset, mTexStorage, level); } } } -void TextureD3D_2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { + ASSERT(target == GL_TEXTURE_2D_ARRAY); + deleteImages(); for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) @@ -2181,53 +1946,23 @@ void TextureD3D_2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei } mImmutable = true; - setCompleteTexStorage(new TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels)); + + bool renderTarget = IsRenderTargetUsage(mUsage); + TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels); + setCompleteTexStorage(storage); } -bool TextureD3D_2DArray::isSamplerComplete(const gl::SamplerState &samplerState) const +void TextureD3D_2DArray::bindTexImage(egl::Surface *surface) { - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei depth = getLayers(0); - - if (width <= 0 || height <= 0 || depth <= 0) - { - return false; - } - - // TODO(geofflang): use context's texture caps - if (!mRenderer->getRendererTextureCaps().get(getBaseLevelInternalFormat()).filterable) - { - 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; + UNREACHABLE(); } -bool TextureD3D_2DArray::isMipmapComplete() const +void TextureD3D_2DArray::releaseTexImage() { - int levelCount = mipLevels(); - - for (int level = 1; level < levelCount; level++) - { - if (!isLevelComplete(level)) - { - return false; - } - } - - return true; + UNREACHABLE(); } + void TextureD3D_2DArray::generateMipmaps() { int baseWidth = getBaseLevelWidth(); @@ -2244,10 +1979,10 @@ void TextureD3D_2DArray::generateMipmaps() if (mTexStorage && mTexStorage->isRenderTarget()) { + mTexStorage->generateMipmaps(); + for (int level = 1; level < levelCount; level++) { - mTexStorage->generateMipmap(level); - for (int layer = 0; layer < mLayerCounts[level]; layer++) { mImageArray[level][layer]->markClean(); @@ -2266,31 +2001,12 @@ void TextureD3D_2DArray::generateMipmaps() } } -unsigned int TextureD3D_2DArray::getRenderTargetSerial(GLint level, GLint layer) +unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0); -} - -RenderTarget *TextureD3D_2DArray::getRenderTarget(GLint level, GLint layer) -{ - // 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, layer); + return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_2DArray::getDepthStencil(GLint level, GLint layer) +RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index) { // ensure the underlying texture is created if (!ensureRenderTarget()) @@ -2298,15 +2014,8 @@ RenderTarget *TextureD3D_2DArray::getDepthStencil(GLint level, GLint layer) return NULL; } - updateStorageLevel(level); - - // ensure this is a depth texture - if (!isDepth(level)) - { - return NULL; - } - - return mTexStorage->getRenderTarget(level, layer); + updateStorageLevel(index.mipIndex); + return mTexStorage->getRenderTarget(index); } void TextureD3D_2DArray::initializeStorage(bool renderTarget) @@ -2332,21 +2041,22 @@ void TextureD3D_2DArray::initializeStorage(bool renderTarget) updateStorage(); } -TextureStorageInterface2DArray *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const +TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); GLsizei depth = getLayers(0); + GLenum internalFormat = getBaseLevelInternalFormat(); 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 TextureStorageInterface2DArray(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels); + return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels); } -void TextureD3D_2DArray::setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage) +void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -2378,9 +2088,9 @@ bool TextureD3D_2DArray::ensureRenderTarget() ASSERT(mTexStorage); if (!mTexStorage->isRenderTarget()) { - TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true); + TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage)) + if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage)) { delete newRenderTargetStorage; return gl::error(GL_OUT_OF_MEMORY, false); @@ -2398,7 +2108,7 @@ const ImageD3D *TextureD3D_2DArray::getBaseLevelImage() const return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL); } -TextureStorageInterface *TextureD3D_2DArray::getBaseLevelStorage() +TextureStorage *TextureD3D_2DArray::getBaseLevelStorage() { return mTexStorage; } @@ -2540,7 +2250,7 @@ void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, G if (isValidLevel(level) && layerTarget < getLayers(level)) { ImageD3D *image = mImageArray[level][layerTarget]; - if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, layerTarget, width, height)) + if (image->copyToStorage2DArray(mTexStorage, level, xoffset, yoffset, layerTarget, width, height)) { image->markClean(); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h index 4a1737a9c4..41c73180de 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h @@ -24,20 +24,23 @@ namespace rx class Image; class ImageD3D; class Renderer; -class TextureStorageInterface; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; -class TextureStorageInterface3D; -class TextureStorageInterface2DArray; +class RenderTarget; +class TextureStorage; -bool IsMipmapFiltered(const gl::SamplerState &samplerState); - -class TextureD3D +class TextureD3D : public TextureImpl { public: TextureD3D(Renderer *renderer); virtual ~TextureD3D(); + static TextureD3D *makeTextureD3D(TextureImpl *texture); + + virtual TextureStorage *getNativeTexture(); + + virtual void setUsage(GLenum usage) { mUsage = usage; } + bool hasDirtyImages() const { return mDirtyImages; } + void resetDirty() { mDirtyImages = false; } + GLint getBaseLevelWidth() const; GLint getBaseLevelHeight() const; GLint getBaseLevelDepth() const; @@ -45,16 +48,19 @@ class TextureD3D bool isImmutable() const { return mImmutable; } + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0; + protected: void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image); bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image); + GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index); void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, Image *image); bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat); bool fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea, - GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget); + GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget); GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; int mipLevels() const; @@ -70,25 +76,22 @@ class TextureD3D private: DISALLOW_COPY_AND_ASSIGN(TextureD3D); - virtual TextureStorageInterface *getBaseLevelStorage() = 0; + virtual void initializeStorage(bool renderTarget) = 0; + + virtual void updateStorage() = 0; + virtual TextureStorage *getBaseLevelStorage() = 0; virtual const ImageD3D *getBaseLevelImage() const = 0; }; -class TextureD3D_2D : public Texture2DImpl, public TextureD3D +class TextureD3D_2D : public TextureD3D { public: TextureD3D_2D(Renderer *renderer); virtual ~TextureD3D_2D(); - static TextureD3D_2D *makeTextureD3D_2D(Texture2DImpl *texture); - - virtual TextureStorageInterface *getNativeTexture(); - - virtual Image *getImage(int level) const; - - virtual void setUsage(GLenum usage); - virtual bool hasDirtyImages() const { return mDirtyImages; } - virtual void resetDirty(); + virtual Image *getImage(int level, int layer) const; + virtual Image *getImage(const gl::ImageIndex &index) const; + virtual GLsizei getLayerCount(int level) const; GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; @@ -96,104 +99,94 @@ class TextureD3D_2D : public Texture2DImpl, public TextureD3D GLenum getActualFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); - virtual void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const; virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual unsigned int getRenderTargetSerial(GLint level); - - virtual RenderTarget *getRenderTarget(GLint level); - virtual RenderTarget *getDepthSencil(GLint level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D); - void initializeStorage(bool renderTarget); - TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorageInterface2D *newCompleteTexStorage); + virtual void initializeStorage(bool renderTarget); + TextureStorage *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - void updateStorage(); + virtual void updateStorage(); bool ensureRenderTarget(); - virtual TextureStorageInterface *getBaseLevelStorage(); + virtual TextureStorage *getBaseLevelStorage(); virtual const ImageD3D *getBaseLevelImage() const; - bool isMipmapComplete() const; bool isValidLevel(int level) const; bool isLevelComplete(int level) const; void updateStorageLevel(int level); - virtual void redefineImage(GLint level, GLenum 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); - TextureStorageInterface2D *mTexStorage; + TextureStorage *mTexStorage; ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; -class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D +class TextureD3D_Cube : public TextureD3D { public: TextureD3D_Cube(Renderer *renderer); virtual ~TextureD3D_Cube(); - static TextureD3D_Cube *makeTextureD3D_Cube(TextureCubeImpl *texture); - - virtual TextureStorageInterface *getNativeTexture(); - - virtual Image *getImage(GLenum target, int level) const; + virtual Image *getImage(int level, int layer) const; + virtual Image *getImage(const gl::ImageIndex &index) const; + virtual GLsizei getLayerCount(int level) const; - virtual void setUsage(GLenum usage); virtual bool hasDirtyImages() const { return mDirtyImages; } - virtual void resetDirty(); + virtual void resetDirty() { mDirtyImages = false; } + virtual void setUsage(GLenum usage) { mUsage = usage; } - GLenum getInternalFormat(GLenum target, GLint level) const; - bool isDepth(GLenum target, GLint level) const; + GLenum getInternalFormat(GLint level, GLint layer) const; + bool isDepth(GLint level, GLint layer) const; - virtual void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); + virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei size); + virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const; - virtual bool isCubeComplete() const; + virtual void bindTexImage(egl::Surface *surface); + virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual unsigned int getRenderTargetSerial(GLenum target, GLint level); - - virtual RenderTarget *getRenderTarget(GLenum target, GLint level); - virtual RenderTarget *getDepthStencil(GLenum target, GLint level); - - static int targetToIndex(GLenum target); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube); - void initializeStorage(bool renderTarget); - TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorageInterfaceCube *newCompleteTexStorage); + virtual void initializeStorage(bool renderTarget); + TextureStorage *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - void updateStorage(); + virtual void updateStorage(); bool ensureRenderTarget(); - virtual TextureStorageInterface *getBaseLevelStorage(); + virtual TextureStorage *getBaseLevelStorage(); virtual const ImageD3D *getBaseLevelImage() const; - bool isMipmapCubeComplete() const; bool isValidFaceLevel(int faceIndex, int level) const; bool isFaceLevelComplete(int faceIndex, int level) const; + bool isCubeComplete() const; void updateStorageFaceLevel(int faceIndex, int level); void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height); @@ -201,24 +194,18 @@ class TextureD3D_Cube : public TextureCubeImpl, public TextureD3D ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - TextureStorageInterfaceCube *mTexStorage; + TextureStorage *mTexStorage; }; -class TextureD3D_3D : public Texture3DImpl, public TextureD3D +class TextureD3D_3D : public TextureD3D { public: TextureD3D_3D(Renderer *renderer); virtual ~TextureD3D_3D(); - static TextureD3D_3D *makeTextureD3D_3D(Texture3DImpl *texture); - - virtual TextureStorageInterface *getNativeTexture(); - - virtual Image *getImage(int level) const; - - virtual void setUsage(GLenum usage); - virtual bool hasDirtyImages() const { return mDirtyImages; } - virtual void resetDirty(); + virtual Image *getImage(int level, int layer) const; + virtual Image *getImage(const gl::ImageIndex &index) const; + virtual GLsizei getLayerCount(int level) const; GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; @@ -226,34 +213,32 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const; - virtual bool isMipmapComplete() const; + virtual void bindTexImage(egl::Surface *surface); + virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual unsigned int getRenderTargetSerial(GLint level, GLint layer); - - virtual RenderTarget *getRenderTarget(GLint level); - virtual RenderTarget *getRenderTarget(GLint level, GLint layer); - virtual RenderTarget *getDepthStencil(GLint level, GLint layer); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D); virtual void initializeStorage(bool renderTarget); - TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorageInterface3D *newCompleteTexStorage); + TextureStorage *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - void updateStorage(); + virtual void updateStorage(); bool ensureRenderTarget(); - virtual TextureStorageInterface *getBaseLevelStorage(); + virtual TextureStorage *getBaseLevelStorage(); virtual const ImageD3D *getBaseLevelImage() const; bool isValidLevel(int level) const; @@ -265,59 +250,51 @@ class TextureD3D_3D : public Texture3DImpl, public TextureD3D ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - TextureStorageInterface3D *mTexStorage; + TextureStorage *mTexStorage; }; -class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D +class TextureD3D_2DArray : public TextureD3D { public: TextureD3D_2DArray(Renderer *renderer); virtual ~TextureD3D_2DArray(); - static TextureD3D_2DArray *makeTextureD3D_2DArray(Texture2DArrayImpl *texture); - - virtual TextureStorageInterface *getNativeTexture(); - virtual Image *getImage(int level, int layer) const; + virtual Image *getImage(const gl::ImageIndex &index) const; virtual GLsizei getLayerCount(int level) const; - virtual void setUsage(GLenum usage); - virtual bool hasDirtyImages() const { return mDirtyImages; } - virtual void resetDirty(); - GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; GLsizei getLayers(GLint level) const; GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); + virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); + virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - virtual bool isSamplerComplete(const gl::SamplerState &samplerState) const; - virtual bool isMipmapComplete() const; + virtual void bindTexImage(egl::Surface *surface); + virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual unsigned int getRenderTargetSerial(GLint level, GLint layer); - - virtual RenderTarget *getRenderTarget(GLint level, GLint layer); - virtual RenderTarget *getDepthStencil(GLint level, GLint layer); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray); virtual void initializeStorage(bool renderTarget); - TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorageInterface2DArray *newCompleteTexStorage); + TextureStorage *createCompleteStorage(bool renderTarget) const; + void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - void updateStorage(); + virtual void updateStorage(); bool ensureRenderTarget(); - virtual TextureStorageInterface *getBaseLevelStorage(); + virtual TextureStorage *getBaseLevelStorage(); virtual const ImageD3D *getBaseLevelImage() const; bool isValidLevel(int level) const; @@ -335,7 +312,7 @@ class TextureD3D_2DArray : public Texture2DArrayImpl, public TextureD3D GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - TextureStorageInterface2DArray *mTexStorage; + TextureStorage *mTexStorage; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp index 846586984c..dedd266c09 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp @@ -1,13 +1,10 @@ -#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. // -// TextureStorage.cpp: Implements the abstract rx::TextureStorageInterface class and its concrete derived -// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the -// GPU-side texture. +// TextureStorage.cpp: Shared members of abstract rx::TextureStorage class. #include "libGLESv2/renderer/d3d/TextureStorage.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" @@ -20,162 +17,35 @@ namespace rx { -unsigned int TextureStorageInterface::mCurrentTextureSerial = 1; -TextureStorageInterface::TextureStorageInterface() - : mTextureSerial(issueTextureSerial()), - mInstance(NULL) -{ -} +unsigned int TextureStorage::mCurrentTextureSerial = 1; -TextureStorageInterface::~TextureStorageInterface() -{ - delete mInstance; -} +TextureStorage::TextureStorage() + : mTextureSerial(issueTextureSerial()), + mFirstRenderTargetSerial(0), + mRenderTargetSerialsLayerStride(0) +{} -bool TextureStorageInterface::isRenderTarget() const +void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride) { - return mInstance->isRenderTarget(); + mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve); + mRenderTargetSerialsLayerStride = rtSerialsLayerStride; } -bool TextureStorageInterface::isManaged() const +unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index) const { - return mInstance->isManaged(); + unsigned int layerOffset = (index.hasLayer() ? (static_cast<unsigned int>(index.layerIndex) * mRenderTargetSerialsLayerStride) : 0); + return mFirstRenderTargetSerial + static_cast<unsigned int>(index.mipIndex) + layerOffset; } -unsigned int TextureStorageInterface::getTextureSerial() const +unsigned int TextureStorage::getTextureSerial() const { return mTextureSerial; } -unsigned int TextureStorageInterface::issueTextureSerial() +unsigned int TextureStorage::issueTextureSerial() { return mCurrentTextureSerial++; } -int TextureStorageInterface::getTopLevel() const -{ - return mInstance->getTopLevel(); -} - -int TextureStorageInterface::getLevelCount() const -{ - return mInstance->getLevelCount(); -} - -TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain) -{ - mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(1); - - mInstance = renderer->createTextureStorage2D(swapchain); -} - -TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) -{ - mInstance = renderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels); - mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount())); -} - -TextureStorageInterface2D::~TextureStorageInterface2D() -{ -} - -RenderTarget *TextureStorageInterface2D::getRenderTarget(GLint level) const -{ - return mInstance->getRenderTarget(level); -} - -void TextureStorageInterface2D::generateMipmap(int level) -{ - mInstance->generateMipmap(level); -} - -unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLint level) const -{ - return mFirstRenderTargetSerial + level; -} - -TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) -{ - mInstance = renderer->createTextureStorageCube(internalformat, renderTarget, size, levels); - mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(static_cast<GLuint>(mInstance->getLevelCount() * 6)); -} - -TextureStorageInterfaceCube::~TextureStorageInterfaceCube() -{ -} - -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) + TextureD3D_Cube::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() -{ -} - -void TextureStorageInterface2DArray::generateMipmap(int level) -{ - mInstance->generateMipmap(level); -} - -RenderTarget *TextureStorageInterface2DArray::getRenderTarget(GLint level, GLint layer) const -{ - return mInstance->getRenderTargetLayer(level, layer); -} - -unsigned int TextureStorageInterface2DArray::getRenderTargetSerial(GLint level, GLint layer) const -{ - return mFirstRenderTargetSerial + static_cast<unsigned int>((layer * mInstance->getLevelCount()) + level); -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h index 0a212e16f2..9cc2c2977b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h @@ -4,15 +4,20 @@ // found in the LICENSE file. // -// TextureStorage.h: Defines the abstract rx::TextureStorageInterface class and its concrete derived -// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the -// GPU-side texture. +// TextureStorage.h: Defines the abstract rx::TextureStorage class. #ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_ #define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_ #include "common/debug.h" +#include <GLES2/gl2.h> + +namespace gl +{ +struct ImageIndex; +} + namespace rx { class Renderer; @@ -22,7 +27,7 @@ class RenderTarget; class TextureStorage { public: - TextureStorage() {}; + TextureStorage(); virtual ~TextureStorage() {}; virtual int getTopLevel() const = 0; @@ -30,114 +35,25 @@ class TextureStorage virtual bool isManaged() const = 0; virtual int getLevelCount() const = 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; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage); - -}; - -class TextureStorageInterface -{ - public: - TextureStorageInterface(); - virtual ~TextureStorageInterface(); - - TextureStorage *getStorageInstance() { return mInstance; } + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual void generateMipmaps() = 0; + unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const; unsigned int getTextureSerial() const; - virtual int getTopLevel() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; - virtual int getLevelCount() const; - protected: - TextureStorage *mInstance; + void initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride); private: - DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface); + DISALLOW_COPY_AND_ASSIGN(TextureStorage); const unsigned int mTextureSerial; static unsigned int issueTextureSerial(); static unsigned int mCurrentTextureSerial; -}; - -class TextureStorageInterface2D : public TextureStorageInterface -{ - public: - TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain); - TextureStorageInterface2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); - virtual ~TextureStorageInterface2D(); - - void generateMipmap(int level); - RenderTarget *getRenderTarget(GLint level) const; - - unsigned int getRenderTargetSerial(GLint level) const; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2D); - - unsigned int mFirstRenderTargetSerial; -}; - -class TextureStorageInterfaceCube : public TextureStorageInterface -{ - public: - TextureStorageInterfaceCube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); - virtual ~TextureStorageInterfaceCube(); - - void generateMipmap(int faceIndex, int level); - RenderTarget *getRenderTarget(GLenum faceTarget, GLint level) const; - - virtual unsigned int getRenderTargetSerial(GLenum target, GLint level) const; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorageInterfaceCube); - - 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; + unsigned int mRenderTargetSerialsLayerStride; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp new file mode 100644 index 0000000000..11596006d0 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp @@ -0,0 +1,38 @@ +// +// Copyright 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. +// + +// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. + +#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" + +namespace rx +{ + +TransformFeedbackD3D::TransformFeedbackD3D() +{ +} + +TransformFeedbackD3D::~TransformFeedbackD3D() +{ +} + +void TransformFeedbackD3D::begin(GLenum primitiveMode) +{ +} + +void TransformFeedbackD3D::end() +{ +} + +void TransformFeedbackD3D::pause() +{ +} + +void TransformFeedbackD3D::resume() +{ +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h new file mode 100644 index 0000000000..7c367aba1d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h @@ -0,0 +1,32 @@ +// +// Copyright 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. +// + +// TransformFeedbackD3D.h: Implements the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ +#define LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ + +#include "libGLESv2/renderer/TransformFeedbackImpl.h" +#include "libGLESv2/angletypes.h" + +namespace rx +{ + +class TransformFeedbackD3D : public TransformFeedbackImpl +{ + public: + TransformFeedbackD3D(); + virtual ~TransformFeedbackD3D(); + + virtual void begin(GLenum primitiveMode); + virtual void end(); + virtual void pause(); + virtual void resume(); +}; + +} + +#endif // LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp index 901ca196a8..4f85eb94fa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp @@ -1,4 +1,3 @@ -#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 @@ -9,9 +8,10 @@ // class with derivations, classes that perform graphics API agnostic vertex buffer operations. #include "libGLESv2/renderer/d3d/VertexBuffer.h" +#include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/BufferD3D.h" + #include "common/mathutil.h" namespace rx @@ -62,7 +62,7 @@ unsigned int VertexBufferInterface::getBufferSize() const return mVertexBuffer->getBufferSize(); } -bool VertexBufferInterface::setBufferSize(unsigned int size) +gl::Error VertexBufferInterface::setBufferSize(unsigned int size) { if (mVertexBuffer->getBufferSize() == 0) { @@ -84,34 +84,39 @@ void VertexBufferInterface::setWritePosition(unsigned int writePosition) mWritePosition = writePosition; } -bool VertexBufferInterface::discard() +gl::Error VertexBufferInterface::discard() { return mVertexBuffer->discard(); } -bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) { + gl::Error error(GL_NO_ERROR); + unsigned int spaceRequired; - if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired)) + error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired); + if (error.isError()) { - return false; + return error; } if (mWritePosition + spaceRequired < mWritePosition) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); } - if (!reserveSpace(mReservedSpace)) + error = reserveSpace(mReservedSpace); + if (error.isError()) { - return false; + return error; } mReservedSpace = 0; - if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition)) + error = mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition); + if (error.isError()) { - return false; + return error; } if (outStreamOffset) @@ -124,21 +129,25 @@ bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &att // Align to 16-byte boundary mWritePosition = rx::roundUp(mWritePosition, 16u); - return true; + return gl::Error(GL_NO_ERROR); } -bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) +gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) { + gl::Error error(GL_NO_ERROR); + unsigned int requiredSpace; - if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace)) + error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace); + if (error.isError()) { - return false; + return error; } // Protect against integer overflow if (mReservedSpace + requiredSpace < mReservedSpace) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to reserve %u extra bytes in internal vertex buffer, " + "it would result in an overflow.", requiredSpace); } mReservedSpace += requiredSpace; @@ -146,7 +155,7 @@ bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib // Align to 16-byte boundary mReservedSpace = rx::roundUp(mReservedSpace, 16u); - return true; + return gl::Error(GL_NO_ERROR); } VertexBuffer* VertexBufferInterface::getVertexBuffer() const @@ -197,25 +206,29 @@ StreamingVertexBufferInterface::~StreamingVertexBufferInterface() { } -bool StreamingVertexBufferInterface::reserveSpace(unsigned int size) +gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) { - bool result = true; unsigned int curBufferSize = getBufferSize(); if (size > curBufferSize) { - result = setBufferSize(std::max(size, 3 * curBufferSize / 2)); + gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2)); + if (error.isError()) + { + return error; + } setWritePosition(0); } else if (getWritePosition() + size > curBufferSize) { - if (!discard()) + gl::Error error = discard(); + if (error.isError()) { - return false; + return error; } setWritePosition(0); } - return result; + return gl::Error(GL_NO_ERROR); } StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false) @@ -251,46 +264,44 @@ bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &att return false; } -bool StaticVertexBufferInterface::reserveSpace(unsigned int size) +gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size) { unsigned int curSize = getBufferSize(); if (curSize == 0) { - setBufferSize(size); - return true; + return setBufferSize(size); } else if (curSize >= size) { - return true; + return gl::Error(GL_NO_ERROR); } else { - UNREACHABLE(); // Static vertex buffers can't be resized - return false; + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized."); } } -bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +gl::Error 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, currentValue, start, count, instances, &streamOffset)) + gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset); + if (error.isError()) { - size_t attributeOffset = static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib); - VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset }; - mCache.push_back(element); + return error; + } - if (outStreamOffset) - { - *outStreamOffset = streamOffset; - } + size_t attributeOffset = static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib); + VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset }; + mCache.push_back(element); - return true; - } - else + if (outStreamOffset) { - return false; + *outStreamOffset = streamOffset; } + + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h index c5022d8c9c..fa747d9cb4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h @@ -11,6 +11,12 @@ #define LIBGLESV2_RENDERER_VERTEXBUFFER_H_ #include "common/angleutils.h" +#include "libGLESv2/Error.h" + +#include <GLES2/gl2.h> + +#include <cstddef> +#include <vector> namespace gl { @@ -28,16 +34,16 @@ class VertexBuffer VertexBuffer(); virtual ~VertexBuffer(); - virtual bool initialize(unsigned int size, bool dynamicUsage) = 0; + virtual gl::Error initialize(unsigned int size, bool dynamicUsage) = 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 gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0; + virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const = 0; virtual unsigned int getBufferSize() const = 0; - virtual bool setBufferSize(unsigned int size) = 0; - virtual bool discard() = 0; + virtual gl::Error setBufferSize(unsigned int size) = 0; + virtual gl::Error discard() = 0; unsigned int getSerial() const; @@ -57,14 +63,14 @@ class VertexBufferInterface VertexBufferInterface(rx::Renderer *renderer, bool dynamic); virtual ~VertexBufferInterface(); - bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); + gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); unsigned int getBufferSize() const; unsigned int getSerial() const; - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); + virtual gl::Error 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; @@ -72,14 +78,14 @@ class VertexBufferInterface VertexBuffer* getVertexBuffer() const; protected: - virtual bool reserveSpace(unsigned int size) = 0; + virtual gl::Error reserveSpace(unsigned int size) = 0; unsigned int getWritePosition() const; void setWritePosition(unsigned int writePosition); - bool discard(); + gl::Error discard(); - bool setBufferSize(unsigned int size); + gl::Error setBufferSize(unsigned int size); private: DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface); @@ -100,7 +106,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface ~StreamingVertexBufferInterface(); protected: - bool reserveSpace(unsigned int size); + gl::Error reserveSpace(unsigned int size); }; class StaticVertexBufferInterface : public VertexBufferInterface @@ -109,13 +115,13 @@ class StaticVertexBufferInterface : public VertexBufferInterface explicit StaticVertexBufferInterface(rx::Renderer *renderer); ~StaticVertexBufferInterface(); - bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); + gl::Error 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* outStreamFffset); protected: - bool reserveSpace(unsigned int size); + gl::Error reserveSpace(unsigned int size); private: struct VertexElement diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp index fc2b8ff0df..7034b78eab 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp @@ -1,4 +1,3 @@ -#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 @@ -10,12 +9,11 @@ #include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/renderer/d3d/BufferD3D.h" - +#include "libGLESv2/renderer/d3d/VertexBuffer.h" +#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/VertexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" namespace { @@ -84,37 +82,22 @@ VertexDataManager::~VertexDataManager() } } -GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], - gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) +gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], + gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) { if (!mStreamingBuffer) { - return GL_OUT_OF_MEMORY; + return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL."); } + // Invalidate static buffers that don't contain matching attributes for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) { translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1); - } - // Invalidate static buffers that don't contain matching attributes - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (translated[i].active && attribs[i].enabled) + if (translated[attributeIndex].active && attribs[attributeIndex].enabled) { - gl::Buffer *buffer = attribs[i].buffer.get(); - - if (buffer) - { - BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation()); - StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer(); - - if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) && - !staticBuffer->directStoragePossible(attribs[i], currentValues[i])) - { - bufferImpl->invalidateStaticData(); - } - } + invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]); } } @@ -123,40 +106,10 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], { if (translated[i].active && attribs[i].enabled) { - gl::Buffer *buffer = attribs[i].buffer.get(); - BufferD3D *bufferImpl = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL; - StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); - - if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i])) + gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances); + if (error.isError()) { - if (staticBuffer) - { - if (staticBuffer->getBufferSize() == 0) - { - int totalCount = ElementsInBuffer(attribs[i], bufferImpl->getSize()); - if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0)) - { - return GL_OUT_OF_MEMORY; - } - } - } - else - { - int totalCount = StreamingBufferElementCount(attribs[i], count, instances); - - // [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 (bufferImpl && ElementsInBuffer(attribs[i], bufferImpl->getSize()) < totalCount) - { - return GL_INVALID_OPERATION; - } - - if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances)) - { - return GL_OUT_OF_MEMORY; - } - } + return error; } } } @@ -168,77 +121,12 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], { if (attribs[i].enabled) { - gl::Buffer *buffer = attribs[i].buffer.get(); - - if (!buffer && attribs[i].pointer == NULL) + gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i], + start, count, instances); + if (error.isError()) { - // This is an application error that would normally result in a crash, but we catch it and return an error - ERR("An enabled vertex array has no buffer and no pointer."); - return GL_INVALID_OPERATION; + return error; } - - BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL; - StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); - bool directStorage = vertexBuffer->directStoragePossible(attribs[i], currentValues[i]); - - unsigned int streamOffset = 0; - unsigned int outputElementSize = 0; - - if (directStorage) - { - outputElementSize = ComputeVertexAttributeStride(attribs[i]); - streamOffset = attribs[i].offset + outputElementSize * start; - } - else if (staticBuffer) - { - if (!staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize)) - { - return GL_OUT_OF_MEMORY; - } - - if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset)) - { - // Convert the entire buffer - int totalCount = ElementsInBuffer(attribs[i], storage->getSize()); - int startIndex = attribs[i].offset / ComputeVertexAttributeStride(attribs[i]); - - if (!staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount, - 0, &streamOffset)) - { - return GL_OUT_OF_MEMORY; - } - } - - unsigned int firstElementOffset = (attribs[i].offset / ComputeVertexAttributeStride(attribs[i])) * outputElementSize; - unsigned int startOffset = (instances == 0 || attribs[i].divisor == 0) ? start * outputElementSize : 0; - if (streamOffset + firstElementOffset + startOffset < streamOffset) - { - return GL_OUT_OF_MEMORY; - } - - streamOffset += firstElementOffset + startOffset; - } - else - { - int totalCount = StreamingBufferElementCount(attribs[i], count, instances); - if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) || - !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, totalCount, instances, - &streamOffset)) - { - return GL_OUT_OF_MEMORY; - } - } - - translated[i].storage = directStorage ? storage : NULL; - translated[i].vertexBuffer = vertexBuffer->getVertexBuffer(); - translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial(); - translated[i].divisor = attribs[i].divisor; - - translated[i].attribute = &attribs[i]; - translated[i].currentValueType = currentValues[i].Type; - translated[i].stride = outputElementSize; - translated[i].offset = streamOffset; } else { @@ -247,34 +135,13 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE); } - StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i]; - - if (mCurrentValue[i] != currentValues[i]) + gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i], + &mCurrentValue[i], &mCurrentValueOffsets[i], + mCurrentValueBuffer[i]); + if (error.isError()) { - if (!buffer->reserveVertexSpace(attribs[i], 1, 0)) - { - return GL_OUT_OF_MEMORY; - } - - unsigned int streamOffset; - if (!buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0, &streamOffset)) - { - return GL_OUT_OF_MEMORY; - } - - mCurrentValue[i] = currentValues[i]; - mCurrentValueOffsets[i] = streamOffset; + return error; } - - translated[i].storage = NULL; - translated[i].vertexBuffer = mCurrentValueBuffer[i]->getVertexBuffer(); - translated[i].serial = mCurrentValueBuffer[i]->getSerial(); - translated[i].divisor = 0; - - translated[i].attribute = &attribs[i]; - translated[i].currentValueType = currentValues[i].Type; - translated[i].stride = 0; - translated[i].offset = mCurrentValueOffsets[i]; } } } @@ -293,7 +160,189 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], } } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); +} + +void VertexDataManager::invalidateMatchingStaticData(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue) const +{ + gl::Buffer *buffer = attrib.buffer.get(); + + if (buffer) + { + BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation()); + StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer(); + + if (staticBuffer && + staticBuffer->getBufferSize() > 0 && + !staticBuffer->lookupAttribute(attrib, NULL) && + !staticBuffer->directStoragePossible(attrib, currentValue)) + { + bufferImpl->invalidateStaticData(); + } + } +} + +gl::Error VertexDataManager::reserveSpaceForAttrib(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + GLsizei count, + GLsizei instances) const +{ + gl::Buffer *buffer = attrib.buffer.get(); + BufferD3D *bufferImpl = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL; + StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL; + VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); + + if (!vertexBuffer->directStoragePossible(attrib, currentValue)) + { + if (staticBuffer) + { + if (staticBuffer->getBufferSize() == 0) + { + int totalCount = ElementsInBuffer(attrib, bufferImpl->getSize()); + gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0); + if (error.isError()) + { + return error; + } + } + } + else + { + int totalCount = StreamingBufferElementCount(attrib, count, instances); + ASSERT(!bufferImpl || ElementsInBuffer(attrib, bufferImpl->getSize()) >= totalCount); + + gl::Error error = mStreamingBuffer->reserveVertexSpace(attrib, totalCount, instances); + if (error.isError()) + { + return error; + } + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances) +{ + gl::Buffer *buffer = attrib.buffer.get(); + ASSERT(buffer || attrib.pointer); + + BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL; + StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL; + VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer); + bool directStorage = vertexBuffer->directStoragePossible(attrib, currentValue); + + unsigned int streamOffset = 0; + unsigned int outputElementSize = 0; + + if (directStorage) + { + outputElementSize = ComputeVertexAttributeStride(attrib); + streamOffset = attrib.offset + outputElementSize * start; + } + else if (staticBuffer) + { + gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); + if (error.isError()) + { + return error; + } + + if (!staticBuffer->lookupAttribute(attrib, &streamOffset)) + { + // Convert the entire buffer + int totalCount = ElementsInBuffer(attrib, storage->getSize()); + int startIndex = attrib.offset / ComputeVertexAttributeStride(attrib); + + gl::Error error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount, + 0, &streamOffset); + if (error.isError()) + { + return error; + } + } + + unsigned int firstElementOffset = (attrib.offset / ComputeVertexAttributeStride(attrib)) * outputElementSize; + unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? start * outputElementSize : 0; + if (streamOffset + firstElementOffset + startOffset < streamOffset) + { + return gl::Error(GL_OUT_OF_MEMORY); + } + + streamOffset += firstElementOffset + startOffset; + } + else + { + int totalCount = StreamingBufferElementCount(attrib, count, instances); + gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); + if (error.isError()) + { + return error; + } + + error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, start, totalCount, instances, &streamOffset); + if (error.isError()) + { + return error; + } + } + + translated->storage = directStorage ? storage : NULL; + translated->vertexBuffer = vertexBuffer->getVertexBuffer(); + translated->serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial(); + translated->divisor = attrib.divisor; + + translated->attribute = &attrib; + translated->currentValueType = currentValue.Type; + translated->stride = outputElementSize; + translated->offset = streamOffset; + + return gl::Error(GL_NO_ERROR); +} + +gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + gl::VertexAttribCurrentValueData *cachedValue, + size_t *cachedOffset, + StreamingVertexBufferInterface *buffer) +{ + if (*cachedValue != currentValue) + { + gl::Error error = buffer->reserveVertexSpace(attrib, 1, 0); + if (error.isError()) + { + return error; + } + + unsigned int streamOffset; + error = buffer->storeVertexAttributes(attrib, currentValue, 0, 1, 0, &streamOffset); + if (error.isError()) + { + return error; + } + + *cachedValue = currentValue; + *cachedOffset = streamOffset; + } + + translated->storage = NULL; + translated->vertexBuffer = buffer->getVertexBuffer(); + translated->serial = buffer->getSerial(); + translated->divisor = 0; + + translated->attribute = &attrib; + translated->currentValueType = currentValue.Type; + translated->stride = 0; + translated->offset = *cachedOffset; + + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h index 4164fbecbb..7728722246 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h @@ -30,6 +30,9 @@ class Renderer; struct TranslatedAttribute { + TranslatedAttribute() : active(false), attribute(NULL), currentValueType(GL_NONE), + offset(0), stride(0), vertexBuffer(NULL), storage(NULL), + serial(0), divisor(0) {}; bool active; const gl::VertexAttribute *attribute; @@ -49,12 +52,34 @@ class VertexDataManager VertexDataManager(rx::Renderer *renderer); virtual ~VertexDataManager(); - GLenum prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], - gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances); + gl::Error 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); + gl::Error reserveSpaceForAttrib(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + GLsizei count, + GLsizei instances) const; + + void invalidateMatchingStaticData(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue) const; + + gl::Error storeAttribute(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances); + + gl::Error storeCurrentValue(const gl::VertexAttribute &attrib, + const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + gl::VertexAttribCurrentValueData *cachedValue, + size_t *cachedOffset, + StreamingVertexBufferInterface *buffer); + rx::Renderer *const mRenderer; StreamingVertexBufferInterface *mStreamingBuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp index 9b0f336ac7..d43e65ea78 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp @@ -1,4 +1,3 @@ -#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 @@ -7,12 +6,12 @@ // Blit11.cpp: Texture copy utility class. -#include "libGLESv2/main.h" -#include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2dps.h" @@ -315,7 +314,6 @@ Blit11::Blit11(rx::Renderer11 *renderer) 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(); @@ -373,18 +371,20 @@ static inline unsigned int GetSwizzleIndex(GLenum swizzle) return colorIndex; } -bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, - GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +gl::Error 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); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); GLenum shaderType = GL_NONE; - switch (gl::GetComponentType(sourceInternalFormat)) + switch (sourceFormatInfo.componentType) { case GL_UNSIGNED_NORMALIZED: case GL_SIGNED_NORMALIZED: @@ -410,7 +410,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget if (i == mSwizzleShaderMap.end()) { UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION, "Internal error, missing swizzle shader."); } const Shader &shader = i->second; @@ -420,8 +420,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget 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; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -438,8 +437,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget 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; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal constant buffer for swizzle, HRESULT: 0x%X.", result); } unsigned int *swizzleIndices = reinterpret_cast<unsigned int*>(mappedResource.pData); @@ -506,7 +504,7 @@ bool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTarget mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, @@ -520,11 +518,13 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source // 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); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); BlitParameters parameters = { 0 }; parameters.mDestinationFormat = destFormat; - parameters.mSignedInteger = gl::GetComponentType(sourceInternalFormat) == GL_INT; + parameters.mSignedInteger = (internalFormatInfo.componentType == GL_INT); parameters.m3DBlit = sourceArea.depth > 1; BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters); @@ -770,18 +770,19 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso DXGI_FORMAT format = GetTextureFormat(source); ASSERT(format == GetTextureFormat(dest)); - unsigned int pixelSize = d3d11::GetFormatPixelBytes(format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + unsigned int pixelSize = dxgiFormatInfo.pixelBytes; unsigned int copyOffset = 0; unsigned int copySize = pixelSize; if (stencilOnly) { - copyOffset = d3d11::GetStencilOffset(format) / 8; - copySize = d3d11::GetStencilBits(format) / 8; + copyOffset = dxgiFormatInfo.depthBits / 8; + copySize = dxgiFormatInfo.stencilBits / 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); + ASSERT(dxgiFormatInfo.stencilBits % 8 == 0 && + dxgiFormatInfo.depthBits % 8 == 0); } D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping; @@ -995,18 +996,17 @@ void Blit11::buildShaderMap() add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I 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" )); - 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_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG 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_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R 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" )); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h index fba89e20ba..d6a0b795f4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h @@ -11,6 +11,9 @@ #include "common/angleutils.h" #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" + +#include <map> namespace rx { @@ -28,8 +31,8 @@ class Blit11 explicit Blit11(Renderer11 *renderer); ~Blit11(); - bool swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, - GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + gl::Error 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, diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index 1301124b2d..ecd4d4672b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,13 +7,9 @@ // Buffer11.cpp Defines the Buffer11 class. #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" - -#if defined(__MINGW32__) && !defined(D3D11_MAP_FLAG_DO_NOT_WAIT) -# define D3D11_MAP_FLAG_DO_NOT_WAIT 0x100000L -#endif +#include "libGLESv2/main.h" namespace rx { @@ -122,6 +117,8 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11 virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); + bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset); + private: ID3D11Buffer *mNativeBuffer; @@ -143,7 +140,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); - void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); private: @@ -166,12 +163,14 @@ Buffer11::Buffer11(Renderer11 *renderer) mMappedStorage(NULL), mResolvedDataRevision(0), mReadUsageCount(0) -{ -} +{} Buffer11::~Buffer11() { - clear(); + for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++) + { + SafeDelete(it->second); + } } Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer) @@ -180,29 +179,20 @@ Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer) return static_cast<Buffer11*>(buffer); } -void Buffer11::clear() +gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) { - for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++) + gl::Error error = setSubData(data, size, 0); + if (error.isError()) { - SafeDelete(it->second); + return error; } - mBufferStorages.clear(); - - mSize = 0; - mResolvedDataRevision = 0; -} - -void Buffer11::setData(const void* data, size_t size, GLenum usage) -{ - mIndexRangeCache.clear(); - - setSubData(data, size, 0); - if (usage == GL_STATIC_DRAW) { initializeStaticData(); } + + return error; } void *Buffer11::getData() @@ -243,16 +233,23 @@ void *Buffer11::getData() mReadUsageCount = 0; + // Only happens if we initialized the buffer with no data (NULL) + if (mResolvedData.empty()) + { + if (!mResolvedData.resize(mSize)) + { + return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + } + } + + ASSERT(mResolvedData.size() >= mSize); + return mResolvedData.data(); } -void Buffer11::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) { size_t requiredSize = size + offset; - mSize = std::max(mSize, requiredSize); - - mIndexRangeCache.invalidateRange(offset, size); - invalidateStaticData(); if (data && size > 0) { @@ -260,8 +257,7 @@ void Buffer11::setSubData(const void* data, size_t size, size_t offset) if (!stagingBuffer) { - // Out-of-memory - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); } // Explicitly resize the staging buffer, preserving data if the new data will not @@ -271,65 +267,78 @@ void Buffer11::setSubData(const void* data, size_t size, size_t offset) bool preserveData = (offset > 0); if (!stagingBuffer->resize(requiredSize, preserveData)) { - // Out-of-memory - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer."); } } - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource); - if (FAILED(result)) + if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer."); } - unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset; - memcpy(offsetBufferPointer, data, size); - - context->Unmap(stagingBuffer->getNativeBuffer(), 0); - stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); } + + mSize = std::max(mSize, requiredSize); + invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { Buffer11 *sourceBuffer = makeBuffer11(source); - if (sourceBuffer) + ASSERT(sourceBuffer != NULL); + + BufferStorage11 *copyDest = getLatestBufferStorage(); + if (!copyDest) + { + copyDest = getStagingBuffer(); + } + + BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage(); + + if (!copySource || !copyDest) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); + } + + // 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 (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) { - BufferStorage11 *dest = getLatestBufferStorage(); - if (!dest) + copySource = sourceBuffer->getStagingBuffer(); + } + else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) + { + copyDest = getStagingBuffer(); + } + + // D3D11 does not allow overlapped copies until 11.1, and only if the + // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap + // Get around this via a different source buffer + if (copySource == copyDest) + { + if (copySource->getUsage() == BUFFER_USAGE_STAGING) { - dest = getStagingBuffer(); + copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); } - - BufferStorage11 *source = sourceBuffer->getLatestBufferStorage(); - if (source && dest) + else { - // 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 = sourceBuffer->getStagingBuffer(); - } - else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable()) - { - dest = getStagingBuffer(); - } - - dest->copyFromStorage(source, sourceOffset, size, destOffset); - dest->setDataRevision(dest->getDataRevision() + 1); + copySource = getStagingBuffer(); } - - mSize = std::max<size_t>(mSize, destOffset + size); } + copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); + copyDest->setDataRevision(copyDest->getDataRevision() + 1); + + mSize = std::max<size_t>(mSize, destOffset + size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { ASSERT(!mMappedStorage); @@ -350,8 +359,7 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) if (!mMappedStorage) { - // Out-of-memory - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer."); } if ((access & GL_MAP_WRITE_BIT) > 0) @@ -360,14 +368,22 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); } - return mMappedStorage->map(offset, length, access); + void *mappedBuffer = mMappedStorage->map(offset, length, access); + if (!mappedBuffer) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); + } + + *mapPtr = mappedBuffer; + return gl::Error(GL_NO_ERROR); } -void Buffer11::unmap() +gl::Error Buffer11::unmap() { ASSERT(mMappedStorage); mMappedStorage->unmap(); mMappedStorage = NULL; + return gl::Error(GL_NO_ERROR); } void Buffer11::markTransformFeedbackUsage() @@ -448,9 +464,11 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) ID3D11Device *device = mRenderer->getDevice(); ID3D11ShaderResourceView *bufferSRV = NULL; + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; bufferSRVDesc.Buffer.ElementOffset = 0; - bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat); + bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes; bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; bufferSRVDesc.Format = srvFormat; @@ -463,7 +481,7 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) return bufferSRV; } -void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) { PackStorage11 *packStorage = getPackStorage(); @@ -471,9 +489,15 @@ void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, cons if (packStorage) { - packStorage->packPixels(srcTexture, srcSubresource, params); + gl::Error error = packStorage->packPixels(srcTexture, srcSubresource, params); + if (error.isError()) + { + return error; + } packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); } + + return gl::Error(GL_NO_ERROR); } Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage) @@ -584,6 +608,14 @@ Buffer11::PackStorage11 *Buffer11::getPackStorage() return static_cast<PackStorage11*>(packStorage); } +bool Buffer11::supportsDirectBinding() const +{ + // Do not support direct buffers for dynamic data. The streaming buffer + // offers better performance for data which changes every frame. + // Check for absence of static buffer interfaces to detect dynamic data. + return (mStaticVertexBuffer && mStaticIndexBuffer); +} + Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage) : mRenderer(renderer), mUsage(usage), @@ -605,7 +637,7 @@ Buffer11::NativeBuffer11::~NativeBuffer11() // Returns true if it recreates the direct buffer bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset, - size_t size, size_t destOffset) + size_t size, size_t destOffset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -716,7 +748,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: bufferDesc->Usage = D3D11_USAGE_DEFAULT; bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; - if (renderer->getMaxTransformFeedbackBuffers() > 0) + if (!static_cast<Renderer11 *>(renderer)->isLevel9()) bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; bufferDesc->CPUAccessFlags = 0; break; @@ -741,7 +773,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren // 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()); + bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, renderer->getRendererCaps().maxUniformBlockSize); break; default: @@ -765,6 +797,25 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc return static_cast<GLubyte*>(mappedResource.pData) + offset; } +bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset) +{ + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, false); + } + + uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset; + memcpy(offsetBufferPointer, data, size); + + context->Unmap(mNativeBuffer, 0); + + return true; +} + void Buffer11::NativeBuffer11::unmap() { ASSERT(mUsage == BUFFER_USAGE_STAGING); @@ -788,9 +839,11 @@ Buffer11::PackStorage11::~PackStorage11() } bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset, - size_t size, size_t destOffset) + size_t size, size_t destOffset) { - UNIMPLEMENTED(); + // We copy through a staging buffer when drawing with a pack buffer, + // or for other cases where we access the pack buffer + UNREACHABLE(); return false; } @@ -827,7 +880,7 @@ void Buffer11::PackStorage11::unmap() // No-op } -void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) { flushQueuedPackCommand(); mQueuedPackCommand = new PackPixelsParams(params); @@ -869,13 +922,15 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub stagingDesc.MiscFlags = 0; hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture); - ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + ASSERT(hr == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging texture."); + } } - if (textureDesc.SampleDesc.Count > 1) - { - UNIMPLEMENTED(); - } + // ReadPixels from multisampled FBOs isn't supported in current GL + ASSERT(textureDesc.SampleDesc.Count <= 1); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); D3D11_BOX srcBox; @@ -888,6 +943,8 @@ void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSub // Asynchronous copy immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); + + return gl::Error(GL_NO_ERROR); } void Buffer11::PackStorage11::flushQueuedPackCommand() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index e56be247c4..5f24fb4e2d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -55,21 +55,20 @@ class Buffer11 : public BufferD3D ID3D11Buffer *getBuffer(BufferUsage usage); ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); bool isMapped() const { return mMappedStorage != NULL; } - void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); // BufferD3D implementation virtual size_t getSize() const { return mSize; } - virtual void clear(); - virtual bool supportsDirectBinding() const { return true; } + virtual bool supportsDirectBinding() const; virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + virtual gl::Error setSubData(const void* data, size_t size, size_t offset); + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(); virtual void markTransformFeedbackUsage(); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp index 5121950da0..765d34fd3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -1,4 +1,3 @@ -#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 @@ -11,11 +10,11 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" - #include "libGLESv2/formatutils.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatps.h" @@ -155,7 +154,7 @@ Clear11::~Clear11() SafeRelease(mRasterizerState); } -void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { // First determine if a scissored clear is needed, this will always require drawing a quad. // @@ -190,7 +189,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame else { UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || @@ -199,7 +198,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame clearParams.scissor.y + clearParams.scissor.height <= 0)) { // Scissor is enabled and the scissor rectangle is outside the renderbuffer - return; + return gl::Error(GL_NO_ERROR); } bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || @@ -218,41 +217,35 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment); if (attachment) { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); if (!renderTarget) { - ERR("Render target pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } - GLenum internalFormat = attachment->getInternalFormat(); - GLenum actualFormat = attachment->getActualFormat(); - GLenum componentType = gl::GetComponentType(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); + if (clearParams.colorClearType == GL_FLOAT && - !(componentType == GL_FLOAT || componentType == GL_UNSIGNED_NORMALIZED || componentType == GL_SIGNED_NORMALIZED)) + !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.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); + "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, + attachment->getInternalFormat()); } - GLuint internalRedBits = gl::GetRedBits(internalFormat); - GLuint internalGreenBits = gl::GetGreenBits(internalFormat); - GLuint internalBlueBits = gl::GetBlueBits(internalFormat); - GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat); - - if ((internalRedBits == 0 || !clearParams.colorMaskRed) && - (internalGreenBits == 0 || !clearParams.colorMaskGreen) && - (internalBlueBits == 0 || !clearParams.colorMaskBlue) && - (internalAlphaBits == 0 || !clearParams.colorMaskAlpha)) + if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && + (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) && + (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) && + (formatInfo.alphaBits == 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)) + (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { // A scissored or masked clear is required MaskedRenderTarget maskAndRt; @@ -271,23 +264,19 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); if (!framebufferRTV) { - ERR("Render target view pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); + // 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); - GLuint actualGreenBits = gl::GetGreenBits(actualFormat); - GLuint actualBlueBits = gl::GetBlueBits(actualFormat); - GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat); - 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), + ((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + ((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + ((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), + ((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), }; deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); @@ -301,16 +290,15 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); if (attachment) { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getDepthStencil()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); if (!renderTarget) { - ERR("Depth stencil render target pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } - GLenum actualFormat = attachment->getActualFormat(); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); - unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << gl::GetStencilBits(actualFormat)) - 1 : 0; + unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << actualFormatInfo.stencilBits) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; if (needScissoredClear || needMaskedStencilClear) @@ -322,8 +310,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); if (!framebufferDSV) { - ERR("Depth stencil view pointer unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | @@ -370,8 +357,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); if (!rtv) { - ERR("Render target view unexpectedly null."); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } rtvs[i] = rtv; @@ -393,8 +379,7 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame 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; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result); } const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL; @@ -459,6 +444,8 @@ void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Frame // Clean up mRenderer->markAllStateDirty(); } + + return gl::Error(GL_NO_ERROR); } ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts) @@ -469,12 +456,12 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& if (i < rts.size()) { RenderTarget11 *rt = rts[i].renderTarget; - GLint internalFormat = rt->getInternalFormat(); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat()); - blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && gl::GetRedBits(internalFormat) > 0); - blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && gl::GetGreenBits(internalFormat) > 0); - blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && gl::GetBlueBits(internalFormat) > 0); - blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && gl::GetAlphaBits(internalFormat) > 0); + blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits > 0); + blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0); + blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits > 0); + blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0); } else { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h index 0cb9a85a6d..be8e187c40 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h @@ -10,6 +10,10 @@ #define LIBGLESV2_RENDERER_CLEAR11_H_ #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" + +#include <map> +#include <vector> namespace gl { @@ -28,7 +32,7 @@ class Clear11 ~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); + gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); private: Renderer11 *mRenderer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp index 8698776650..a841b52862 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp @@ -1,4 +1,3 @@ -#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 @@ -8,8 +7,8 @@ // Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. #include "libGLESv2/renderer/d3d/d3d11/Fence11.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" +#include "libGLESv2/main.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp index 2165bec305..7536713af4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp @@ -1,4 +1,3 @@ -#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 @@ -11,13 +10,13 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" +#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" - #include "libGLESv2/main.h" + #include "common/utilities.h" -#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" -#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { @@ -27,11 +26,17 @@ Image11::Image11() mStagingTexture = NULL; mRenderer = NULL; mDXGIFormat = DXGI_FORMAT_UNKNOWN; + mRecoverFromStorage = false; + mAssociatedStorage = NULL; + mAssociatedStorageLevel = 0; + mAssociatedStorageLayerTarget = 0; + mRecoveredFromStorageCount = 0; } Image11::~Image11() { - SafeRelease(mStagingTexture); + disassociateStorage(); + releaseStagingTexture(); } Image11 *Image11::makeImage11(Image *img) @@ -46,8 +51,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) 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); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat()); + ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); D3D11_MAPPED_SUBRESOURCE destMapped; HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); @@ -70,8 +75,9 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData); uint8_t *destData = reinterpret_cast<uint8_t*>(destMapped.pData); - mipFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, - destData, destMapped.RowPitch, destMapped.DepthPitch); + dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), + sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, + destData, destMapped.RowPitch, destMapped.DepthPitch); dest->unmap(); src->unmap(); @@ -81,33 +87,117 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) 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))); + // If mDirty is true + // AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be recovered from TextureStorage + // AND the texture doesn't require init data (i.e. a blank new texture will suffice) + // then isDirty should still return false. + if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)) + { + return false; + } + + return mDirty; +} + +bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); + return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image11::copyToStorageCube(TextureStorage *storage, int face, 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); + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); + return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) { - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, 0, width, height, 1); + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); + return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface3D *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) { - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, zoffset, width, height, depth); + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); + return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height); } -bool Image11::copyToStorage(TextureStorageInterface2DArray *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) +bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, 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); + // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times, + // then we should just keep the staging texture around to prevent the copying from impacting perf. + // We allow the Image11 to copy its data to/from TextureStorage once. + // This accounts for an app making a late call to glGenerateMipmap. + bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2); + + if (attemptToReleaseStagingTexture) + { + // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it. + storage11->releaseAssociatedImage(level, layerTarget, this); + } + + bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1); + + // Once the image data has been copied into the Storage, we can release it locally. + if (attemptToReleaseStagingTexture && updateSubresourceSuccess) + { + storage11->associateImage(this, level, layerTarget); + releaseStagingTexture(); + mRecoverFromStorage = true; + mAssociatedStorage = storage11; + mAssociatedStorageLevel = level; + mAssociatedStorageLayerTarget = layerTarget; + } + + return updateSubresourceSuccess; +} + +bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const +{ + return (mAssociatedStorage == textureStorage); +} + +bool Image11::recoverFromAssociatedStorage() +{ + if (mRecoverFromStorage) + { + createStagingTexture(); + + bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + + // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data. + // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten. + ASSERT(textureStorageCorrect); + + if (textureStorageCorrect) + { + // CopySubResource from the Storage to the Staging texture + mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth); + mRecoveredFromStorageCount += 1; + } + + // Reset all the recovery parameters, even if the texture storage association is broken. + disassociateStorage(); + + return textureStorageCorrect; + } + + return false; +} + +void Image11::disassociateStorage() +{ + if (mRecoverFromStorage) + { + // Make the texturestorage release the Image11 too + mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + + mRecoverFromStorage = false; + mAssociatedStorage = NULL; + mAssociatedStorageLevel = 0; + mAssociatedStorageLayerTarget = 0; + } } bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) @@ -117,6 +207,11 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mInternalFormat != internalformat || forceRelease) { + // End the association with the TextureStorage, since that data will be out of date. + // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined. + disassociateStorage(); + mRecoveredFromStorageCount = 0; + mRenderer = Renderer11::makeRenderer11(renderer); mWidth = width; @@ -126,12 +221,14 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mTarget = target; // compute the d3d format that will be used - mDXGIFormat = gl_d3d11::GetTexFormat(internalformat); - mActualFormat = d3d11_gl::GetInternalFormat(mDXGIFormat); - mRenderable = gl_d3d11::GetRTVFormat(internalformat) != DXGI_FORMAT_UNKNOWN; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); + mDXGIFormat = formatInfo.texFormat; + mActualFormat = dxgiFormatInfo.internalFormat; + mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); SafeRelease(mStagingTexture); - mDirty = gl_d3d11::RequiresTextureDataInitialization(mInternalFormat); + mDirty = (formatInfo.dataInitializerFunction != NULL); return true; } @@ -153,12 +250,15 @@ DXGI_FORMAT Image11::getDXGIFormat() const void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint unpackAlignment, GLenum type, const void *input) { - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, width, unpackAlignment); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, type, width, height, unpackAlignment); - GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpackAlignment); - LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, type); - ASSERT(loadFunction != NULL); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); D3D11_MAPPED_SUBRESOURCE mappedImage; HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); @@ -179,18 +279,20 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, const void *input) { - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, 1); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, height, 1); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); - GLuint outputPixelSize = d3d11::GetFormatPixelBytes(mDXGIFormat); - GLuint outputBlockWidth = d3d11::GetBlockWidth(mDXGIFormat); - GLuint outputBlockHeight = d3d11::GetBlockHeight(mDXGIFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; + GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; ASSERT(xoffset % outputBlockWidth == 0); ASSERT(yoffset % outputBlockHeight == 0); - LoadImageFunction loadFunction = d3d11::GetImageLoadFunction(mInternalFormat, GL_UNSIGNED_BYTE); - ASSERT(loadFunction != NULL); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); D3D11_MAPPED_SUBRESOURCE mappedImage; HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); @@ -287,13 +389,12 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y } // determine the offset coordinate into the destination buffer - GLsizei rowOffset = gl::GetPixelBytes(mActualFormat) * xoffset; - void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; + GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset; + uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; - GLenum format = gl::GetFormat(mInternalFormat); - GLenum type = gl::GetType(mInternalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - mRenderer->readPixels(source, x, y, width, height, format, type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); } @@ -306,6 +407,11 @@ ID3D11Resource *Image11::getStagingTexture() return mStagingTexture; } +void Image11::releaseStagingTexture() +{ + SafeRelease(mStagingTexture); +} + unsigned int Image11::getStagingSubresource() { createStagingTexture(); @@ -349,7 +455,7 @@ void Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; @@ -390,7 +496,7 @@ void Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (gl_d3d11::RequiresTextureDataInitialization(mInternalFormat)) + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; @@ -427,6 +533,9 @@ HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { createStagingTexture(); + // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE. + recoverFromAssociatedStorage(); + HRESULT result = E_FAIL; if (mStagingTexture) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h index 7d873a2794..a76a61f036 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h @@ -23,8 +23,7 @@ namespace rx { class Renderer; class Renderer11; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; +class TextureStorage11; class Image11 : public ImageD3D { @@ -38,10 +37,10 @@ class Image11 : public ImageD3D virtual bool isDirty() const; - 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 copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height); virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); @@ -54,6 +53,10 @@ class Image11 : public ImageD3D virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + bool recoverFromAssociatedStorage(); + bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; + void disassociateStorage(); + protected: HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); @@ -61,15 +64,24 @@ class Image11 : public ImageD3D private: DISALLOW_COPY_AND_ASSIGN(Image11); + bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + ID3D11Resource *getStagingTexture(); unsigned int getStagingSubresource(); void createStagingTexture(); + void releaseStagingTexture(); Renderer11 *mRenderer; DXGI_FORMAT mDXGIFormat; ID3D11Resource *mStagingTexture; unsigned int mStagingSubresource; + + bool mRecoverFromStorage; + TextureStorage11 *mAssociatedStorage; + int mAssociatedStorageLevel; + int mAssociatedStorageLayerTarget; + unsigned int mRecoveredFromStorageCount; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp index 03e4e6611b..9a61182ee9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp @@ -1,4 +1,3 @@ -#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 @@ -25,7 +24,7 @@ IndexBuffer11::~IndexBuffer11() SafeRelease(mBuffer); } -bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { SafeRelease(mBuffer); @@ -46,7 +45,7 @@ bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool d HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); if (FAILED(result)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); } } @@ -54,7 +53,7 @@ bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool d mIndexType = indexType; mDynamicUsage = dynamic; - return true; + return gl::Error(GL_NO_ERROR); } IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) @@ -63,50 +62,42 @@ IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) return static_cast<IndexBuffer11*>(indexBuffer); } -bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { - if (mBuffer) + if (!mBuffer) { - // Check for integer overflows and out-out-bounds map requests - if (offset + size < offset || offset + size > mBufferSize) - { - ERR("Index buffer map range is not inside the buffer."); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + // Check for integer overflows and out-out-bounds map requests + if (offset + size < offset || offset + size > mBufferSize) + { + return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer."); + } - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Index buffer map failed with error 0x%08x", result); - return false; - } + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset; - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); } + + *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset; + return gl::Error(GL_NO_ERROR); } -bool IndexBuffer11::unmapBuffer() +gl::Error IndexBuffer11::unmapBuffer() { - if (mBuffer) + if (!mBuffer) { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - dxContext->Unmap(mBuffer, 0); - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); } + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + dxContext->Unmap(mBuffer, 0); + return gl::Error(GL_NO_ERROR); } GLenum IndexBuffer11::getIndexType() const @@ -119,7 +110,7 @@ unsigned int IndexBuffer11::getBufferSize() const return mBufferSize; } -bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) +gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) { if (bufferSize > mBufferSize || indexType != mIndexType) { @@ -127,33 +118,29 @@ bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool IndexBuffer11::discard() +gl::Error IndexBuffer11::discard() { - if (mBuffer) + 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("Index buffer map failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - dxContext->Unmap(mBuffer, 0); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); } + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } DXGI_FORMAT IndexBuffer11::getIndexFormat() const @@ -172,4 +159,4 @@ ID3D11Buffer *IndexBuffer11::getBuffer() const return mBuffer; } -}
\ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h index e821b7f3d1..f7c2b38e7e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h @@ -21,18 +21,18 @@ class IndexBuffer11 : public IndexBuffer explicit IndexBuffer11(Renderer11 *const renderer); virtual ~IndexBuffer11(); - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer); - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); + virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual gl::Error unmapBuffer(); virtual GLenum getIndexType() const; virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); + virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); - virtual bool discard(); + virtual gl::Error discard(); DXGI_FORMAT getIndexFormat() const; ID3D11Buffer *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp index 3536fafac9..d835e4fa68 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -1,4 +1,3 @@ -#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 @@ -12,10 +11,10 @@ #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/VertexDataManager.h" -#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "third_party/murmurhash/MurmurHash3.h" @@ -86,16 +85,15 @@ void InputLayoutCache::markDirty() } } -GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary) +gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary) { int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices); if (!mDevice || !mDeviceContext) { - ERR("InputLayoutCache is not initialized."); - return GL_INVALID_OPERATION; + return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized."); } InputLayoutKey ilKey = { 0 }; @@ -109,7 +107,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M 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); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(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 @@ -118,7 +116,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; ilKey.elements[ilKey.elementCount].desc.SemanticIndex = i; - ilKey.elements[ilKey.elementCount].desc.Format = dxgiFormat; + ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat; ilKey.elements[ilKey.elementCount].desc.InputSlot = i; ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; @@ -150,8 +148,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); if (FAILED(result)) { - ERR("Failed to crate input layout, result: 0x%08x", result); - return GL_INVALID_OPERATION; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result); } if (mInputLayoutMap.size() >= kMaxInputLayouts) @@ -223,7 +220,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff); } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h index 5d0ac60537..cc71ac3f6f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h @@ -11,8 +11,14 @@ #define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ #include "libGLESv2/Constants.h" +#include "libGLESv2/Error.h" #include "common/angleutils.h" +#include <GLES2/gl2.h> + +#include <cstddef> +#include <unordered_map> + namespace gl { class ProgramBinary; @@ -32,8 +38,8 @@ class InputLayoutCache void clear(); void markDirty(); - GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary); + gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary); private: DISALLOW_COPY_AND_ASSIGN(InputLayoutCache); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp index 07040342c7..a4e84f91c2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -1,4 +1,3 @@ -#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 @@ -11,15 +10,15 @@ // #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" -#include "libGLESv2/formatutils.h" -#include "libGLESv2/Texture.h" -#include "libGLESv2/Buffer.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Buffer.h" #include "libGLESv2/Context.h" // Precompiled shaders @@ -125,7 +124,7 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons 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); + unsigned int bytesPerPixel = gl::GetInternalFormatInfo(internalFormat).pixelBytes; unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment); unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel); @@ -160,10 +159,11 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un // 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); - GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); + GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; + GLenum sourceFormat = gl::GetFormatTypeInfo(unsizedFormat, sourcePixelsType).internalFormat; - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat); + const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat); + DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation()); ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); @@ -239,8 +239,7 @@ void PixelTransfer11::buildShaderMap() ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const { - GLenum componentType = gl::GetComponentType(internalFormat); - + GLenum componentType = gl::GetInternalFormatInfo(internalFormat).componentType; if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED) { componentType = GL_FLOAT; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h index 2e2fee8f50..ed1a3ae1d0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h @@ -13,6 +13,10 @@ #include "common/platform.h" +#include <GLES2/gl2.h> + +#include <map> + namespace gl { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp index e5e00325b2..7109be3e28 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp @@ -1,4 +1,3 @@ -#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 @@ -12,35 +11,18 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/main.h" -#if defined(__MINGW32__) // Provide undefined struct -typedef struct D3D11_QUERY_DATA_SO_STATISTICS -{ - UINT64 NumPrimitivesWritten; - UINT64 PrimitivesStorageNeeded; -} D3D11_QUERY_DATA_SO_STATISTICS; -#endif +#include <GLES2/gl2ext.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) +Query11::Query11(rx::Renderer11 *renderer, GLenum type) + : QueryImpl(type), + mResult(0), + mQueryFinished(false), + mRenderer(renderer), + mQuery(NULL) { - mRenderer = renderer; - mQuery = NULL; } Query11::~Query11() @@ -48,7 +30,7 @@ Query11::~Query11() SafeRelease(mQuery); } -void Query11::begin() +gl::Error Query11::begin() { if (mQuery == NULL) { @@ -56,69 +38,85 @@ void Query11::begin() queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); queryDesc.MiscFlags = 0; - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); } } mRenderer->getDeviceContext()->Begin(mQuery); + return gl::Error(GL_NO_ERROR); } -void Query11::end() +gl::Error Query11::end() { ASSERT(mQuery); mRenderer->getDeviceContext()->End(mQuery); - mStatus = GL_FALSE; + mQueryFinished = false; mResult = GL_FALSE; + + return gl::Error(GL_NO_ERROR); } -GLuint Query11::getResult() +gl::Error Query11::getResult(GLuint *params) { - if (mQuery != NULL) + while (!mQueryFinished) { - while (!testQuery()) + gl::Error error = testQuery(); + if (error.isError()) + { + return error; + } + + if (!mQueryFinished) { 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; + ASSERT(mQueryFinished); + *params = mResult; + + return gl::Error(GL_NO_ERROR); } -GLboolean Query11::isResultAvailable() +gl::Error Query11::isResultAvailable(GLuint *available) { - if (mQuery != NULL) + gl::Error error = testQuery(); + if (error.isError()) { - testQuery(); + return error; } - return mStatus; + *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + + return gl::Error(GL_NO_ERROR); } -GLboolean Query11::testQuery() +gl::Error Query11::testQuery() { - if (mQuery != NULL && mStatus != GL_TRUE) + if (!mQueryFinished) { - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ASSERT(mQuery); - bool queryFinished = false; + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); 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) + HRESULT result = context->GetData(mQuery, &numPixels, sizeof(numPixels), 0); + if (FAILED(result)) { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); + } + + if (result == S_OK) + { + mQueryFinished = true; mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; } } @@ -126,11 +124,17 @@ GLboolean Query11::testQuery() case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: { - UINT64 numPrimitives = 0; - queryFinished = checkStreamOutPrimitivesWritten(context, mQuery, &numPrimitives); - if (queryFinished) + D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; + HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 0); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); + } + + if (result == S_OK) { - mResult = static_cast<GLuint>(numPrimitives); + mQueryFinished = true; + mResult = static_cast<GLuint>(soStats.NumPrimitivesWritten); } } break; @@ -140,24 +144,13 @@ GLboolean Query11::testQuery() break; } - if (queryFinished) - { - mStatus = GL_TRUE; - } - else if (mRenderer->testDeviceLost(true)) + if (!mQueryFinished && mRenderer->testDeviceLost(true)) { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); } - - return mStatus; } - return GL_TRUE; // prevent blocking when query is null -} - -bool Query11::isStarted() const -{ - return (mQuery != NULL); + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h index 7a3df46d4f..822f2542ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h @@ -21,16 +21,19 @@ class Query11 : public QueryImpl Query11(rx::Renderer11 *renderer, GLenum type); virtual ~Query11(); - virtual void begin(); - virtual void end(); - virtual GLuint getResult(); - virtual GLboolean isResultAvailable(); - virtual bool isStarted() const; + virtual gl::Error begin(); + virtual gl::Error end(); + virtual gl::Error getResult(GLuint *params); + virtual gl::Error isResultAvailable(GLuint *available); private: DISALLOW_COPY_AND_ASSIGN(Query11); - GLboolean testQuery(); + gl::Error testQuery(); + + GLuint mResult; + + bool mQueryFinished; rx::Renderer11 *mRenderer; ID3D11Query *mQuery; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp index b185d97604..71b931f27e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -15,6 +14,7 @@ #include "libGLESv2/FramebufferAttachment.h" #include "common/debug.h" + #include "third_party/murmurhash/MurmurHash3.h" namespace rx @@ -79,39 +79,37 @@ bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendSta return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; } -ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState) +gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, + ID3D11BlendState **outBlendState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } bool mrt = false; + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + BlendStateKey key = { 0 }; key.blendState = blendState; - for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { - const gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i); + const gl::FramebufferAttachment *attachment = colorbuffers[colorAttachment]; + + auto rtChannels = key.rtChannels[colorAttachment]; + if (attachment) { - if (i > 0) + if (colorAttachment > 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; + rtChannels[0] = attachment->getRedSize() > 0; + rtChannels[1] = attachment->getGreenSize() > 0; + rtChannels[2] = attachment->getBlueSize() > 0; + rtChannels[3] = attachment->getAlphaSize() > 0; } } @@ -120,7 +118,8 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebu { BlendStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outBlendState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -172,13 +171,13 @@ ID3D11BlendState *RenderStateCache::getBlendState(const gl::Framebuffer *framebu HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState); if (FAILED(result) || !dx11BlendState) { - ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); } mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++))); - return dx11BlendState; + *outBlendState = dx11BlendState; + return gl::Error(GL_NO_ERROR); } } @@ -196,12 +195,12 @@ bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, cons return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; } -ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled) +gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } RasterizerStateKey key = { 0 }; @@ -213,7 +212,8 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer { RasterizerStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outRasterizerState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -267,13 +267,13 @@ ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::Rasterizer HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); if (FAILED(result) || !dx11RasterizerState) { - ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); } mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++))); - return dx11RasterizerState; + *outRasterizerState = dx11RasterizerState; + return gl::Error(GL_NO_ERROR); } } @@ -291,12 +291,11 @@ bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; } -ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState) +gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState); @@ -304,7 +303,8 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS { DepthStencilStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outDSState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -345,13 +345,13 @@ ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthS HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); if (FAILED(result) || !dx11DepthStencilState) { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); } mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++))); - return dx11DepthStencilState; + *outDSState = dx11DepthStencilState; + return gl::Error(GL_NO_ERROR); } } @@ -369,12 +369,11 @@ bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl: return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0; } -ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState) +gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState) { if (!mDevice) { - ERR("RenderStateCache is not initialized."); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } SamplerStateMap::iterator keyIter = mSamplerStateCache.find(samplerState); @@ -382,7 +381,8 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa { SamplerStateCounterPair &state = keyIter->second; state.second = mCounter++; - return state.first; + *outSamplerState = state.first; + return gl::Error(GL_NO_ERROR); } else { @@ -423,13 +423,13 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); if (FAILED(result) || !dx11SamplerState) { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11SamplerState, HRESULT: 0x%X.", result); } mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++))); - return dx11SamplerState; + *outSamplerState = dx11SamplerState; + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h index e6380fbd82..d5471a3061 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h @@ -11,8 +11,11 @@ #define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ #include "libGLESv2/angletypes.h" +#include "libGLESv2/Error.h" #include "common/angleutils.h" +#include <unordered_map> + namespace gl { class Framebuffer; @@ -31,10 +34,10 @@ class RenderStateCache void initialize(ID3D11Device *device); void clear(); - 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); + gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState); + gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState); + gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState); + gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState); private: DISALLOW_COPY_AND_ASSIGN(RenderStateCache); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp index 6aa75ae5bd..3041f21faa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp @@ -1,4 +1,3 @@ -#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 @@ -10,7 +9,6 @@ #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" - #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/main.h" @@ -219,8 +217,9 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, mDepth = depth; mSamples = samples; - mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format); - mActualFormat = d3d11_gl::GetInternalFormat(desc.Format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mInternalFormat = dxgiFormatInfo.internalFormat; + mActualFormat = dxgiFormatInfo.internalFormat; } } @@ -265,8 +264,9 @@ RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, mDepth = depth; mSamples = samples; - mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format); - mActualFormat = d3d11_gl::GetInternalFormat(desc.Format); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mInternalFormat = dxgiFormatInfo.internalFormat; + mActualFormat = dxgiFormatInfo.internalFormat; } } @@ -278,18 +278,11 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height mDepthStencil = NULL; mShaderResource = NULL; - DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat); - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat); - DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat); - DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); - DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat); - int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples); - if (supportedSamples < 0) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } + const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); if (width > 0 && height > 0) { @@ -299,7 +292,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = texFormat; + desc.Format = formatInfo.texFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -310,14 +303,14 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height // 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) + bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + if (formatInfo.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); + bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); } desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | @@ -339,7 +332,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = srvFormat; + srvDesc.Format = formatInfo.srvFormat; srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; @@ -357,7 +350,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = dsvFormat; + dsvDesc.Format = formatInfo.dsvFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; @@ -376,7 +369,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = rtvFormat; + rtvDesc.Format = formatInfo.rtvFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); @@ -391,7 +384,7 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height } ASSERT(SUCCEEDED(result)); - if (gl_d3d11::RequiresTextureDataInitialization(internalFormat)) + if (formatInfo.dataInitializerFunction != NULL) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -401,12 +394,13 @@ RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height } } + mWidth = width; mHeight = height; mDepth = 1; mInternalFormat = internalFormat; mSamples = supportedSamples; - mActualFormat = d3d11_gl::GetInternalFormat(texFormat); + mActualFormat = dxgiFormatInfo.internalFormat; mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp index 3ba0cc767b..b29b2ef910 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -7,14 +6,16 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. -#include "libGLESv2/main.h" -#include "common/utilities.h" #include "common/platform.h" +#include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" +#include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" @@ -35,8 +36,15 @@ #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" + #include "libEGL/Display.h" +#include "common/utilities.h" + +#include <EGL/eglext.h> + +#include <sstream> + // 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 @@ -49,31 +57,6 @@ #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1 #endif -#ifndef D3D11_PS_INPUT_REGISTER_COUNT -# define D3D11_PS_INPUT_REGISTER_COUNT 32 -#endif -#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT -# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 -#endif -#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 -#endif -#ifndef D3D11_SO_BUFFER_SLOT_COUNT -# define D3D11_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT -# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT -# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 -#endif -#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 -#endif -#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 -#endif - namespace rx { static const DXGI_FORMAT RenderTargetFormats[] = @@ -117,8 +100,6 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r mDeviceLost = false; - mMaxSupportedSamples = 0; - mDevice = NULL; mDeviceContext = NULL; mDxgiAdapter = NULL; @@ -320,16 +301,6 @@ EGLint Renderer11::initialize() } #endif - mMaxSupportedSamples = 0; - - 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); - } - #if !defined(ANGLE_PLATFORM_WINRT) static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) @@ -369,6 +340,17 @@ void Renderer11::initializeDevice() ASSERT(!mPixelTransfer); mPixelTransfer = new PixelTransfer11(this); + const gl::Caps &rendererCaps = getRendererCaps(); + + mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + + mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + + mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits); + markAllStateDirty(); } @@ -378,34 +360,22 @@ int Renderer11::generateConfigs(ConfigDesc **configDescList) unsigned int numDepthFormats = ArraySize(DepthStencilFormats); (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; int numConfigs = 0; - + for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) { - for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) + const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]); + const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat); + if (renderTargetFormatCaps.renderable) { - DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - UINT formatSupport = 0; - HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport); - - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) + for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) { - DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - - bool depthStencilFormatOK = true; - - if (depthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - UINT depthStencilSupport = 0; - result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport); - depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); - } - - if (depthStencilFormatOK) + const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]); + const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat); + if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN) { ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat); + newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat; + newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat; newConfig.multiSample = 0; // FIXME: enumerate multi-sampling newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast newConfig.es3Capable = true; @@ -468,43 +438,45 @@ SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareH return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); } -void Renderer11::generateSwizzle(gl::Texture *texture) +gl::Error Renderer11::generateSwizzle(gl::Texture *texture) { if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); + TextureStorage *texStorage = texture->getNativeTexture(); if (texStorage) { - TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); - storage11->generateSwizzles(texture->getSamplerState().swizzleRed, - texture->getSamplerState().swizzleGreen, - texture->getSamplerState().swizzleBlue, - texture->getSamplerState().swizzleAlpha); + gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed, + texture->getSamplerState().swizzleGreen, + texture->getSamplerState().swizzleBlue, + texture->getSamplerState().swizzleAlpha); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { if (type == gl::SAMPLER_PIXEL) { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) + ID3D11SamplerState *dxSamplerState = NULL; + gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + if (error.isError()) { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for pixel shaders at slot %i.", index); + return error; } + ASSERT(dxSamplerState != NULL); mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); mCurPixelSamplerStates[index] = samplerState; @@ -514,22 +486,18 @@ void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::Samp } else if (type == gl::SAMPLER_VERTEX) { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) + ID3D11SamplerState *dxSamplerState = NULL; + gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + if (error.isError()) { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for vertex shaders at slot %i.", index); + return error; } + ASSERT(dxSamplerState != NULL); mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); mCurVertexSamplerStates[index] = samplerState; @@ -538,38 +506,37 @@ void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::Samp mForceSetVertexSamplerStates[index] = false; } else UNREACHABLE(); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { ID3D11ShaderResourceView *textureSRV = NULL; bool forceSetTexture = false; if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); - if (texStorage) - { - TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); - gl::SamplerState samplerState; - texture->getSamplerStateWithNativeOffset(&samplerState); - textureSRV = storage11->getSRV(samplerState); - } + TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + TextureStorage *texStorage = textureImpl->getNativeTexture(); + ASSERT(texStorage != NULL); + + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); + gl::SamplerState samplerState; + texture->getSamplerStateWithNativeOffset(&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); - forceSetTexture = texture->hasDirtyImages(); + forceSetTexture = textureImpl->hasDirtyImages(); + textureImpl->resetDirty(); } if (type == gl::SAMPLER_PIXEL) { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) { @@ -580,11 +547,7 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur } else if (type == gl::SAMPLER_VERTEX) { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } + ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) { @@ -594,9 +557,11 @@ void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *textur mCurVertexSRVs[index] = textureSRV; } else UNREACHABLE(); + + return gl::Error(GL_NO_ERROR); } -bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) +gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) { for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) { @@ -608,7 +573,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con if (!constantBuffer) { - return false; + return gl::Error(GL_OUT_OF_MEMORY); } if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial()) @@ -630,7 +595,7 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con if (!constantBuffer) { - return false; + return gl::Error(GL_OUT_OF_MEMORY); } if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial()) @@ -642,18 +607,18 @@ bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], con } } - return true; + return gl::Error(GL_NO_ERROR); } -void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) +gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) { if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) { - ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled); - if (!dxRasterState) + ID3D11RasterizerState *dxRasterState = NULL; + gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState); + if (error.isError()) { - ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" - "rasterizer state."); + return error; } mDeviceContext->RSSetState(dxRasterState); @@ -662,23 +627,27 @@ void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) } mForceSetRasterState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error 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::ColorF)) != 0 || sampleMask != mCurSampleMask) { - ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState); - if (!dxBlendState) + ID3D11BlendState *dxBlendState = NULL; + gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState); + if (error.isError()) { - ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " - "blend state."); + return error; } + ASSERT(dxBlendState != NULL); + float blendColors[4] = {0.0f}; if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) @@ -704,10 +673,12 @@ void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendStat } mForceSetBlendState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) +gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) { if (mForceSetDepthStencilState || memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 || @@ -717,13 +688,15 @@ void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilS ASSERT(stencilRef == stencilBackRef); ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); - ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState); - if (!dxDepthStencilState) + ID3D11DepthStencilState *dxDepthStencilState = NULL; + gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState); + if (error.isError()) { - ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, " - "setting the default depth stencil state."); + return error; } + ASSERT(dxDepthStencilState); + // 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); @@ -738,6 +711,8 @@ void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilS } mForceSetDepthStencilState = false; + + return gl::Error(GL_NO_ERROR); } void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -768,7 +743,7 @@ void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mForceSetScissor = false; } -bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { gl::Rectangle actualViewport = viewport; @@ -795,11 +770,6 @@ bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z dxViewport.MinDepth = actualZNear; dxViewport.MaxDepth = actualZFar; - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - return false; // Nothing to render - } - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || actualZNear != mCurNear || actualZFar != mCurFar; @@ -829,7 +799,6 @@ bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z } mForceSetViewport = false; - return true; } bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) @@ -862,7 +831,7 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) return count >= minCount; } -bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) { // Get the color render buffer and serial // Also extract the render target dimensions and view @@ -873,39 +842,37 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; bool missingColorRenderTarget = true; - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { - const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment); - gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment); + gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - if (colorbuffer && drawBufferState != GL_NONE) + if (colorbuffer) { // 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)); // check for zero-sized default framebuffer, which is a special case. // in this case we do not wish to modify any state and just silently return false. // this will not report any gl error but will cause the calling method to return. if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) { - return false; + return gl::Error(GL_NO_ERROR); } - renderTargetSerials[colorAttachment] = colorbuffer->getSerial(); + renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer); // Extract the render target dimensions and view - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!renderTarget) { - ERR("render target pointer unexpectedly null."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); if (!framebufferRTVs[colorAttachment]) { - ERR("render target view pointer unexpectedly null."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } if (missingColorRenderTarget) @@ -921,37 +888,35 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) } } - // Get the depth stencil render buffer and serials + // Get the depth stencil render buffter and serials gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer(); unsigned int depthbufferSerial = 0; unsigned int stencilbufferSerial = 0; if (depthStencil) { - depthbufferSerial = depthStencil->getSerial(); + depthbufferSerial = GetAttachmentSerial(depthStencil); } else if (framebuffer->getStencilbuffer()) { depthStencil = framebuffer->getStencilbuffer(); - stencilbufferSerial = depthStencil->getSerial(); + stencilbufferSerial = GetAttachmentSerial(depthStencil); } ID3D11DepthStencilView* framebufferDSV = NULL; if (depthStencil) { - RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil()); + RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil); if (!depthStencilRenderTarget) { - ERR("render target pointer unexpectedly null."); SafeRelease(framebufferRTVs); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); if (!framebufferDSV) { - ERR("depth stencil view pointer unexpectedly null."); SafeRelease(framebufferRTVs); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); } // If there is no render buffer, the width, height and format values come from @@ -996,54 +961,54 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) invalidateFramebufferSwizzles(framebuffer); - return true; + return gl::Error(GL_NO_ERROR); } -GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) + gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + if (error.isError()) { - return err; + return error; } return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); } -GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + if (error.isError()) { - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + return error; + } - ID3D11Buffer *buffer = NULL; - DXGI_FORMAT bufferFormat = indexBuffer->getIndexFormat(); + ID3D11Buffer *buffer = NULL; + DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; - if (indexInfo->storage) - { - Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage); - buffer = storage->getBuffer(BUFFER_USAGE_INDEX); - } - else - { - buffer = indexBuffer->getBuffer(); - } + if (indexInfo->storage) + { + Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage); + buffer = storage->getBuffer(BUFFER_USAGE_INDEX); + } + else + { + IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + buffer = indexBuffer->getBuffer(); + } - if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) - { - mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); + if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) + { + mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); - mAppliedIB = buffer; - mAppliedIBFormat = bufferFormat; - mAppliedIBOffset = indexInfo->startOffset; - } + mAppliedIB = buffer; + mAppliedIBFormat = bufferFormat; + mAppliedIBOffset = indexInfo->startOffset; } - return err; + return gl::Error(GL_NO_ERROR); } void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) @@ -1084,7 +1049,7 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff } } -void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +gl::Error Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) { if (mode == GL_POINTS && transformFeedbackActive) { @@ -1117,43 +1082,51 @@ void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool } mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0); + + return gl::Error(GL_NO_ERROR); } else if (mode == GL_LINE_LOOP) { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(count, GL_NONE, NULL, 0, NULL); } else if (mode == GL_TRIANGLE_FAN) { - drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); + return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); } else if (instances > 0) { mDeviceContext->DrawInstanced(count, instances, 0, 0); + return gl::Error(GL_NO_ERROR); } else { mDeviceContext->Draw(count, 0); + return gl::Error(GL_NO_ERROR); } } -void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) +gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) { + int minIndex = static_cast<int>(indexInfo.indexRange.start); + if (mode == GL_LINE_LOOP) { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_TRIANGLE_FAN) { - drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances); + return drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances); } else if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0); + mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); + return gl::Error(GL_NO_ERROR); } else { - mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex)); + mDeviceContext->DrawIndexed(count, 0, -minIndex); + return gl::Error(GL_NO_ERROR); } } @@ -1235,7 +1208,7 @@ static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvo } } -void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1252,13 +1225,11 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1268,23 +1239,22 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / indexTypeSize)) { - 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); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } - const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * indexTypeSize; - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, indexType)) + const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } if (indexType == GL_UNSIGNED_SHORT) @@ -1293,10 +1263,10 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory)); unsigned int indexBufferOffset = offset; - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); @@ -1305,16 +1275,18 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) { - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; } mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) +gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1330,13 +1302,11 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic if (!mTriangleFanIB) { mTriangleFanIB = new StreamingIndexBufferInterface(this); - if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType)) + gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType); + if (error.isError()) { - delete mTriangleFanIB; - mTriangleFanIB = NULL; - - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mTriangleFanIB); + return error; } } @@ -1348,35 +1318,35 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int); if (numTris > (std::numeric_limits<unsigned int>::max() / (indexTypeSize * 3))) { - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); } const unsigned int spaceNeeded = (numTris * 3) * indexTypeSize; - if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType)) + gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType); + if (error.isError()) { - ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } if (indexType == GL_UNSIGNED_SHORT) fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory)); else fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory)); + unsigned int indexBufferOffset = offset; - if (!mTriangleFanIB->unmapBuffer()) + error = mTriangleFanIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); @@ -1385,7 +1355,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) { - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; mAppliedIBOffset = indexBufferOffset; @@ -1399,10 +1369,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic { mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) { ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); @@ -1463,9 +1435,11 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::Vertex { programBinary->dirtyAllUniforms(); } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) { const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); @@ -1492,8 +1466,9 @@ void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) } } - const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage()); - const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage()); + const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation()); + const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage()); + const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage()); ASSERT(vertexUniformStorage); ASSERT(fragmentUniformStorage); @@ -1619,12 +1594,21 @@ void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; } + + return gl::Error(GL_NO_ERROR); } -void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { - mClear->clearFramebuffer(clearParams, frameBuffer); + gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer); + if (error.isError()) + { + return error; + } + invalidateFramebufferSwizzles(frameBuffer); + + return gl::Error(GL_NO_ERROR); } void Renderer11::markAllStateDirty() @@ -1638,15 +1622,18 @@ void Renderer11::markAllStateDirty() mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; - for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size()); + for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) { - mForceSetVertexSamplerStates[i] = true; - mCurVertexSRVs[i] = NULL; + mForceSetVertexSamplerStates[vsamplerId] = true; + mCurVertexSRVs[vsamplerId] = NULL; } - for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + + ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); + for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) { - mForceSetPixelSamplerStates[i] = true; - mCurPixelSRVs[i] = NULL; + mForceSetPixelSamplerStates[fsamplerId] = true; + mCurPixelSRVs[fsamplerId] = NULL; } mForceSetBlendState = true; @@ -1803,6 +1790,7 @@ bool Renderer11::testDeviceResettable() void Renderer11::release() { + releaseShaderCompiler(); releaseDeviceResources(); SafeRelease(mDxgiFactory); @@ -1877,29 +1865,6 @@ GUID Renderer11::getAdapterIdentifier() const return adapterId; } -unsigned int Renderer11::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - unsigned int Renderer11::getReservedVertexUniformVectors() const { return 0; // Driver uniforms are stored in a separate constant buffer @@ -1910,85 +1875,6 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const return 0; // Driver uniforms are stored in a separate constant buffer } -unsigned int Renderer11::getMaxVertexUniformVectors() const -{ - META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); - return MAX_VERTEX_UNIFORM_VECTORS_D3D11; -} - -unsigned int Renderer11::getMaxFragmentUniformVectors() const -{ - META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); - return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11; -} - -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(); - case D3D_FEATURE_LEVEL_9_3: - return 10 - getReservedVaryings(); - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 8 - 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_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers(); - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - 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(); - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - unsigned int Renderer11::getReservedVertexUniformBuffers() const { // we reserve one buffer for the application uniforms, and one for driver uniforms @@ -2001,81 +1887,6 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const 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; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - 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; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - 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; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - bool Renderer11::getShareHandleSupport() const { // We only currently support share handles with BGRA surfaces, because @@ -2090,29 +1901,6 @@ 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(); -} - -bool Renderer11::getSRGBTextureSupport() const -{ - return true; -} - int Renderer11::getMajorShaderModel() const { switch (mFeatureLevel) @@ -2122,8 +1910,7 @@ int Renderer11::getMajorShaderModel() const case D3D_FEATURE_LEVEL_10_0: case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return D3D10_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MAJOR_VERSION; // 4 default: UNREACHABLE(); return 0; } } @@ -2152,100 +1939,12 @@ int Renderer11::getMaxSwapInterval() const return 4; } -int Renderer11::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -GLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const -{ - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - 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); - if (componentType != GL_INT && componentType != GL_UNSIGNED_INT) - { - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - 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); - if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) - { - return; - } - - DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat); - 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) - { - return 0; - } - - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - if (iter != mMultisampleSupportMap.end()) - { - const MultisampleSupportInfo& info = iter->second; - for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - if (info.qualityLevels[i] > 0) - { - return i + 1; - } - } - } - - return -1; -} - -bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance()); - TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance()); + TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source); + TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2257,12 +1956,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStor return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance()); - TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance()); + TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source); + TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2274,12 +1973,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSt return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance()); - TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance()); + TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source); + TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2291,12 +1990,12 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStor return false; } -bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) { if (source && dest) { - TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance()); - TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance()); + TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source); + TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest); mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); @@ -2308,8 +2007,8 @@ bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, Textur return false; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2318,7 +2017,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2332,14 +2031,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level)); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2369,8 +2069,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2379,7 +2079,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2393,14 +2093,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level)); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2430,8 +2131,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level) +bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2440,7 +2141,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2454,14 +2155,15 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance()); + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); if (!storage11) { ERR("Failed to retrieve the texture storage from the destination."); return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { ERR("Failed to retrieve the render target from the destination storage."); @@ -2491,8 +2193,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return ret; } -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level) +bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); if (!colorbuffer) @@ -2501,7 +2203,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (!sourceRenderTarget) { ERR("Failed to retrieve the render target from the frame buffer."); @@ -2515,7 +2217,7 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance()); + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); if (!storage11) { SafeRelease(source); @@ -2523,7 +2225,8 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset)); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); if (!destRenderTarget) { SafeRelease(source); @@ -2604,6 +2307,21 @@ RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum forma return renderTarget; } +ShaderImpl *Renderer11::createShader(GLenum type) +{ + return new ShaderD3D(type, this); +} + +ProgramImpl *Renderer11::createProgram() +{ + return new ProgramD3D(this); +} + +void Renderer11::releaseShaderCompiler() +{ + ShaderD3D::releaseCompiler(); +} + ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers) @@ -2818,30 +2536,39 @@ FenceImpl *Renderer11::createFence() return new Fence11(this); } +TransformFeedbackImpl* Renderer11::createTransformFeedback() +{ + return new TransformFeedbackD3D(); +} + bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const { ASSERT(getRendererExtensions().pixelBufferObject); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat); + // sRGB formats do not work with D3D11 buffer SRVs - if (gl::GetColorEncoding(internalFormat) == GL_SRGB) + if (internalFormatInfo.colorEncoding == GL_SRGB) { return false; } // We cannot support direct copies to non-color-renderable formats - if (gl_d3d11::GetRTVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + if (d3d11FormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { return false; } // We skip all 3-channel formats since sometimes format support is missing - if (gl::GetComponentCount(internalFormat) == 3) + if (internalFormatInfo.componentCount == 3) { return false; } // We don't support formats which we can't represent without conversion - if (getNativeTextureFormat(internalFormat) != internalFormat) + if (dxgiFormatInfo.internalFormat != internalFormat) { return false; } @@ -2860,7 +2587,7 @@ bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, { ASSERT(colorbuffer != NULL); - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); if (renderTarget) { *subresourceIndex = renderTarget->getSubresourceIndex(); @@ -2905,7 +2632,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *readRenderTarget = readBuffer->getRenderTarget(); + RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -2919,7 +2646,7 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); + RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget, false, false)) @@ -2947,8 +2674,9 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return gl::error(GL_OUT_OF_MEMORY, false); } - RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); - RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); + RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); + RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); + ASSERT(readRenderTarget && drawRenderTarget); if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false, blitDepth, blitStencil)) @@ -2962,8 +2690,8 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read return true; } -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) +gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; @@ -2978,19 +2706,33 @@ void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsi area.width = width; area.height = height; - if (pack.pixelBuffer.get() != NULL) + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != NULL) { - rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(pack.pixelBuffer.get()->getImplementation()); + rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); - packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + + gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + if (error.isError()) + { + return error; + } + + packBuffer->getIndexRangeCache()->clear(); } else { - readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + if (error.isError()) + { + return error; + } } SafeRelease(colorBufferTexture); } + + return gl::Error(GL_NO_ERROR); } Image *Renderer11::createImage() @@ -3031,28 +2773,23 @@ TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, b return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); } -Texture2DImpl *Renderer11::createTexture2D() +TextureImpl *Renderer11::createTexture(GLenum target) { - return new TextureD3D_2D(this); -} - -TextureCubeImpl *Renderer11::createTextureCube() -{ - return new TextureD3D_Cube(this); -} - -Texture3DImpl *Renderer11::createTexture3D() -{ - return new TextureD3D_3D(this); -} + switch(target) + { + case GL_TEXTURE_2D: return new TextureD3D_2D(this); + case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); + case GL_TEXTURE_3D: return new TextureD3D_3D(this); + case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this); + default: + UNREACHABLE(); + } -Texture2DArrayImpl *Renderer11::createTexture2DArray() -{ - return new TextureD3D_2DArray(this); + return NULL; } -void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels) +gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ASSERT(area.width >= 0); ASSERT(area.height >= 0); @@ -3077,7 +2814,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou if (safeArea.width == 0 || safeArea.height == 0) { // no work to do - return; + return gl::Error(GL_NO_ERROR); } D3D11_TEXTURE2D_DESC stagingDesc; @@ -3097,8 +2834,7 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); if (FAILED(result)) { - ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result); } ID3D11Texture2D* srcTex = NULL; @@ -3120,9 +2856,8 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); if (FAILED(result)) { - ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result); SafeRelease(stagingTex); - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result); } mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); @@ -3150,9 +2885,11 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou packPixels(stagingTex, packParams, pixels); SafeRelease(stagingTex); + + return gl::Error(GL_NO_ERROR); } -void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, void *pixelsOut) +void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) { D3D11_TEXTURE2D_DESC textureDesc; readTexture->GetDesc(&textureDesc); @@ -3162,39 +2899,37 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams UNUSED_ASSERTION_VARIABLE(hr); ASSERT(SUCCEEDED(hr)); - unsigned char *source; + uint8_t *source; int inputPitch; if (params.pack.reverseRowOrder) { - source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); + source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); inputPitch = -static_cast<int>(mapping.RowPitch); } else { - source = static_cast<unsigned char*>(mapping.pData); + source = static_cast<uint8_t*>(mapping.pData); inputPitch = static_cast<int>(mapping.RowPitch); } - GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format); - GLenum sourceFormat = gl::GetFormat(sourceInternalFormat); - GLenum sourceType = gl::GetType(sourceInternalFormat); - - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); - - if (sourceFormat == params.format && sourceType == params.type) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) { - unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset; + uint8_t *dest = pixelsOut + params.offset; for (int y = 0; y < params.area.height; y++) { - memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize); + memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes); } } else { - GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type); - GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat); + const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); + ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type); + + const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(params.format, params.type); + const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); - ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type); if (fastCopyFunc) { // Fast copy is possible through some special function @@ -3202,8 +2937,8 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams { 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; + uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; fastCopyFunc(src, dest); } @@ -3211,10 +2946,7 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams } else { - ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format); - ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type); - - unsigned char temp[16]; // Maximum size of any Color<T> type used. + uint8_t 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)); @@ -3223,13 +2955,13 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams { 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; + uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; // readFunc and writeFunc will be using the same type of color, CopyTexImage // will not allow the copy otherwise. - readFunc(src, temp); - writeFunc(temp, dest); + sourceDXGIFormatInfo.colorReadFunction(src, temp); + destFormatTypeInfo.colorWriteFunction(temp, dest); } } } @@ -3328,9 +3060,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; - bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat()) > 0; - bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat()) > 0; - bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat()); + bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit); if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && @@ -3404,7 +3135,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R } else { - GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat()); + GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format; result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, scissor, format, filter); } @@ -3457,7 +3188,9 @@ ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel) { ASSERT(attachment->isTexture()); - TextureStorage *texStorage = attachment->getTextureStorage(); + gl::Texture *texture = attachment->getTexture(); + + TextureStorage *texStorage = texture->getNativeTexture(); if (texStorage) { TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); @@ -3515,46 +3248,14 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -GLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const -{ - return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat)); -} - rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { - return gl_d3d11::GetVertexConversionType(vertexFormat); + return d3d11::GetVertexFormatInfo(vertexFormat).conversionType; } 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; + return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat).nativeFormat).componentType; } void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h index b54f75d859..2a53fa1672 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -59,37 +59,37 @@ class Renderer11 : public Renderer virtual SwapChain *createSwapChain(EGLNativeWindowType 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 gl::Error generateSwizzle(gl::Texture *texture); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - 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); + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); + virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask); + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); virtual bool applyPrimitiveType(GLenum mode, GLsizei count); - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual void applyUniforms(const gl::ProgramBinary &programBinary); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const 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 gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive); + virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); + virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); + virtual gl::Error 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, bool transformFeedbackActive); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual gl::Error 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); + virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void markAllStateDirty(); @@ -103,63 +103,48 @@ class Renderer11 : public Renderer virtual std::string getRendererDescription() const; virtual GUID getAdapterIdentifier() const; - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; - 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 getShareHandleSupport() const; virtual bool getPostSubBufferSupport() const; - virtual int getMaxRecommendedElementsIndices() const; - virtual int getMaxRecommendedElementsVertices() const; - virtual bool getSRGBTextureSupport() const; virtual int getMajorShaderModel() 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; - // 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 copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); + + virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, 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); + + virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + // Shader creation + virtual ShaderImpl *createShader(GLenum type); + virtual ProgramImpl *createProgram(); + // Shader operations + virtual void releaseShaderCompiler(); virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers); @@ -178,10 +163,7 @@ class Renderer11 : public Renderer virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Texture creation - virtual Texture2DImpl *createTexture2D(); - virtual TextureCubeImpl *createTextureCube(); - virtual Texture3DImpl *createTexture3D(); - virtual Texture2DArrayImpl *createTexture2DArray(); + virtual TextureImpl *createTexture(GLenum target); // Buffer creation virtual BufferImpl *createBuffer(); @@ -195,6 +177,9 @@ class Renderer11 : public Renderer virtual QueryImpl *createQuery(GLenum type); virtual FenceImpl *createFence(); + // Transform Feedback creation + virtual TransformFeedbackImpl* createTransformFeedback(); + // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; @@ -211,10 +196,9 @@ class Renderer11 : public Renderer 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); + void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *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; @@ -223,11 +207,11 @@ class Renderer11 : public Renderer virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const; - 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); + gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error 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, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels); + gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, @@ -253,19 +237,6 @@ class Renderer11 : public Renderer RenderStateCache mStateCache; - // 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<GLenum, MultisampleSupportInfo> MultisampleSupportMap; - MultisampleSupportMap mMultisampleSupportMap; - - unsigned int mMaxSupportedSamples; - // current render target states unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; unsigned int mAppliedDepthbufferSerial; @@ -275,15 +246,15 @@ class Renderer11 : public Renderer rx::RenderTarget::Desc mRenderTargetDesc; // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> mCurVertexSamplerStates; - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetPixelSamplerStates; + std::vector<gl::SamplerState> mCurPixelSamplerStates; // Currently applied textures - ID3D11ShaderResourceView *mCurVertexSRVs[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - ID3D11ShaderResourceView *mCurPixelSRVs[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs; + std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs; // Currently applied blend state bool mForceSetBlendState; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp index 5a7c987494..52f34887fb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -9,7 +8,6 @@ // executable implementation details. #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" - #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" namespace rx diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp index 0341df10f9..4b29be055d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -7,12 +6,13 @@ // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. -#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" - #include "common/platform.h" +#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" + +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h" @@ -94,8 +94,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(backbufferWidth >= 1); ASSERT(backbufferHeight >= 1); -#if !defined(ANGLE_PLATFORM_WINRT) // Preserve the render target content +#if !defined(ANGLE_PLATFORM_WINRT) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { @@ -107,6 +107,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei releaseOffscreenTexture(); + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer if (mAppCreatedShareHandle) @@ -135,11 +137,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); - if (offscreenTextureDesc.Width != (UINT)backbufferWidth - || offscreenTextureDesc.Height != (UINT)backbufferHeight - || offscreenTextureDesc.Format != gl_d3d11::GetTexFormat(mBackBufferFormat) - || offscreenTextureDesc.MipLevels != 1 - || offscreenTextureDesc.ArraySize != 1) + if (offscreenTextureDesc.Width != (UINT)backbufferWidth || + offscreenTextureDesc.Height != (UINT)backbufferHeight || + offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || + offscreenTextureDesc.MipLevels != 1 || + offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); release(); @@ -153,7 +155,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; @@ -209,7 +211,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; - offscreenRTVDesc.Format = gl_d3d11::GetRTVFormat(mBackBufferFormat); + offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.Texture2D.MipSlice = 0; @@ -218,7 +220,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; - offscreenSRVDesc.Format = gl_d3d11::GetSRVFormat(mBackBufferFormat); + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = -1; @@ -227,12 +229,14 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource"); + const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat); + if (mDepthBufferFormat != GL_NONE) { D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; - depthStencilTextureDesc.Format = gl_d3d11::GetTexFormat(mDepthBufferFormat); + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.SampleDesc.Count = 1; @@ -260,7 +264,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; - depthStencilDesc.Format = gl_d3d11::GetDSVFormat(mDepthBufferFormat); + depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; @@ -270,7 +274,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; - depthStencilSRVDesc.Format = gl_d3d11::GetSRVFormat(mDepthBufferFormat); + depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = -1; @@ -343,8 +347,8 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) #else const int bufferCount = 2; #endif - DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::GetTexFormat(mBackBufferFormat); - result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); if (FAILED(result)) { @@ -361,6 +365,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) } } #endif + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) @@ -409,14 +414,17 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap if (mWindow) { + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); + IDXGIFactory *factory = mRenderer->getDxgiFactory(); + #if !defined(ANGLE_PLATFORM_WINRT) DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; swapChainDesc.BufferDesc.Width = backbufferWidth; swapChainDesc.BufferDesc.Height = backbufferHeight; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; - swapChainDesc.BufferDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SampleDesc.Count = 1; @@ -437,7 +445,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = 0; swapChainDesc.Height = 0; - swapChainDesc.Format = gl_d3d11::GetTexFormat(mBackBufferFormat); + swapChainDesc.Format = backbufferFormatInfo.texFormat; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; @@ -460,7 +468,6 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap mViewportWidth = swapChainDesc.Width; mViewportHeight = swapChainDesc.Height; #endif - if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); @@ -530,7 +537,7 @@ void SwapChain11::initPassThroughResources() samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; - samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + samplerDesc.MaxLOD = FLT_MAX; result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); ASSERT(SUCCEEDED(result)); @@ -636,7 +643,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG // Draw deviceContext->Draw(4, 0); -#if ANGLE_FORCE_VSYNC_OFF +#ifdef ANGLE_FORCE_VSYNC_OFF result = mSwapChain->Present(0, 0); #else result = mSwapChain->Present(mSwapInterval, 0); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp index 00b81b7c92..91e7147da6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -9,17 +8,18 @@ // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" - -#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/main.h" +#include "libGLESv2/ImageIndex.h" #include "common/utilities.h" -#include "libGLESv2/main.h" namespace rx { @@ -126,15 +126,16 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTa { UINT bindFlags = 0; - if (gl_d3d11::GetSRVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_SHADER_RESOURCE; } - if (gl_d3d11::GetDSVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN) + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_DEPTH_STENCIL; } - if (gl_d3d11::GetRTVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN && renderTarget) + if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) { bindFlags |= D3D11_BIND_RENDER_TARGET; } @@ -195,7 +196,7 @@ UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) { bool swizzleRequired = samplerState.swizzleRequired(); - bool mipmapping = IsMipmapFiltered(samplerState); + 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) @@ -239,7 +240,7 @@ ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel) } } -void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) { SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (int level = 0; level < getLevelCount(); level++) @@ -255,16 +256,17 @@ void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, Blit11 *blitter = mRenderer->getBlitter(); - if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha)) + gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + if (error.isError()) { - mSwizzleCache[level] = swizzleTarget; - } - else - { - ERR("Failed to swizzle texture."); + return error; } + + mSwizzleCache[level] = swizzleTarget; } } + + return gl::Error(GL_NO_ERROR); } void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) @@ -308,7 +310,8 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign ASSERT(dstTexture); - if (!fullCopy && (d3d11::GetDepthBits(mTextureFormat) > 0 || d3d11::GetStencilBits(mTextureFormat) > 0)) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) { // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead Blit11 *blitter = mRenderer->getBlitter(); @@ -319,11 +322,13 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign } else { + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + 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.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth); + srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight); srcBox.front = copyArea.z; srcBox.back = copyArea.z + copyArea.depth; @@ -338,6 +343,27 @@ bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsign return false; } +bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth) +{ + if (dstTexture) + { + ID3D11Resource *srcTexture = getResource(); + unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + + ASSERT(srcTexture); + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset, + srcTexture, srcSubresource, NULL); + return true; + } + + return false; +} + void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) { if (source && dest) @@ -356,7 +382,7 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1 Blit11 *blitter = mRenderer->getBlitter(); blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, - gl::GetFormat(source->getInternalFormat()), GL_LINEAR); + gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); } } } @@ -371,14 +397,15 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree } TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) + : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), + mTexture(swapchain->getOffscreenTexture()), + mSwizzleTexture(NULL) { - mTexture = swapchain->getOffscreenTexture(); mTexture->AddRef(); - mSwizzleTexture = NULL; for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mRenderTarget[i] = NULL; mSwizzleRenderTargets[i] = NULL; } @@ -401,33 +428,37 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch offscreenRTV->GetDesc(&rtvDesc); mRenderTargetFormat = rtvDesc.Format; - GLenum internalFormat = d3d11_gl::GetInternalFormat(mTextureFormat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalFormat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalFormat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat); + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; + + initializeSerials(1, 1); } TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) - : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) + : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)), + mTexture(NULL), + mSwizzleTexture(NULL) { - mTexture = NULL; - mSwizzleTexture = NULL; - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mRenderTarget[i] = NULL; mSwizzleRenderTargets[i] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // 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 @@ -441,7 +472,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform D3D11_TEXTURE2D_DESC desc; desc.Width = width; // Compressed texture size constraints? desc.Height = height; - desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); + desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); desc.ArraySize = 1; desc.Format = mTextureFormat; desc.SampleDesc.Count = 1; @@ -474,10 +505,27 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform mTextureDepth = 1; } } + + initializeSerials(getLevelCount(), 1); } TextureStorage11_2D::~TextureStorage11_2D() { + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[i]->recoverFromAssociatedStorage(); + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -494,13 +542,80 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage return static_cast<TextureStorage11_2D*>(storage); } +void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[level] == expectedImage); + ASSERT(retValue); + return retValue; + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + ASSERT(mAssociatedImages[level] == expectedImage); + + if (mAssociatedImages[level] == expectedImage) + { + mAssociatedImages[level] = NULL; + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[level]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_2D::getResource() const { return mTexture; } -RenderTarget *TextureStorage11_2D::getRenderTarget(int level) +RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index) { + ASSERT(!index.hasLayer()); + + int level = index.mipIndex; + if (level >= 0 && level < getLevelCount()) { if (!mRenderTarget[level]) @@ -595,14 +710,22 @@ ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipL return SRV; } -void TextureStorage11_2D::generateMipmap(int level) +void TextureStorage11_2D::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined + + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level); - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - generateMipmapLayer(source, dest); + generateMipmapLayer(source, dest); + } } ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() @@ -671,11 +794,6 @@ ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel } } -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, renderTarget)) { @@ -687,17 +805,19 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal mSwizzleRenderTargets[level] = NULL; for (unsigned int face = 0; face < 6; face++) { + mAssociatedImages[face][level] = NULL; mRenderTarget[face][level] = NULL; } } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // if the size is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation @@ -739,10 +859,31 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal mTextureDepth = 1; } } + + initializeSerials(getLevelCount() * 6, 6); } + TextureStorage11_Cube::~TextureStorage11_Cube() { + for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + for (unsigned int face = 0; face < 6; face++) + { + if (mAssociatedImages[face][level] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[face][level]->recoverFromAssociatedStorage(); + } + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -762,16 +903,96 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS return static_cast<TextureStorage11_Cube*>(storage); } +void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + mAssociatedImages[layerTarget][level] = image; + } + } +} + +bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); + ASSERT(retValue); + return retValue; + } + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + if (0 <= layerTarget && layerTarget < 6) + { + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); + + if (mAssociatedImages[layerTarget][level] == expectedImage) + { + mAssociatedImages[layerTarget][level] = NULL; + } + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < 6); + + if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) + { + if (0 <= layerTarget && layerTarget < 6) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + } + } + } + } +} + ID3D11Resource *TextureStorage11_Cube::getResource() const { return mTexture; } -RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level) +RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index) { + int faceIndex = index.layerIndex; + int level = index.mipIndex; + if (level >= 0 && level < getLevelCount()) { - int faceIndex = TextureD3D_Cube::targetToIndex(faceTarget); if (!mRenderTarget[faceIndex][level]) { ID3D11Device *device = mRenderer->getDevice(); @@ -865,10 +1086,8 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi 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) + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; @@ -897,14 +1116,25 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi return SRV; } -void TextureStorage11_Cube::generateMipmap(int faceIndex, int level) +void TextureStorage11_Cube::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined - 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)); + for (int faceIndex = 0; faceIndex < 6; faceIndex++) + { + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level); - generateMipmapLayer(source, dest); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + + generateMipmapLayer(source, dest); + } + } } ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() @@ -976,11 +1206,6 @@ ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLev } } -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, renderTarget)) @@ -990,17 +1215,19 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { + mAssociatedImages[i] = NULL; mLevelRenderTargets[i] = NULL; mSwizzleRenderTargets[i] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // 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 @@ -1045,10 +1272,27 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform mTextureDepth = desc.Depth; } } + + initializeSerials(getLevelCount() * depth, depth); } TextureStorage11_3D::~TextureStorage11_3D() { + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != NULL) + { + bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + mAssociatedImages[i]->recoverFromAssociatedStorage(); + } + } + } + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -1071,6 +1315,69 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage return static_cast<TextureStorage11_3D*>(storage); } +void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + mAssociatedImages[level] = image; + } +} + +bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages[level] == expectedImage); + ASSERT(retValue); + return retValue; + } + + return false; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + ASSERT(mAssociatedImages[level] == expectedImage); + + if (mAssociatedImages[level] == expectedImage) + { + mAssociatedImages[level] = NULL; + } + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); + + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + // No need to let the old Image recover its data, if it is also the incoming Image. + if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[level]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_3D::getResource() const { return mTexture; @@ -1098,20 +1405,24 @@ ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipL return SRV; } -RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel) +RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index) { + int mipLevel = index.mipIndex; + if (mipLevel >= 0 && mipLevel < getLevelCount()) { - if (!mLevelRenderTargets[mipLevel]) + ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + + if (!index.hasLayer()) { - ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); - if (!srv) + if (!mLevelRenderTargets[mipLevel]) { - return NULL; - } + ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); + if (!srv) + { + return NULL; + } - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; @@ -1136,35 +1447,22 @@ RenderTarget *TextureStorage11_3D::getRenderTarget(int 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()) + return mLevelRenderTargets[mipLevel]; + } + else { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + int layer = index.layerIndex; - // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + 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; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.Format = mRenderTargetFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; @@ -1188,28 +1486,30 @@ RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer) SafeRelease(rtv); SafeRelease(srv); } - else - { - UNREACHABLE(); - } - } - return mLevelLayerRenderTargets[key]; - } - else - { - return NULL; + return mLevelLayerRenderTargets[key]; + } } + + return NULL; } -void TextureStorage11_3D::generateMipmap(int level) +void TextureStorage11_3D::generateMipmaps() { - invalidateSwizzleCacheLevel(level); + // Base level must already be defined + + for (int level = 1; level < getLevelCount(); level++) + { + invalidateSwizzleCacheLevel(level); + + gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1); + gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level); - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - generateMipmapLayer(source, dest); + generateMipmapLayer(source, dest); + } } ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() @@ -1279,12 +1579,6 @@ ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel } } -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, renderTarget)) @@ -1297,13 +1591,14 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mSwizzleRenderTargets[level] = NULL; } - mTextureFormat = gl_d3d11::GetTexFormat(internalformat); - mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat); - mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat); - mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat); - mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat); - mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat); - mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); + mTextureFormat = formatInfo.texFormat; + mShaderResourceFormat = formatInfo.srvFormat; + mDepthStencilFormat = formatInfo.dsvFormat; + mRenderTargetFormat = formatInfo.rtvFormat; + mSwizzleTextureFormat = formatInfo.swizzleTexFormat; + mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; + mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; // 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 @@ -1350,10 +1645,25 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mTextureDepth = desc.ArraySize; } } + + initializeSerials(getLevelCount() * depth, depth); } TextureStorage11_2DArray::~TextureStorage11_2DArray() { + for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++) + { + bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // We must let the Images recover their data before we delete it from the TextureStorage. + i->second->recoverFromAssociatedStorage(); + } + } + mAssociatedImages.clear(); + SafeRelease(mTexture); SafeRelease(mSwizzleTexture); @@ -1375,6 +1685,66 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray return static_cast<TextureStorage11_2DArray*>(storage); } +void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget) +{ + ASSERT(0 <= level && level < getLevelCount()); + + if (0 <= level && level < getLevelCount()) + { + LevelLayerKey key(level, layerTarget); + mAssociatedImages[key] = image; + } +} + +bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +{ + LevelLayerKey key(level, layerTarget); + + // This validation check should never return false. It means the Image/TextureStorage association is broken. + bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + ASSERT(retValue); + return retValue; +} + +// disassociateImage allows an Image to end its association with a Storage. +void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage) +{ + LevelLayerKey key(level, layerTarget); + + bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + mAssociatedImages[key] = NULL; + } +} + +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. +void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +{ + LevelLayerKey key(level, layerTarget); + + ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end()); + + if (mAssociatedImages.find(key) != mAssociatedImages.end()) + { + if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage) + { + // Ensure that the Image is still associated with this TextureStorage. This should be true. + bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this); + ASSERT(imageAssociationCorrect); + + if (imageAssociationCorrect) + { + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to NULL too. + mAssociatedImages[key]->recoverFromAssociatedStorage(); + } + } + } +} + ID3D11Resource *TextureStorage11_2DArray::getResource() const { return mTexture; @@ -1404,8 +1774,13 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int return SRV; } -RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer) +RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index) { + ASSERT(index.hasLayer()); + + int mipLevel = index.mipIndex; + int layer = index.layerIndex; + if (mipLevel >= 0 && mipLevel < getLevelCount()) { LevelLayerKey key(mipLevel, layer); @@ -1470,15 +1845,23 @@ RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int l } } -void TextureStorage11_2DArray::generateMipmap(int level) +void TextureStorage11_2DArray::generateMipmaps() { - invalidateSwizzleCacheLevel(level); - for (unsigned int layer = 0; layer < mTextureDepth; layer++) + // Base level must already be defined + + for (int level = 0; level < getLevelCount(); level++) { - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer)); + invalidateSwizzleCacheLevel(level); + for (unsigned int layer = 0; layer < mTextureDepth; layer++) + { + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer); + gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer); - generateMipmapLayer(source, dest); + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + + generateMipmapLayer(source, dest); + } } } @@ -1551,9 +1934,4 @@ ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mip } } -unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const -{ - return mTextureDepth; -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h index 6be7bac8e2..9d63b2699d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h @@ -11,8 +11,16 @@ #define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ #include "libGLESv2/Texture.h" +#include "libGLESv2/Error.h" #include "libGLESv2/renderer/d3d/TextureStorage.h" +#include <map> + +namespace gl +{ +struct ImageIndex; +} + namespace rx { class RenderTarget; @@ -20,6 +28,7 @@ class RenderTarget11; class Renderer; class Renderer11; class SwapChain11; +class Image11; class TextureStorage11 : public TextureStorage { @@ -34,12 +43,9 @@ class TextureStorage11 : public TextureStorage 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 RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; + virtual void generateMipmaps() = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; @@ -47,7 +53,7 @@ class TextureStorage11 : public TextureStorage virtual int getLevelCount() const; UINT getSubresourceIndex(int mipLevel, int layerTarget) const; - void generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); void invalidateSwizzleCacheLevel(int mipLevel); void invalidateSwizzleCache(); @@ -55,6 +61,15 @@ class TextureStorage11 : public TextureStorage int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level, + int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth); + + virtual void associateImage(Image11* image, int level, int layerTarget) = 0; + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0; + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0; + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0; + protected: TextureStorage11(Renderer *renderer, UINT bindFlags); void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); @@ -70,8 +85,6 @@ class TextureStorage11 : public TextureStorage 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; @@ -148,16 +161,19 @@ class TextureStorage11_2D : public TextureStorage11 static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); - virtual void generateMipmap(int level); + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); @@ -168,6 +184,8 @@ class TextureStorage11_2D : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_Cube : public TextureStorage11 @@ -179,16 +197,19 @@ class TextureStorage11_Cube : public TextureStorage11 static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - virtual void generateMipmap(int faceIndex, int level); + virtual void generateMipmaps(); + + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); @@ -199,6 +220,8 @@ class TextureStorage11_Cube : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_3D : public TextureStorage11 @@ -211,17 +234,21 @@ class TextureStorage11_3D : public TextureStorage11 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); + // Handles both layer and non-layer RTs + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); + + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D); @@ -236,6 +263,8 @@ class TextureStorage11_3D : public TextureStorage11 ID3D11Texture3D *mTexture; ID3D11Texture3D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_2DArray : public TextureStorage11 @@ -248,16 +277,19 @@ class TextureStorage11_2DArray : public TextureStorage11 static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTargetLayer(int mipLevel, int layer); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + + virtual void generateMipmaps(); - virtual void generateMipmap(int level); + virtual void associateImage(Image11* image, int level, int layerTarget); + virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); + virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); + virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); protected: virtual ID3D11Resource *getSwizzleTexture(); virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); - virtual unsigned int getTextureLevelDepth(int mipLevel) const; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray); @@ -271,6 +303,9 @@ class TextureStorage11_2DArray : public TextureStorage11 ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + + typedef std::map<LevelLayerKey, Image11*> ImageMap; + ImageMap mAssociatedImages; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp index 2f47ec0a67..9bc5b1d2d1 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -1,4 +1,3 @@ -#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 @@ -9,11 +8,10 @@ #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" - -#include "libGLESv2/Buffer.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" -#include "libGLESv2/VertexAttribute.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/VertexAttribute.h" namespace rx { @@ -30,7 +28,7 @@ VertexBuffer11::~VertexBuffer11() SafeRelease(mBuffer); } -bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) +gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) { SafeRelease(mBuffer); @@ -51,13 +49,14 @@ bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); if (FAILED(result)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return true; + + return gl::Error(GL_NO_ERROR); } VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) @@ -66,66 +65,62 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *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) +gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) { - if (mBuffer) + if (!mBuffer) { - gl::Buffer *buffer = attrib.buffer.get(); - int inputStride = ComputeVertexAttributeStride(attrib); - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - 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; - } + gl::Buffer *buffer = attrib.buffer.get(); + int inputStride = ComputeVertexAttributeStride(attrib); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result); + } - const char *input = NULL; - if (attrib.enabled) + uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset; + + const uint8_t *input = NULL; + if (attrib.enabled) + { + if (buffer) { - if (buffer) - { - Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset); - } - else - { - input = static_cast<const char*>(attrib.pointer); - } + Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); + input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset); } else { - input = reinterpret_cast<const char*>(currentValue.FloatValues); - } - - if (instances == 0 || attrib.divisor == 0) - { - input += inputStride * start; + input = static_cast<const uint8_t*>(attrib.pointer); } - - 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; + input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues); + } + + if (instances == 0 || attrib.divisor == 0) + { + input += inputStride * start; } + + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat); + ASSERT(vertexFormatInfo.copyFunction != NULL); + vertexFormatInfo.copyFunction(input, inputStride, count, output); + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } -bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const +gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, + GLsizei instances, unsigned int *outSpaceRequired) const { unsigned int elementCount = 0; if (attrib.enabled) @@ -136,30 +131,25 @@ bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei } else { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1)) - { - // Round up - elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.divisor); - } - else - { - elementCount = instances / attrib.divisor; - } + // Round up to divisor, if possible + elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); } gl::VertexFormat vertexFormat(attrib); - unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat)); + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat); + unsigned int elementSize = dxgiFormatInfo.pixelBytes; if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) { if (outSpaceRequired) { *outSpaceRequired = elementSize * elementCount; } - return true; + return gl::Error(GL_NO_ERROR); } else { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); } } else @@ -169,7 +159,7 @@ bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei { *outSpaceRequired = elementSize * 4; } - return true; + return gl::Error(GL_NO_ERROR); } } @@ -178,7 +168,7 @@ unsigned int VertexBuffer11::getBufferSize() const return mBufferSize; } -bool VertexBuffer11::setBufferSize(unsigned int size) +gl::Error VertexBuffer11::setBufferSize(unsigned int size) { if (size > mBufferSize) { @@ -186,33 +176,29 @@ bool VertexBuffer11::setBufferSize(unsigned int size) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool VertexBuffer11::discard() +gl::Error VertexBuffer11::discard() { - if (mBuffer) + 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; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - dxContext->Unmap(mBuffer, 0); + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - return true; - } - else + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) { - ERR("Vertex buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result); } + + dxContext->Unmap(mBuffer, 0); + + return gl::Error(GL_NO_ERROR); } ID3D11Buffer *VertexBuffer11::getBuffer() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h index c2a5aa7afd..0e10da1df8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h @@ -21,19 +21,19 @@ class VertexBuffer11 : public VertexBuffer explicit VertexBuffer11(rx::Renderer11 *const renderer); virtual ~VertexBuffer11(); - virtual bool initialize(unsigned int size, bool dynamicUsage); + virtual gl::Error initialize(unsigned int size, bool dynamicUsage); static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + virtual gl::Error 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 gl::Error 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(); + virtual gl::Error setBufferSize(unsigned int size); + virtual gl::Error discard(); ID3D11Buffer *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp index c991fd4991..c07828757d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp @@ -1,4 +1,3 @@ -#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 @@ -18,384 +17,236 @@ namespace rx { -struct D3D11FormatInfo +namespace d3d11 { - DXGI_FORMAT mTexFormat; - DXGI_FORMAT mSRVFormat; - DXGI_FORMAT mRTVFormat; - DXGI_FORMAT mDSVFormat; - - D3D11FormatInfo() - : mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN) - { } - D3D11FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) - : mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat) - { } -}; +typedef std::map<DXGI_FORMAT, GLenum> DXGIToESFormatMap; -// 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, D3D11FormatInfo> D3D11ES3FormatPair; -typedef std::map<GLenum, D3D11FormatInfo> D3D11ES3FormatMap; +inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) +{ + map->insert(std::make_pair(key, value)); +} -static D3D11ES3FormatMap BuildD3D11FormatMap() +static DXGIToESFormatMap BuildDXGIToESFormatMap() { - D3D11ES3FormatMap map; + DXGIToESFormatMap map; - // | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - map.insert(D3D11ES3FormatPair(GL_NONE, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8, D3D11FormatInfo(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8, D3D11FormatInfo(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB565, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA4, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB5_A1, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8_SNORM, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB10_A2, D3D11FormatInfo(DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB10_A2UI, D3D11FormatInfo(DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_SRGB8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_SRGB8_ALPHA8, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16F, D3D11FormatInfo(DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16F, D3D11FormatInfo(DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16F, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16F, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32F, D3D11FormatInfo(DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32F, D3D11FormatInfo(DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32F, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32F, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R11F_G11F_B10F, D3D11FormatInfo(DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB9_E5, D3D11FormatInfo(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8I, D3D11FormatInfo(DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R8UI, D3D11FormatInfo(DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16I, D3D11FormatInfo(DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R16UI, D3D11FormatInfo(DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32I, D3D11FormatInfo(DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_R32UI, D3D11FormatInfo(DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8I, D3D11FormatInfo(DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16I, D3D11FormatInfo(DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32I, D3D11FormatInfo(DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RG32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8I, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16I, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32I, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8I, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA8UI, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16I, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA16UI, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32I, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA32UI, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); - // 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, D3D11FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGB, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_RGBA, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_BGRA_EXT, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN))); + 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); - // 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, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_EXT, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_ALPHA32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_ALPHA16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGRA8_EXT, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGRA4_ANGLEX, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); - map.insert(D3D11ES3FormatPair(GL_BGR5_A1_ANGLEX, D3D11FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ))); + 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); - // Depth stencil formats - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT16, D3D11FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT24, D3D11FormatInfo(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, D3D11FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT ))); - map.insert(D3D11ES3FormatPair(GL_DEPTH24_STENCIL8, D3D11FormatInfo(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, D3D11FormatInfo(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, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + 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); - // From GL_ANGLE_depth_texture - // Since D3D11 doesn't have a D32_UNORM format, use D24S8 which has comparable precision and matches the ES3 format. - map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ))); + 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); - // 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, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_R11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RG11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_RG11_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA8_ETC2_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, D3D11FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); + AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); - // From GL_EXT_texture_compression_dxt1 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); + AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); - // From GL_ANGLE_texture_compression_dxt3 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + 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); - // From GL_ANGLE_texture_compression_dxt5 - map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN))); + 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_R32_TYPELESS, GL_DEPTH_COMPONENT32F); + AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); + + 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 bool GetD3D11FormatInfo(GLenum internalFormat, D3D11FormatInfo *outFormatInfo) +struct D3D11FastCopyFormat { - static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap(); - D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); - if (iter != formatMap.end()) - { - if (outFormatInfo) - { - *outFormatInfo = iter->second; - } - return true; - } - else + GLenum destFormat; + GLenum destType; + ColorCopyFunction copyFunction; + + D3D11FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) + : destFormat(destFormat), destType(destType), copyFunction(copyFunction) + { } + + bool operator<(const D3D11FastCopyFormat& other) const { - return false; + return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; } -} +}; -// 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; +typedef std::multimap<DXGI_FORMAT, D3D11FastCopyFormat> D3D11FastCopyMap; -static void UnimplementedLoadFunction(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) +static D3D11FastCopyMap BuildFastCopyMap() { - UNIMPLEMENTED(); -} + D3D11FastCopyMap map; -static void UnreachableLoadFunction(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - UNREACHABLE(); -} + map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); -// 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)); + return map; } -D3D11LoadFunctionMap buildD3D11LoadFunctionMap() +struct DXGIDepthStencilInfo { - 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, LoadRGBA4ToRGBA8 ); - 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, LoadRGB5A1ToRGBA8 ); - insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, LoadRGB10A2ToRGBA8 ); - insertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, LoadToNative<GLhalf, 4> ); - insertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 4> ); - insertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, LoadToNative<GLfloat, 4> ); - insertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, Load32FTo16F<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, LoadToNative3To4<GLubyte, 0xFF> ); - 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, LoadToNative3To4<GLbyte, 0x7F> ); - insertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, LoadR5G6B5ToRGBA8 ); - 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_RGB16F, GL_HALF_FLOAT_OES, LoadToNative3To4<GLhalf, gl::Float16One>); - insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, LoadRGB16FToRG11B10F ); - insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT_OES, LoadRGB16FToRG11B10F ); - insertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, LoadRGB16FToRGB9E5 ); - insertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT_OES, LoadRGB16FToRGB9E5 ); - insertLoadFunction(&map, GL_RGB32F, GL_FLOAT, LoadToNative3To4<GLfloat, gl::Float32One>); - insertLoadFunction(&map, GL_RGB16F, GL_FLOAT, LoadRGB32FToRGBA16F ); - insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, LoadRGB32FToRG11B10F ); - insertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, LoadRGB32FToRGB9E5 ); - 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_RG16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 2> ); - insertLoadFunction(&map, GL_RG32F, GL_FLOAT, LoadToNative<GLfloat, 2> ); - insertLoadFunction(&map, GL_RG16F, GL_FLOAT, Load32FTo16F<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_R16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 1> ); - insertLoadFunction(&map, GL_R32F, GL_FLOAT, LoadToNative<GLfloat, 1> ); - insertLoadFunction(&map, GL_R16F, GL_FLOAT, Load32FTo16F<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, LoadR32ToR24G8 ); - insertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, LoadR32ToR16 ); - insertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, LoadToNative<GLfloat, 1> ); - insertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, LoadR32ToR24G8 ); - insertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadToNative<GLuint, 2> ); + unsigned int depthBits; + unsigned int depthOffset; + unsigned int stencilBits; + unsigned int stencilOffset; +}; - // 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 ); +typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap; +typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair; - // From GL_OES_texture_float - insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, LoadLA32FToRGBA32F ); - insertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, LoadL32FToRGBA32F ); - insertLoadFunction(&map, GL_ALPHA, GL_FLOAT, LoadA32FToRGBA32F ); +static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, DXGI_FORMAT format, unsigned int depthBits, + unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) +{ + DXGIDepthStencilInfo info; + info.depthBits = depthBits; + info.depthOffset = depthOffset; + info.stencilBits = stencilBits; + info.stencilOffset = stencilOffset; - // From GL_OES_texture_half_float - insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, LoadL16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); - insertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, LoadA16FToRGBA16F ); - insertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); + map->insert(std::make_pair(format, info)); +} - // From GL_EXT_texture_storage - insertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToBGRA8 ); - insertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 ); - insertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 ); - insertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F ); - insertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, LoadL32FToRGBA32F ); - insertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, LoadLA32FToRGBA32F ); - insertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, LoadA16FToRGBA16F ); - insertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, LoadL16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); - insertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); +static DepthStencilInfoMap BuildDepthStencilInfoMap() +{ + DepthStencilInfoMap map; - // From GL_ANGLE_depth_texture - insertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0, 0, 0); - // From GL_EXT_texture_format_BGRA8888 - 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, LoadRGBA4ToRGBA8 ); - 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, LoadRGB5A1ToRGBA8 ); - insertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 0, 8, 24); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 8, 24); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 0, 8, 24); - // 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 ); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0, 0, 0); - // From GL_EXT_texture_compression_dxt1 - insertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); - insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 0, 8, 32); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 8, 32); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 0, 8, 32); - // From GL_ANGLE_texture_compression_dxt3 - insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); + return map; +} - // From GL_ANGLE_texture_compression_dxt5 - insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); +typedef std::map<DXGI_FORMAT, DXGIFormat> DXGIFormatInfoMap; + +DXGIFormat::DXGIFormat() + : pixelBytes(0), + blockWidth(0), + blockHeight(0), + depthBits(0), + depthOffset(0), + stencilBits(0), + stencilOffset(0), + internalFormat(GL_NONE), + componentType(GL_NONE), + mipGenerationFunction(NULL), + colorReadFunction(NULL), + fastCopyFunctions() +{ +} - return map; +ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const +{ + FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); + return (iter != fastCopyFunctions.end()) ? iter->second : NULL; } -// A map to determine the pixel size and mipmap generation function of a given DXGI format -struct DXGIFormatInfo +void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, + GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc) { - GLuint mPixelBits; - GLuint mBlockWidth; - GLuint mBlockHeight; - GLenum mComponentType; + DXGIFormat info; + info.pixelBytes = pixelBits / 8; + info.blockWidth = blockWidth; + info.blockHeight = blockHeight; - MipGenerationFunction mMipGenerationFunction; - ColorReadFunction mColorReadFunction; + static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap(); + DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat); + if (dsInfoIter != dsInfoMap.end()) + { + info.depthBits = dsInfoIter->second.depthBits; + info.depthOffset = dsInfoIter->second.depthOffset; + info.stencilBits = dsInfoIter->second.stencilBits; + info.stencilOffset = dsInfoIter->second.stencilOffset; + } + else + { + info.depthBits = 0; + info.depthOffset = 0; + info.stencilBits = 0; + info.stencilOffset = 0; + } - DXGIFormatInfo() - : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mComponentType(GL_NONE), mMipGenerationFunction(NULL), - mColorReadFunction(NULL) - { } + static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap(); + DXGIToESFormatMap::const_iterator dxgiToESIter = dxgiToESMap.find(dxgiFormat); + info.internalFormat = (dxgiToESIter != dxgiToESMap.end()) ? dxgiToESIter->second : GL_NONE; - 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) - { } -}; + info.componentType = componentType; -typedef std::map<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoMap; + info.mipGenerationFunction = mipFunc; + info.colorReadFunction = readFunc; -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 const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); + std::pair<D3D11FastCopyMap::const_iterator, D3D11FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(dxgiFormat); + for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) + { + info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); + } + + map->insert(std::make_pair(dxgiFormat, info)); } +// A map to determine the pixel size and mipmap generation function of a given DXGI format static DXGIFormatInfoMap BuildDXGIFormatInfoMap() { DXGIFormatInfoMap map; - // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function + // | 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>); @@ -473,240 +324,38 @@ static DXGIFormatInfoMap BuildDXGIFormatInfoMap() 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 BuildDXGIToESFormatMap() -{ - 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_R32_TYPELESS, GL_DEPTH_COMPONENT32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); - - 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 const DXGIToESFormatMap &GetDXGIToESFormatMap() -{ - static const DXGIToESFormatMap map = BuildDXGIToESFormatMap(); - return map; -} - -static const DXGIFormatInfoMap &GetDXGIFormatInfoMap() +const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format) { 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; + return iter->second; } else { - return false; + static DXGIFormat defaultInfo; + return defaultInfo; } } struct SwizzleSizeType { - unsigned int mMaxComponentSize; - GLenum mComponentType; + size_t maxComponentSize; + GLenum componentType; SwizzleSizeType() - : mMaxComponentSize(0), mComponentType(GL_NONE) + : maxComponentSize(0), componentType(GL_NONE) { } - SwizzleSizeType(unsigned int maxComponentSize, GLenum componentType) - : mMaxComponentSize(maxComponentSize), mComponentType(componentType) + SwizzleSizeType(size_t maxComponentSize, GLenum componentType) + : maxComponentSize(maxComponentSize), componentType(componentType) { } bool operator<(const SwizzleSizeType& other) const { - return (mMaxComponentSize != other.mMaxComponentSize) ? (mMaxComponentSize < other.mMaxComponentSize) - : (mComponentType < other.mComponentType); + return (maxComponentSize != other.maxComponentSize) ? (maxComponentSize < other.maxComponentSize) + : (componentType < other.componentType); } }; @@ -752,6 +401,7 @@ static SwizzleInfoMap BuildSwizzleInfoMap() return map; } + typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitializerPair; typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitializerMap; @@ -774,430 +424,477 @@ static InternalFormatInitializerMap BuildInternalFormatInitializerMap() return map; } -static const SwizzleInfoMap &GetSwizzleInfoMap() +// 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, LoadImageFunction> TypeLoadFunctionPair; +typedef std::map<GLenum, std::vector<TypeLoadFunctionPair> > D3D11LoadFunctionMap; + +static void UnimplementedLoadFunction(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - static const SwizzleInfoMap map = BuildSwizzleInfoMap(); - return map; + UNIMPLEMENTED(); } -static const SwizzleFormatInfo GetSwizzleFormatInfo(GLenum internalFormat) +static void UnreachableLoadFunction(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - // Get the maximum sized component - unsigned int maxBits = 1; + UNREACHABLE(); +} - if (gl::IsFormatCompressed(internalFormat)) - { - unsigned int compressedBitsPerBlock = gl::GetPixelBytes(internalFormat) * 8; - unsigned int blockSize = gl::GetCompressedBlockWidth(internalFormat) * - gl::GetCompressedBlockHeight(internalFormat); - maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); - } - else - { - maxBits = std::max(maxBits, gl::GetAlphaBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetRedBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetGreenBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetBlueBits( internalFormat)); - maxBits = std::max(maxBits, gl::GetLuminanceBits(internalFormat)); - maxBits = std::max(maxBits, gl::GetDepthBits( internalFormat)); - } +// 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)[internalFormat].push_back(TypeLoadFunctionPair(type, loadFunc)); +} - maxBits = roundUp(maxBits, 8U); +D3D11LoadFunctionMap BuildD3D11LoadFunctionMap() +{ + D3D11LoadFunctionMap map; - GLenum componentType = gl::GetComponentType(internalFormat); + // | 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, LoadRGBA4ToRGBA8 ); + 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, LoadRGB5A1ToRGBA8 ); + InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, LoadRGB10A2ToRGBA8 ); + InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, LoadToNative<GLhalf, 4> ); + InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 4> ); + InsertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, LoadToNative<GLfloat, 4> ); + InsertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, Load32FTo16F<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, LoadToNative3To4<GLubyte, 0xFF> ); + 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, LoadToNative3To4<GLbyte, 0x7F> ); + InsertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, LoadR5G6B5ToRGBA8 ); + 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_RGB16F, GL_HALF_FLOAT_OES, LoadToNative3To4<GLhalf, gl::Float16One>); + InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, LoadRGB16FToRG11B10F ); + InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT_OES, LoadRGB16FToRG11B10F ); + InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, LoadRGB16FToRGB9E5 ); + InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT_OES, LoadRGB16FToRGB9E5 ); + InsertLoadFunction(&map, GL_RGB32F, GL_FLOAT, LoadToNative3To4<GLfloat, gl::Float32One>); + InsertLoadFunction(&map, GL_RGB16F, GL_FLOAT, LoadRGB32FToRGBA16F ); + InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, LoadRGB32FToRG11B10F ); + InsertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, LoadRGB32FToRGB9E5 ); + 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_RG16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 2> ); + InsertLoadFunction(&map, GL_RG32F, GL_FLOAT, LoadToNative<GLfloat, 2> ); + InsertLoadFunction(&map, GL_RG16F, GL_FLOAT, Load32FTo16F<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_R16F, GL_HALF_FLOAT_OES, LoadToNative<GLhalf, 1> ); + InsertLoadFunction(&map, GL_R32F, GL_FLOAT, LoadToNative<GLfloat, 1> ); + InsertLoadFunction(&map, GL_R16F, GL_FLOAT, Load32FTo16F<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, LoadR32ToR24G8 ); + InsertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, LoadR32ToR16 ); + InsertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, LoadToNative<GLfloat, 1> ); + InsertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, LoadR32ToR24G8 ); + InsertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadToNative<GLuint, 2> ); - const SwizzleInfoMap &map = GetSwizzleInfoMap(); - SwizzleInfoMap::const_iterator iter = map.find(SwizzleSizeType(maxBits, componentType)); + // 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 ); - if (iter != map.end()) - { - return iter->second; - } - else - { - UNREACHABLE(); - static const SwizzleFormatInfo defaultFormatInfo; - return defaultFormatInfo; - } -} + // From GL_OES_texture_float + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, LoadLA32FToRGBA32F ); + InsertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, LoadL32FToRGBA32F ); + InsertLoadFunction(&map, GL_ALPHA, GL_FLOAT, LoadA32FToRGBA32F ); -static const InternalFormatInitializerMap &GetInternalFormatInitializerMap() -{ - static const InternalFormatInitializerMap map = BuildInternalFormatInitializerMap(); - return map; -} + // From GL_OES_texture_half_float + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, LoadL16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); + InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, LoadA16FToRGBA16F ); + InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); -namespace d3d11 -{ + // From GL_EXT_texture_storage + InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8 ); + InsertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 ); + InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 ); + InsertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F ); + InsertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, LoadL32FToRGBA32F ); + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, LoadLA32FToRGBA32F ); + InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, LoadA16FToRGBA16F ); + InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, LoadL16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); + InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); -MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format) -{ - DXGIFormatInfo formatInfo; - if (GetDXGIFormatInfo(format, &formatInfo)) - { - return formatInfo.mMipGenerationFunction; - } - else - { - UNREACHABLE(); - return NULL; - } -} + // From GL_ANGLE_depth_texture + InsertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 ); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type) -{ - 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; - } -} + // From GL_EXT_texture_format_BGRA8888 + 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, LoadRGBA4ToRGBA8 ); + 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, LoadRGB5A1ToRGBA8 ); + InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 4> ); -GLuint GetFormatPixelBytes(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mPixelBits / 8; - } - else - { - UNREACHABLE(); - return 0; - } -} + // 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 ); -GLuint GetBlockWidth(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mBlockWidth; - } - else - { - UNREACHABLE(); - return 0; - } -} + // From GL_EXT_texture_compression_dxt1 + InsertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); + InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); -GLuint GetBlockHeight(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mBlockHeight; - } - else - { - UNREACHABLE(); - return 0; - } -} + // From GL_ANGLE_texture_compression_dxt3 + InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); -GLenum GetComponentType(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) - { - return dxgiFormatInfo.mComponentType; - } - else - { - UNREACHABLE(); - return GL_NONE; - } -} + // From GL_ANGLE_texture_compression_dxt5 + InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); -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; - } + return map; } -GLuint GetDepthOffset(DXGI_FORMAT format) +// 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::map<GLenum, TextureFormat> D3D11ES3FormatMap; + +TextureFormat::TextureFormat() + : texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + renderFormat(DXGI_FORMAT_UNKNOWN), + swizzleTexFormat(DXGI_FORMAT_UNKNOWN), + swizzleSRVFormat(DXGI_FORMAT_UNKNOWN), + swizzleRTVFormat(DXGI_FORMAT_UNKNOWN), + dataInitializerFunction(NULL), + loadFunctions() { - 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) +static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) { - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) + TextureFormat info; + info.texFormat = texFormat; + info.srvFormat = srvFormat; + info.rtvFormat = rtvFormat; + info.dsvFormat = dsvFormat; + + // Given a GL internal format, the renderFormat is the DSV format if it is depth- or stencil-renderable, + // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise. + if (dsvFormat != DXGI_FORMAT_UNKNOWN) { - return dxgiDSInfo.mStencilBits; + info.renderFormat = dsvFormat; } - else + else if (rtvFormat != DXGI_FORMAT_UNKNOWN) { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; + info.renderFormat = rtvFormat; } -} - -GLuint GetStencilOffset(DXGI_FORMAT format) -{ - DXGIDepthStencilInfo dxgiDSInfo; - if (GetDepthStencilInfo(format, &dxgiDSInfo)) + else if (texFormat != DXGI_FORMAT_UNKNOWN) { - return dxgiDSInfo.mStencilOffset; + info.renderFormat = texFormat; } else { - // Since the depth stencil info map does not contain all used DXGI formats, - // we should not assert that the format exists - return 0; + info.renderFormat = DXGI_FORMAT_UNKNOWN; } -} -void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + // Compute the swizzle formats + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0) { - 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) + if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN || + srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN) { - while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) + // Get the maximum sized component + unsigned int maxBits = 1; + if (formatInfo.compressed) + { + unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8; + unsigned int blockSize = formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight; + maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); + } + else { - *requestWidth <<= 1; - *requestHeight <<= 1; - upsampleCount++; + maxBits = std::max(maxBits, formatInfo.alphaBits); + maxBits = std::max(maxBits, formatInfo.redBits); + maxBits = std::max(maxBits, formatInfo.greenBits); + maxBits = std::max(maxBits, formatInfo.blueBits); + maxBits = std::max(maxBits, formatInfo.luminanceBits); + maxBits = std::max(maxBits, formatInfo.depthBits); } + + maxBits = roundUp(maxBits, 8U); + + static const SwizzleInfoMap swizzleMap = BuildSwizzleInfoMap(); + SwizzleInfoMap::const_iterator swizzleIter = swizzleMap.find(SwizzleSizeType(maxBits, formatInfo.componentType)); + ASSERT(swizzleIter != swizzleMap.end()); + + const SwizzleFormatInfo &swizzleInfo = swizzleIter->second; + info.swizzleTexFormat = swizzleInfo.mTexFormat; + info.swizzleSRVFormat = swizzleInfo.mSRVFormat; + info.swizzleRTVFormat = swizzleInfo.mRTVFormat; + } + else + { + // The original texture format is suitable for swizzle operations + info.swizzleTexFormat = texFormat; + info.swizzleSRVFormat = srvFormat; + info.swizzleRTVFormat = rtvFormat; } - *levelOffset = upsampleCount; } else { - UNREACHABLE(); + // Not possible to swizzle with this texture format since it is either unsized or GL_NONE + info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN; + info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN; + info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN; } -} -const DXGIFormatSet &GetAllUsedDXGIFormats() -{ - static DXGIFormatSet formatSet = BuildAllDXGIFormatSet(); - return formatSet; -} + // Check if there is an initialization function for this texture format + static const InternalFormatInitializerMap initializerMap = BuildInternalFormatInitializerMap(); + InternalFormatInitializerMap::const_iterator initializerIter = initializerMap.find(internalFormat); + info.dataInitializerFunction = (initializerIter != initializerMap.end()) ? initializerIter->second : NULL; -ColorReadFunction GetColorReadFunction(DXGI_FORMAT format) -{ - DXGIFormatInfo dxgiFormatInfo; - if (GetDXGIFormatInfo(format, &dxgiFormatInfo)) + // Gather all the load functions for this internal format + static const D3D11LoadFunctionMap loadFunctions = BuildD3D11LoadFunctionMap(); + D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat); + if (loadFunctionIter != loadFunctions.end()) { - return dxgiFormatInfo.mColorReadFunction; - } - else - { - UNREACHABLE(); - return NULL; + const std::vector<TypeLoadFunctionPair> &loadFunctionVector = loadFunctionIter->second; + for (size_t i = 0; i < loadFunctionVector.size(); i++) + { + GLenum type = loadFunctionVector[i].first; + LoadImageFunction function = loadFunctionVector[i].second; + info.loadFunctions.insert(std::make_pair(type, function)); + } } -} - -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; -} + map->insert(std::make_pair(internalFormat, info)); } -namespace gl_d3d11 +static D3D11ES3FormatMap BuildD3D11FormatMap() { + D3D11ES3FormatMap map; -DXGI_FORMAT GetTexFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mTexFormat; - } - else - { - UNREACHABLE(); - return DXGI_FORMAT_UNKNOWN; - } -} + // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | + InsertD3D11FormatInfo(&map, GL_NONE, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R8, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG8, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB565, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA4, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB5_A1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB10_A2, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB10_A2UI, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_SRGB8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_SRGB8_ALPHA8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R16F, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG16F, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R32F, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG32F, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R11F_G11F_B10F, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB9_E5, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R8I, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R8UI, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R16I, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R16UI, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R32I, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_R32UI, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG8I, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG8UI, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG16I, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG16UI, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG32I, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RG32UI, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN); -DXGI_FORMAT GetSRVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mSRVFormat; - } - else - { - UNREACHABLE(); - return DXGI_FORMAT_UNKNOWN; - } -} + // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format? + InsertD3D11FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_LUMINANCE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGB, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_RGBA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_BGRA_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN); -DXGI_FORMAT GetRTVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mRTVFormat; - } - else - { - UNREACHABLE(); - return DXGI_FORMAT_UNKNOWN; - } -} + // From GL_EXT_texture_storage + // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | + InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_BGRA8_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_BGRA4_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_BGR5_A1_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); -DXGI_FORMAT GetDSVFormat(GLenum internalFormat) -{ - D3D11FormatInfo d3d11FormatInfo; - if (GetD3D11FormatInfo(internalFormat, &d3d11FormatInfo)) - { - return d3d11FormatInfo.mDSVFormat; - } - else - { - return DXGI_FORMAT_UNKNOWN; - } -} + // Depth stencil formats + InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM ); + InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); + InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT ); + InsertD3D11FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); + InsertD3D11FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + InsertD3D11FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); -// 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) -{ - DXGI_FORMAT targetFormat = GetDSVFormat(internalFormat); - if (targetFormat == DXGI_FORMAT_UNKNOWN) - targetFormat = GetRTVFormat(internalFormat); - if (targetFormat == DXGI_FORMAT_UNKNOWN) - targetFormat = GetTexFormat(internalFormat); + // From GL_ANGLE_depth_texture + // Since D3D11 doesn't have a D32_UNORM format, use D24S8 which has comparable precision and matches the ES3 format. + InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT); - return targetFormat; -} + // 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 | + InsertD3D11FormatInfo(&map, GL_COMPRESSED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); -DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mTexFormat; - } - else - { - return GetTexFormat(internalFormat); - } -} + // From GL_EXT_texture_compression_dxt1 + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); -DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mSRVFormat; - } - else - { - return GetSRVFormat(internalFormat); - } -} + // From GL_ANGLE_texture_compression_dxt3 + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); -DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat) -{ - if (GetRTVFormat(internalFormat) == DXGI_FORMAT_UNKNOWN || gl::GetComponentCount(internalFormat) != 4) - { - const SwizzleFormatInfo &swizzleInfo = GetSwizzleFormatInfo(internalFormat); - return swizzleInfo.mRTVFormat; - } - else - { - return GetRTVFormat(internalFormat); - } -} + // From GL_ANGLE_texture_compression_dxt5 + InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); -bool RequiresTextureDataInitialization(GLint internalFormat) -{ - const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); - return map.find(internalFormat) != map.end(); + return map; } -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat) { - const InternalFormatInitializerMap &map = GetInternalFormatInitializerMap(); - InternalFormatInitializerMap::const_iterator iter = map.find(internalFormat); - if (iter != map.end()) + static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap(); + D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) { return iter->second; } else { - UNREACHABLE(); - return NULL; + static const TextureFormat defaultInfo; + return defaultInfo; } } -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, VertexFormat> D3D11VertexFormatInfoMap; +typedef std::pair<gl::VertexFormat, VertexFormat> D3D11VertexFormatPair; -typedef std::map<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatInfoMap; - -typedef std::pair<gl::VertexFormat, D3D11VertexFormatInfo> D3D11VertexFormatPair; +VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), + nativeFormat(DXGI_FORMAT_UNKNOWN), + copyFunction(NULL) +{ +} -static void addVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount, +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))); + + VertexFormat info; + info.conversionType = conversionType; + info.nativeFormat = nativeFormat; + info.copyFunction = copyFunction; + + map->insert(D3D11VertexFormatPair(inputFormat, info)); } -static void addIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount, +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))); + + VertexFormat info; + info.conversionType = conversionType; + info.nativeFormat = nativeFormat; + info.copyFunction = copyFunction; + + map->insert(D3D11VertexFormatPair(inputFormat, info)); } static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() @@ -1211,245 +908,165 @@ static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() // // 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>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>); + AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 0>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, INT8_MAX>); + AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, UINT8_MAX>); + AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 1>); + AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 0>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, INT16_MAX>); + AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, UINT16_MAX>); + AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>); + AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, true>); + AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 0>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<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>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3>); + AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<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>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 0>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 0>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, gl::Float16One>); + AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 0>); + AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<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>); + AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, false, true>); + AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<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); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<false, false, true>); + AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData<GLuint, 1, 0>); // // 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>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>); + AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 0>); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<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>); + AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData<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); + AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 0>); return map; } -static bool GetD3D11VertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D11VertexFormatInfo *outVertexFormatInfo) +const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat) { 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) -{ - const DXGIToESFormatMap &formatMap = GetDXGIToESFormatMap(); - DXGIToESFormatMap::const_iterator iter = formatMap.find(format); - if (iter != formatMap.end()) - { return iter->second; } else { - UNREACHABLE(); - return GL_NONE; + static const VertexFormat defaultInfo; + return defaultInfo; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h index d77fccfe9c..ea11aaa74c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h @@ -12,65 +12,70 @@ #include "libGLESv2/formatutils.h" +#include <map> + namespace rx { -class Renderer; - namespace d3d11 { -typedef std::set<DXGI_FORMAT> DXGIFormatSet; +typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap; -MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat, GLenum type); +struct DXGIFormat +{ + DXGIFormat(); -GLuint GetFormatPixelBytes(DXGI_FORMAT format); -GLuint GetBlockWidth(DXGI_FORMAT format); -GLuint GetBlockHeight(DXGI_FORMAT format); -GLenum GetComponentType(DXGI_FORMAT format); + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; -GLuint GetDepthBits(DXGI_FORMAT format); -GLuint GetDepthOffset(DXGI_FORMAT format); -GLuint GetStencilBits(DXGI_FORMAT format); -GLuint GetStencilOffset(DXGI_FORMAT format); + GLuint depthBits; + GLuint depthOffset; + GLuint stencilBits; + GLuint stencilOffset; -void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + GLenum internalFormat; + GLenum componentType; -const DXGIFormatSet &GetAllUsedDXGIFormats(); + MipGenerationFunction mipGenerationFunction; + ColorReadFunction colorReadFunction; -ColorReadFunction GetColorReadFunction(DXGI_FORMAT format); -ColorCopyFunction GetFastCopyFunction(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType); + FastCopyFunctionMap fastCopyFunctions; + ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; +}; +const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format); -} - -namespace gl_d3d11 +struct TextureFormat { + TextureFormat(); -DXGI_FORMAT GetTexFormat(GLenum internalFormat); -DXGI_FORMAT GetSRVFormat(GLenum internalFormat); -DXGI_FORMAT GetRTVFormat(GLenum internalFormat); -DXGI_FORMAT GetDSVFormat(GLenum internalFormat); -DXGI_FORMAT GetRenderableFormat(GLenum internalFormat); - -DXGI_FORMAT GetSwizzleTexFormat(GLint internalFormat); -DXGI_FORMAT GetSwizzleSRVFormat(GLint internalFormat); -DXGI_FORMAT GetSwizzleRTVFormat(GLint internalFormat); + DXGI_FORMAT texFormat; + DXGI_FORMAT srvFormat; + DXGI_FORMAT rtvFormat; + DXGI_FORMAT dsvFormat; + DXGI_FORMAT renderFormat; -bool RequiresTextureDataInitialization(GLint internalFormat); -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + DXGI_FORMAT swizzleTexFormat; + DXGI_FORMAT swizzleSRVFormat; + DXGI_FORMAT swizzleRTVFormat; -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); + InitializeTextureDataFunction dataInitializerFunction; -} + typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap; + LoadFunctionMap loadFunctions; +}; +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat); -namespace d3d11_gl +struct VertexFormat { + VertexFormat(); -GLenum GetInternalFormat(DXGI_FORMAT format); + VertexConversionType conversionType; + DXGI_FORMAT nativeFormat; + VertexCopyFunction copyFunction; +}; +const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp index d914a8201b..2af97e73f0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -10,8 +9,14 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Framebuffer.h" + #include "common/debug.h" +#include <algorithm> + #ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY # define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2 #endif @@ -21,6 +26,12 @@ #ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT # define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 #endif +#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT +# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535 +#endif +#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT +# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575 +#endif #ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION # define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512 #endif @@ -45,6 +56,48 @@ #ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION # define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 #endif +#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP +# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 +#endif +#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP +# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 +#endif +#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT +# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 +#endif +#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT +# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 +#endif +#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT +# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 +#endif +#ifndef D3D11_SO_BUFFER_SLOT_COUNT +# define D3D11_SO_BUFFER_SLOT_COUNT 4 +#endif +#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT +# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 +#endif +#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT +# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 +#endif +#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE +# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 +#endif +#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE +# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 +#endif +#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT +# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 +#endif +#ifndef D3D11_PS_INPUT_REGISTER_COUNT +# define D3D11_PS_INPUT_REGISTER_COUNT 32 +#endif +#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT +# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 +#endif +#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT +# define D3D11_VS_OUTPUT_REGISTER_COUNT 32 +#endif namespace rx { @@ -258,16 +311,13 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De { gl::TextureCaps textureCaps; - DXGI_FORMAT textureFormat = gl_d3d11::GetTexFormat(internalFormat); - DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat); - DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat); - DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat); - DXGI_FORMAT renderFormat = gl_d3d11::GetRenderableFormat(internalFormat); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); UINT formatSupport; - if (SUCCEEDED(device->CheckFormatSupport(textureFormat, &formatSupport))) + if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport))) { - if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); } @@ -279,13 +329,13 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De } } - if (SUCCEEDED(device->CheckFormatSupport(renderFormat, &formatSupport)) && + if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)) { for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) { UINT qualityCount = 0; - if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, &qualityCount)) && + if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) && qualityCount > 0) { textureCaps.sampleCounts.insert(sampleCount); @@ -293,11 +343,11 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11De } } - textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(srvFormat, &formatSupport)) && + textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0; - textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(rtvFormat, &formatSupport)) && + textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) || - (SUCCEEDED(device->CheckFormatSupport(dsvFormat, &formatSupport)) && + (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) && ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0)); return textureCaps; @@ -317,7 +367,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; + case D3D_FEATURE_LEVEL_9_1: return true; // Provided that mipmaps & wrap modes are not used default: UNREACHABLE(); return false; } @@ -441,9 +491,8 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 1; /* D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; */ + case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; case D3D_FEATURE_LEVEL_9_2: @@ -554,13 +603,412 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) } } +static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's + // returned from glGetInteger + META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's + // returned from glGetInteger + META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; + case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; + + // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots" + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 16; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 255; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedVertexUniformBuffers() +{ + // Reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); + + // Uniform blocks not supported in D3D9 feature levels + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedVertexOutputVectors() +{ + // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize + return 4; +} + +static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + // Use D3D9 SM3 and SM2 limits + case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // Vertex textures not supported in D3D9 feature levels according to + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 32; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetReservedPixelUniformBuffers() +{ + // Reserve one buffer for the application uniforms, and one for driver uniforms + return 2; +} + +static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); + + // Uniform blocks not supported in D3D9 feature levels + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); + + // Use D3D9 SM3 and SM2 limits + case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 16; + + default: UNREACHABLE(); return 0; + } +} + +static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) +{ + // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of + // any buffer that could be allocated. + + const size_t bytesPerComponent = 4 * sizeof(float); + + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + 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; + + // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 4096 * bytesPerComponent; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + 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; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return GetMaximumVertexOutputVectors(featureLevel) * 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + +static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { +#if _MSC_VER >= 1700 + case D3D_FEATURE_LEVEL_11_1: +#endif + case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / + GetMaximumStreamOutputBuffers(featureLevel); + + + // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used. + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return 0; + + default: UNREACHABLE(); return 0; + } +} + void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) { + GLuint maxSamples = 0; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) { gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device); textureCapsMap->insert(*internalFormat, textureCaps); + + maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); + + if (gl::GetInternalFormatInfo(*internalFormat).compressed) + { + caps->compressedTextureFormats.push_back(*internalFormat); + } } D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel(); @@ -595,6 +1043,54 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text caps->minAliasedLineWidth = 1.0f; caps->maxAliasedLineWidth = 1.0f; + // Primitive count limits + caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); + caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + // We do not wait for server fence objects internally, so report a max timeout of zero. + caps->maxServerWaitTimeout = 0; + + // Vertex shader limits + caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel); + caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4; + caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel); + caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel); + caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; + caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel); + + // Fragment shader limits + caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4; + caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel); + caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel); + caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4; + caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel); + caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); + caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); + + // Aggregate shader limits + caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks; + caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel); + + // Setting a large alignment forces uniform buffers to bind with zero offset + caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max()); + + caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks; + caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) + + static_cast<GLint64>(caps->maxVertexUniformComponents); + caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) + + static_cast<GLint64>(caps->maxFragmentUniformComponents); + caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; + caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel); + caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel); + caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); + caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel); + // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = true; @@ -617,6 +1113,7 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; + extensions->maxSamples = maxSamples; extensions->instancedArrays = GetInstancingSupport(featureLevel); extensions->packReverseRowOrder = true; extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel); @@ -631,12 +1128,33 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text namespace d3d11 { +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) || + *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight)) + { + while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; +} + void GenerateInitialTextureData(GLint internalFormat, 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); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat); + ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat); outSubresourceData->resize(mipLevels); outData->resize(mipLevels); @@ -647,11 +1165,11 @@ void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint heigh 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 rowWidth = dxgiFormatInfo.pixelBytes * mipWidth; unsigned int imageSize = rowWidth * height; outData->at(i).resize(rowWidth * mipHeight * mipDepth); - initializeFunc(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); + d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); outSubresourceData->at(i).pSysMem = outData->at(i).data(); outSubresourceData->at(i).SysMemPitch = rowWidth; @@ -687,6 +1205,12 @@ HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) #endif } +RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +{ + RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); + return RenderTarget11::makeRenderTarget11(renderTarget); +} + } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h index 4de9bfa86d..4c05eb9256 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h @@ -13,8 +13,16 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include <vector> + +namespace gl +{ +class FramebufferAttachment; +} + namespace rx { +class RenderTarget11; namespace gl_d3d11 { @@ -47,6 +55,8 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text namespace d3d11 { +void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth, GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, std::vector< std::vector<BYTE> > *outData); @@ -166,6 +176,8 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu context->Unmap(constantBuffer, 0); } +RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); + } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp index f486e5a4cc..f061a32c52 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,8 +7,6 @@ // Blit9.cpp: Surface copy utility class. #include "libGLESv2/renderer/d3d/d3d9/Blit9.h" - -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" @@ -17,9 +14,11 @@ #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/main.h" namespace { +// Precompiled shaders #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h" #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h" #include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h" @@ -209,7 +208,7 @@ bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) return true; } -bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; @@ -217,9 +216,9 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { source = renderTarget->getSurface(); @@ -231,10 +230,10 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); bool result = false; - + if (destSurface) { result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); @@ -245,7 +244,7 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return result; } -bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RenderTarget9 *renderTarget = NULL; IDirect3DSurface9 *source = NULL; @@ -253,9 +252,9 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { source = renderTarget->getSurface(); @@ -267,7 +266,7 @@ bool Blit9::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum de return gl::error(GL_OUT_OF_MEMORY, false); } - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); bool result = false; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h index 3635bca932..46a3ee1cf3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h @@ -11,6 +11,8 @@ #include "common/angleutils.h" +#include <GLES2/gl2.h> + namespace gl { class Framebuffer; @@ -19,8 +21,7 @@ class Framebuffer; namespace rx { class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; +class TextureStorage; class Blit9 { @@ -30,8 +31,8 @@ class Blit9 // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); + bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp index 347bde0c65..c02db515a2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -8,8 +7,8 @@ // Buffer9.cpp Defines the Buffer9 class. #include "libGLESv2/renderer/d3d/d3d9/Buffer9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" namespace rx { @@ -18,13 +17,11 @@ Buffer9::Buffer9(rx::Renderer9 *renderer) : BufferD3D(), mRenderer(renderer), mSize(0) -{ - -} +{} Buffer9::~Buffer9() { - + mSize = 0; } Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) @@ -33,18 +30,13 @@ Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) return static_cast<Buffer9*>(buffer); } -void Buffer9::clear() -{ - mSize = 0; -} - -void Buffer9::setData(const void* data, size_t size, GLenum usage) +gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) { if (size > mMemory.size()) { if (!mMemory.resize(size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -54,14 +46,14 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - mIndexRangeCache.clear(); - invalidateStaticData(); if (usage == GL_STATIC_DRAW) { initializeStaticData(); } + + return gl::Error(GL_NO_ERROR); } void *Buffer9::getData() @@ -69,13 +61,13 @@ void *Buffer9::getData() return mMemory.data(); } -void Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) { if (offset + size > mMemory.size()) { if (!mMemory.resize(offset + size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -85,32 +77,35 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset) memcpy(mMemory.data() + offset, data, size); } - mIndexRangeCache.invalidateRange(offset, size); - invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { + // Note: this method is currently unreachable Buffer9* sourceBuffer = makeBuffer9(source); - if (sourceBuffer) - { - memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - } + ASSERT(sourceBuffer); + + memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -// We do not suppot buffer mapping in D3D9 -GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access) +// We do not support buffer mapping in D3D9 +gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } -void Buffer9::unmap() +gl::Error Buffer9::unmap() { UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } void Buffer9::markTransformFeedbackUsage() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h index ec25ec30c9..e78182f905 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h @@ -27,17 +27,16 @@ class Buffer9 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } - virtual void clear(); virtual bool supportsDirectBinding() const { return false; } virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + virtual gl::Error setSubData(const void* data, size_t size, size_t offset); + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(); virtual void markTransformFeedbackUsage(); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp index d2437cadf3..e352a5f50a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp @@ -1,4 +1,3 @@ -#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 @@ -8,9 +7,9 @@ // Fence9.cpp: Defines the rx::Fence9 class. #include "libGLESv2/renderer/d3d/d3d9/Fence9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp index e237c3b6e1..18383fba78 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp @@ -1,5 +1,3 @@ - -#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 @@ -10,17 +8,16 @@ // the actual underlying surfaces of a Texture. #include "libGLESv2/renderer/d3d/d3d9/Image9.h" - +#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" #include "libGLESv2/main.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" -#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" -#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" -#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" -#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" namespace rx { @@ -53,8 +50,8 @@ 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); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + ASSERT(d3dFormatInfo.mipGenerationFunction != NULL); D3DLOCKED_RECT sourceLocked = {0}; result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); @@ -69,8 +66,8 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour if (sourceData && destData) { - mipFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); + d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, + destData, destLocked.Pitch, 0); } destSurface->UnlockRect(); @@ -99,22 +96,23 @@ void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *so { D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT destLock = {0}; - + source->LockRect(&sourceLock, NULL, 0); dest->LockRect(&destLock, NULL, 0); - + if (sourceLock.pBits && destLock.pBits) { D3DSURFACE_DESC desc; source->GetDesc(&desc); - int blockHeight = d3d9::GetBlockHeight(desc.Format); - int rows = desc.Height / blockHeight; + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; - int bytes = d3d9::GetBlockSize(desc.Format, desc.Width, blockHeight); - ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); + unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); + ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) && + bytes <= static_cast<unsigned int>(destLock.Pitch)); - for(int i = 0; i < rows; i++) + for(unsigned int i = 0; i < rows; i++) { memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); } @@ -147,12 +145,14 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform mInternalFormat = internalformat; // compute the d3d format that will be used - mD3DFormat = gl_d3d9::GetTextureFormat(internalformat); - mActualFormat = d3d9_gl::GetInternalFormat(mD3DFormat); - mRenderable = gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN; + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat); + mD3DFormat = d3d9FormatInfo.texFormat; + mActualFormat = d3dFormatInfo.internalFormat; + mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN); SafeRelease(mSurface); - mDirty = gl_d3d9::RequiresTextureDataInitialization(mInternalFormat); + mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL); return true; } @@ -194,10 +194,9 @@ void Image9::createSurface() newTexture->GetSurfaceLevel(levelToFetch, &newSurface); SafeRelease(newTexture); - if (gl_d3d9::RequiresTextureDataInitialization(mInternalFormat)) + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + if (d3dFormatInfo.dataInitializerFunction != NULL) { - InitializeTextureDataFunction initializeFunc = gl_d3d9::GetTextureDataInitializationFunction(mInternalFormat); - RECT entireRect; entireRect.left = 0; entireRect.right = mWidth; @@ -208,7 +207,8 @@ void Image9::createSurface() result = newSurface->LockRect(&lockedRect, &entireRect, 0); ASSERT(SUCCEEDED(result)); - initializeFunc(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits), lockedRect.Pitch, 0); + d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits), + lockedRect.Pitch, 0); result = newSurface->UnlockRect(); ASSERT(SUCCEEDED(result)); @@ -260,7 +260,7 @@ 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; + return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty; } IDirect3DSurface9 *Image9::getSurface() @@ -270,15 +270,15 @@ IDirect3DSurface9 *Image9::getSurface() return mSurface; } -void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level) +void Image9::setManagedSurface2D(TextureStorage *storage, int level) { - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); setManagedSurface(storage9->getSurfaceLevel(level, false)); } -void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) +void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) { - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); } @@ -301,28 +301,28 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) } } -bool Image9::copyToStorage(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { ASSERT(getSurface() != NULL); - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); } -bool Image9::copyToStorage(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +bool Image9::copyToStorageCube(TextureStorage *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()); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); 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) +bool Image9::copyToStorage3D(TextureStorage *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) +bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); @@ -368,7 +368,7 @@ bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint } else { - // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + // 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)); @@ -387,10 +387,11 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, type, width, unpackAlignment); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); - LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); - ASSERT(loadFunction != NULL); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); + ASSERT(d3dFormatInfo.loadFunction != NULL); RECT lockRect = { @@ -405,9 +406,9 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width return; } - loadFunction(width, height, depth, - reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, - reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); + d3dFormatInfo.loadFunction(width, height, depth, + reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0, + reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); unlock(); } @@ -418,14 +419,16 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); - GLsizei inputRowPitch = gl::GetRowPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, 1); - GLsizei inputDepthPitch = gl::GetDepthPitch(mInternalFormat, GL_UNSIGNED_BYTE, width, height, 1); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1); - ASSERT(xoffset % d3d9::GetBlockWidth(mD3DFormat) == 0); - ASSERT(yoffset % d3d9::GetBlockHeight(mD3DFormat) == 0); + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - LoadImageFunction loadFunction = d3d9::GetImageLoadFunction(mInternalFormat); - ASSERT(loadFunction != NULL); + ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0); + ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0); + + ASSERT(d3d9FormatInfo.loadFunction != NULL); RECT lockRect = { @@ -440,9 +443,9 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs return; } - loadFunction(width, height, depth, - reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch, - reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); + d3d9FormatInfo.loadFunction(width, height, depth, + reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch, + reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0); unlock(); } @@ -459,9 +462,9 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } - + if (renderTarget) { surface = renderTarget->getSurface(); @@ -478,7 +481,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, IDirect3DSurface9 *renderTargetData = NULL; D3DSURFACE_DESC description; surface->GetDesc(&description); - + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); if (FAILED(result)) @@ -514,7 +517,7 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, D3DLOCKED_RECT destLock = {0}; result = lock(&destLock, &destRect); - + if (FAILED(result)) { ERR("Failed to lock the destination surface (rectangle might be invalid)."); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h index 2d1536f24b..08d8ee3545 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h @@ -22,8 +22,6 @@ namespace rx { class Renderer; class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; class Image9 : public ImageD3D { @@ -44,12 +42,12 @@ class Image9 : public ImageD3D virtual bool isDirty() const; IDirect3DSurface9 *getSurface(); - virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); - virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level); - 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 setManagedSurface2D(TextureStorage *storage, int level); + virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level); + virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + virtual bool copyToStorage2DArray(TextureStorage *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); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp index 472e6981a8..1c51b9e985 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -26,7 +25,7 @@ IndexBuffer9::~IndexBuffer9() SafeRelease(mIndexBuffer); } -bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { SafeRelease(mIndexBuffer); @@ -34,28 +33,17 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy if (bufferSize > 0) { - D3DFORMAT format; + D3DFORMAT format = D3DFMT_UNKNOWN; if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE) { format = D3DFMT_INDEX16; } else if (indexType == GL_UNSIGNED_INT) { - if (mRenderer->getRendererExtensions().elementIndexUint) - { - format = D3DFMT_INDEX32; - } - else - { - ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices."); - return false; - } - } - else - { - ERR("Invalid index type %u.", indexType); - return false; + ASSERT(mRenderer->getRendererExtensions().elementIndexUint); + format = D3DFMT_INDEX32; } + else UNREACHABLE(); DWORD usageFlags = D3DUSAGE_WRITEONLY; if (dynamic) @@ -66,8 +54,7 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); if (FAILED(result)) { - ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); } } @@ -75,7 +62,7 @@ bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dy mIndexType = indexType; mDynamic = dynamic; - return true; + return gl::Error(GL_NO_ERROR); } IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) @@ -84,48 +71,40 @@ IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) return static_cast<IndexBuffer9*>(indexBuffer); } -bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { - if (mIndexBuffer) + if (!mIndexBuffer) { - DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - void *mapPtr = NULL; - HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); - if (FAILED(result)) - { - ERR("Index buffer lock failed with error 0x%08x", result); - return false; - } + DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; - *outMappedMemory = mapPtr; - return true; - } - else + void *mapPtr = NULL; + HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); } + + *outMappedMemory = mapPtr; + return gl::Error(GL_NO_ERROR); } -bool IndexBuffer9::unmapBuffer() +gl::Error IndexBuffer9::unmapBuffer() { - if (mIndexBuffer) + if (!mIndexBuffer) { - HRESULT result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Index buffer unlock failed with error 0x%08x", result); - return false; - } - - return true; + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); } - else + + HRESULT result = mIndexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); } + + return gl::Error(GL_NO_ERROR); } GLenum IndexBuffer9::getIndexType() const @@ -138,7 +117,7 @@ unsigned int IndexBuffer9::getBufferSize() const return mBufferSize; } -bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) +gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) { if (bufferSize > mBufferSize || indexType != mIndexType) { @@ -146,38 +125,33 @@ bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool IndexBuffer9::discard() +gl::Error IndexBuffer9::discard() { - if (mIndexBuffer) + if (!mIndexBuffer) { - void *dummy; - HRESULT result; - - result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + } - result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } + void *dummy; + HRESULT result; - return true; + result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); } - else + + result = mIndexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Index buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); } + + return gl::Error(GL_NO_ERROR); } D3DFORMAT IndexBuffer9::getIndexFormat() const @@ -196,4 +170,4 @@ IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const return mIndexBuffer; } -}
\ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h index cfc20e1c64..d0970d6ac5 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h @@ -21,18 +21,18 @@ class IndexBuffer9 : public IndexBuffer explicit IndexBuffer9(Renderer9 *const renderer); virtual ~IndexBuffer9(); - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer); - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); + virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual gl::Error unmapBuffer(); virtual GLenum getIndexType() const; virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); + virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); - virtual bool discard(); + virtual gl::Error discard(); D3DFORMAT getIndexFormat() const; IDirect3DIndexBuffer9 *getBuffer() const; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp index 3c6f1d0d43..815fc01a9b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp @@ -1,4 +1,3 @@ -#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 @@ -7,19 +6,22 @@ // Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. - #include "libGLESv2/renderer/d3d/d3d9/Query9.h" -#include "libGLESv2/main.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/main.h" + +#include <GLES2/gl2ext.h> namespace rx { - -Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) +Query9::Query9(rx::Renderer9 *renderer, GLenum type) + : QueryImpl(type), + mResult(GL_FALSE), + mQueryFinished(false), + mRenderer(renderer), + mQuery(NULL) { - mRenderer = renderer; - mQuery = NULL; } Query9::~Query9() @@ -27,73 +29,91 @@ Query9::~Query9() SafeRelease(mQuery); } -void Query9::begin() +gl::Error Query9::begin() { if (mQuery == NULL) { - if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) + HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); } } HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to begin internal query, result: 0x%X.", result); + } + + return gl::Error(GL_NO_ERROR); } -void Query9::end() +gl::Error Query9::end() { ASSERT(mQuery); HRESULT result = mQuery->Issue(D3DISSUE_END); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result); + } - mStatus = GL_FALSE; + mQueryFinished = false; mResult = GL_FALSE; + + return gl::Error(GL_NO_ERROR); } -GLuint Query9::getResult() +gl::Error Query9::getResult(GLuint *params) { - if (mQuery != NULL) + while (!mQueryFinished) { - while (!testQuery()) + gl::Error error = testQuery(); + if (error.isError()) + { + return error; + } + + if (!mQueryFinished) { Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } } } - return mResult; + ASSERT(mQueryFinished); + *params = mResult; + + return gl::Error(GL_NO_ERROR); } -GLboolean Query9::isResultAvailable() +gl::Error Query9::isResultAvailable(GLuint *available) { - if (mQuery != NULL) + gl::Error error = testQuery(); + if (error.isError()) { - testQuery(); + return error; } - return mStatus; + *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + + return gl::Error(GL_NO_ERROR); } -GLboolean Query9::testQuery() +gl::Error Query9::testQuery() { - if (mQuery != NULL && mStatus != GL_TRUE) + if (!mQueryFinished) { + ASSERT(mQuery); + DWORD numPixels = 0; HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); if (hres == S_OK) { - mStatus = GL_TRUE; + mQueryFinished = true; switch (getType()) { @@ -101,25 +121,24 @@ GLboolean Query9::testQuery() case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; break; + default: - ASSERT(false); + UNREACHABLE(); + break; } } else if (d3d9::isDeviceLostError(hres)) { mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + } + else if (mRenderer->testDeviceLost(true)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); } - - return mStatus; } - return GL_TRUE; // prevent blocking when query is null -} - -bool Query9::isStarted() const -{ - return (mQuery != NULL); + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h index 62906230c4..513e0ba6fd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h @@ -21,16 +21,18 @@ class Query9 : public QueryImpl Query9(rx::Renderer9 *renderer, GLenum type); virtual ~Query9(); - virtual void begin(); - virtual void end(); - virtual GLuint getResult(); - virtual GLboolean isResultAvailable(); - virtual bool isStarted() const; + virtual gl::Error begin(); + virtual gl::Error end(); + virtual gl::Error getResult(GLuint *params); + virtual gl::Error isResultAvailable(GLuint *available); private: DISALLOW_COPY_AND_ASSIGN(Query9); - GLboolean testQuery(); + gl::Error testQuery(); + + GLuint mResult; + bool mQueryFinished; rx::Renderer9 *mRenderer; IDirect3DQuery9 *mQuery; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp index 49bd9b4000..13321ac8cd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -10,7 +9,6 @@ #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" - #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/main.h" @@ -33,8 +31,9 @@ RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) mHeight = description.Height; mDepth = 1; - mInternalFormat = d3d9_gl::GetInternalFormat(description.Format); - mActualFormat = d3d9_gl::GetInternalFormat(description.Format); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format); + mInternalFormat = d3dFormatInfo.internalFormat; + mActualFormat = d3dFormatInfo.internalFormat; mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType); } } @@ -44,15 +43,11 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, mRenderer = Renderer9::makeRenderer9(renderer); mRenderTarget = NULL; - D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); - int supportedSamples = mRenderer->getNearestSupportedSamples(renderFormat, samples); + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat); + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat); - if (supportedSamples == -1) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } + const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); HRESULT result = D3DERR_INVALIDCALL; @@ -62,18 +57,17 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, bool requiresInitialization = false; - if (gl::GetDepthBits(internalFormat) > 0 || - gl::GetStencilBits(internalFormat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - result = device->CreateDepthStencilSurface(width, height, renderFormat, + result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &mRenderTarget, NULL); } else { - requiresInitialization = gl_d3d9::RequiresTextureDataInitialization(internalFormat); - - result = device->CreateRenderTarget(width, height, renderFormat, + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); + result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &mRenderTarget, NULL); } @@ -105,7 +99,7 @@ RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, mDepth = 1; mInternalFormat = internalFormat; mSamples = supportedSamples; - mActualFormat = d3d9_gl::GetInternalFormat(renderFormat); + mActualFormat = d3dFormatInfo.internalFormat; } RenderTarget9::~RenderTarget9() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp index 2c8a79f964..d63f9b8582 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -7,17 +6,6 @@ // 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" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/renderer/d3d/IndexDataManager.h" -#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" @@ -33,11 +21,25 @@ #include "libGLESv2/renderer/d3d/d3d9/Query9.h" #include "libGLESv2/renderer/d3d/d3d9/Fence9.h" #include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h" +#include "libGLESv2/renderer/d3d/IndexDataManager.h" +#include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" +#include "libGLESv2/main.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/angletypes.h" #include "libEGL/Display.h" -#include "third_party/trace_event/trace_event.h" +#include "common/utilities.h" + +#include <sstream> // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 @@ -117,13 +119,12 @@ Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint req mDeviceLost = false; - mMaxSupportedSamples = 0; - mMaskedClearSavedState = NULL; mVertexDataManager = NULL; mIndexDataManager = NULL; mLineLoopIB = NULL; + mCountingIB = NULL; mMaxNullColorbufferLRU = 0; for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) @@ -155,6 +156,7 @@ Renderer9::~Renderer9() void Renderer9::release() { + releaseShaderCompiler(); releaseDeviceResources(); SafeRelease(mDevice); @@ -186,7 +188,6 @@ EGLint Renderer9::initialize() return EGL_NOT_INITIALIZED; } - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) @@ -203,14 +204,12 @@ EGLint Renderer9::initialize() // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { - TRACE_EVENT0("gpu", "Direct3DCreate9"); mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } @@ -229,7 +228,6 @@ EGLint Renderer9::initialize() // Give up on getting device caps after about one second. { - TRACE_EVENT0("gpu", "GetDeviceCaps"); for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); @@ -264,7 +262,6 @@ EGLint Renderer9::initialize() } { - TRACE_EVENT0("gpu", "GetAdapterIdentifier"); mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); } @@ -297,22 +294,10 @@ EGLint Renderer9::initialize() mMaxSwapInterval = std::max(mMaxSwapInterval, 4); } - mMaxSupportedSamples = 0; - - const d3d9::D3DFormatSet &d3d9Formats = d3d9::GetAllUsedD3DFormats(); - for (d3d9::D3DFormatSet::const_iterator i = d3d9Formats.begin(); i != d3d9Formats.end(); ++i) - { - TRACE_EVENT0("gpu", "getMultiSampleSupport"); - MultisampleSupportInfo support = getMultiSampleSupport(*i); - mMultiSampleSupport[*i] = support; - mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples); - } - static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); { - TRACE_EVENT0("gpu", "CreateWindowEx"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); } @@ -324,7 +309,6 @@ EGLint Renderer9::initialize() behaviorFlags |= D3DCREATE_MULTITHREADED; { - TRACE_EVENT0("gpu", "D3d9_CreateDevice"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) @@ -334,7 +318,6 @@ EGLint Renderer9::initialize() if (FAILED(result)) { - TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); if (FAILED(result)) @@ -346,13 +329,11 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { - TRACE_EVENT0("gpu", "mDevice_QueryInterface"); result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); ASSERT(SUCCEEDED(result)); } { - TRACE_EVENT0("gpu", "ShaderCache initialize"); mVertexShaderCache.initialize(mDevice); mPixelShaderCache.initialize(mDevice); } @@ -369,8 +350,6 @@ EGLint Renderer9::initialize() initializeDevice(); - d3d9::InitializeVertexTranslations(this); - return EGL_SUCCESS; } @@ -392,6 +371,17 @@ void Renderer9::initializeDevice() mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f } + const gl::Caps &rendererCaps = getRendererCaps(); + + mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + + mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + + mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits); + markAllStateDirty(); mSceneStarted = false; @@ -436,40 +426,24 @@ int Renderer9::generateConfigs(ConfigDesc **configDescList) for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) { - D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); - - if (SUCCEEDED(result)) + const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]); + const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat); + if (renderTargetFormatCaps.renderable) { for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) { - D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - HRESULT result = D3D_OK; - - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); - } - - if (SUCCEEDED(result)) + const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]); + const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat); + if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN) { - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); - } - - if (SUCCEEDED(result)) - { - ConfigDesc newConfig; - 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; - } + ConfigDesc newConfig; + newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat; + newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat; + newConfig.multiSample = 0; // FIXME: enumerate multi-sampling + newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]); + newConfig.es3Capable = false; + + (*configDescList)[numConfigs++] = newConfig; } } } @@ -635,6 +609,11 @@ FenceImpl *Renderer9::createFence() return new Fence9(this); } +TransformFeedbackImpl* Renderer9::createTransformFeedback() +{ + return new TransformFeedbackD3D(); +} + bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. @@ -649,16 +628,17 @@ bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsi return false; } -void Renderer9::generateSwizzle(gl::Texture *texture) +gl::Error Renderer9::generateSwizzle(gl::Texture *texture) { // Swizzled textures are not available in ES2 or D3D9 UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } -void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) { - bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) { @@ -682,9 +662,11 @@ void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::Sampl forceSetSamplers[index] = false; appliedSamplers[index] = samplerState; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; @@ -692,14 +674,16 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture unsigned int serial = 0; bool forceSetTexture = false; - unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + std::vector<unsigned int> &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; if (texture) { - TextureStorageInterface *texStorage = texture->getNativeTexture(); + TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + + TextureStorage *texStorage = textureImpl->getNativeTexture(); if (texStorage) { - TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance()); + TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); d3dTexture = storage9->getBaseTexture(); } // If we get NULL back from getBaseTexture here, something went wrong @@ -707,7 +691,8 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture ASSERT(d3dTexture != NULL); serial = texture->getTextureSerial(); - forceSetTexture = texture->hasDirtyImages(); + forceSetTexture = textureImpl->hasDirtyImages(); + textureImpl->resetDirty(); } if (forceSetTexture || appliedSerials[index] != serial) @@ -716,15 +701,17 @@ void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture } appliedSerials[index] = serial; + + return gl::Error(GL_NO_ERROR); } -bool Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[]) +gl::Error Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[]) { // No effect in ES2/D3D9 - return true; + return gl::Error(GL_NO_ERROR); } -void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) { bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; @@ -760,10 +747,12 @@ void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) } mForceSetRasterState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error 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::ColorF)) != 0; @@ -828,10 +817,11 @@ void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState // drawing is done. // http://code.google.com/p/angleproject/issues/detail?id=169 - DWORD colorMask = gl_d3d9::ConvertColorMask(gl::GetRedBits(internalFormat) > 0 && blendState.colorMaskRed, - gl::GetGreenBits(internalFormat) > 0 && blendState.colorMaskGreen, - gl::GetBlueBits(internalFormat) > 0 && blendState.colorMaskBlue, - gl::GetAlphaBits(internalFormat) > 0 && blendState.colorMaskAlpha); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed, + formatInfo.greenBits > 0 && blendState.colorMaskGreen, + formatInfo.blueBits > 0 && blendState.colorMaskBlue, + formatInfo.alphaBits > 0 && blendState.colorMaskAlpha); if (colorMask == 0 && !zeroColorMaskAllowed) { // Enable green channel, but set blending so nothing will be drawn. @@ -863,10 +853,12 @@ void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState } mForceSetBlendState = false; + + return gl::Error(GL_NO_ERROR); } -void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) +gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) { bool depthStencilStateChanged = mForceSetDepthStencilState || memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; @@ -955,6 +947,8 @@ void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilSt } mForceSetDepthStencilState = false; + + return gl::Error(GL_NO_ERROR); } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -984,7 +978,7 @@ void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mForceSetScissor = false; } -bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { gl::Rectangle actualViewport = viewport; @@ -1008,11 +1002,6 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF dxViewport.MinZ = actualZNear; dxViewport.MaxZ = actualZFar; - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - return false; // Nothing to render - } - float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || @@ -1065,7 +1054,6 @@ bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF } mForceSetViewport = false; - return true; } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) @@ -1133,7 +1121,7 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme } gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); - gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(nullRenderbuffer); + gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1154,7 +1142,7 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme return nullbuffer; } -bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error 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. @@ -1165,27 +1153,25 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) } if (!attachment) { - ERR("unable to locate renderbuffer for FBO."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO."); } bool renderTargetChanged = false; - unsigned int renderTargetSerial = attachment->getSerial(); + unsigned int renderTargetSerial = GetAttachmentSerial(attachment); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device IDirect3DSurface9 *renderTargetSurface = NULL; - RenderTarget *renderTarget = attachment->getRenderTarget(); + RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment); if (renderTarget) { - renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface(); + renderTargetSurface = renderTarget->getSurface(); } if (!renderTargetSurface) { - ERR("render target pointer unexpectedly null."); - return false; // Context must be lost + return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); } mDevice->SetRenderTarget(0, renderTargetSurface); @@ -1200,12 +1186,12 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) unsigned int stencilbufferSerial = 0; if (depthStencil) { - depthbufferSerial = depthStencil->getSerial(); + depthbufferSerial = GetAttachmentSerial(depthStencil); } else if (framebuffer->getStencilbuffer()) { depthStencil = framebuffer->getStencilbuffer(); - stencilbufferSerial = depthStencil->getSerial(); + stencilbufferSerial = GetAttachmentSerial(depthStencil); } if (depthbufferSerial != mAppliedDepthbufferSerial || @@ -1219,17 +1205,16 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) if (depthStencil) { IDirect3DSurface9 *depthStencilSurface = NULL; - RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil(); + rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil); if (depthStencilRenderTarget) { - depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface(); + depthStencilSurface = depthStencilRenderTarget->getSurface(); } if (!depthStencilSurface) { - ERR("depth stencil pointer unexpectedly null."); - return false; // Context must be lost + return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null."); } mDevice->SetDepthStencilSurface(depthStencilSurface); @@ -1272,42 +1257,43 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) mRenderTargetDescInitialized = true; } - return true; + return gl::Error(GL_NO_ERROR); } -GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) + gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + if (error.isError()) { - return err; + return error; } return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + if (error.isError()) { - // Directly binding the storage buffer is not supported for d3d9 - ASSERT(indexInfo->storage == NULL); + return error; + } - if (indexInfo->serial != mAppliedIBSerial) - { - IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(indexInfo->storage == NULL); - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = indexInfo->serial; - } + if (indexInfo->serial != mAppliedIBSerial) + { + IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = indexInfo->serial; } - return err; + return gl::Error(GL_NO_ERROR); } void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) @@ -1315,7 +1301,7 @@ void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffe UNREACHABLE(); } -void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) +gl::Error Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) { ASSERT(!transformFeedbackActive); @@ -1323,62 +1309,66 @@ void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool t if (mode == GL_LINE_LOOP) { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(count, GL_NONE, NULL, 0, NULL); } else if (instances > 0) { - StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count); - if (countingIB) + StaticIndexBufferInterface *countingIB = NULL; + gl::Error error = getCountingIB(count, &countingIB); + if (error.isError()) { - if (mAppliedIBSerial != countingIB->getSerial()) - { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); + return error; + } - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = countingIB->getSerial(); - } + if (mAppliedIBSerial != countingIB->getSerial()) + { + IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); - for (int i = 0; i < mRepeatDraw; i++) - { - mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); - } + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = countingIB->getSerial(); } - else + + for (int i = 0; i < mRepeatDraw; i++) { - ERR("Could not create a counting index buffer for glDrawArraysInstanced."); - return gl::error(GL_OUT_OF_MEMORY); + mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); } + + return gl::Error(GL_NO_ERROR); } else // Regular case { mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); + return gl::Error(GL_NO_ERROR); } } -void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) { startScene(); + int minIndex = static_cast<int>(indexInfo.indexRange.start); + if (mode == GL_POINTS) { - drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_LINE_LOOP) { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); } else { for (int i = 0; i < mRepeatDraw; i++) { - GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1; + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); } + return gl::Error(GL_NO_ERROR); } } -void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) @@ -1396,13 +1386,11 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1411,23 +1399,22 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, 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); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } - const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) + const unsigned int spaceNeeded = (static_cast<unsigned int>(count)+1) * sizeof(unsigned int); + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset = 0; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } startIndex = static_cast<unsigned int>(offset) / 4; @@ -1466,10 +1453,10 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, default: UNREACHABLE(); } - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } } else @@ -1477,13 +1464,11 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + if (error.isError()) { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + SafeDelete(mLineLoopIB); + return error; } } @@ -1492,23 +1477,22 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned short>::max() / sizeof(unsigned short))) { - ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned short); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) + gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + if (error.isError()) { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } void* mappedMemory = NULL; unsigned int offset; - if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + if (error.isError()) { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } startIndex = static_cast<unsigned int>(offset) / 2; @@ -1547,10 +1531,10 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, default: UNREACHABLE(); } - if (!mLineLoopIB->unmapBuffer()) + error = mLineLoopIB->unmapBuffer(); + if (error.isError()) { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); + return error; } } @@ -1563,19 +1547,23 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); + + return gl::Error(GL_NO_ERROR); } template <typename T> -static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) +static gl::Error 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]) - minIndex; device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); } + + return gl::Error(GL_NO_ERROR); } -void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error 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. @@ -1589,15 +1577,87 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi switch (type) { - 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(); + case GL_UNSIGNED_BYTE: return drawPoints<GLubyte>(mDevice, count, indices, minIndex); + case GL_UNSIGNED_SHORT: return drawPoints<GLushort>(mDevice, count, indices, minIndex); + case GL_UNSIGNED_INT: return drawPoints<GLuint>(mDevice, count, indices, minIndex); + default: UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); } } -void Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **outIB) +{ + // Update the counting index buffer if it is not large enough or has not been created yet. + if (count <= 65536) // 16-bit indices + { + const unsigned int spaceNeeded = count * sizeof(unsigned short); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + + void *mappedMemory = NULL; + gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); + if (error.isError()) + { + return error; + } + + unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory); + for (size_t i = 0; i < count; i++) + { + data[i] = i; + } + + error = mCountingIB->unmapBuffer(); + if (error.isError()) + { + return error; + } + } + } + else if (getRendererExtensions().elementIndexUint) + { + const unsigned int spaceNeeded = count * sizeof(unsigned int); + + if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) + { + SafeDelete(mCountingIB); + mCountingIB = new StaticIndexBufferInterface(this); + mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + + void *mappedMemory = NULL; + gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); + if (error.isError()) + { + return error; + } + + unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); + for (size_t i = 0; i < count; i++) + { + data[i] = i; + } + + error = mCountingIB->unmapBuffer(); + if (error.isError()) + { + return error; + } + } + } + else + { + return gl::Error(GL_OUT_OF_MEMORY, "Could not create a counting index buffer for glDrawArraysInstanced."); + } + + *outIB = mCountingIB; + return gl::Error(GL_NO_ERROR); +} + +gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) { ASSERT(!transformFeedbackActive); ASSERT(!rasterizerDiscard); @@ -1632,9 +1692,11 @@ void Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexF mDxUniformsDirty = true; mAppliedProgramSerial = programSerial; } + + return gl::Error(GL_NO_ERROR); } -void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) { const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); @@ -1686,6 +1748,8 @@ void Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); mDxUniformsDirty = false; } + + return gl::Error(GL_NO_ERROR); } void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) @@ -1733,13 +1797,13 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) { if (clearParams.colorClearType != GL_FLOAT) { // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } bool clearColor = clearParams.clearColor[0]; @@ -1749,7 +1813,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f { // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return; + return gl::Error(GL_INVALID_OPERATION); } } @@ -1759,7 +1823,7 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && frameBuffer->hasStencil()) { - unsigned int stencilSize = gl::GetStencilBits(frameBuffer->getStencilbuffer()->getActualFormat()); + unsigned int stencilSize = gl::GetInternalFormatInfo((frameBuffer->getStencilbuffer()->getActualFormat())).stencilBits; stencilUnmasked = (0x1 << stencilSize) - 1; } @@ -1770,29 +1834,19 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { - gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment->getInternalFormat(); - GLenum actualFormat = attachment->getActualFormat(); - - GLuint internalRedBits = gl::GetRedBits(internalFormat); - GLuint internalGreenBits = gl::GetGreenBits(internalFormat); - GLuint internalBlueBits = gl::GetBlueBits(internalFormat); - GLuint internalAlphaBits = gl::GetAlphaBits(internalFormat); + const gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer(); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); + const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); - GLuint actualRedBits = gl::GetRedBits(actualFormat); - GLuint actualGreenBits = gl::GetGreenBits(actualFormat); - GLuint actualBlueBits = gl::GetBlueBits(actualFormat); - GLuint actualAlphaBits = gl::GetAlphaBits(actualFormat); + color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), + gl::unorm<8>((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), + gl::unorm<8>((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); - 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)) + if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { needMaskedColorClear = true; } @@ -1956,6 +2010,8 @@ void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *f mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); } + + return gl::Error(GL_NO_ERROR); } void Renderer9::markAllStateDirty() @@ -1972,12 +2028,15 @@ void Renderer9::markAllStateDirty() mForceSetViewport = true; mForceSetBlendState = true; - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size()); + for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) { mForceSetVertexSamplerStates[i] = true; mCurVertexTextureSerials[i] = 0; } - for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + + ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size()); + for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) { mForceSetPixelSamplerStates[i] = true; mCurPixelTextureSerials[i] = 0; @@ -2009,6 +2068,7 @@ void Renderer9::releaseDeviceResources() SafeDelete(mVertexDataManager); SafeDelete(mIndexDataManager); SafeDelete(mLineLoopIB); + SafeDelete(mCountingIB); for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { @@ -2219,43 +2279,6 @@ GUID Renderer9::getAdapterIdentifier() const return mAdapterIdentifier.DeviceIdentifier; } -Renderer9::MultisampleSupportInfo Renderer9::getMultiSampleSupport(D3DFORMAT format) -{ - 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); - - 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; -} - -unsigned int Renderer9::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0; -} - -unsigned int Renderer9::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - unsigned int Renderer9::getReservedVertexUniformVectors() const { return 2; // dx_ViewAdjust and dx_DepthRange. @@ -2266,33 +2289,6 @@ unsigned int Renderer9::getReservedFragmentUniformVectors() const return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. } -unsigned int Renderer9::getMaxVertexUniformVectors() const -{ - return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors(); -} - -unsigned int Renderer9::getMaxFragmentUniformVectors() const -{ - const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2; - - return maxPixelConstantVectors - getReservedFragmentUniformVectors(); -} - -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; @@ -2303,26 +2299,6 @@ 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::getShareHandleSupport() const { // PIX doesn't seem to support using share handles, so disable them. @@ -2334,25 +2310,6 @@ bool Renderer9::getPostSubBufferSupport() const return true; } -int Renderer9::getMaxRecommendedElementsIndices() const -{ - // ES3 only - UNREACHABLE(); - return 0; -} - -int Renderer9::getMaxRecommendedElementsVertices() const -{ - // ES3 only - UNREACHABLE(); - return 0; -} - -bool Renderer9::getSRGBTextureSupport() const -{ - return false; -} - int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2373,92 +2330,14 @@ int Renderer9::getMaxSwapInterval() const return mMaxSwapInterval; } -int Renderer9::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -GLsizei Renderer9::getMaxSupportedFormatSamples(GLenum internalFormat) const -{ - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalFormat); - 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); - 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); - 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) - { - return requested; - } - - MultisampleSupportMap::const_iterator itr = mMultiSampleSupport.find(format); - if (itr == mMultiSampleSupport.end()) - { - if (format == D3DFMT_UNKNOWN) - return 0; - return -1; - } - - for (unsigned int i = requested; i < ArraySize(itr->second.supportedSamples); ++i) - { - if (itr->second.supportedSamples[i] && i != D3DMULTISAMPLE_NONMASKABLE) - { - return i; - } - } - - return -1; -} - -bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) { bool result = false; if (source && dest) { - TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance()); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance()); + TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source); + TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest); int levels = source9->getLevelCount(); for (int i = 0; i < levels; ++i) @@ -2481,14 +2360,14 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStora return result; } -bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) { bool result = false; if (source && dest) { - TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance()); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance()); + TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source); + TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest); int levels = source9->getLevelCount(); for (int f = 0; f < 6; f++) { @@ -2513,14 +2392,14 @@ bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureSto return result; } -bool Renderer9::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source) +bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); return false; } -bool Renderer9::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source) +bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); @@ -2544,8 +2423,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2553,11 +2432,11 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); + return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); } -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2565,19 +2444,19 @@ bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sou rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); + return mBlit->copyCube(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) +bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *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) +bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); @@ -2602,11 +2481,11 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (readBuffer) { - readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget()); + readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer); } if (drawBuffer) { - drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget()); + drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer); } if (readRenderTarget) @@ -2731,11 +2610,11 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (readBuffer) { - readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil()); + readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer); } if (drawBuffer) { - drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil()); + drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer); } if (readDepthStencil) @@ -2768,8 +2647,8 @@ 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, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels) +gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ASSERT(pack.pixelBuffer.get() == NULL); @@ -2779,7 +2658,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (colorbuffer) { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); } if (renderTarget) @@ -2790,7 +2669,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (!surface) { // context must be lost - return; + return gl::Error(GL_NO_ERROR); } D3DSURFACE_DESC desc; @@ -2800,7 +2679,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments."); } HRESULT result; @@ -2812,7 +2691,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { // Use the pixels ptr as a shared handle to write directly into client's memory result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, - D3DPOOL_SYSTEMMEM, &systemSurface, &pixels); + D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels)); if (FAILED(result)) { // Try again without the shared handle @@ -2828,7 +2707,7 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels."); } } @@ -2844,20 +2723,19 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz if (d3d9::isDeviceLostError(result)) { notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY); } else { UNREACHABLE(); - return; } + return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data."); } if (directToPixels) { SafeRelease(systemSurface); - return; + return gl::Error(GL_NO_ERROR); } RECT rect; @@ -2874,44 +2752,40 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz UNREACHABLE(); SafeRelease(systemSurface); - return; // No sensible error to generate + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target."); } - unsigned char *source; + uint8_t *source; int inputPitch; if (pack.reverseRowOrder) { - source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); + source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); inputPitch = -lock.Pitch; } else { - source = (unsigned char*)lock.pBits; + source = reinterpret_cast<uint8_t*>(lock.pBits); inputPitch = lock.Pitch; } - GLenum sourceInternalFormat = d3d9_gl::GetInternalFormat(desc.Format); - GLenum sourceFormat = gl::GetFormat(sourceInternalFormat); - GLenum sourceType = gl::GetType(sourceInternalFormat); - - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); - - if (sourceFormat == format && sourceType == type) + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); + if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) { // Direct copy possible - unsigned char *dest = static_cast<unsigned char*>(pixels); for (int y = 0; y < rect.bottom - rect.top; y++) { - memcpy(dest + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourcePixelSize); + memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes); } } else { - GLenum destInternalFormat = gl::GetSizedInternalFormat(format, type); - GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat); - GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat); + const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type); + + const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type); + const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); - ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type); if (fastCopyFunc) { // Fast copy is possible through some special function @@ -2919,8 +2793,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz { for (int x = 0; x < rect.right - rect.left; x++) { - void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; - void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; fastCopyFunc(src, dest); } @@ -2928,22 +2802,18 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz } else { - ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format); - ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type); - - gl::ColorF temp; - + uint8_t temp[sizeof(gl::ColorF)]; for (int y = 0; y < rect.bottom - rect.top; y++) { for (int x = 0; x < rect.right - rect.left; x++) { - void *dest = reinterpret_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize; - void *src = source + y * inputPitch + x * sourcePixelSize; + uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; // readFunc and writeFunc will be using the same type of color, CopyTexImage // will not allow the copy otherwise. - readFunc(src, &temp); - writeFunc(&temp, dest); + sourceD3DFormatInfo.colorReadFunction(src, temp); + destFormatTypeInfo.colorWriteFunction(temp, dest); } } } @@ -2951,6 +2821,8 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz systemSurface->UnlockRect(); SafeRelease(systemSurface); + + return gl::Error(GL_NO_ERROR); } RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) @@ -2977,6 +2849,21 @@ RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format return renderTarget; } +ShaderImpl *Renderer9::createShader(GLenum type) +{ + return new ShaderD3D(type, this); +} + +ProgramImpl *Renderer9::createProgram() +{ + return new ProgramD3D(this); +} + +void Renderer9::releaseShaderCompiler() +{ + ShaderD3D::releaseCompiler(); +} + ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers) @@ -3200,24 +3087,16 @@ TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bo return NULL; } -Texture2DImpl *Renderer9::createTexture2D() -{ - return new TextureD3D_2D(this); -} - -TextureCubeImpl *Renderer9::createTextureCube() -{ - return new TextureD3D_Cube(this); -} - -Texture3DImpl *Renderer9::createTexture3D() +TextureImpl *Renderer9::createTexture(GLenum target) { - return new TextureD3D_3D(this); -} + switch(target) + { + case GL_TEXTURE_2D: return new TextureD3D_2D(this); + case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); + default: UNREACHABLE(); + } -Texture2DArrayImpl *Renderer9::createTexture2DArray() -{ - return new TextureD3D_2DArray(this); + return NULL; } bool Renderer9::getLUID(LUID *adapterLuid) const @@ -3234,20 +3113,14 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -GLenum Renderer9::getNativeTextureFormat(GLenum internalFormat) const -{ - return d3d9_gl::GetInternalFormat(gl_d3d9::GetTextureFormat(internalFormat)); -} - rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { - return d3d9::GetVertexConversionType(vertexFormat); + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; } GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const { - D3DDECLTYPE declType = d3d9::GetNativeVertexFormat(vertexFormat); - return d3d9::GetDeclTypeComponentType(declType); + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType; } void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h index 070623c9db..dd5f30268a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h @@ -27,6 +27,7 @@ namespace rx class VertexDataManager; class IndexDataManager; class StreamingIndexBufferInterface; +class StaticIndexBufferInterface; struct TranslatedAttribute; class Blit9; @@ -59,38 +60,38 @@ 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); - 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 gl::Error generateSwizzle(gl::Texture *texture); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - virtual bool setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - 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); + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); + virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask); + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual void applyUniforms(const gl::ProgramBinary &programBinary); + virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive); + virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const 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 gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], + GLint first, GLsizei count, GLsizei instances); + virtual gl::Error 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, bool transformFeedbackActive); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); + virtual gl::Error 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); + virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void markAllStateDirty(); @@ -105,63 +106,49 @@ class Renderer9 : public Renderer virtual std::string getRendererDescription() const; virtual GUID getAdapterIdentifier() const; - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; - 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 getShareHandleSupport() const; virtual bool getPostSubBufferSupport() const; - virtual int getMaxRecommendedElementsIndices() const; - virtual int getMaxRecommendedElementsVertices() const; - virtual bool getSRGBTextureSupport() const; virtual int getMajorShaderModel() 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; - // 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 copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); + virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); + + virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, 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); + + virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + // Shader creation + virtual ShaderImpl *createShader(GLenum type); + virtual ProgramImpl *createProgram(); + // Shader operations + virtual void releaseShaderCompiler(); virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, bool separatedOutputBuffers); @@ -180,10 +167,7 @@ class Renderer9 : public Renderer virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); // Texture creation - virtual Texture2DImpl *createTexture2D(); - virtual TextureCubeImpl *createTextureCube(); - virtual Texture3DImpl *createTexture3D(); - virtual Texture2DArrayImpl *createTexture2DArray(); + virtual TextureImpl *createTexture(GLenum target); // Buffer creation virtual BufferImpl *createBuffer(); @@ -197,6 +181,9 @@ class Renderer9 : public Renderer virtual QueryImpl *createQuery(GLenum type); virtual FenceImpl *createFence(); + // Transform Feedback creation + virtual TransformFeedbackImpl* createTransformFeedback(); + // 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, @@ -208,7 +195,6 @@ class Renderer9 : public Renderer 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; @@ -223,8 +209,10 @@ class Renderer9 : public Renderer 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, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + + gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer); @@ -269,17 +257,6 @@ class Renderer9 : public Renderer bool mVertexTextureSupport; - 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; unsigned int mAppliedDepthbufferSerial; @@ -318,15 +295,15 @@ class Renderer9 : public Renderer GLuint mCurSampleMask; // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetVertexSamplerStates; + std::vector<gl::SamplerState> mCurVertexSamplerStates; - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<bool> mForceSetPixelSamplerStates; + std::vector<gl::SamplerState> mCurPixelSamplerStates; // Currently applied textures - unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; + std::vector<unsigned int> mCurVertexTextureSerials; + std::vector<unsigned int> mCurPixelTextureSerials; unsigned int mAppliedIBSerial; IDirect3DVertexShader9 *mAppliedVertexShader; @@ -347,6 +324,7 @@ class Renderer9 : public Renderer IndexDataManager *mIndexDataManager; StreamingIndexBufferInterface *mLineLoopIB; + StaticIndexBufferInterface *mCountingIB; enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; struct NullColorbufferCacheEntry diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h index a03528c9b5..2ad3022839 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h @@ -12,6 +12,10 @@ #include "common/debug.h" +#include <cstddef> +#include <unordered_map> +#include <string> + namespace rx { template <typename ShaderObject> diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp index c10ddbf6ce..bc7120461b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -1,4 +1,3 @@ -#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 diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp index c6567b635f..0aeaabb1ca 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -50,7 +49,7 @@ void SwapChain9::release() static DWORD convertInterval(EGLint interval) { -#if ANGLE_FORCE_VSYNC_OFF +#ifdef ANGLE_FORCE_VSYNC_OFF return D3DPRESENT_INTERVAL_IMMEDIATE; #else switch(interval) @@ -101,9 +100,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI pShareHandle = &mShareHandle; } + const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat); result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - gl_d3d9::GetTextureFormat(mBackBufferFormat), - D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, + pShareHandle); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); @@ -150,12 +150,14 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI SafeRelease(oldRenderTarget); } + const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat); + if (mWindow) { D3DPRESENT_PARAMETERS presentParameters = {0}; - presentParameters.AutoDepthStencilFormat = gl_d3d9::GetRenderFormat(mDepthBufferFormat); + presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat; presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = gl_d3d9::GetRenderFormat(mBackBufferFormat); + presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = mWindow; @@ -207,7 +209,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI if (mDepthBufferFormat != GL_NONE) { result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - gl_d3d9::GetRenderFormat(mDepthBufferFormat), + depthBufferd3dFormatInfo.renderFormat, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); if (FAILED(result)) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp index b065ee80fe..f44e33db18 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -9,15 +8,15 @@ // classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the // D3D9 texture. -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/d3d/TextureD3D.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h" #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/Texture.h" +#include "libGLESv2/main.h" namespace rx { @@ -43,12 +42,13 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) { DWORD d3dusage = 0; - if (gl::GetDepthBits(internalformat) > 0 || - gl::GetStencilBits(internalformat) > 0) + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { d3dusage |= D3DUSAGE_DEPTHSTENCIL; } - else if (renderTarget && (gl_d3d9::GetRenderFormat(internalformat) != D3DFMT_UNKNOWN)) + else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN)) { d3dusage |= D3DUSAGE_RENDERTARGET; } @@ -95,6 +95,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain mRenderTarget = NULL; initializeRenderTarget(); + initializeSerials(1, 1); } TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) @@ -107,11 +108,11 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat if (width > 0 && height > 0) { IDirect3DDevice9 *device = mRenderer->getDevice(); - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); - d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel); UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; - HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); + HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -121,6 +122,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat } initializeRenderTarget(); + initializeSerials(getLevelCount(), 1); } TextureStorage9_2D::~TextureStorage9_2D() @@ -157,23 +159,28 @@ IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) return surface; } -RenderTarget *TextureStorage9_2D::getRenderTarget(int level) +RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/) { return mRenderTarget; } -void TextureStorage9_2D::generateMipmap(int level) +void TextureStorage9_2D::generateMipmaps() { - IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); - IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + // Base level must already be defined - if (upper != NULL && lower != NULL) + for (int level = 1; level < getLevelCount(); level++) { - mRenderer->boxFilter(upper, lower); - } + IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); + IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + + if (upper != NULL && lower != NULL) + { + mRenderer->boxFilter(upper, lower); + } - SafeRelease(upper); - SafeRelease(lower); + SafeRelease(upper); + SafeRelease(lower); + } } IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const @@ -208,11 +215,11 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo { IDirect3DDevice9 *device = mRenderer->getDevice(); int height = size; - D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat); - d3d9::MakeValidSize(false, format, &size, &height, &mTopLevel); + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel); UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; - HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); + HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -222,6 +229,7 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalfo } initializeRenderTarget(); + initializeSerials(getLevelCount() * 6, 6); } TextureStorage9_Cube::~TextureStorage9_Cube() @@ -263,23 +271,31 @@ IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, in return surface; } -RenderTarget *TextureStorage9_Cube::getRenderTargetFace(GLenum faceTarget, int level) +RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index) { - return mRenderTarget[TextureD3D_Cube::targetToIndex(faceTarget)]; + return mRenderTarget[index.layerIndex]; } -void TextureStorage9_Cube::generateMipmap(int faceIndex, int level) +void TextureStorage9_Cube::generateMipmaps() { - 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); + // Base level must already be defined - if (upper != NULL && lower != NULL) + for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - mRenderer->boxFilter(upper, lower); - } + for (int level = 1; level < getLevelCount(); level++) + { + 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); + } - SafeRelease(upper); - SafeRelease(lower); + SafeRelease(upper); + SafeRelease(lower); + } + } } IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h index cc7c155d34..e698c7dd56 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h @@ -34,11 +34,8 @@ class TextureStorage9 : public TextureStorage DWORD getUsage() const; virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; - 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 RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual void generateMipmaps() = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; @@ -68,9 +65,9 @@ class TextureStorage9_2D : public TextureStorage9 static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); - virtual RenderTarget *getRenderTarget(int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int level); + virtual void generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D); @@ -90,9 +87,9 @@ class TextureStorage9_Cube : public TextureStorage9 static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); - virtual RenderTarget *getRenderTargetFace(GLenum faceTarget, int level); + virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int faceIndex, int level); + virtual void generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp index d260640dbe..4cf7779118 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -1,4 +1,3 @@ -#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 @@ -8,18 +7,17 @@ // VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. #include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/vertexconversion.h" #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" -#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" - #include "libGLESv2/Buffer.h" namespace rx { -VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) +VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer) { mVertexBuffer = NULL; mBufferSize = 0; @@ -31,7 +29,7 @@ VertexBuffer9::~VertexBuffer9() SafeRelease(mVertexBuffer); } -bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) +gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) { SafeRelease(mVertexBuffer); @@ -49,14 +47,13 @@ bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) if (FAILED(result)) { - ERR("Out of memory allocating a vertex buffer of size %lu.", size); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return true; + return gl::Error(GL_NO_ERROR); } VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) @@ -65,84 +62,80 @@ VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *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) +gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, + GLint start, GLsizei count, GLsizei instances, unsigned int offset) { - if (mVertexBuffer) + if (!mVertexBuffer) { - gl::Buffer *buffer = attrib.buffer.get(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - int inputStride = gl::ComputeVertexAttributeStride(attrib); - int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); + gl::Buffer *buffer = attrib.buffer.get(); - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + int inputStride = gl::ComputeVertexAttributeStride(attrib); + int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); - void *mapPtr = NULL; + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - unsigned int mapSize; - if (!spaceRequired(attrib, count, instances, &mapSize)) - { - return false; - } + uint8_t *mapPtr = NULL; - HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); + unsigned int mapSize; + gl::Error error = spaceRequired(attrib, count, instances, &mapSize); + if (error.isError()) + { + return error; + } - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } + HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void**>(&mapPtr), lockFlags); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); + } - const char *input = NULL; - if (attrib.enabled) + const uint8_t *input = NULL; + if (attrib.enabled) + { + if (buffer) { - if (buffer) - { - BufferImpl *storage = buffer->getImplementation(); - input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset); - } - else - { - input = static_cast<const char*>(attrib.pointer); - } + BufferImpl *storage = buffer->getImplementation(); + input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset); } else { - input = reinterpret_cast<const char*>(currentValue.FloatValues); + input = static_cast<const uint8_t*>(attrib.pointer); } + } + else + { + input = reinterpret_cast<const uint8_t*>(currentValue.FloatValues); + } - if (instances == 0 || attrib.divisor == 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); - } + if (instances == 0 || attrib.divisor == 0) + { + input += inputStride * start; + } - mVertexBuffer->Unlock(); + gl::VertexFormat vertexFormat(attrib, currentValue.Type); + const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); + bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; - return true; + if (!needsConversion && inputStride == elementSize) + { + size_t copySize = static_cast<size_t>(count) * static_cast<size_t>(inputStride); + memcpy(mapPtr, input, copySize); } else { - ERR("Vertex buffer not initialized."); - return false; + d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr); } + + mVertexBuffer->Unlock(); + + return gl::Error(GL_NO_ERROR); } -bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const +gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const { return spaceRequired(attrib, count, instances, outSpaceRequired); } @@ -152,7 +145,7 @@ unsigned int VertexBuffer9::getBufferSize() const return mBufferSize; } -bool VertexBuffer9::setBufferSize(unsigned int size) +gl::Error VertexBuffer9::setBufferSize(unsigned int size) { if (size > mBufferSize) { @@ -160,38 +153,33 @@ bool VertexBuffer9::setBufferSize(unsigned int size) } else { - return true; + return gl::Error(GL_NO_ERROR); } } -bool VertexBuffer9::discard() +gl::Error VertexBuffer9::discard() { - if (mVertexBuffer) + 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; - } + return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + } - result = mVertexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } + void *dummy; + HRESULT result; - return true; + result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal buffer for discarding, HRESULT: 0x%08x", result); } - else + + result = mVertexBuffer->Unlock(); + if (FAILED(result)) { - ERR("Vertex buffer not initialized."); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal buffer for discarding, HRESULT: 0x%08x", result); } + + return gl::Error(GL_NO_ERROR); } IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const @@ -199,11 +187,11 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const return mVertexBuffer; } -bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) +gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) const { gl::VertexFormat vertexFormat(attrib, GL_FLOAT); - unsigned int elementSize = d3d9::GetVertexElementSize(vertexFormat); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); if (attrib.enabled) { @@ -214,28 +202,21 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t } else { - if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1)) - { - // Round up - elementCount = (static_cast<unsigned int>(instances) + (attrib.divisor - 1)) / attrib.divisor; - } - else - { - elementCount = static_cast<unsigned int>(instances) / attrib.divisor; - } + // Round up to divisor, if possible + elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor); } - if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) + if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount) { if (outSpaceRequired) { - *outSpaceRequired = elementSize * elementCount; + *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount; } - return true; + return gl::Error(GL_NO_ERROR); } else { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); } } else @@ -245,7 +226,7 @@ bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t { *outSpaceRequired = elementSize * 4; } - return true; + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h index fc4b6b6d26..bdcf4bb64a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h @@ -18,35 +18,35 @@ class Renderer9; class VertexBuffer9 : public VertexBuffer { public: - explicit VertexBuffer9(rx::Renderer9 *const renderer); + explicit VertexBuffer9(rx::Renderer9 *renderer); virtual ~VertexBuffer9(); - virtual bool initialize(unsigned int size, bool dynamicUsage); + virtual gl::Error 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 gl::Error 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 gl::Error 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(); + virtual gl::Error setBufferSize(unsigned int size); + virtual gl::Error discard(); IDirect3DVertexBuffer9 *getBuffer() const; private: DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); - rx::Renderer9 *const mRenderer; + rx::Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; bool mDynamicUsage; - static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired); + gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) const; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp index 303d8ad299..cefd786f11 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -1,4 +1,3 @@ -#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 @@ -7,11 +6,11 @@ // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" #include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/VertexAttribute.h" namespace rx { @@ -41,13 +40,27 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) { *repeatDraw = 1; int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; + if (instances == 0) + { + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + { + if (attributes[i].divisor != 0) + { + // If a divisor is set, it still applies even if an instanced draw was not used, so treat + // as a single-instance draw. + instances = 1; + break; + } + } + } + if (instances > 0) { // Find an indexed attribute to be mapped to D3D stream 0 @@ -68,12 +81,14 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } } - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS) - { - return GL_INVALID_OPERATION; - } + // The validation layer checks that there is at least one active attribute with a zero divisor as per + // the GL_ANGLE_instanced_arrays spec. + ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS); } + D3DCAPS9 caps; + device->GetDeviceCaps(&caps); + D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; @@ -133,10 +148,11 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat); element->Stream = stream; element->Offset = 0; - element->Type = d3d9::GetNativeVertexFormat(vertexFormat); + element->Type = d3d9VertexInfo.nativeFormat; element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; element->UsageIndex = programBinary->getSemanticIndex(i); @@ -172,7 +188,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl mLastSetVDecl = entry->vertexDeclaration; } - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } } @@ -194,12 +210,17 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl } memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); - device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result); + } + device->SetVertexDeclaration(lastCache->vertexDeclaration); mLastSetVDecl = lastCache->vertexDeclaration; lastCache->lruCount = ++mMaxLru; - return GL_NO_ERROR; + return gl::Error(GL_NO_ERROR); } void VertexDeclarationCache::markStateDirty() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h index 004e28df4f..9af36e0d7a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -9,6 +9,7 @@ #ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ #define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ +#include "libGLESv2/Error.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h" namespace gl @@ -25,7 +26,7 @@ class VertexDeclarationCache VertexDeclarationCache(); ~VertexDeclarationCache(); - GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); + gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); void markStateDirty(); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp index f5d1da62b3..f3acaf7987 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp @@ -1,4 +1,3 @@ -#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 @@ -18,255 +17,134 @@ 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(*FallbackPredicateFunction)(); - -template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> -static void FallbackLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - if (pred()) - { - prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } - else - { - fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } -} - -static void UnreachableLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) +namespace d3d9 { - UNREACHABLE(); -} const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); -struct D3D9FormatInfo +struct D3D9FastCopyFormat { - D3DFORMAT mTexFormat; - D3DFORMAT mRenderFormat; - LoadImageFunction mLoadFunction; + GLenum destFormat; + GLenum destType; + ColorCopyFunction copyFunction; - D3D9FormatInfo() - : mTexFormat(D3DFMT_NULL), mRenderFormat(D3DFMT_NULL), mLoadFunction(NULL) + D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) + : destFormat(destFormat), destType(destType), copyFunction(copyFunction) { } - D3D9FormatInfo(D3DFORMAT textureFormat, D3DFORMAT renderFormat, LoadImageFunction loadFunc) - : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc) - { } + bool operator<(const D3D9FastCopyFormat& other) const + { + return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; + } }; -typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair; -typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap; +typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap; -static D3D9FormatMap BuildD3D9FormatMap() +static D3D9FastCopyMap BuildFastCopyMap() { - D3D9FormatMap map; + D3D9FastCopyMap map; - // | Internal format | Texture format | Render format | Load function | - map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ))); - - map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D32, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ))); - map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ))); // TODO: What's the texture format? - - map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> ))); - map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>))); - map.insert(D3D9FormatPair(GL_RG32F_EXT, D3D9FormatInfo(D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> ))); - map.insert(D3D9FormatPair(GL_R32F_EXT, D3D9FormatInfo(D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> ))); - map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F ))); - - map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> ))); - map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> ))); - map.insert(D3D9FormatPair(GL_RG16F_EXT, D3D9FormatInfo(D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> ))); - map.insert(D3D9FormatPair(GL_R16F_EXT, D3D9FormatInfo(D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> ))); - map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ))); - map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ))); - - map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>))); - - map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ))); - map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>))); - map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_R8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ))); - map.insert(D3D9FormatPair(GL_RG8_EXT, D3D9FormatInfo(D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 ))); - - map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> ))); - map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ))); - map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ))); - - map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ))); - map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<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(D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> ))); - map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> ))); + map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); return map; } -static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo) +// A map to determine the pixel size and mip generation function of a given D3D format +typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap; + +D3DFormat::D3DFormat() + : pixelBytes(0), + blockWidth(0), + blockHeight(0), + internalFormat(GL_NONE), + mipGenerationFunction(NULL), + colorReadFunction(NULL), + fastCopyFunctions() { - 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 +ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const { - GLuint mPixelBits; - GLuint mBlockWidth; - GLuint mBlockHeight; - GLenum mInternalFormat; - - MipGenerationFunction mMipGenerationFunction; - ColorReadFunction mColorReadFunction; + FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); + return (iter != fastCopyFunctions.end()) ? iter->second : NULL; +} - D3DFormatInfo() - : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL), - mColorReadFunction(NULL) - { } +static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, + GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc, + ColorReadFunction colorReadFunc) +{ + D3DFormat info; + info.pixelBytes = bits / 8; + info.blockWidth = blockWidth; + info.blockHeight = blockHeight; + info.internalFormat = internalFormat; + info.mipGenerationFunction = mipFunc; + info.colorReadFunction = colorReadFunc; - 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) - { } -}; + static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); + std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format); + for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) + { + info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); + } -typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair; -typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap; + map->insert(std::make_pair(format, info)); +} 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 ))); + // | D3DFORMAT | S |W |H | Internal format | Mip generation function | Color read function | + InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, GL_NONE, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>); + InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ); + InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>); + + InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); + + InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ); + InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ); return map; } -static const D3D9FormatInfoMap &GetD3D9FormatInfoMap() +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) { 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; + return iter->second; } else { - return false; + static const D3DFormat defaultInfo; + return defaultInfo; } } -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; @@ -275,160 +153,148 @@ 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>)); + 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; -} +// 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. -namespace d3d9 -{ +typedef bool(*FallbackPredicateFunction)(); -MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format) +template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> +static void FallbackLoad(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + if (pred()) { - return d3dFormatInfo.mMipGenerationFunction; + prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); } else { - UNREACHABLE(); - return NULL; + fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); } } -LoadImageFunction GetImageLoadFunction(GLenum internalFormat) +static void UnreachableLoad(size_t width, size_t height, size_t depth, + const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, + uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mLoadFunction; - } - else - { - UNREACHABLE(); - return NULL; - } + UNREACHABLE(); } -GLuint GetFormatPixelBytes(D3DFORMAT format) -{ - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mPixelBits / 8; - } - else - { - UNREACHABLE(); - return 0; - } -} +typedef std::pair<GLenum, TextureFormat> D3D9FormatPair; +typedef std::map<GLenum, TextureFormat> D3D9FormatMap; -GLuint GetBlockWidth(D3DFORMAT format) +TextureFormat::TextureFormat() + : texFormat(D3DFMT_NULL), + renderFormat(D3DFMT_NULL), + dataInitializerFunction(NULL), + loadFunction(UnreachableLoad) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mBlockWidth; - } - else - { - UNREACHABLE(); - return 0; - } } -GLuint GetBlockHeight(D3DFORMAT format) +static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalFormat, D3DFORMAT texFormat, + D3DFORMAT renderFormat, LoadImageFunction loadFunction) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - return d3dFormatInfo.mBlockHeight; - } - else - { - UNREACHABLE(); - return 0; - } -} + TextureFormat info; + info.texFormat = texFormat; + info.renderFormat = renderFormat; -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; + static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap(); + InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat); + info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL; - return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; - } - else - { - UNREACHABLE(); - return 0; - } + info.loadFunction = loadFunction; + + map->insert(std::make_pair(internalFormat, info)); } -void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +static D3D9FormatMap BuildD3D9FormatMap() { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) - { - int upsampleCount = 0; + D3D9FormatMap map; - GLsizei blockWidth = d3dFormatInfo.mBlockWidth; - GLsizei blockHeight = d3dFormatInfo.mBlockHeight; + // | Internal format | Texture format | Render format | Load function | + InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); + + // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely + // supported. We're allowed to do this because: + // - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format + // resolutions of our own choosing. + // - OES_depth_texture states that downsampling of the depth formats is allowed. + // - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it + // introduces. + // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed. + + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, D3DFMT_INTZ, D3DFMT_D24X8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad ); + InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8, D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ); // TODO: What's the texture format? + + InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> ); + InsertD3D9FormatInfo(&map, GL_RGB32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>); + InsertD3D9FormatInfo(&map, GL_RG32F_EXT, D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> ); + InsertD3D9FormatInfo(&map, GL_R32F_EXT, D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> ); + InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F ); + + InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> ); + InsertD3D9FormatInfo(&map, GL_RGB16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> ); + InsertD3D9FormatInfo(&map, GL_RG16F_EXT, D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> ); + InsertD3D9FormatInfo(&map, GL_R16F_EXT, D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> ); + InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); + + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>); + + InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>); + InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); + InsertD3D9FormatInfo(&map, GL_RG8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 ); + + InsertD3D9FormatInfo(&map, GL_BGRA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> ); + InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ); + InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ); + + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 16> ); - // 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; - } -} + // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and + // then changing the format and loading function appropriately. + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> ); + InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> ); -const D3DFormatSet &GetAllUsedD3DFormats() -{ - static const D3DFormatSet formatSet = BuildAllD3DFormatSet(); - return formatSet; + return map; } -ColorReadFunction GetColorReadFunction(D3DFORMAT format) +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat) { - D3DFormatInfo d3dFormatInfo; - if (GetD3D9FormatInfo(format, &d3dFormatInfo)) + static const D3D9FormatMap formatMap = BuildD3D9FormatMap(); + D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat); + if (iter != formatMap.end()) { - return d3dFormatInfo.mColorReadFunction; + return iter->second; } else { - UNREACHABLE(); - return NULL; + static const TextureFormat defaultInfo; + return defaultInfo; } } -ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) -{ - 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) +static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) { switch (declType) { @@ -451,27 +317,13 @@ GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) // 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; + VertexFormat preferredConversion; + VertexFormat 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) @@ -623,14 +475,35 @@ public: enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; }; +VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), + outputElementSize(0), + copyFunction(NULL), + nativeFormat(D3DDECLTYPE_UNUSED), + componentType(GL_NONE) +{ +} + // Initialize a TranslationInfo +VertexFormat CreateVertexFormatInfo(bool identity, size_t elementSize, VertexCopyFunction copyFunc, D3DDECLTYPE nativeFormat) +{ + VertexFormat formatInfo; + formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU; + formatInfo.outputElementSize = elementSize; + formatInfo.copyFunction = copyFunc; + formatInfo.nativeFormat = nativeFormat; + formatInfo.componentType = GetDeclTypeComponentType(nativeFormat); + return formatInfo; +} + #define TRANSLATION(type, norm, size, preferred) \ - { \ + CreateVertexFormatInfo \ + ( \ 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) \ { \ @@ -651,168 +524,63 @@ public: { 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] +static inline unsigned int ComputeTypeIndex(GLenum type) { - 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) -}; + 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; -void InitializeVertexTranslations(const rx::Renderer9 *renderer) -{ - DWORD declTypes = renderer->getCapsDeclTypes(); + default: UNREACHABLE(); return 5; + } +} - for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat) +{ + static bool initialized = false; + static DWORD intializedDeclTypes = 0; + static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + if (!initialized) { - for (unsigned int j = 0; j < 2; j++) + const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] { - for (unsigned int k = 0; k < 4; k++) + 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) + }; + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) { - if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; - } - else + for (unsigned int k = 0; k < 4; k++) { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; + if (translations[i][j][k].capsFlag == 0 || (supportedDeclTypes & translations[i][j][k].capsFlag) != 0) + { + formatConverters[i][j][k] = translations[i][j][k].preferredConversion; + } + else + { + formatConverters[i][j][k] = translations[i][j][k].fallbackConversion; + } } } } + initialized = true; + intializedDeclTypes = supportedDeclTypes; } -} - -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; - } -} + ASSERT(intializedDeclTypes == supportedDeclTypes); -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) -{ - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mTexFormat; - } - else - { - return D3DFMT_UNKNOWN; - } -} - -D3DFORMAT GetRenderFormat(GLenum internalFormat) -{ - D3D9FormatInfo d3d9FormatInfo; - if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) - { - return d3d9FormatInfo.mRenderFormat; - } - else - { - 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) -{ - GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat); - GLenum convertedFormat = gl::GetFormat(internalFormat); - return convertedFormat == format; + return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h index 26388794e0..f26fe43b36 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h @@ -12,6 +12,8 @@ #include "libGLESv2/formatutils.h" +#include <map> + namespace rx { @@ -20,55 +22,50 @@ class Renderer9; namespace d3d9 { -typedef std::set<D3DFORMAT> D3DFormatSet; - -MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format); -LoadImageFunction GetImageLoadFunction(GLenum internalFormat); - -GLuint GetFormatPixelBytes(D3DFORMAT format); -GLuint GetBlockWidth(D3DFORMAT format); -GLuint GetBlockHeight(D3DFORMAT format); -GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height); +typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap; -void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); - -const D3DFormatSet &GetAllUsedD3DFormats(); +struct D3DFormat +{ + D3DFormat(); -ColorReadFunction GetColorReadFunction(D3DFORMAT format); -ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType); + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; -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 internalFormat; -GLenum GetDeclTypeComponentType(D3DDECLTYPE declType); -int GetDeclTypeComponentCount(D3DDECLTYPE declType); -bool IsDeclTypeNormalized(D3DDECLTYPE declType); + MipGenerationFunction mipGenerationFunction; + ColorReadFunction colorReadFunction; -void InitializeVertexTranslations(const rx::Renderer9 *renderer); + FastCopyFunctionMap fastCopyFunctions; + ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; +}; +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); -} - -namespace gl_d3d9 +struct VertexFormat { + VertexFormat(); -D3DFORMAT GetTextureFormat(GLenum internalForma); -D3DFORMAT GetRenderFormat(GLenum internalFormat); + VertexConversionType conversionType; + size_t outputElementSize; + VertexCopyFunction copyFunction; + D3DDECLTYPE nativeFormat; + GLenum componentType; +}; +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat); -D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples); +struct TextureFormat +{ + TextureFormat(); -bool RequiresTextureDataInitialization(GLint internalFormat); -InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat); + D3DFORMAT texFormat; + D3DFORMAT renderFormat; -} - -namespace d3d9_gl -{ + InitializeTextureDataFunction dataInitializerFunction; -GLenum GetInternalFormat(D3DFORMAT format); -GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); + LoadImageFunction loadFunction; +}; +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp index 68e5378fbb..e7a91e62d6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 @@ -11,9 +10,10 @@ #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/formatutils.h" -#include "common/mathutil.h" -#include "libGLESv2/Context.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" +#include "common/mathutil.h" #include "common/debug.h" #include "third_party/systeminfo/SystemInfo.h" @@ -246,40 +246,55 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) +{ + return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE; +} + } namespace d3d9_gl { +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) +{ + return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; +} + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) +{ + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat; + GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format; + return convertedFormat == format; +} + static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType, UINT adapter, D3DFORMAT adapterFormat) { gl::TextureCaps textureCaps; - D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); - if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0) + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, renderFormat)); - textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, renderFormat)); - textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, renderFormat)) || - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, renderFormat)); + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); } else { - D3DFORMAT textureFormat = gl_d3d9::GetTextureFormat(internalFormat); - textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, textureFormat)) && - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, textureFormat)); - textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, textureFormat)); - textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, textureFormat)) || - SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, textureFormat)); + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat)); } + textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)); + textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)) || + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)); + textureCaps.sampleCounts.insert(1); for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); - HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, renderFormat, TRUE, multisampleType, NULL); + HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL); if (SUCCEEDED(result)) { textureCaps.sampleCounts.insert(i); @@ -302,12 +317,20 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT D3DDISPLAYMODE currentDisplayMode; d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); + GLuint maxSamples = 0; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) { gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter, currentDisplayMode.Format); textureCapsMap->insert(*internalFormat, textureCaps); + + maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); + + if (gl::GetInternalFormatInfo(*internalFormat).compressed) + { + caps->compressedTextureFormats.push_back(*internalFormat); + } } // GL core feature limits @@ -347,6 +370,77 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT caps->minAliasedLineWidth = 1.0f; caps->maxAliasedLineWidth = 1.0f; + // Primitive count limits (unused in ES2) + caps->maxElementsIndices = 0; + caps->maxElementsVertices = 0; + + // Program and shader binary formats (no supported shader binary formats) + caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); + + // WaitSync is ES3-only, set to zero + caps->maxServerWaitTimeout = 0; + + // Vertex shader limits + caps->maxVertexAttributes = 16; + + const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange. + const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; + caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors; + caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4; + + caps->maxVertexUniformBlocks = 0; + + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10; + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8; + caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3 + : MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4; + + // Only Direct3D 10 ready devices support all the necessary vertex texture formats. + // We test this using D3D9 by checking support for the R16F format. + if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F))) + { + const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4; + caps->maxVertexTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3; + } + else + { + caps->maxVertexTextureImageUnits = 0; + } + + // Fragment shader limits + const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. + + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224; + const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32; + caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 + : MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors; + caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4; + caps->maxFragmentUniformBlocks = 0; + caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; + caps->maxTextureImageUnits = 16; + caps->minProgramTexelOffset = 0; + caps->maxProgramTexelOffset = 0; + + // Aggregate shader limits (unused in ES2) + caps->maxUniformBufferBindings = 0; + caps->maxUniformBlockSize = 0; + caps->uniformBufferOffsetAlignment = 0; + caps->maxCombinedUniformBlocks = 0; + caps->maxCombinedVertexUniformComponents = 0; + caps->maxCombinedFragmentUniformComponents = 0; + caps->maxVaryingComponents = 0; + + // Aggregate shader limits + caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4; + caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; + + // Transform feedback limits + caps->maxTransformFeedbackInterleavedComponents = 0; + caps->maxTransformFeedbackSeparateAttributes = 0; + caps->maxTransformFeedbackSeparateComponents = 0; + // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16); @@ -394,6 +488,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; + extensions->maxSamples = maxSamples; extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); extensions->packReverseRowOrder = true; extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; @@ -406,4 +501,42 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT } +namespace d3d9 +{ + +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth; + GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight; + return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight); +} + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) +{ + const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format); + + int upsampleCount = 0; + // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. + if (isImage || *requestWidth < static_cast<GLsizei>(d3dFormatInfo.blockWidth) || + *requestHeight < static_cast<GLsizei>(d3dFormatInfo.blockHeight)) + { + while (*requestWidth % d3dFormatInfo.blockWidth != 0 || *requestHeight % d3dFormatInfo.blockHeight != 0) + { + *requestWidth <<= 1; + *requestHeight <<= 1; + upsampleCount++; + } + } + *levelOffset = upsampleCount; +} + +RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +{ + RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); + return RenderTarget9::makeRenderTarget9(renderTarget); +} + +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h index 7f3c65d3e0..b0a940e60a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// renderer9_utils.h: Conversion functions and other utility routines +// renderer9_utils.h: Conversion functions and other utility routines // specific to the D3D9 renderer #ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H @@ -13,8 +13,14 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +namespace gl +{ +class FramebufferAttachment; +} + namespace rx { +class RenderTarget9; namespace gl_d3d9 { @@ -31,11 +37,17 @@ 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); +D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); + } namespace d3d9_gl { +GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); + void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions); @@ -44,6 +56,10 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT namespace d3d9 { +GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height); + +void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset); + inline bool isDeviceLostError(HRESULT errorCode) { switch (errorCode) @@ -58,6 +74,8 @@ inline bool isDeviceLostError(HRESULT errorCode) } } +RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); + } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp index 4a294608ae..1986191a75 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp @@ -1,4 +1,3 @@ -#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 diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp index dcf347d421..f777b30be6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp @@ -1,4 +1,3 @@ -#include "precompiled.h" // // 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 diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h b/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h index 590b9d48a3..81ba8a0767 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h @@ -10,6 +10,10 @@ #ifndef LIBGLESV2_VERTEXCONVERSION_H_ #define LIBGLESV2_VERTEXCONVERSION_H_ +#include <limits> +#include <cstdint> +#include <cstddef> + namespace rx { @@ -154,11 +158,13 @@ struct VertexDataConverter static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); - static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out) + static void convertArray(const uint8_t *input, size_t stride, size_t n, uint8_t *output) { + OutputType *out = reinterpret_cast<OutputType*>(output); + for (std::size_t i = 0; i < n; i++) { - const InputType *ein = pointerAddBytes(in, i * stride); + const InputType *ein = reinterpret_cast<const InputType*>(input + i * stride); copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero())); copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero())); @@ -169,19 +175,7 @@ struct VertexDataConverter } } - static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out) - { - return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out)); - } - private: - // Advance the given pointer by a number of bytes (not pointed-to elements). - template <class T> - static T *pointerAddBytes(T *basePtr, std::size_t numBytes) - { - return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes); - } - static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) { if (WidenRule::finalWidth > elementindex) |