summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@digia.com>2014-09-25 13:22:55 +0300
committerAndrew Knight <andrew.knight@digia.com>2014-09-29 16:09:29 +0200
commit311157c3c6849e8efccd88f7594bb34c570a6780 (patch)
treea50c252b638488326529c0e69aa05e42abce7462 /src/3rdparty/angle/src/libGLESv2
parent04d3a89e20d49a3b5015b071bfdedc81973b090c (diff)
ANGLE: Upgrade to 2.1~abce76206141
Upgrade to address issues discovered since the last upgrade. Patch notes: 0000-General-fixes-for-ANGLE-2.1.patch added removal of the unused third-party tracing functions 0003-Fix-compilation-with-MinGW-gcc-64-bit.patch removed as it is no longer needed 0011-ANGLE-Fix-compilation-error-on-MinGW-caused-by-trace.patch removed as it is no longer needed 0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch now supports MinGW 64-bit [ChangeLog][Third-party libraries] ANGLE updated to 2.1~f8602ad91e4f Task-number: QTBUG-40649 Task-number: QTBUG-40658 Task-number: QTBUG-41031 Task-number: QTBUG-41081 Task-number: QTBUG-41308 Task-number: QTBUG-41563 Change-Id: I9f776c8d5cb94ddb12d608a8d5630bfc54437bea Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Oliver Wolff <oliver.wolff@digia.com> Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/BinaryStream.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.cpp67
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Caps.cpp94
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Caps.h53
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp974
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.h114
-rw-r--r--src/3rdparty/angle/src/libGLESv2/DynamicHLSL.h96
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Error.cpp48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Error.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp163
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.h28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp385
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h157
-rw-r--r--src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/HandleAllocator.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp57
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.cpp23
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp822
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.h133
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Query.cpp33
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Query.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp31
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Sampler.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp476
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.h135
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.cpp124
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.h24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.cpp787
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.h154
-rw-r--r--src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/TransformFeedback.h9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Uniform.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Uniform.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexArray.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexArray.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/constants.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/formatutils.cpp1581
-rw-r--r--src/3rdparty/angle/src/libGLESv2/formatutils.h98
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp3334
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.def3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d.def3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp44
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.cpp9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.h32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/queryconversions.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp57
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h58
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h126
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h54
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h134
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h31
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp11
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h298
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl288
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp (renamed from src/3rdparty/angle/src/libGLESv2/DynamicHLSL.cpp)190
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h104
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h27
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp296
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp205
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h87
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp457
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h94
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp990
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h221
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp160
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h114
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp101
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp357
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h29
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp231
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp93
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp203
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp99
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp129
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp86
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h11
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp1051
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h143
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp682
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h85
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp152
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp1723
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h81
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp564
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp23
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h11
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp119
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp120
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp103
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp851
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h138
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp80
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp189
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h20
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp47
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp734
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h71
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp165
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h20
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES.cpp757
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES.h67
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES2.cpp314
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES2.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES3.cpp785
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES3.h18
173 files changed, 13256 insertions, 12421 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
index 1cbfc6751d..4d7dde04e1 100644
--- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
+++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
@@ -12,6 +12,10 @@
#include "common/angleutils.h"
#include "common/mathutil.h"
+#include <cstddef>
+#include <string>
+#include <vector>
+
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
index a47b8f402f..3b2a1a912a 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.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
@@ -31,59 +30,99 @@ Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
Buffer::~Buffer()
{
- delete mBuffer;
+ SafeDelete(mBuffer);
}
-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
{
+ gl::Error error = mBuffer->setData(data, size, usage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mIndexRangeCache.clear();
mUsage = usage;
mSize = size;
- mBuffer->setData(data, size, usage);
+
+ return error;
}
-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
+Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
- mBuffer->setSubData(data, size, offset);
+ gl::Error error = mBuffer->setSubData(data, size, offset);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mIndexRangeCache.invalidateRange(offset, size);
+
+ return error;
}
-void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
{
- mBuffer->copySubData(source->getImplementation(), size, sourceOffset, destOffset);
+ gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mIndexRangeCache.invalidateRange(destOffset, size);
+
+ return error;
}
-GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
+Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
{
ASSERT(!mMapped);
ASSERT(offset + length <= mSize);
- void *dataPointer = mBuffer->map(offset, length, access);
+ Error error = mBuffer->map(offset, length, access, &mMapPointer);
+ if (error.isError())
+ {
+ mMapPointer = NULL;
+ return error;
+ }
mMapped = GL_TRUE;
- mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer));
mMapOffset = static_cast<GLint64>(offset);
mMapLength = static_cast<GLint64>(length);
mAccessFlags = static_cast<GLint>(access);
- return mMapPointer;
+ if ((access & GL_MAP_WRITE_BIT) > 0)
+ {
+ mIndexRangeCache.invalidateRange(offset, length);
+ }
+
+ return error;
}
-void Buffer::unmap()
+Error Buffer::unmap()
{
ASSERT(mMapped);
- mBuffer->unmap();
+ Error error = mBuffer->unmap();
+ if (error.isError())
+ {
+ return error;
+ }
mMapped = GL_FALSE;
mMapPointer = NULL;
mMapOffset = 0;
mMapLength = 0;
mAccessFlags = 0;
+
+ return error;
}
void Buffer::markTransformFeedbackUsage()
{
// TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
mBuffer->markTransformFeedbackUsage();
+ mIndexRangeCache.clear();
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
index 389c3d4b00..35a6767502 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
@@ -11,8 +11,11 @@
#ifndef LIBGLESV2_BUFFER_H_
#define LIBGLESV2_BUFFER_H_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+#include "libGLESv2/renderer/IndexRangeCache.h"
namespace rx
{
@@ -30,13 +33,13 @@ class Buffer : public RefCountObject
virtual ~Buffer();
- void bufferData(const void *data, GLsizeiptr size, GLenum usage);
- void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
- void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
- GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
- void unmap();
+ Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
+ Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+ Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+ Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
+ Error unmap();
- GLenum getUsage() const { return mUsage; }
+ GLenum getUsage() const { return mUsage; }
GLint getAccessFlags() const { return mAccessFlags; }
GLboolean isMapped() const { return mMapped; }
GLvoid *getMapPointer() const { return mMapPointer; }
@@ -48,18 +51,23 @@ class Buffer : public RefCountObject
void markTransformFeedbackUsage();
+ rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
+ const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; }
+
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
rx::BufferImpl *mBuffer;
GLenum mUsage;
- GLsizeiptr mSize;
+ GLint64 mSize;
GLint mAccessFlags;
GLboolean mMapped;
GLvoid *mMapPointer;
GLint64 mMapOffset;
GLint64 mMapLength;
+
+ rx::IndexRangeCache mIndexRangeCache;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Caps.cpp b/src/3rdparty/angle/src/libGLESv2/Caps.cpp
index c1c4dc9ee7..983800c0e6 100644
--- a/src/3rdparty/angle/src/libGLESv2/Caps.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Caps.cpp
@@ -24,6 +24,30 @@ TextureCaps::TextureCaps()
{
}
+GLuint TextureCaps::getMaxSamples() const
+{
+ return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
+}
+
+GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
+{
+ if (requestedSamples == 0)
+ {
+ return 0;
+ }
+
+ for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
+ {
+ GLuint samples = *i;
+ if (samples >= requestedSamples)
+ {
+ return samples;
+ }
+ }
+
+ return 0;
+}
+
void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
{
mCapsMap.insert(std::make_pair(internalFormat, caps));
@@ -158,12 +182,17 @@ std::vector<std::string> Extensions::getStrings() const
}
static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector<GLenum> &requiredFormats,
- bool requiresFiltering, bool requiresRendering)
+ bool requiresTexturing, bool requiresFiltering, bool requiresRendering)
{
for (size_t i = 0; i < requiredFormats.size(); i++)
{
const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
+ if (requiresTexturing && !cap.texturable)
+ {
+ return false;
+ }
+
if (requiresFiltering && !cap.filterable)
{
return false;
@@ -185,7 +214,7 @@ static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCap
requiredFormats.push_back(GL_RGB8);
requiredFormats.push_back(GL_RGBA8);
- return GetFormatSupport(textureCaps, requiredFormats, true, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Checks for GL_EXT_texture_format_BGRA8888 support
@@ -194,7 +223,7 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_BGRA8_EXT);
- return GetFormatSupport(textureCaps, requiredFormats, true, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Checks for GL_OES_texture_half_float support
@@ -204,7 +233,7 @@ static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGB16F);
requiredFormats.push_back(GL_RGBA16F);
- return GetFormatSupport(textureCaps, requiredFormats, false, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
// Checks for GL_OES_texture_half_float_linear support
@@ -214,7 +243,7 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text
requiredFormats.push_back(GL_RGB16F);
requiredFormats.push_back(GL_RGBA16F);
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Checks for GL_OES_texture_float support
@@ -224,7 +253,7 @@ static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGB32F);
requiredFormats.push_back(GL_RGBA32F);
- return GetFormatSupport(textureCaps, requiredFormats, false, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
// Checks for GL_OES_texture_float_linear support
@@ -234,7 +263,7 @@ static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureC
requiredFormats.push_back(GL_RGB32F);
requiredFormats.push_back(GL_RGBA32F);
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Checks for GL_EXT_texture_rg support
@@ -254,7 +283,7 @@ static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool ch
requiredFormats.push_back(GL_RG32F);
}
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_EXT_texture_compression_dxt1
@@ -264,7 +293,7 @@ static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt3
@@ -273,7 +302,7 @@ static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt5
@@ -282,7 +311,7 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredFormats;
requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
- return GetFormatSupport(textureCaps, requiredFormats, true, false);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false);
}
// Check for GL_ANGLE_texture_compression_dxt5
@@ -295,8 +324,8 @@ static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
std::vector<GLenum> requiredRenderFormats;
requiredRenderFormats.push_back(GL_SRGB8_ALPHA8);
- return GetFormatSupport(textureCaps, requiredFilterFormats, true, false) &&
- GetFormatSupport(textureCaps, requiredRenderFormats, false, true);
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) &&
+ GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true);
}
// Check for GL_ANGLE_depth_texture
@@ -307,7 +336,7 @@ static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES);
requiredFormats.push_back(GL_DEPTH24_STENCIL8_OES);
- return GetFormatSupport(textureCaps, requiredFormats, true, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, true);
}
// Check for GL_EXT_color_buffer_float
@@ -322,7 +351,7 @@ static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
requiredFormats.push_back(GL_RGBA32F);
requiredFormats.push_back(GL_R11F_G11F_B10F);
- return GetFormatSupport(textureCaps, requiredFormats, false, true);
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true);
}
void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
@@ -356,7 +385,40 @@ Caps::Caps()
maxViewportHeight(0),
minAliasedPointSize(0),
maxAliasedPointSize(0),
- minAliasedLineWidth(0)
+ minAliasedLineWidth(0),
+ // Table 6.29
+ maxElementsIndices(0),
+ maxElementsVertices(0),
+ maxServerWaitTimeout(0),
+ // Table 6.31
+ maxVertexAttributes(0),
+ maxVertexUniformComponents(0),
+ maxVertexUniformVectors(0),
+ maxVertexUniformBlocks(0),
+ maxVertexOutputComponents(0),
+ maxVertexTextureImageUnits(0),
+ // Table 6.32
+ maxFragmentUniformComponents(0),
+ maxFragmentUniformVectors(0),
+ maxFragmentUniformBlocks(0),
+ maxFragmentInputComponents(0),
+ maxTextureImageUnits(0),
+ minProgramTexelOffset(0),
+ maxProgramTexelOffset(0),
+
+ maxUniformBufferBindings(0),
+ maxUniformBlockSize(0),
+ uniformBufferOffsetAlignment(0),
+ maxCombinedUniformBlocks(0),
+ maxCombinedVertexUniformComponents(0),
+ maxCombinedFragmentUniformComponents(0),
+ maxVaryingComponents(0),
+ maxVaryingVectors(0),
+ maxCombinedTextureImageUnits(0),
+
+ maxTransformFeedbackInterleavedComponents(0),
+ maxTransformFeedbackSeparateAttributes(0),
+ maxTransformFeedbackSeparateComponents(0)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Caps.h b/src/3rdparty/angle/src/libGLESv2/Caps.h
index a08618ec9c..a00e554176 100644
--- a/src/3rdparty/angle/src/libGLESv2/Caps.h
+++ b/src/3rdparty/angle/src/libGLESv2/Caps.h
@@ -17,6 +17,8 @@
namespace gl
{
+typedef std::set<GLuint> SupportedSampleSet;
+
struct TextureCaps
{
TextureCaps();
@@ -30,7 +32,14 @@ struct TextureCaps
// Support for being used as a framebuffer attachment or renderbuffer format
bool renderable;
- std::set<GLuint> sampleCounts;
+ SupportedSampleSet sampleCounts;
+
+ // Get the maximum number of samples supported
+ GLuint getMaxSamples() const;
+
+ // Get the number of supported samples that is at least as many as requested. Returns 0 if
+ // there are no sample counts available
+ GLuint getNearestSamples(GLuint requestedSamples) const;
};
class TextureCapsMap
@@ -68,6 +77,7 @@ struct Extensions
// GL_OES_texture_float, GL_OES_texture_float_linear
// GL_EXT_texture_rg
// GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5
+ // GL_EXT_sRGB
// GL_ANGLE_depth_texture
// GL_EXT_color_buffer_float
void setTextureExtensionSupport(const TextureCapsMap &textureCaps);
@@ -166,6 +176,7 @@ struct Extensions
// GL_ANGLE_framebuffer_multisample
bool framebufferMultisample;
+ GLuint maxSamples;
// GL_ANGLE_instanced_arrays
bool instancedArrays;
@@ -215,6 +226,46 @@ struct Caps
GLfloat minAliasedLineWidth;
GLfloat maxAliasedLineWidth;
+ // Table 6.29, implementation dependent values (cont.)
+ GLuint maxElementsIndices;
+ GLuint maxElementsVertices;
+ std::vector<GLenum> compressedTextureFormats;
+ std::vector<GLenum> programBinaryFormats;
+ std::vector<GLenum> shaderBinaryFormats;
+ GLuint64 maxServerWaitTimeout;
+
+ // Table 6.31, implementation dependent vertex shader limits
+ GLuint maxVertexAttributes;
+ GLuint maxVertexUniformComponents;
+ GLuint maxVertexUniformVectors;
+ GLuint maxVertexUniformBlocks;
+ GLuint maxVertexOutputComponents;
+ GLuint maxVertexTextureImageUnits;
+
+ // Table 6.32, implementation dependent fragment shader limits
+ GLuint maxFragmentUniformComponents;
+ GLuint maxFragmentUniformVectors;
+ GLuint maxFragmentUniformBlocks;
+ GLuint maxFragmentInputComponents;
+ GLuint maxTextureImageUnits;
+ GLint minProgramTexelOffset;
+ GLint maxProgramTexelOffset;
+
+ // Table 6.33, implementation dependent aggregate shader limits
+ GLuint maxUniformBufferBindings;
+ GLuint64 maxUniformBlockSize;
+ GLuint uniformBufferOffsetAlignment;
+ GLuint maxCombinedUniformBlocks;
+ GLuint64 maxCombinedVertexUniformComponents;
+ GLuint64 maxCombinedFragmentUniformComponents;
+ GLuint maxVaryingComponents;
+ GLuint maxVaryingVectors;
+ GLuint maxCombinedTextureImageUnits;
+
+ // Table 6.34, implementation dependent transform feedback limits
+ GLuint maxTransformFeedbackInterleavedComponents;
+ GLuint maxTransformFeedbackSeparateAttributes;
+ GLuint maxTransformFeedbackSeparateComponents;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index 99df85b0d3..5342de1331 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.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
@@ -12,6 +11,7 @@
#include "libGLESv2/main.h"
#include "common/utilities.h"
+#include "common/platform.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
@@ -24,7 +24,6 @@
#include "libGLESv2/Texture.h"
#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h"
@@ -33,8 +32,8 @@
#include "libEGL/Surface.h"
-#undef near
-#undef far
+#include <sstream>
+#include <iterator>
namespace gl
{
@@ -45,6 +44,7 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
ASSERT(robustAccess == false); // Unimplemented
initCaps(clientVersion);
+ mState.initialize(mCaps, clientVersion);
mClientVersion = clientVersion;
@@ -66,16 +66,26 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0));
- mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTextureCube(), 0));
- mTexture3DZero.set(new Texture3D(mRenderer->createTexture3D(), 0));
- mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture2DArray(), 0));
+ mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
+ bindTexture(GL_TEXTURE_2D, 0);
+
+ mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
+ bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+ if (mClientVersion >= 3)
+ {
+ // TODO: These could also be enabled via extension
+ mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
+ bindTexture(GL_TEXTURE_3D, 0);
+
+ mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
+ bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+ }
bindVertexArray(0);
bindArrayBuffer(0);
bindElementArrayBuffer(0);
- bindTextureCubeMap(0);
- bindTexture2D(0);
+
bindReadFramebuffer(0);
bindDrawFramebuffer(0);
bindRenderbuffer(0);
@@ -101,23 +111,15 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In the initial state, a default transform feedback object is bound and treated as
// a transform feedback object with a name of zero. That object is bound any time
// BindTransformFeedback is called with id of zero
- mTransformFeedbackZero.set(new TransformFeedback(0));
+ mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0));
bindTransformFeedback(0);
- mInvalidEnum = false;
- mInvalidValue = false;
- mInvalidOperation = false;
- mOutOfMemory = false;
- mInvalidFramebufferOperation = false;
-
mHasBeenCurrent = false;
mContextLost = false;
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
- mNumCompressedTextureFormats = 0;
-
mState.setContext(this);
}
@@ -161,15 +163,17 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
}
- for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+ for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
{
- mIncompleteTextures[type].set(NULL);
+ i->second.set(NULL);
}
+ mIncompleteTextures.clear();
- mTexture2DZero.set(NULL);
- mTextureCubeMapZero.set(NULL);
- mTexture3DZero.set(NULL);
- mTexture2DArrayZero.set(NULL);
+ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+ {
+ i->second.set(NULL);
+ }
+ mZeroTextures.clear();
mResourceManager->release();
}
@@ -178,23 +182,6 @@ void Context::makeCurrent(egl::Surface *surface)
{
if (!mHasBeenCurrent)
{
- mMajorShaderModel = mRenderer->getMajorShaderModel();
- mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
-
- mNumCompressedTextureFormats = 0;
- if (mExtensions.textureCompressionDXT1)
- {
- mNumCompressedTextureFormats += 2;
- }
- if (mExtensions.textureCompressionDXT3)
- {
- mNumCompressedTextureFormats += 1;
- }
- if (mExtensions.textureCompressionDXT5)
- {
- mNumCompressedTextureFormats += 1;
- }
-
initRendererString();
initExtensionStrings();
@@ -287,7 +274,7 @@ GLuint Context::createSampler()
GLuint Context::createTransformFeedback()
{
GLuint handle = mTransformFeedbackAllocator.allocate();
- TransformFeedback *transformFeedback = new TransformFeedback(handle);
+ TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle);
transformFeedback->addRef();
mTransformFeedbackMap[handle] = transformFeedback;
return handle;
@@ -528,32 +515,11 @@ void Context::bindElementArrayBuffer(unsigned int buffer)
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
}
-void Context::bindTexture2D(GLuint texture)
+void Context::bindTexture(GLenum target, GLuint texture)
{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+ mResourceManager->checkTextureAllocation(texture, target);
- mState.setSamplerTexture(TEXTURE_2D, getTexture(texture));
-}
-
-void Context::bindTextureCubeMap(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
-
- mState.setSamplerTexture(TEXTURE_CUBE, getTexture(texture));
-}
-
-void Context::bindTexture3D(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
-
- mState.setSamplerTexture(TEXTURE_3D, getTexture(texture));
-}
-
-void Context::bindTexture2DArray(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
-
- mState.setSamplerTexture(TEXTURE_2D_ARRAY, getTexture(texture));
+ mState.setSamplerTexture(target, getTexture(texture));
}
void Context::bindReadFramebuffer(GLuint framebuffer)
@@ -596,7 +562,7 @@ void Context::bindVertexArray(GLuint vertexArray)
void Context::bindSampler(GLuint textureUnit, GLuint sampler)
{
- ASSERT(textureUnit < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS); // TODO: Update for backend-determined array size
+ ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
mResourceManager->checkSamplerAllocation(sampler);
mState.setSamplerBinding(textureUnit, getSampler(sampler));
@@ -678,7 +644,7 @@ void Context::linkProgram(GLuint program)
{
Program *programObject = mResourceManager->getProgram(program);
- bool linked = programObject->link();
+ bool linked = programObject->link(getCaps());
// if the current program was relinked successfully we
// need to install the new executables
@@ -688,11 +654,11 @@ void Context::linkProgram(GLuint program)
}
}
-void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
+void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
{
Program *programObject = mResourceManager->getProgram(program);
- bool loaded = programObject->setProgramBinary(binary, length);
+ bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
// if the current program was reloaded successfully we
// need to install the new executables
@@ -708,26 +674,35 @@ void Context::bindTransformFeedback(GLuint transformFeedback)
mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
}
-void Context::beginQuery(GLenum target, GLuint query)
+Error Context::beginQuery(GLenum target, GLuint query)
{
Query *queryObject = getQuery(query, true, target);
ASSERT(queryObject);
- // set query as active for specified target
+ // begin query
+ Error error = queryObject->begin();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // set query as active for specified target only if begin succeeded
mState.setActiveQuery(target, queryObject);
- // begin query
- queryObject->begin();
+ return Error(GL_NO_ERROR);
}
-void Context::endQuery(GLenum target)
+Error Context::endQuery(GLenum target)
{
Query *queryObject = mState.getActiveQuery(target);
ASSERT(queryObject);
- queryObject->end();
+ gl::Error error = queryObject->end();
+ // Always unbind the query, even if there was an error. This may delete the query object.
mState.setActiveQuery(target, NULL);
+
+ return error;
}
void Context::setFramebufferZero(Framebuffer *buffer)
@@ -755,15 +730,16 @@ void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum inter
RenderbufferStorage *renderbuffer = NULL;
- if (GetDepthBits(internalformat) > 0 && GetStencilBits(internalformat) > 0)
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
{
renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
}
- else if (GetDepthBits(internalformat) > 0)
+ else if (formatInfo.depthBits > 0)
{
renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
}
- else if (GetStencilBits(internalformat) > 0)
+ else if (formatInfo.stencilBits > 0)
{
renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
}
@@ -815,7 +791,7 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
{
if (!query->second && create)
{
- query->second = new Query(mRenderer, type, handle);
+ query->second = new Query(mRenderer->createQuery(type), handle);
query->second->addRef();
}
return query->second;
@@ -841,36 +817,29 @@ Texture *Context::getTargetTexture(GLenum target) const
Texture2D *Context::getTexture2D() const
{
- return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D));
+ return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
}
TextureCubeMap *Context::getTextureCubeMap() const
{
- return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_CUBE));
+ return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
}
Texture3D *Context::getTexture3D() const
{
- return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_3D));
+ return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
}
Texture2DArray *Context::getTexture2DArray() const
{
- return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D_ARRAY));
+ return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
}
-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
+Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
if (mState.getSamplerTextureId(sampler, type) == 0)
{
- switch (type)
- {
- default: UNREACHABLE();
- case TEXTURE_2D: return mTexture2DZero.get();
- case TEXTURE_CUBE: return mTextureCubeMapZero.get();
- case TEXTURE_3D: return mTexture3DZero.get();
- case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
- }
+ return mZeroTextures.at(type).get();
}
else
{
@@ -921,45 +890,39 @@ void Context::getIntegerv(GLenum pname, GLint *params)
switch (pname)
{
- case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
- case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
- case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break;
- case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
- case GL_MAX_VARYING_COMPONENTS: *params = mRenderer->getMaxVaryingVectors() * 4; break;
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
- case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
- case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break;
+ case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
+ case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
+ case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
- case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
- case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
//case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
- case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break;
- case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break;
- case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break;
- case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break;
- case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
case GL_MAJOR_VERSION: *params = mClientVersion; break;
case GL_MINOR_VERSION: *params = 0; break;
- case GL_MAX_ELEMENTS_INDICES: *params = mRenderer->getMaxRecommendedElementsIndices(); break;
- case GL_MAX_ELEMENTS_VERTICES: *params = mRenderer->getMaxRecommendedElementsVertices(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mRenderer->getMaxTransformFeedbackBuffers(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackSeparateComponents(); break;
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
- params[0] = mNumCompressedTextureFormats;
- break;
- case GL_MAX_SAMPLES_ANGLE:
- *params = static_cast<GLint>(getMaxSupportedSamples());
- break;
+ case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
+ case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = mCaps.compressedTextureFormats.size(); break;
+ case GL_MAX_SAMPLES_ANGLE: *params = mExtensions.maxSamples; break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE:
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
{
@@ -978,30 +941,22 @@ void Context::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
- {
- if (mExtensions.textureCompressionDXT1)
- {
- *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- }
- if (mExtensions.textureCompressionDXT3)
- {
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
- }
- if (mExtensions.textureCompressionDXT5)
- {
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
- }
- }
+ std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
break;
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
*params = mResetStrategy;
break;
- case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
- *params = 1;
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ *params = mCaps.shaderBinaryFormats.size();
break;
- case GL_PROGRAM_BINARY_FORMATS_OES:
- *params = GL_PROGRAM_BINARY_ANGLE;
+ case GL_SHADER_BINARY_FORMATS:
+ std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
+ break;
+ case GL_NUM_PROGRAM_BINARY_FORMATS:
+ *params = mCaps.programBinaryFormats.size();
+ break;
+ case GL_PROGRAM_BINARY_FORMATS:
+ std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
break;
case GL_NUM_EXTENSIONS:
*params = static_cast<GLint>(mExtensionStrings.size());
@@ -1022,25 +977,16 @@ void Context::getInteger64v(GLenum pname, GLint64 *params)
*params = mCaps.maxElementIndex;
break;
case GL_MAX_UNIFORM_BLOCK_SIZE:
- *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
+ *params = mCaps.maxUniformBlockSize;
break;
case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
- {
- GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
- GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
- *params = uniformBufferComponents + defaultBufferComponents;
- }
+ *params = mCaps.maxCombinedVertexUniformComponents;
break;
case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
- {
- GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
- GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
- *params = uniformBufferComponents + defaultBufferComponents;
- }
+ *params = mCaps.maxCombinedFragmentUniformComponents;
break;
case GL_MAX_SERVER_WAIT_TIMEOUT:
- // We do not wait for server fence objects internally, so report a max timeout of zero.
- *params = 0;
+ *params = mCaps.maxServerWaitTimeout;
break;
default:
UNREACHABLE();
@@ -1087,13 +1033,19 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_COMPRESSED_TEXTURE_FORMATS:
{
*type = GL_INT;
- *numParams = mNumCompressedTextureFormats;
+ *numParams = mCaps.compressedTextureFormats.size();
+ }
+ return true;
+ case GL_PROGRAM_BINARY_FORMATS_OES:
+ {
+ *type = GL_INT;
+ *numParams = mCaps.programBinaryFormats.size();
}
return true;
case GL_SHADER_BINARY_FORMATS:
{
*type = GL_INT;
- *numParams = 0;
+ *numParams = mCaps.shaderBinaryFormats.size();
}
return true;
case GL_MAX_VERTEX_ATTRIBS:
@@ -1162,7 +1114,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
- case GL_PROGRAM_BINARY_FORMATS_OES:
{
*type = GL_INT;
*numParams = 1;
@@ -1360,28 +1311,29 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
// Applies the render target surface, depth stencil surface, viewport rectangle and
// scissor rectangle to the renderer
-bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
+Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
{
Framebuffer *framebufferObject = mState.getDrawFramebuffer();
ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
- mRenderer->applyRenderTarget(framebufferObject);
+ gl::Error error = mRenderer->applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
float nearZ, farZ;
mState.getDepthRange(&nearZ, &farZ);
- if (!mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
- ignoreViewport))
- {
- return false;
- }
+ mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
+ ignoreViewport);
mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
-void Context::applyState(GLenum drawMode)
+Error Context::applyState(GLenum drawMode)
{
Framebuffer *framebufferObject = mState.getDrawFramebuffer();
int samples = framebufferObject->getSamples();
@@ -1390,7 +1342,11 @@ void Context::applyState(GLenum drawMode)
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
- mRenderer->setRasterizerState(rasterizer);
+ Error error = mRenderer->setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
unsigned int mask = 0;
if (mState.isSampleCoverageEnabled())
@@ -1400,7 +1356,6 @@ void Context::applyState(GLenum drawMode)
mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
if (coverageValue != 0)
{
-
float threshold = 0.5f;
for (int i = 0; i < samples; ++i)
@@ -1424,117 +1379,185 @@ void Context::applyState(GLenum drawMode)
{
mask = 0xFFFFFFFF;
}
- mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
+ error = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
+ rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
- rasterizer.frontFace == GL_CCW);
+ return Error(GL_NO_ERROR);
}
// Applies the shaders and shader constants to the Direct3D 9 device
-void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
+Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
{
const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
- VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
const Framebuffer *fbo = mState.getDrawFramebuffer();
- mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- programBinary->applyUniforms();
+ return programBinary->applyUniforms();
}
-size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
- TextureType *outTextureTypes, SamplerState *outSamplers)
+Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
{
size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
for (size_t i = 0; i < samplerRange; i++)
{
- outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i); // OpenGL texture image unit index
+ GLenum textureType = programBinary->getSamplerTextureType(type, i);
+ GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
if (textureUnit != -1)
{
- outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
- outTextures[i]->getSamplerStateWithNativeOffset(&outSamplers[i]);
- Sampler *samplerObject = mState.getSampler(textureUnit);
- if (samplerObject)
+ Texture* texture = getSamplerTexture(textureUnit, textureType);
+ if (texture->getSamplerState().swizzleRequired())
{
- samplerObject->getState(&outSamplers[i]);
+ Error error = mRenderer->generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
- else
- {
- outTextures[i] = NULL;
- }
}
- return samplerRange;
+ return Error(GL_NO_ERROR);
}
-void Context::generateSwizzles(Texture *textures[], size_t count)
+Error Context::generateSwizzles(ProgramBinary *programBinary)
{
- for (size_t i = 0; i < count; i++)
+ Error error = generateSwizzles(programBinary, SAMPLER_VERTEX);
+ if (error.isError())
{
- if (textures[i] && textures[i]->getSamplerState().swizzleRequired())
- {
- mRenderer->generateSwizzle(textures[i]);
- }
+ return error;
}
+
+ error = generateSwizzles(programBinary, SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return Error(GL_NO_ERROR);
}
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
-void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
- size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
- size_t framebufferSerialCount)
+Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
{
- // Range of Direct3D samplers of given sampler type
- size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
- : mRenderer->getMaxVertexTextureImageUnits();
-
- for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
+ size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{
- Texture *texture = textures[samplerIndex];
- const SamplerState &sampler = samplers[samplerIndex];
- TextureType textureType = textureTypes[samplerIndex];
-
- if (texture)
+ GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
+ if (textureUnit != -1)
{
+ SamplerState sampler;
+ Texture* texture = getSamplerTexture(textureUnit, textureType);
+ texture->getSamplerStateWithNativeOffset(&sampler);
+
+ Sampler *samplerObject = mState.getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
// TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler) &&
+ if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
!std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
{
- mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
- mRenderer->setTexture(shaderType, samplerIndex, texture);
- texture->resetDirty();
+ Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mRenderer->setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
}
else
{
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
Texture *incompleteTexture = getIncompleteTexture(textureType);
- mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
- incompleteTexture->resetDirty();
+ gl::Error error = mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
else
{
- mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
- for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
+ : mCaps.maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
{
- mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return Error(GL_NO_ERROR);
}
-bool Context::applyUniformBuffers()
+Error Context::applyTextures(ProgramBinary *programBinary)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
+
+ Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Context::applyUniformBuffers()
{
Program *programObject = getProgram(mState.getCurrentProgramId());
ProgramBinary *programBinary = programObject->getProgramBinary();
- std::vector<gl::Buffer*> boundBuffers;
+ std::vector<Buffer*> boundBuffers;
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
{
@@ -1543,7 +1566,7 @@ bool Context::applyUniformBuffers()
if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
{
// undefined behaviour
- return false;
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
}
else
{
@@ -1553,7 +1576,7 @@ bool Context::applyUniformBuffers()
}
}
- return programBinary->applyUniformBuffers(boundBuffers);
+ return programBinary->applyUniformBuffers(boundBuffers, getCaps());
}
bool Context::applyTransformFeedbackBuffers()
@@ -1589,28 +1612,25 @@ void Context::markTransformFeedbackUsage()
}
}
-void Context::clear(GLbitfield mask)
+Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
ClearParameters clearParams = mState.getClearParameters(mask);
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
+Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfv can be called to clear the color buffer or depth buffer
@@ -1632,19 +1652,16 @@ void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
clearParams.depthClearValue = values[0];
}
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
+Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferuv can only be called to clear a color buffer
@@ -1656,19 +1673,16 @@ void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *
clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
+Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfv can be called to clear the color buffer or stencil buffer
@@ -1690,19 +1704,16 @@ void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
clearParams.stencilClearValue = values[1];
}
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
+Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfi can only be called to clear a depth stencil buffer
@@ -1712,135 +1723,145 @@ void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int sten
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
- gl::Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Framebuffer *framebuffer = mState.getReadFramebuffer();
- bool isSized = IsSizedInternalFormat(format);
- GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type));
- GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, width, mState.getPackAlignment());
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+ const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
+ GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
- mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), pixels);
+ return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
+ reinterpret_cast<uint8_t*>(pixels));
}
-void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
+Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
ASSERT(mState.getCurrentProgramId() != 0);
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
- Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
- Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
- TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
- SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
- size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
- generateSwizzles(vsTextures, vsTextureCount);
- generateSwizzles(psTextures, psTextureCount);
+ Error error = generateSwizzles(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
if (!mRenderer->applyPrimitiveType(mode, count))
{
- return;
+ return Error(GL_NO_ERROR);
}
- if (!applyRenderTarget(mode, false))
+ error = applyRenderTarget(mode, false);
+ if (error.isError())
{
- return;
+ return error;
}
- applyState(mode);
+ error = applyState(mode);
+ if (error.isError())
+ {
+ return error;
+ }
- GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
- if (err != GL_NO_ERROR)
+ error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
- applyShaders(programBinary, transformFeedbackActive);
-
- FramebufferTextureSerialArray frameBufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
+ error = applyShaders(programBinary, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
- applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+ error = applyTextures(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
- if (!applyUniformBuffers())
+ error = applyUniformBuffers();
+ if (error.isError())
{
- return;
+ return error;
}
if (!skipDraw(mode))
{
- mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
+ error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
if (transformFeedbackActive)
{
markTransformFeedbackUsage();
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
+Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const rx::RangeUI &indexRange)
{
ASSERT(mState.getCurrentProgramId() != 0);
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
- Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
- Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
- TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
- SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
- size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
- generateSwizzles(vsTextures, vsTextureCount);
- generateSwizzles(psTextures, psTextureCount);
+ Error error = generateSwizzles(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
if (!mRenderer->applyPrimitiveType(mode, count))
{
- return;
+ return Error(GL_NO_ERROR);
}
- if (!applyRenderTarget(mode, false))
+ error = applyRenderTarget(mode, false);
+ if (error.isError())
{
- return;
+ return error;
}
- applyState(mode);
+ error = applyState(mode);
+ if (error.isError())
+ {
+ return error;
+ }
VertexArray *vao = mState.getVertexArray();
rx::TranslatedIndexData indexInfo;
- GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (err != GL_NO_ERROR)
+ indexInfo.indexRange = indexRange;
+ error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
- GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
- err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.getVertexAttribCurrentValues(), indexInfo.minIndex, vertexCount, instances);
- if (err != GL_NO_ERROR)
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
+ mState.getVertexAttribCurrentValues(),
+ indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
@@ -1848,23 +1869,34 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
// layer.
ASSERT(!transformFeedbackActive);
- applyShaders(programBinary, transformFeedbackActive);
-
- FramebufferTextureSerialArray frameBufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
+ error = applyShaders(programBinary, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
- applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+ error = applyTextures(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
- if (!applyUniformBuffers())
+ error = applyUniformBuffers();
+ if (error.isError())
{
- return;
+ return error;
}
if (!skipDraw(mode))
{
- mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return Error(GL_NO_ERROR);
}
// Implements glFlush when block is false, glFinish when block is true
@@ -1873,71 +1905,28 @@ void Context::sync(bool block)
mRenderer->sync(block);
}
-void Context::recordInvalidEnum()
-{
- mInvalidEnum = true;
-}
-
-void Context::recordInvalidValue()
-{
- mInvalidValue = true;
-}
-
-void Context::recordInvalidOperation()
-{
- mInvalidOperation = true;
-}
-
-void Context::recordOutOfMemory()
+void Context::recordError(const Error &error)
{
- mOutOfMemory = true;
-}
-
-void Context::recordInvalidFramebufferOperation()
-{
- mInvalidFramebufferOperation = true;
+ if (error.isError())
+ {
+ mErrors.insert(error.getCode());
+ }
}
// Get one of the recorded errors and clear its flag, if any.
// [OpenGL ES 2.0.24] section 2.5 page 13.
GLenum Context::getError()
{
- if (mInvalidEnum)
- {
- mInvalidEnum = false;
-
- return GL_INVALID_ENUM;
- }
-
- if (mInvalidValue)
+ if (mErrors.empty())
{
- mInvalidValue = false;
-
- return GL_INVALID_VALUE;
- }
-
- if (mInvalidOperation)
- {
- mInvalidOperation = false;
-
- return GL_INVALID_OPERATION;
- }
-
- if (mOutOfMemory)
- {
- mOutOfMemory = false;
-
- return GL_OUT_OF_MEMORY;
+ return GL_NO_ERROR;
}
-
- if (mInvalidFramebufferOperation)
+ else
{
- mInvalidFramebufferOperation = false;
-
- return GL_INVALID_FRAMEBUFFER_OPERATION;
+ GLenum error = *mErrors.begin();
+ mErrors.erase(mErrors.begin());
+ return error;
}
-
- return GL_NO_ERROR;
}
GLenum Context::getResetStatus()
@@ -1989,53 +1978,6 @@ const Extensions &Context::getExtensions() const
return mExtensions;
}
-int Context::getMajorShaderModel() const
-{
- return mMajorShaderModel;
-}
-
-unsigned int Context::getMaximumCombinedTextureImageUnits() const
-{
- return mRenderer->getMaxCombinedTextureImageUnits();
-}
-
-unsigned int Context::getMaximumCombinedUniformBufferBindings() const
-{
- return mRenderer->getMaxVertexShaderUniformBuffers() +
- mRenderer->getMaxFragmentShaderUniformBuffers();
-}
-
-int Context::getMaxSupportedSamples() const
-{
- return mRenderer->getMaxSupportedSamples();
-}
-
-GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
-{
- return mRenderer->getMaxSupportedFormatSamples(internalFormat);
-}
-
-GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
-{
- return mRenderer->getNumSampleCounts(internalFormat);
-}
-
-void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
-{
- mRenderer->getSampleCounts(internalFormat, bufSize, params);
-}
-
-unsigned int Context::getMaxTransformFeedbackBufferBindings() const
-{
- return mRenderer->getMaxTransformFeedbackBuffers();
-}
-
-GLintptr Context::getUniformBufferOffsetAlignment() const
-{
- // setting a large alignment forces uniform buffers to bind with zero offset
- return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
-}
-
void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
{
Framebuffer *framebuffer = mState.getReadFramebuffer();
@@ -2044,9 +1986,12 @@ void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, G
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
ASSERT(attachment);
- *internalFormat = attachment->getActualFormat();
- *format = gl::GetFormat(attachment->getActualFormat());
- *type = gl::GetType(attachment->getActualFormat());
+ GLenum actualFormat = attachment->getActualFormat();
+ const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
+
+ *internalFormat = actualFormat;
+ *format = actualFormatInfo.format;
+ *type = actualFormatInfo.type;
}
void Context::detachTexture(GLuint texture)
@@ -2127,32 +2072,31 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler);
}
-Texture *Context::getIncompleteTexture(TextureType type)
+Texture *Context::getIncompleteTexture(GLenum type)
{
- Texture *t = mIncompleteTextures[type].get();
-
- if (t == NULL)
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
{
const GLubyte color[] = { 0, 0, 0, 255 };
const PixelUnpackState incompleteUnpackState(1);
+ Texture* t = NULL;
switch (type)
{
default:
UNREACHABLE();
// default falls through to TEXTURE_2D
- case TEXTURE_2D:
+ case GL_TEXTURE_2D:
{
- Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture2D(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2d;
}
break;
- case TEXTURE_CUBE:
+ case GL_TEXTURE_CUBE_MAP:
{
- TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTextureCube(), Texture::INCOMPLETE_TEXTURE_ID);
+ TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
@@ -2165,18 +2109,18 @@ Texture *Context::getIncompleteTexture(TextureType type)
}
break;
- case TEXTURE_3D:
+ case GL_TEXTURE_3D:
{
- Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture3D(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete3d;
}
break;
- case TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
{
- Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture2DArray(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2darray;
@@ -2187,7 +2131,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
mIncompleteTextures[type].set(t);
}
- return t;
+ return mIncompleteTextures[type].get();
}
bool Context::skipDraw(GLenum drawMode)
@@ -2359,14 +2303,16 @@ size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray
FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
if (attachment && attachment->isTexture())
{
- (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
+ Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
}
}
FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
if (depthStencilAttachment && depthStencilAttachment->isTexture())
{
- (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
+ Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
}
std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
@@ -2396,114 +2342,19 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true;
}
- gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
- gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+ Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
if (blitRenderTarget || blitDepth || blitStencil)
{
- const gl::Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
+ const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
blitRenderTarget, blitDepth, blitStencil, filter);
}
}
-void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
- GLint x, GLint y, GLsizei width, GLsizei height)
-{
- Framebuffer *frameBuffer = NULL;
- switch (target)
- {
- case GL_FRAMEBUFFER:
- case GL_DRAW_FRAMEBUFFER:
- frameBuffer = mState.getDrawFramebuffer();
- break;
- case GL_READ_FRAMEBUFFER:
- frameBuffer = mState.getReadFramebuffer();
- break;
- default:
- UNREACHABLE();
- }
-
- if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
- {
- for (int i = 0; i < numAttachments; ++i)
- {
- rx::RenderTarget *renderTarget = NULL;
-
- if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
- {
- gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
- if (attachment)
- {
- renderTarget = attachment->getRenderTarget();
- }
- }
- else if (attachments[i] == GL_COLOR)
- {
- gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
- if (attachment)
- {
- renderTarget = attachment->getRenderTarget();
- }
- }
- else
- {
- gl::FramebufferAttachment *attachment = NULL;
- switch (attachments[i])
- {
- case GL_DEPTH_ATTACHMENT:
- case GL_DEPTH:
- attachment = frameBuffer->getDepthbuffer();
- break;
- case GL_STENCIL_ATTACHMENT:
- case GL_STENCIL:
- attachment = frameBuffer->getStencilbuffer();
- break;
- case GL_DEPTH_STENCIL_ATTACHMENT:
- attachment = frameBuffer->getDepthOrStencilbuffer();
- break;
- default:
- UNREACHABLE();
- }
-
- if (attachment)
- {
- renderTarget = attachment->getDepthStencil();
- }
- }
-
- if (renderTarget)
- {
- renderTarget->invalidate(x, y, width, height);
- }
- }
- }
-}
-
-bool Context::hasMappedBuffer(GLenum target) const
+void Context::releaseShaderCompiler()
{
- if (target == GL_ARRAY_BUFFER)
- {
- for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
- {
- const gl::VertexAttribute &vertexAttrib = mState.getVertexAttribState(attribIndex);
- gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
- if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
- {
- return true;
- }
- }
- }
- else if (target == GL_ELEMENT_ARRAY_BUFFER)
- {
- Buffer *elementBuffer = mState.getTargetBuffer(target);
- return (elementBuffer && elementBuffer->isMapped());
- }
- else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
- {
- UNIMPLEMENTED();
- }
- else UNREACHABLE();
- return false;
+ mRenderer->releaseShaderCompiler();
}
void Context::initCaps(GLuint clientVersion)
@@ -2524,20 +2375,45 @@ void Context::initCaps(GLuint clientVersion)
//mExtensions.sRGB = false;
}
+ // Apply implementation limits
+ mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
+ mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+ mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+ mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+ GLuint maxSamples = 0;
+ mCaps.compressedTextureFormats.clear();
+
const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
{
GLenum format = i->first;
TextureCaps formatCaps = i->second;
- if (formatCaps.texturable && IsValidInternalFormat(format, mExtensions, clientVersion))
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+
+ // Update the format caps based on the client version and extensions
+ formatCaps.texturable = formatInfo.textureSupport(clientVersion, mExtensions);
+ formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions);
+ formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions);
+
+ // OpenGL ES does not support multisampling with integer formats
+ if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
+ {
+ formatCaps.sampleCounts.clear();
+ }
+ maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
+
+ if (formatCaps.texturable && formatInfo.compressed)
{
- // Update the format caps based on the client version and extensions
- formatCaps.renderable = IsRenderingSupported(format, mExtensions, clientVersion);
- formatCaps.filterable = IsFilteringSupported(format, mExtensions, clientVersion);
- mTextureCaps.insert(format, formatCaps);
+ mCaps.compressedTextureFormats.push_back(format);
}
+
+ mTextureCaps.insert(format, formatCaps);
}
+
+ mExtensions.maxSamples = maxSamples;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
index 6c93c74e79..1b888aec83 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
@@ -10,23 +10,24 @@
#ifndef LIBGLESV2_CONTEXT_H_
#define LIBGLESV2_CONTEXT_H_
-#include "angle_gl.h"
-
-#include <string>
-#include <set>
-#include <map>
-#include <unordered_map>
-#include <array>
-
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
#include "libGLESv2/HandleAllocator.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/State.h"
+#include "angle_gl.h"
+
+#include <string>
+#include <set>
+#include <map>
+#include <unordered_map>
+#include <array>
+
namespace rx
{
class Renderer;
@@ -114,10 +115,7 @@ class Context
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
- void bindTexture2D(GLuint texture);
- void bindTextureCubeMap(GLuint texture);
- void bindTexture3D(GLuint texture);
- void bindTexture2DArray(GLuint texture);
+ void bindTexture(GLenum target, GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@@ -133,11 +131,11 @@ class Context
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
void linkProgram(GLuint program);
- void setProgramBinary(GLuint program, const void *binary, GLint length);
+ void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
- void beginQuery(GLenum target, GLuint query);
- void endQuery(GLenum target);
+ Error beginQuery(GLenum target, GLuint query);
+ Error endQuery(GLenum target);
void setFramebufferZero(Framebuffer *framebuffer);
@@ -169,7 +167,7 @@ class Context
Texture3D *getTexture3D() const;
Texture2DArray *getTexture2DArray() const;
- Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+ Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
bool isSampler(GLuint samplerName) const;
@@ -184,22 +182,20 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
- void clear(GLbitfield mask);
- void clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
- void clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
- void clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
- void clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
-
- void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
- void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
- void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
+ Error clear(GLbitfield mask);
+ Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
+ Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
+ Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
+ Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
+
+ Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+ Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
+ Error drawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const rx::RangeUI &indexRange);
void sync(bool block); // flush/finish
- void recordInvalidEnum();
- void recordInvalidValue();
- void recordInvalidOperation();
- void recordOutOfMemory();
- void recordInvalidFramebufferOperation();
+ void recordError(const Error &error);
GLenum getError();
GLenum getResetStatus();
@@ -211,15 +207,6 @@ class Context
const TextureCapsMap &getTextureCaps() const;
const Extensions &getExtensions() const;
- int getMajorShaderModel() const;
- unsigned int getMaximumCombinedTextureImageUnits() const;
- unsigned int getMaximumCombinedUniformBufferBindings() const;
- GLsizei getMaxSupportedSamples() const;
- GLsizei getMaxSupportedFormatSamples(GLenum internalFormat) const;
- GLsizei getNumSampleCounts(GLenum internalFormat) const;
- void getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const;
- unsigned int getMaxTransformFeedbackBufferBindings() const;
- GLintptr getUniformBufferOffsetAlignment() const;
const std::string &getRendererString() const;
const std::string &getExtensionString() const;
@@ -231,29 +218,26 @@ class Context
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
- void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
- GLint x, GLint y, GLsizei width, GLsizei height);
-
- bool hasMappedBuffer(GLenum target) const;
-
rx::Renderer *getRenderer() { return mRenderer; }
State &getState() { return mState; }
const State &getState() const { return mState; }
+ void releaseShaderCompiler();
+
private:
DISALLOW_COPY_AND_ASSIGN(Context);
// TODO: std::array may become unavailable using older versions of GCC
typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
- bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
- void applyState(GLenum drawMode);
- void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
- void applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
- size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
- size_t framebufferSerialCount);
- bool applyUniformBuffers();
+ Error applyRenderTarget(GLenum drawMode, bool ignoreViewport);
+ Error applyState(GLenum drawMode);
+ Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
+ Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
+ size_t framebufferSerialCount);
+ Error applyTextures(ProgramBinary *programBinary);
+ Error applyUniformBuffers();
bool applyTransformFeedbackBuffers();
void markTransformFeedbackUsage();
@@ -265,10 +249,10 @@ class Context
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
- void generateSwizzles(Texture *textures[], size_t count);
- size_t getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
- TextureType *outTextureTypes, SamplerState *outSamplers);
- Texture *getIncompleteTexture(TextureType type);
+ Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
+ Error generateSwizzles(ProgramBinary *programBinary);
+
+ Texture *getIncompleteTexture(GLenum type);
bool skipDraw(GLenum drawMode);
@@ -289,10 +273,9 @@ class Context
int mClientVersion;
- BindingPointer<Texture2D> mTexture2DZero;
- BindingPointer<TextureCubeMap> mTextureCubeMapZero;
- BindingPointer<Texture3D> mTexture3DZero;
- BindingPointer<Texture2DArray> mTexture2DArrayZero;
+ typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
+ TextureMap mZeroTextures;
+ TextureMap mIncompleteTextures;
typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
@@ -319,14 +302,9 @@ class Context
std::string mExtensionString;
std::vector<std::string> mExtensionStrings;
- BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
-
// Recorded errors
- bool mInvalidEnum;
- bool mInvalidValue;
- bool mInvalidOperation;
- bool mOutOfMemory;
- bool mInvalidFramebufferOperation;
+ typedef std::set<GLenum> ErrorSet;
+ ErrorSet mErrors;
// Current/lost context flags
bool mHasBeenCurrent;
@@ -335,10 +313,6 @@ class Context
GLenum mResetStrategy;
bool mRobustAccess;
- int mMajorShaderModel;
- bool mSupportsVertexTexture;
- int mNumCompressedTextureFormats;
-
ResourceManager *mResourceManager;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/DynamicHLSL.h
deleted file mode 100644
index 68abd6e1a4..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/DynamicHLSL.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// DynamicHLSL.h: Interface for link and run-time HLSL generation
-//
-
-#ifndef LIBGLESV2_DYNAMIC_HLSL_H_
-#define LIBGLESV2_DYNAMIC_HLSL_H_
-
-#include "common/angleutils.h"
-#include "libGLESv2/constants.h"
-
-namespace rx
-{
-class Renderer;
-}
-
-namespace sh
-{
-struct Attribute;
-struct ShaderVariable;
-}
-
-namespace gl
-{
-
-class InfoLog;
-class FragmentShader;
-class VertexShader;
-struct VariableLocation;
-struct LinkedVarying;
-struct VertexAttribute;
-struct VertexFormat;
-struct PackedVarying;
-
-typedef const PackedVarying *VaryingPacking[IMPLEMENTATION_MAX_VARYING_VECTORS][4];
-
-struct PixelShaderOuputVariable
-{
- GLenum type;
- std::string name;
- std::string source;
- size_t outputIndex;
-};
-
-class DynamicHLSL
-{
- public:
- explicit DynamicHLSL(rx::Renderer *const renderer);
-
- int packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader,
- VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
- std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const VertexFormat inputLayout[],
- const sh::Attribute shaderAttributes[]) const;
- std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
- bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
- bool generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
- std::string& pixelHLSL, std::string& vertexHLSL,
- FragmentShader *fragmentShader, VertexShader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings,
- std::vector<LinkedVarying> *linkedVaryings,
- std::map<int, VariableLocation> *programOutputVars,
- std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
- bool *outUsesFragDepth) const;
-
- std::string generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
- void getInputLayoutSignature(const 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(VertexShader *shader) const;
- void storeUserLinkedVaryings(const VertexShader *vertexShader, std::vector<LinkedVarying> *linkedVaryings) const;
- void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<LinkedVarying> *linkedVaryings) const;
- void defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const;
- std::string generatePointSpriteHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const;
-
- // Prepend an underscore
- static std::string decorateVariable(const std::string &name);
-
- std::string generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const;
-};
-
-}
-
-#endif // LIBGLESV2_DYNAMIC_HLSL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Error.cpp b/src/3rdparty/angle/src/libGLESv2/Error.cpp
new file mode 100644
index 0000000000..cc7d17eb37
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Error.cpp
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+
+// Error.cpp: Implements the gl::Error class which encapsulates an OpenGL error
+// and optional error message.
+
+#include "libGLESv2/Error.h"
+
+#include "common/angleutils.h"
+
+#include <cstdarg>
+
+namespace gl
+{
+
+Error::Error(GLenum errorCode)
+ : mCode(errorCode),
+ mMessage()
+{
+}
+
+Error::Error(GLenum errorCode, const char *msg, ...)
+ : mCode(errorCode),
+ mMessage()
+{
+ va_list vararg;
+ va_start(vararg, msg);
+ mMessage = FormatString(msg, vararg);
+ va_end(vararg);
+}
+
+Error::Error(const Error &other)
+ : mCode(other.mCode),
+ mMessage(other.mMessage)
+{
+}
+
+Error &Error::operator=(const Error &other)
+{
+ mCode = other.mCode;
+ mMessage = other.mMessage;
+ return *this;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Error.h b/src/3rdparty/angle/src/libGLESv2/Error.h
new file mode 100644
index 0000000000..b70b5a531c
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Error.h
@@ -0,0 +1,39 @@
+//
+// 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.
+
+// Error.h: Defines the gl::Error class which encapsulates an OpenGL error
+// and optional error message.
+
+#ifndef LIBGLESV2_ERROR_H_
+#define LIBGLESV2_ERROR_H_
+
+#include "angle_gl.h"
+
+#include <string>
+
+namespace gl
+{
+
+class Error
+{
+ public:
+ explicit Error(GLenum errorCode);
+ Error(GLenum errorCode, const char *msg, ...);
+ Error(const Error &other);
+ Error &operator=(const Error &other);
+
+ GLenum getCode() const { return mCode; }
+ bool isError() const { return (mCode != GL_NO_ERROR); }
+
+ const std::string &getMessage() const { return mMessage; }
+
+ private:
+ GLenum mCode;
+ std::string mMessage;
+};
+
+}
+
+#endif // LIBGLESV2_ERROR_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
index 31d149d629..ee9a07a5c4 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
@@ -1,4 +1,3 @@
-#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
@@ -23,6 +22,8 @@
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
+#include "angle_gl.h"
+
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
index b90d2f6023..5bf7b3fce8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.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
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
index f808175250..5b21433f90 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.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
@@ -9,15 +8,60 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
#include "libGLESv2/Framebuffer.h"
-
#include "libGLESv2/main.h"
-#include "common/utilities.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/Context.h"
-#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+
+#include "common/utilities.h"
+
+namespace rx
+{
+RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+{
+ if (attachment->isTexture())
+ {
+ gl::Texture *texture = attachment->getTexture();
+ ASSERT(texture);
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ const gl::ImageIndex *index = attachment->getTextureImageIndex();
+ ASSERT(index);
+ return textureD3D->getRenderTarget(*index);
+ }
+
+ gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ ASSERT(renderbuffer);
+
+ // TODO: cast to RenderbufferD3D
+ return renderbuffer->getStorage()->getRenderTarget();
+}
+
+// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
+unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
+{
+ if (attachment->isTexture())
+ {
+ gl::Texture *texture = attachment->getTexture();
+ ASSERT(texture);
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ const gl::ImageIndex *index = attachment->getTextureImageIndex();
+ ASSERT(index);
+ return textureD3D->getRenderTargetSerial(*index);
+ }
+
+ gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ ASSERT(renderbuffer);
+
+ // TODO: cast to RenderbufferD3D
+ return renderbuffer->getStorage()->getSerial();
+}
+
+}
namespace gl
{
@@ -47,7 +91,7 @@ Framebuffer::~Framebuffer()
SafeDelete(mStencilbuffer);
}
-FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
+FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
{
if (handle == 0)
{
@@ -62,15 +106,14 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
return NULL;
case GL_RENDERBUFFER:
- return new RenderbufferAttachment(context->getRenderbuffer(handle));
+ return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
case GL_TEXTURE_2D:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D)
{
- Texture2D *tex2D = static_cast<Texture2D*>(texture);
- return new Texture2DAttachment(tex2D, level);
+ return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
}
else
{
@@ -88,8 +131,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
{
- TextureCubeMap *texCube = static_cast<TextureCubeMap*>(texture);
- return new TextureCubeMapAttachment(texCube, type, level);
+ return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
}
else
{
@@ -102,8 +144,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_3D)
{
- Texture3D *tex3D = static_cast<Texture3D*>(texture);
- return new Texture3DAttachment(tex3D, level, layer);
+ return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
}
else
{
@@ -116,8 +157,7 @@ FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle,
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
{
- Texture2DArray *tex2DArray = static_cast<Texture2DArray*>(texture);
- return new Texture2DArrayAttachment(tex2DArray, level, layer);
+ return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
}
else
{
@@ -135,24 +175,25 @@ void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLui
{
ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
SafeDelete(mColorbuffers[colorAttachment]);
- mColorbuffers[colorAttachment] = createAttachment(type, colorbuffer, level, layer);
+ GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
+ mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
SafeDelete(mDepthbuffer);
- mDepthbuffer = createAttachment(type, depthbuffer, level, layer);
+ mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
SafeDelete(mStencilbuffer);
- mStencilbuffer = createAttachment(type, stencilbuffer, level, layer);
+ mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
}
void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
{
- FramebufferAttachment *attachment = createAttachment(type, depthStencilBuffer, level, layer);
+ FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
@@ -164,7 +205,7 @@ void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer,
// Make a new attachment object to ensure we do not double-delete
// See angle issue 686
- mStencilbuffer = createAttachment(type, depthStencilBuffer, level, layer);
+ mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
}
}
@@ -364,6 +405,7 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = colorbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (colorbuffer->isTexture())
{
if (!formatCaps.renderable)
@@ -371,14 +413,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
- if (gl::GetDepthBits(internalformat) > 0 || gl::GetStencilBits(internalformat) > 0)
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
- if (!formatCaps.renderable || gl::GetDepthBits(internalformat) > 0 || gl::GetStencilBits(internalformat) > 0)
+ if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -403,7 +445,7 @@ GLenum Framebuffer::completeness() const
// in GLES 3.0, there is no such restriction
if (clientVersion < 3)
{
- if (gl::GetPixelBytes(colorbuffer->getInternalFormat()) != colorbufferSize)
+ if (formatInfo.pixelBytes != colorbufferSize)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
@@ -427,7 +469,7 @@ GLenum Framebuffer::completeness() const
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
- colorbufferSize = gl::GetPixelBytes(colorbuffer->getInternalFormat());
+ colorbufferSize = formatInfo.pixelBytes;
missingAttachment = false;
}
}
@@ -443,10 +485,9 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = mDepthbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mDepthbuffer->isTexture())
{
- GLenum internalformat = mDepthbuffer->getInternalFormat();
-
// depth texture attachments require OES/ANGLE_depth_texture
// TODO(geofflang): use context's extensions
if (!mRenderer->getRendererExtensions().depthTextures)
@@ -459,14 +500,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
- if (gl::GetDepthBits(internalformat) == 0)
+ if (formatInfo.depthBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
- if (!formatCaps.renderable || gl::GetDepthBits(internalformat) == 0)
+ if (!formatCaps.renderable || formatInfo.depthBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -499,10 +540,9 @@ GLenum Framebuffer::completeness() const
GLenum internalformat = mStencilbuffer->getInternalFormat();
// TODO(geofflang): use context's texture caps
const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mStencilbuffer->isTexture())
{
- GLenum internalformat = mStencilbuffer->getInternalFormat();
-
// texture stencil attachments come along as part
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
// TODO(geofflang): use context's extensions
@@ -516,14 +556,14 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_UNSUPPORTED;
}
- if (gl::GetStencilBits(internalformat) == 0)
+ if (formatInfo.stencilBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
- if (!formatCaps.renderable || gl::GetStencilBits(internalformat) == 0)
+ if (!formatCaps.renderable || formatInfo.stencilBits == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -562,18 +602,47 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_COMPLETE;
}
+void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+{
+ GLuint maxDimension = caps.maxRenderbufferSize;
+ invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+}
+
+void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
+ for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
+ {
+ GLenum attachmentTarget = attachments[attachIndex];
+
+ gl::FramebufferAttachment *attachment =
+ (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
+ getAttachment(attachmentTarget);
+
+ if (attachment)
+ {
+ rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
+ if (renderTarget)
+ {
+ renderTarget->invalidate(x, y, width, height);
+ }
+ }
+ }
+}
+
DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
: Framebuffer(renderer, 0)
{
Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
- mColorbuffers[0] = new RenderbufferAttachment(colorRenderbuffer);
+ mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
// Make a new attachment objects to ensure we do not double-delete
// See angle issue 686
- mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
- mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(depthStencilBuffer) : NULL);
+ mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
+ mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
mDrawBufferStates[0] = GL_BACK;
mReadBufferState = GL_BACK;
@@ -606,6 +675,31 @@ bool Framebuffer::hasValidDepthStencil() const
mDepthbuffer->id() == mStencilbuffer->id());
}
+ColorbufferInfo Framebuffer::getColorbuffersForRender() const
+{
+ ColorbufferInfo colorbuffersForRender;
+
+ for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
+ {
+ GLenum drawBufferState = mDrawBufferStates[colorAttachment];
+ FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
+
+ if (colorbuffer != NULL && drawBufferState != GL_NONE)
+ {
+ ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
+ colorbuffersForRender.push_back(colorbuffer);
+ }
+#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
+ else
+ {
+ colorbuffersForRender.push_back(NULL);
+ }
+#endif
+ }
+
+ return colorbuffersForRender;
+}
+
GLenum DefaultFramebuffer::completeness() const
{
// The default framebuffer *must* always be complete, though it may not be
@@ -617,6 +711,7 @@ FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) cons
{
switch (attachment)
{
+ case GL_COLOR:
case GL_BACK:
return getColorbuffer(0);
case GL_DEPTH:
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
index 035e16fa45..cc12d22953 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
@@ -10,6 +10,8 @@
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
+#include <vector>
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "constants.h"
@@ -26,6 +28,9 @@ class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
class DepthStencilbuffer;
+struct Caps;
+
+typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
class Framebuffer
{
@@ -67,6 +72,15 @@ class Framebuffer
virtual GLenum completeness() const;
bool hasValidDepthStencil() const;
+ void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
+ void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
+ GLint x, GLint y, GLsizei width, GLsizei height);
+
+ // Use this method to retrieve the color buffer map when doing rendering.
+ // It will apply a workaround for poor shader performance on some systems
+ // by compacting the list to skip NULL values.
+ ColorbufferInfo getColorbuffersForRender() const;
+
protected:
rx::Renderer *mRenderer;
@@ -79,10 +93,10 @@ class Framebuffer
FramebufferAttachment *mDepthbuffer;
FramebufferAttachment *mStencilbuffer;
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
- FramebufferAttachment *createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const;
+ FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
};
class DefaultFramebuffer : public Framebuffer
@@ -99,4 +113,14 @@ class DefaultFramebuffer : public Framebuffer
}
+namespace rx
+{
+class RenderTarget;
+
+// TODO: place this in FramebufferD3D.h
+RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
+
+}
+
#endif // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
index 5855301c97..540ede1cd2 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -9,21 +8,22 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-
#include "libGLESv2/Texture.h"
+#include "libGLESv2/formatutils.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
#include "common/utilities.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Renderbuffer.h"
namespace gl
{
////// FramebufferAttachment Implementation //////
-FramebufferAttachment::FramebufferAttachment()
+FramebufferAttachment::FramebufferAttachment(GLenum binding)
+ : mBinding(binding)
{
}
@@ -33,42 +33,42 @@ FramebufferAttachment::~FramebufferAttachment()
GLuint FramebufferAttachment::getRedSize() const
{
- return (gl::GetRedBits(getInternalFormat()) > 0) ? gl::GetRedBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).redBits > 0) ? GetInternalFormatInfo(getActualFormat()).redBits : 0;
}
GLuint FramebufferAttachment::getGreenSize() const
{
- return (gl::GetGreenBits(getInternalFormat()) > 0) ? gl::GetGreenBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).greenBits > 0) ? GetInternalFormatInfo(getActualFormat()).greenBits : 0;
}
GLuint FramebufferAttachment::getBlueSize() const
{
- return (gl::GetBlueBits(getInternalFormat()) > 0) ? gl::GetBlueBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).blueBits > 0) ? GetInternalFormatInfo(getActualFormat()).blueBits : 0;
}
GLuint FramebufferAttachment::getAlphaSize() const
{
- return (gl::GetAlphaBits(getInternalFormat()) > 0) ? gl::GetAlphaBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).alphaBits > 0) ? GetInternalFormatInfo(getActualFormat()).alphaBits : 0;
}
GLuint FramebufferAttachment::getDepthSize() const
{
- return (gl::GetDepthBits(getInternalFormat()) > 0) ? gl::GetDepthBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).depthBits > 0) ? GetInternalFormatInfo(getActualFormat()).depthBits : 0;
}
GLuint FramebufferAttachment::getStencilSize() const
{
- return (gl::GetStencilBits(getInternalFormat()) > 0) ? gl::GetStencilBits(getActualFormat()) : 0;
+ return (GetInternalFormatInfo(getInternalFormat()).stencilBits > 0) ? GetInternalFormatInfo(getActualFormat()).stencilBits : 0;
}
GLenum FramebufferAttachment::getComponentType() const
{
- return gl::GetComponentType(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).componentType;
}
GLenum FramebufferAttachment::getColorEncoding() const
{
- return gl::GetColorEncoding(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).colorEncoding;
}
bool FramebufferAttachment::isTexture() const
@@ -76,340 +76,85 @@ bool FramebufferAttachment::isTexture() const
return (type() != GL_RENDERBUFFER);
}
-///// Texture2DAttachment Implementation ////////
-
-Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
-{
- mTexture2D.set(texture);
-}
-
-Texture2DAttachment::~Texture2DAttachment()
-{
- mTexture2D.set(NULL);
-}
-
-rx::RenderTarget *Texture2DAttachment::getRenderTarget()
-{
- return mTexture2D->getRenderTarget(mLevel);
-}
-
-rx::RenderTarget *Texture2DAttachment::getDepthStencil()
-{
- return mTexture2D->getDepthSencil(mLevel);
-}
-
-rx::TextureStorage *Texture2DAttachment::getTextureStorage()
-{
- return mTexture2D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture2DAttachment::getWidth() const
-{
- return mTexture2D->getWidth(mLevel);
-}
-
-GLsizei Texture2DAttachment::getHeight() const
-{
- return mTexture2D->getHeight(mLevel);
-}
-
-GLenum Texture2DAttachment::getInternalFormat() const
-{
- return mTexture2D->getInternalFormat(mLevel);
-}
-
-GLenum Texture2DAttachment::getActualFormat() const
-{
- return mTexture2D->getActualFormat(mLevel);
-}
-
-GLsizei Texture2DAttachment::getSamples() const
-{
- return 0;
-}
-
-unsigned int Texture2DAttachment::getSerial() const
-{
- return mTexture2D->getRenderTargetSerial(mLevel);
-}
-
-GLuint Texture2DAttachment::id() const
-{
- return mTexture2D->id();
-}
-
-GLenum Texture2DAttachment::type() const
-{
- return GL_TEXTURE_2D;
-}
-
-GLint Texture2DAttachment::mipLevel() const
-{
- return mLevel;
-}
-
-GLint Texture2DAttachment::layer() const
-{
- return 0;
-}
-
-unsigned int Texture2DAttachment::getTextureSerial() const
-{
- return mTexture2D->getTextureSerial();
-}
-
-///// TextureCubeMapAttachment Implementation ////////
-
-TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
- : mFaceTarget(faceTarget), mLevel(level)
-{
- mTextureCubeMap.set(texture);
-}
-
-TextureCubeMapAttachment::~TextureCubeMapAttachment()
-{
- mTextureCubeMap.set(NULL);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
-{
- return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
-{
- return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
-}
-
-rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
-{
- return mTextureCubeMap->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei TextureCubeMapAttachment::getWidth() const
-{
- return mTextureCubeMap->getWidth(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getHeight() const
-{
- return mTextureCubeMap->getHeight(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getInternalFormat() const
-{
- return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getActualFormat() const
-{
- return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getSamples() const
-{
- return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getSerial() const
-{
- return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
-}
-
-GLuint TextureCubeMapAttachment::id() const
-{
- return mTextureCubeMap->id();
-}
-
-GLenum TextureCubeMapAttachment::type() const
-{
- return mFaceTarget;
-}
-
-GLint TextureCubeMapAttachment::mipLevel() const
-{
- return mLevel;
-}
-
-GLint TextureCubeMapAttachment::layer() const
-{
- return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getTextureSerial() const
-{
- return mTextureCubeMap->getTextureSerial();
-}
-
-///// Texture3DAttachment Implementation ////////
-
-Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer)
- : mLevel(level), mLayer(layer)
-{
- mTexture3D.set(texture);
-}
-
-Texture3DAttachment::~Texture3DAttachment()
-{
- mTexture3D.set(NULL);
-}
-
-rx::RenderTarget *Texture3DAttachment::getRenderTarget()
-{
- return mTexture3D->getRenderTarget(mLevel, mLayer);
-}
-
-rx::RenderTarget *Texture3DAttachment::getDepthStencil()
-{
- return mTexture3D->getDepthStencil(mLevel, mLayer);
-}
-
-rx::TextureStorage *Texture3DAttachment::getTextureStorage()
-{
- return mTexture3D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture3DAttachment::getWidth() const
-{
- return mTexture3D->getWidth(mLevel);
-}
-
-GLsizei Texture3DAttachment::getHeight() const
-{
- return mTexture3D->getHeight(mLevel);
-}
+///// TextureAttachment Implementation ////////
-GLenum Texture3DAttachment::getInternalFormat() const
+TextureAttachment::TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index)
+ : FramebufferAttachment(binding),
+ mIndex(index)
{
- return mTexture3D->getInternalFormat(mLevel);
+ mTexture.set(texture);
}
-GLenum Texture3DAttachment::getActualFormat() const
+TextureAttachment::~TextureAttachment()
{
- return mTexture3D->getActualFormat(mLevel);
+ mTexture.set(NULL);
}
-GLsizei Texture3DAttachment::getSamples() const
+GLsizei TextureAttachment::getSamples() const
{
return 0;
}
-unsigned int Texture3DAttachment::getSerial() const
-{
- return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture3DAttachment::id() const
-{
- return mTexture3D->id();
-}
-
-GLenum Texture3DAttachment::type() const
-{
- return GL_TEXTURE_3D;
-}
-
-GLint Texture3DAttachment::mipLevel() const
-{
- return mLevel;
-}
-
-GLint Texture3DAttachment::layer() const
-{
- return mLayer;
-}
-
-unsigned int Texture3DAttachment::getTextureSerial() const
-{
- return mTexture3D->getTextureSerial();
-}
-
-////// Texture2DArrayAttachment Implementation //////
-
-Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer)
- : mLevel(level), mLayer(layer)
-{
- mTexture2DArray.set(texture);
-}
-
-Texture2DArrayAttachment::~Texture2DArrayAttachment()
-{
- mTexture2DArray.set(NULL);
-}
-
-rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget()
+GLuint TextureAttachment::id() const
{
- return mTexture2DArray->getRenderTarget(mLevel, mLayer);
+ return mTexture->id();
}
-rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil()
+GLsizei TextureAttachment::getWidth() const
{
- return mTexture2DArray->getDepthStencil(mLevel, mLayer);
+ return mTexture->getWidth(mIndex);
}
-rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage()
+GLsizei TextureAttachment::getHeight() const
{
- return mTexture2DArray->getNativeTexture()->getStorageInstance();
+ return mTexture->getHeight(mIndex);
}
-GLsizei Texture2DArrayAttachment::getWidth() const
+GLenum TextureAttachment::getInternalFormat() const
{
- return mTexture2DArray->getWidth(mLevel);
+ return mTexture->getInternalFormat(mIndex);
}
-GLsizei Texture2DArrayAttachment::getHeight() const
+GLenum TextureAttachment::getActualFormat() const
{
- return mTexture2DArray->getHeight(mLevel);
+ return mTexture->getActualFormat(mIndex);
}
-GLenum Texture2DArrayAttachment::getInternalFormat() const
+GLenum TextureAttachment::type() const
{
- return mTexture2DArray->getInternalFormat(mLevel);
+ return mIndex.type;
}
-GLenum Texture2DArrayAttachment::getActualFormat() const
+GLint TextureAttachment::mipLevel() const
{
- return mTexture2DArray->getActualFormat(mLevel);
+ return mIndex.mipIndex;
}
-GLsizei Texture2DArrayAttachment::getSamples() const
+GLint TextureAttachment::layer() const
{
- return 0;
-}
-
-unsigned int Texture2DArrayAttachment::getSerial() const
-{
- return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture2DArrayAttachment::id() const
-{
- return mTexture2DArray->id();
-}
-
-GLenum Texture2DArrayAttachment::type() const
-{
- return GL_TEXTURE_2D_ARRAY;
+ return mIndex.layerIndex;
}
-GLint Texture2DArrayAttachment::mipLevel() const
+Texture *TextureAttachment::getTexture()
{
- return mLevel;
+ return mTexture.get();
}
-GLint Texture2DArrayAttachment::layer() const
+const ImageIndex *TextureAttachment::getTextureImageIndex() const
{
- return mLayer;
+ return &mIndex;
}
-unsigned int Texture2DArrayAttachment::getTextureSerial() const
+Renderbuffer *TextureAttachment::getRenderbuffer()
{
- return mTexture2DArray->getTextureSerial();
+ UNREACHABLE();
+ return NULL;
}
////// RenderbufferAttachment Implementation //////
-RenderbufferAttachment::RenderbufferAttachment(Renderbuffer *renderbuffer)
+RenderbufferAttachment::RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer)
+ : FramebufferAttachment(binding)
{
ASSERT(renderbuffer);
mRenderbuffer.set(renderbuffer);
@@ -420,22 +165,6 @@ RenderbufferAttachment::~RenderbufferAttachment()
mRenderbuffer.set(NULL);
}
-rx::RenderTarget *RenderbufferAttachment::getRenderTarget()
-{
- return mRenderbuffer->getStorage()->getRenderTarget();
-}
-
-rx::RenderTarget *RenderbufferAttachment::getDepthStencil()
-{
- return mRenderbuffer->getStorage()->getDepthStencil();
-}
-
-rx::TextureStorage *RenderbufferAttachment::getTextureStorage()
-{
- UNREACHABLE();
- return NULL;
-}
-
GLsizei RenderbufferAttachment::getWidth() const
{
return mRenderbuffer->getWidth();
@@ -461,11 +190,6 @@ GLsizei RenderbufferAttachment::getSamples() const
return mRenderbuffer->getStorage()->getSamples();
}
-unsigned int RenderbufferAttachment::getSerial() const
-{
- return mRenderbuffer->getStorage()->getSerial();
-}
-
GLuint RenderbufferAttachment::id() const
{
return mRenderbuffer->id();
@@ -486,10 +210,21 @@ GLint RenderbufferAttachment::layer() const
return 0;
}
-unsigned int RenderbufferAttachment::getTextureSerial() const
+Texture *RenderbufferAttachment::getTexture()
{
UNREACHABLE();
- return 0;
+ return NULL;
+}
+
+const ImageIndex *RenderbufferAttachment::getTextureImageIndex() const
+{
+ UNREACHABLE();
+ return NULL;
+}
+
+Renderbuffer *RenderbufferAttachment::getRenderbuffer()
+{
+ return mRenderbuffer.get();
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
index 18768f9831..c18ef7364d 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
@@ -10,10 +10,11 @@
#ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
#define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
-#include "angle_gl.h"
-
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+#include "Texture.h"
+
+#include "angle_gl.h"
namespace rx
{
@@ -24,10 +25,6 @@ class TextureStorage;
namespace gl
{
-class Texture2D;
-class TextureCubeMap;
-class Texture3D;
-class Texture2DArray;
class Renderbuffer;
// FramebufferAttachment implements a GL framebuffer attachment.
@@ -39,7 +36,7 @@ class Renderbuffer;
class FramebufferAttachment
{
public:
- FramebufferAttachment();
+ explicit FramebufferAttachment(GLenum binding);
virtual ~FramebufferAttachment();
// Helper methods
@@ -56,184 +53,80 @@ class FramebufferAttachment
bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
- // Child class interface
- virtual rx::RenderTarget *getRenderTarget() = 0;
- virtual rx::RenderTarget *getDepthStencil() = 0;
- virtual rx::TextureStorage *getTextureStorage() = 0;
+ GLenum getBinding() const { return mBinding; }
+ // Child class interface
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0;
virtual GLenum getActualFormat() const = 0;
virtual GLsizei getSamples() const = 0;
- virtual unsigned int getSerial() const = 0;
-
virtual GLuint id() const = 0;
virtual GLenum type() const = 0;
virtual GLint mipLevel() const = 0;
virtual GLint layer() const = 0;
- virtual unsigned int getTextureSerial() const = 0;
- private:
- DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
-};
-
-class Texture2DAttachment : public FramebufferAttachment
-{
- public:
- Texture2DAttachment(Texture2D *texture, GLint level);
-
- virtual ~Texture2DAttachment();
-
- rx::RenderTarget *getRenderTarget();
- rx::RenderTarget *getDepthStencil();
- rx::TextureStorage *getTextureStorage();
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
-
- virtual GLuint id() const;
- virtual GLenum type() const;
- virtual GLint mipLevel() const;
- virtual GLint layer() const;
- virtual unsigned int getTextureSerial() const;
+ virtual Texture *getTexture() = 0;
+ virtual const ImageIndex *getTextureImageIndex() const = 0;
+ virtual Renderbuffer *getRenderbuffer() = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(Texture2DAttachment);
+ DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
- BindingPointer<Texture2D> mTexture2D;
- const GLint mLevel;
+ GLenum mBinding;
};
-class TextureCubeMapAttachment : public FramebufferAttachment
+class TextureAttachment : public FramebufferAttachment
{
public:
- TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level);
+ TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index);
+ virtual ~TextureAttachment();
- virtual ~TextureCubeMapAttachment();
-
- rx::RenderTarget *getRenderTarget();
- rx::RenderTarget *getDepthStencil();
- rx::TextureStorage *getTextureStorage();
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
-
virtual GLuint id() const;
- virtual GLenum type() const;
- virtual GLint mipLevel() const;
- virtual GLint layer() const;
- virtual unsigned int getTextureSerial() const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment);
-
- BindingPointer<TextureCubeMap> mTextureCubeMap;
- const GLint mLevel;
- const GLenum mFaceTarget;
-};
-
-class Texture3DAttachment : public FramebufferAttachment
-{
- public:
- Texture3DAttachment(Texture3D *texture, GLint level, GLint layer);
-
- virtual ~Texture3DAttachment();
-
- rx::RenderTarget *getRenderTarget();
- rx::RenderTarget *getDepthStencil();
- rx::TextureStorage *getTextureStorage();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
- virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
- virtual unsigned int getTextureSerial() const;
- private:
- DISALLOW_COPY_AND_ASSIGN(Texture3DAttachment);
-
- BindingPointer<Texture3D> mTexture3D;
- const GLint mLevel;
- const GLint mLayer;
-};
-
-class Texture2DArrayAttachment : public FramebufferAttachment
-{
- public:
- Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer);
-
- virtual ~Texture2DArrayAttachment();
-
- rx::RenderTarget *getRenderTarget();
- rx::RenderTarget *getDepthStencil();
- rx::TextureStorage *getTextureStorage();
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
-
- virtual GLuint id() const;
- virtual GLenum type() const;
- virtual GLint mipLevel() const;
- virtual GLint layer() const;
- virtual unsigned int getTextureSerial() const;
+ virtual Texture *getTexture();
+ virtual const ImageIndex *getTextureImageIndex() const;
+ virtual Renderbuffer *getRenderbuffer();
private:
- DISALLOW_COPY_AND_ASSIGN(Texture2DArrayAttachment);
+ DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
- BindingPointer<Texture2DArray> mTexture2DArray;
- const GLint mLevel;
- const GLint mLayer;
+ BindingPointer<Texture> mTexture;
+ ImageIndex mIndex;
};
class RenderbufferAttachment : public FramebufferAttachment
{
public:
- RenderbufferAttachment(Renderbuffer *renderbuffer);
+ RenderbufferAttachment(GLenum binding, Renderbuffer *renderbuffer);
virtual ~RenderbufferAttachment();
- rx::RenderTarget *getRenderTarget();
- rx::RenderTarget *getDepthStencil();
- rx::TextureStorage *getTextureStorage();
-
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
- virtual unsigned int getSerial() const;
-
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
virtual GLint layer() const;
- virtual unsigned int getTextureSerial() const;
+
+ virtual Texture *getTexture();
+ virtual const ImageIndex *getTextureImageIndex() const;
+ virtual Renderbuffer *getRenderbuffer();
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment);
diff --git a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
index 37da99aa18..c498f8a178 100644
--- a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2002-2011 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/HandleAllocator.h b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h
index bbded02f99..a89cc86775 100644
--- a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h
+++ b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h
@@ -10,12 +10,12 @@
#ifndef LIBGLESV2_HANDLEALLOCATOR_H_
#define LIBGLESV2_HANDLEALLOCATOR_H_
+#include "common/angleutils.h"
+
#include "angle_gl.h"
#include <vector>
-#include "common/angleutils.h"
-
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
new file mode 100644
index 0000000000..3522b997e8
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
@@ -0,0 +1,57 @@
+//
+// 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.
+//
+
+// ImageIndex.cpp: Implementation for ImageIndex methods.
+
+#include "libGLESv2/ImageIndex.h"
+#include "libGLESv2/Texture.h"
+#include "common/utilities.h"
+
+namespace gl
+{
+
+ImageIndex::ImageIndex(const ImageIndex &other)
+ : type(other.type),
+ mipIndex(other.mipIndex),
+ layerIndex(other.layerIndex)
+{}
+
+ImageIndex &ImageIndex::operator=(const ImageIndex &other)
+{
+ type = other.type;
+ mipIndex = other.mipIndex;
+ layerIndex = other.layerIndex;
+ return *this;
+}
+
+ImageIndex ImageIndex::Make2D(GLint mipIndex)
+{
+ return ImageIndex(GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL);
+}
+
+ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
+{
+ ASSERT(gl::IsCubemapTextureTarget(target));
+ return ImageIndex(target, mipIndex, TextureCubeMap::targetToLayerIndex(target));
+}
+
+ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex)
+{
+ return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex);
+}
+
+ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
+{
+ return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
+}
+
+ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
+ : type(typeIn),
+ mipIndex(mipIndexIn),
+ layerIndex(layerIndexIn)
+{}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
new file mode 100644
index 0000000000..9f2df88061
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+// ImageIndex.h: A helper struct for indexing into an Image array
+
+#ifndef LIBGLESV2_IMAGE_INDEX_H_
+#define LIBGLESV2_IMAGE_INDEX_H_
+
+#include "angle_gl.h"
+
+namespace gl
+{
+
+struct ImageIndex
+{
+ GLenum type;
+ GLint mipIndex;
+ GLint layerIndex;
+
+ ImageIndex(const ImageIndex &other);
+ ImageIndex &operator=(const ImageIndex &other);
+
+ bool hasLayer() const { return layerIndex != ENTIRE_LEVEL; }
+
+ static ImageIndex Make2D(GLint mipIndex);
+ static ImageIndex MakeCube(GLenum target, GLint mipIndex);
+ static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
+ static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
+
+ static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+
+ private:
+ ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+};
+
+}
+
+#endif // LIBGLESV2_IMAGE_INDEX_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp
index 8a9fb04800..9bfda09a64 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Program.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,6 +10,7 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
@@ -173,7 +173,7 @@ bool Program::attachShader(Shader *shader)
return false;
}
- mVertexShader = (VertexShader*)shader;
+ mVertexShader = shader;
mVertexShader->addRef();
}
else if (shader->getType() == GL_FRAGMENT_SHADER)
@@ -183,7 +183,7 @@ bool Program::attachShader(Shader *shader)
return false;
}
- mFragmentShader = (FragmentShader*)shader;
+ mFragmentShader = shader;
mFragmentShader->addRef();
}
else UNREACHABLE();
@@ -244,16 +244,16 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
-bool Program::link()
+bool Program::link(const Caps &caps)
{
unlink(false);
mInfoLog.reset();
resetUniformBlockBindings();
- mProgramBinary.set(new ProgramBinary(mRenderer));
+ mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
- mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
+ mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
return mLinked;
}
@@ -303,14 +303,15 @@ ProgramBinary* Program::getProgramBinary() const
return mProgramBinary.get();
}
-bool Program::setProgramBinary(const void *binary, GLsizei length)
+bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
{
unlink(false);
mInfoLog.reset();
- mProgramBinary.set(new ProgramBinary(mRenderer));
- mLinked = mProgramBinary->load(mInfoLog, binary, length);
+ mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
+ mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
+
if (!mLinked)
{
mProgramBinary.set(NULL);
@@ -502,14 +503,14 @@ bool Program::isFlaggedForDeletion() const
return mDeleteStatus;
}
-void Program::validate()
+void Program::validate(const Caps &caps)
{
mInfoLog.reset();
ProgramBinary *programBinary = getProgramBinary();
if (isLinked() && programBinary)
{
- programBinary->validate(mInfoLog);
+ programBinary->validate(mInfoLog, caps);
}
else
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h
index ce821a470b..6528dd1191 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.h
+++ b/src/3rdparty/angle/src/libGLESv2/Program.h
@@ -10,14 +10,17 @@
#ifndef LIBGLESV2_PROGRAM_H_
#define LIBGLESV2_PROGRAM_H_
-#include <string>
-#include <set>
-
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/ProgramBinary.h"
+#include <GLES2/gl2.h>
+
+#include <vector>
+#include <string>
+#include <set>
+
namespace rx
{
class Renderer;
@@ -25,9 +28,8 @@ class Renderer;
namespace gl
{
+struct Caps;
class ResourceManager;
-class FragmentShader;
-class VertexShader;
class Shader;
extern const char * const g_fakepath;
@@ -75,9 +77,9 @@ class Program
void bindAttributeLocation(GLuint index, const char *name);
- bool link();
+ bool link(const Caps &caps);
bool isLinked();
- bool setProgramBinary(const void *binary, GLsizei length);
+ bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
ProgramBinary *getProgramBinary() const;
int getInfoLogLength() const;
@@ -110,7 +112,7 @@ class Program
void flagForDeletion();
bool isFlaggedForDeletion() const;
- void validate();
+ void validate(const Caps &caps);
bool isValidated() const;
GLint getProgramBinaryLength() const;
@@ -121,8 +123,8 @@ class Program
void unlink(bool destroy = false);
void resetUniformBlockBindings();
- FragmentShader *mFragmentShader;
- VertexShader *mVertexShader;
+ Shader *mFragmentShader;
+ Shader *mVertexShader;
AttributeBindings mAttributeBindings;
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index 9fad5fbfc5..3f6d9e0ef9 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.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,33 +10,34 @@
#include "libGLESv2/BinaryStream.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/ShaderExecutable.h"
#include "common/debug.h"
#include "common/version.h"
#include "common/utilities.h"
+#include "common/platform.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Program.h"
+#include "libGLESv2/renderer/ProgramImpl.h"
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
-#include "libGLESv2/DynamicHLSL.h"
#include "common/blocklayout.h"
-#undef near
-#undef far
-
namespace gl
{
namespace
{
-TextureType GetTextureType(GLenum samplerType)
+GLenum GetTextureType(GLenum samplerType)
{
switch (samplerType)
{
@@ -45,26 +45,26 @@ TextureType GetTextureType(GLenum samplerType)
case GL_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
case GL_SAMPLER_3D:
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
- return TEXTURE_3D;
+ return GL_TEXTURE_3D;
case GL_SAMPLER_CUBE:
case GL_SAMPLER_CUBE_SHADOW:
- return TEXTURE_CUBE;
+ return GL_TEXTURE_CUBE_MAP;
case GL_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
- return TEXTURE_CUBE;
+ return GL_TEXTURE_CUBE_MAP;
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_ARRAY_SHADOW:
- return TEXTURE_2D_ARRAY;
+ return GL_TEXTURE_2D_ARRAY;
default: UNREACHABLE();
}
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
}
unsigned int ParseAndStripArrayIndex(std::string* name)
@@ -83,7 +83,7 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
return subscript;
}
-void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
{
size_t layoutIndex = 0;
for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
@@ -109,6 +109,26 @@ void GetInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes
}
}
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
+{
+ std::vector<GLenum> defaultPixelOutput(1);
+
+ ASSERT(!shaderOutputVars.empty());
+ defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+ return defaultPixelOutput;
+}
+
+bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
+{
+ return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const sh::ShaderVariable &var)
+{
+ return false;
+}
+
}
VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -169,45 +189,30 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
unsigned int ProgramBinary::mCurrentSerial = 1;
-ProgramBinary::ProgramBinary(rx::Renderer *renderer)
+ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
- mRenderer(renderer),
- mDynamicHLSL(NULL),
- mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+ mProgram(impl),
mGeometryExecutable(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mUsesPointSize(false),
mShaderVersion(100),
mDirtySamplerMapping(true),
- mVertexUniformStorage(NULL),
- mFragmentUniformStorage(NULL),
mValidated(false),
mSerial(issueSerial())
{
+ ASSERT(impl);
+
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mSemanticIndex[index] = -1;
}
-
- for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
- {
- mSamplersPS[index].active = false;
- }
-
- for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
- {
- mSamplersVS[index].active = false;
- }
-
- mDynamicHLSL = new DynamicHLSL(renderer);
}
ProgramBinary::~ProgramBinary()
{
reset();
- SafeDelete(mDynamicHLSL);
+ SafeDelete(mProgram);
}
unsigned int ProgramBinary::getSerial() const
@@ -227,17 +232,21 @@ unsigned int ProgramBinary::issueSerial()
rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
{
- std::vector<GLenum> outputs(IMPLEMENTATION_MAX_DRAW_BUFFERS);
- for (size_t outputIndex = 0; outputIndex < IMPLEMENTATION_MAX_DRAW_BUFFERS; outputIndex++)
+ std::vector<GLenum> outputs;
+
+ const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
- if (fbo->getColorbuffer(outputIndex) != NULL)
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
{
- // Always output floats for now
- outputs[outputIndex] = GL_FLOAT;
+ outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
}
else
{
- outputs[outputIndex] = GL_NONE;
+ outputs.push_back(GL_NONE);
}
}
@@ -254,15 +263,9 @@ rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std
}
}
- std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
- outputSignature);
-
- // Generate new pixel executable
InfoLog tempInfoLog;
- rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- mPixelWorkarounds);
+ rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
+ mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
if (!pixelExecutable)
{
@@ -281,7 +284,7 @@ rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std
rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
{
GLenum signature[MAX_VERTEX_ATTRIBS];
- mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+ mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
{
@@ -291,16 +294,9 @@ rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const Ver
}
}
- // Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
-
- // Generate new vertex executable
InfoLog tempInfoLog;
- rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL.c_str(),
- rx::SHADER_VERTEX,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- mVertexWorkarounds);
+ rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
+ mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
if (!vertexExecutable)
{
@@ -366,7 +362,7 @@ bool ProgramBinary::usesPointSize() const
bool ProgramBinary::usesPointSpriteEmulation() const
{
- return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+ return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
}
bool ProgramBinary::usesGeometryShader() const
@@ -374,26 +370,22 @@ bool ProgramBinary::usesGeometryShader() const
return usesPointSpriteEmulation();
}
-// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
-GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
+GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
{
GLint logicalTextureUnit = -1;
switch (type)
{
case SAMPLER_PIXEL:
- ASSERT(samplerIndex < ArraySize(mSamplersPS));
-
- if (mSamplersPS[samplerIndex].active)
+ ASSERT(samplerIndex < caps.maxTextureImageUnits);
+ if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
{
logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
}
break;
case SAMPLER_VERTEX:
- ASSERT(samplerIndex < ArraySize(mSamplersVS));
-
- if (mSamplersVS[samplerIndex].active)
+ ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+ if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
{
logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
}
@@ -401,7 +393,7 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
default: UNREACHABLE();
}
- if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
{
return logicalTextureUnit;
}
@@ -411,22 +403,22 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
// Returns the texture type for a given Direct3D 9 sampler type and
// index (0-15 for the pixel shader and 0-3 for the vertex shader).
-TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
switch (type)
{
case SAMPLER_PIXEL:
- ASSERT(samplerIndex < ArraySize(mSamplersPS));
+ ASSERT(samplerIndex < mSamplersPS.size());
ASSERT(mSamplersPS[samplerIndex].active);
return mSamplersPS[samplerIndex].textureType;
case SAMPLER_VERTEX:
- ASSERT(samplerIndex < ArraySize(mSamplersVS));
+ ASSERT(samplerIndex < mSamplersVS.size());
ASSERT(mSamplersVS[samplerIndex].active);
return mSamplersVS[samplerIndex].textureType;
default: UNREACHABLE();
}
- return TEXTURE_2D;
+ return GL_TEXTURE_2D;
}
GLint ProgramBinary::getUniformLocation(std::string name)
@@ -562,38 +554,64 @@ void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum
if (targetUniform->type == targetUniformType)
{
- T *target = (T*)targetUniform->data + mUniformIndex[location].element * 4;
+ T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
+ T *dest = target + (i * 4);
+ const T *source = v + (i * components);
+
for (int c = 0; c < components; c++)
{
- SetIfDirty(target + c, v[c], &targetUniform->dirty);
+ SetIfDirty(dest + c, source[c], &targetUniform->dirty);
}
for (int c = components; c < 4; c++)
{
- SetIfDirty(target + c, T(0), &targetUniform->dirty);
+ SetIfDirty(dest + c, T(0), &targetUniform->dirty);
}
- target += 4;
- v += components;
}
}
else if (targetUniform->type == targetBoolType)
{
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+ GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
+ GLint *dest = boolParams + (i * 4);
+ const T *source = v + (i * components);
+
for (int c = 0; c < components; c++)
{
- SetIfDirty(boolParams + c, (v[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
+ SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
}
for (int c = components; c < 4; c++)
{
- SetIfDirty(boolParams + c, GL_FALSE, &targetUniform->dirty);
+ SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
}
- boolParams += 4;
- v += components;
+ }
+ }
+ else if (IsSampler(targetUniform->type))
+ {
+ ASSERT(targetUniformType == GL_INT);
+
+ GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ bool wasDirty = targetUniform->dirty;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = target + (i * 4);
+ const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
+
+ SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
+ SetIfDirty(dest + 1, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 2, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 3, 0, &targetUniform->dirty);
+ }
+
+ if (!wasDirty && targetUniform->dirty)
+ {
+ mDirtySamplerMapping = true;
}
}
else UNREACHABLE();
@@ -761,48 +779,7 @@ void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboole
void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
- LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
- if (targetUniform->type == GL_INT || IsSampler(targetUniform->type))
- {
- GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- SetIfDirty(target + 0, v[0], &targetUniform->dirty);
- SetIfDirty(target + 1, 0, &targetUniform->dirty);
- SetIfDirty(target + 2, 0, &targetUniform->dirty);
- SetIfDirty(target + 3, 0, &targetUniform->dirty);
- target += 4;
- v += 1;
- }
- }
- else if (targetUniform->type == GL_BOOL)
- {
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- SetIfDirty(boolParams + 0, (v[0] == 0) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
- SetIfDirty(boolParams + 1, GL_FALSE, &targetUniform->dirty);
- SetIfDirty(boolParams + 2, GL_FALSE, &targetUniform->dirty);
- SetIfDirty(boolParams + 3, GL_FALSE, &targetUniform->dirty);
- boolParams += 4;
- v += 1;
- }
- }
- else UNREACHABLE();
-
- // Set a special flag if we change a sampler uniform
- if (IsSampler(targetUniform->type) &&
- (memcmp(targetUniform->data, v, sizeof(GLint)) != 0))
- {
- mDirtySamplerMapping = true;
- }
+ setUniform(location, count, v, GL_INT);
}
void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -841,20 +818,10 @@ void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *
}
template <typename T>
-bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType)
+void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
{
LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
- // sized queries -- ensure the provided buffer is large enough
- if (bufSize)
- {
- int requiredBytes = VariableExternalSize(targetUniform->type);
- if (*bufSize < requiredBytes)
- {
- return false;
- }
- }
-
if (IsMatrixType(targetUniform->type))
{
const int rows = VariableRowCount(targetUniform->type);
@@ -919,23 +886,21 @@ bool ProgramBinary::getUniformv(GLint location, GLsizei *bufSize, T *params, GLe
default: UNREACHABLE();
}
}
-
- return true;
}
-bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
+void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
{
- return getUniformv(location, bufSize, params, GL_FLOAT);
+ getUniformv(location, params, GL_FLOAT);
}
-bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
+void ProgramBinary::getUniformiv(GLint location, GLint *params)
{
- return getUniformv(location, bufSize, params, GL_INT);
+ getUniformv(location, params, GL_INT);
}
-bool ProgramBinary::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
+void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
{
- return getUniformv(location, bufSize, params, GL_UNSIGNED_INT);
+ getUniformv(location, params, GL_UNSIGNED_INT);
}
void ProgramBinary::dirtyAllUniforms()
@@ -976,7 +941,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
- if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < mSamplersPS.size())
{
ASSERT(mSamplersPS[samplerIndex].active);
mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -992,7 +957,7 @@ void ProgramBinary::updateSamplerMapping()
{
unsigned int samplerIndex = firstIndex + i;
- if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < mSamplersVS.size())
{
ASSERT(mSamplersVS[samplerIndex].active);
mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
@@ -1005,25 +970,31 @@ void ProgramBinary::updateSamplerMapping()
}
// Applies all the uniforms set for this program object to the renderer
-void ProgramBinary::applyUniforms()
+Error ProgramBinary::applyUniforms()
{
updateSamplerMapping();
- mRenderer->applyUniforms(*this);
+ Error error = mProgram->getRenderer()->applyUniforms(*this);
+ if (error.isError())
+ {
+ return error;
+ }
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
mUniforms[uniformIndex]->dirty = false;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
+Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
{
const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
- const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
- const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+ const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
+ const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
ASSERT(boundBuffers.size() == mUniformBlocks.size());
@@ -1037,16 +1008,20 @@ bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuff
if (uniformBuffer->getSize() < uniformBlock->dataSize)
{
// undefined behaviour
- return false;
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
}
- ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader());
+ // Unnecessary to apply an unreferenced standard or shared UBO
+ if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+ {
+ continue;
+ }
if (uniformBlock->isReferencedByVertexShader())
{
unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
ASSERT(vertexUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers());
+ ASSERT(registerIndex < caps.maxVertexUniformBlocks);
vertexUniformBuffers[registerIndex] = uniformBuffer;
}
@@ -1054,15 +1029,15 @@ bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuff
{
unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers());
+ ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
fragmentUniformBuffers[registerIndex] = uniformBuffer;
}
}
- return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+ return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
}
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
{
std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
@@ -1072,24 +1047,32 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShade
PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
bool matched = false;
+ // Built-in varyings obey special rules
+ if (input->isBuiltIn())
+ {
+ continue;
+ }
+
for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
{
PackedVarying *output = &vertexVaryings[vertVaryingIndex];
if (output->name == input->name)
{
- if (!linkValidateVariables(infoLog, output->name, *input, *output))
+ if (!linkValidateVaryings(infoLog, output->name, *input, *output))
{
return false;
}
output->registerIndex = input->registerIndex;
+ output->columnIndex = input->columnIndex;
matched = true;
break;
}
}
- if (!matched)
+ // We permit unmatched, unreferenced varyings
+ if (!matched && input->staticUse)
{
infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
return false;
@@ -1099,17 +1082,19 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShade
return true;
}
-bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
+bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
return false;
#else
+ ASSERT(binaryFormat == mProgram->getBinaryFormat());
+
reset();
BinaryInputStream stream(binary, length);
- int format = stream.readInt<int>();
- if (format != GL_PROGRAM_BINARY_ANGLE)
+ GLenum format = stream.readInt<GLenum>();
+ if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
return false;
@@ -1149,18 +1134,23 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
initAttributesByLayout();
- for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+ const unsigned int psSamplerCount = stream.readInt<unsigned int>();
+ for (unsigned int i = 0; i < psSamplerCount; ++i)
{
- stream.readBool(&mSamplersPS[i].active);
- stream.readInt(&mSamplersPS[i].logicalTextureUnit);
- stream.readInt(&mSamplersPS[i].textureType);
+ Sampler sampler;
+ stream.readBool(&sampler.active);
+ stream.readInt(&sampler.logicalTextureUnit);
+ stream.readInt(&sampler.textureType);
+ mSamplersPS.push_back(sampler);
}
-
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+ const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
+ for (unsigned int i = 0; i < vsSamplerCount; ++i)
{
- stream.readBool(&mSamplersVS[i].active);
- stream.readInt(&mSamplersVS[i].logicalTextureUnit);
- stream.readInt(&mSamplersVS[i].textureType);
+ Sampler sampler;
+ stream.readBool(&sampler.active);
+ stream.readInt(&sampler.logicalTextureUnit);
+ stream.readInt(&sampler.textureType);
+ mSamplersVS.push_back(sampler);
}
stream.readInt(&mUsedVertexSamplerRange);
@@ -1260,10 +1250,6 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.readInt(&varying.semanticIndexCount);
}
- stream.readString(&mVertexHLSL);
-
- stream.readInt(&mVertexWorkarounds);
-
const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
{
@@ -1280,7 +1266,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
unsigned int vertexShaderSize = stream.readInt<unsigned int>();
const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+ rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
vertexShaderSize, rx::SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
@@ -1292,7 +1278,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
// generated converted input layout
GLenum signature[MAX_VERTEX_ATTRIBS];
- mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
+ mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
// add new binary
mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
@@ -1300,20 +1286,6 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.skip(vertexShaderSize);
}
- 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);
- }
-
const size_t pixelShaderCount = stream.readInt<unsigned int>();
for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
{
@@ -1326,10 +1298,11 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
const size_t pixelShaderSize = stream.readInt<unsigned int>();
const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
- rx::SHADER_PIXEL,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+ rx::Renderer *renderer = mProgram->getRenderer();
+ rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
+ rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
@@ -1347,9 +1320,11 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
if (geometryShaderSize > 0)
{
const char *geometryShaderFunction = (const char*) binary + stream.offset();
- mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+ rx::Renderer *renderer = mProgram->getRenderer();
+ mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
+ geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
+
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
@@ -1358,29 +1333,39 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.skip(geometryShaderSize);
}
+ if (!mProgram->load(infoLog, &stream))
+ {
+ return false;
+ }
+
const char *ptr = (const char*) binary + stream.offset();
const GUID *binaryIdentifier = (const GUID *) ptr;
ptr += sizeof(GUID);
- GUID identifier = mRenderer->getAdapterIdentifier();
+ GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
return false;
}
- initializeUniformStorage();
+ mProgram->initializeUniformStorage(mUniforms);
return true;
#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
}
-bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
+bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
+ if (binaryFormat)
+ {
+ *binaryFormat = mProgram->getBinaryFormat();
+ }
+
BinaryOutputStream stream;
- stream.writeInt(GL_PROGRAM_BINARY_ANGLE);
+ stream.writeInt(mProgram->getBinaryFormat());
stream.writeInt(ANGLE_MAJOR_VERSION);
stream.writeInt(ANGLE_MINOR_VERSION);
stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
@@ -1395,14 +1380,16 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeInt(mSemanticIndex[i]);
}
- for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
+ stream.writeInt(mSamplersPS.size());
+ for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
{
stream.writeInt(mSamplersPS[i].active);
stream.writeInt(mSamplersPS[i].logicalTextureUnit);
stream.writeInt(mSamplersPS[i].textureType);
}
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
+ stream.writeInt(mSamplersVS.size());
+ for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
{
stream.writeInt(mSamplersVS[i].active);
stream.writeInt(mSamplersVS[i].logicalTextureUnit);
@@ -1477,9 +1464,6 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeInt(varying.semanticIndexCount);
}
- stream.writeString(mVertexHLSL);
- stream.writeInt(mVertexWorkarounds);
-
stream.writeInt(mVertexExecutables.size());
for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
{
@@ -1501,20 +1485,6 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeBytes(vertexBlob, vertexShaderSize);
}
- stream.writeString(mPixelHLSL);
- stream.writeInt(mPixelWorkarounds);
- stream.writeInt(mUsesFragDepth);
-
- stream.writeInt(mPixelShaderKey.size());
- for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < mPixelShaderKey.size(); pixelShaderKeyIndex++)
- {
- const PixelShaderOuputVariable &variable = mPixelShaderKey[pixelShaderKeyIndex];
- stream.writeInt(variable.type);
- stream.writeString(variable.name);
- stream.writeString(variable.source);
- stream.writeInt(variable.outputIndex);
- }
-
stream.writeInt(mPixelExecutables.size());
for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
{
@@ -1543,7 +1513,17 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.writeBytes(geometryBlob, geometryShaderSize);
}
- GUID identifier = mRenderer->getAdapterIdentifier();
+ if (!mProgram->save(&stream))
+ {
+ if (length)
+ {
+ *length = 0;
+ }
+
+ return false;
+ }
+
+ GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
@@ -1583,7 +1563,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
GLint ProgramBinary::getLength()
{
GLint length;
- if (save(NULL, INT_MAX, &length))
+ if (save(NULL, NULL, INT_MAX, &length))
{
return length;
}
@@ -1593,68 +1573,56 @@ GLint ProgramBinary::getLength()
}
}
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode)
+bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
return false;
}
+ ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
return false;
}
+ ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
reset();
- mTransformFeedbackBufferMode = transformFeedbackBufferMode;
-
- mShaderVersion = vertexShader->getShaderVersion();
+ mSamplersPS.resize(caps.maxTextureImageUnits);
+ mSamplersVS.resize(caps.maxVertexTextureImageUnits);
- mPixelHLSL = fragmentShader->getHLSL();
- mPixelWorkarounds = fragmentShader->getD3DWorkarounds();
-
- mVertexHLSL = vertexShader->getHLSL();
- mVertexWorkarounds = vertexShader->getD3DWorkarounds();
+ mTransformFeedbackBufferMode = transformFeedbackBufferMode;
- // Map the varyings to the register file
- VaryingPacking packing = { NULL };
- int registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShader, vertexShader, transformFeedbackVaryings);
+ rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
- if (registers < 0)
- {
- return false;
- }
+ mShaderVersion = vertexShaderD3D->getShaderVersion();
- if (!linkVaryings(infoLog, fragmentShader, vertexShader))
- {
- return false;
- }
-
- mUsesPointSize = vertexShader->usesPointSize();
+ int registers;
std::vector<LinkedVarying> linkedVaryings;
- if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, registers, packing, mPixelHLSL, mVertexHLSL,
- fragmentShader, vertexShader, transformFeedbackVaryings,
- &linkedVaryings, &mOutputVariables, &mPixelShaderKey, &mUsesFragDepth))
+ if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
{
return false;
}
+ mUsesPointSize = vertexShaderD3D->usesPointSize();
+
bool success = true;
- if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
+ if (!linkAttributes(infoLog, attributeBindings, vertexShader))
{
success = false;
}
- if (!linkUniforms(infoLog, *vertexShader, *fragmentShader))
+ if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
}
// special case for gl_DepthRange, the only built-in uniform (also a struct)
- if (vertexShader->usesDepthRange() || fragmentShader->usesDepthRange())
+ if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
{
const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
@@ -1663,13 +1631,13 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
}
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader))
+ if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
{
success = false;
}
if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings))
+ transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
{
success = false;
}
@@ -1677,23 +1645,19 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
if (success)
{
VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
- GetInputLayoutFromShader(vertexShader->activeAttributes(), defaultInputLayout);
+ GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
- std::vector<GLenum> defaultPixelOutput(IMPLEMENTATION_MAX_DRAW_BUFFERS);
- for (size_t i = 0; i < defaultPixelOutput.size(); i++)
- {
- defaultPixelOutput[i] = (i == 0) ? GL_FLOAT : GL_NONE;
- }
+ std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
if (usesGeometryShader())
{
- std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShader, vertexShader);
- mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- rx::ANGLE_D3D_WORKAROUND_NONE);
+ std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+ mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
+ rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ rx::ANGLE_D3D_WORKAROUND_NONE);
}
if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
@@ -1708,15 +1672,20 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
{
+ const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+
unsigned int usedLocations = 0;
- const std::vector<sh::Attribute> &activeAttributes = vertexShader->activeAttributes();
+ const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
// Link attributes that have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
- const sh::Attribute &attribute = activeAttributes[attributeIndex];
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
mShaderAttributes[attributeIndex] = attribute;
@@ -1755,9 +1724,12 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
}
// Link attributes that don't have a binding location
- for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+ for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
{
- const sh::Attribute &attribute = activeAttributes[attributeIndex];
+ const sh::Attribute &attribute = shaderAttributes[attributeIndex];
+
+ ASSERT(attribute.staticUse);
+
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier
@@ -1778,7 +1750,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{
- int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+ int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
for (int r = 0; r < rows; r++)
@@ -1811,32 +1783,29 @@ bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::strin
return false;
}
- return true;
-}
-
-template <class ShaderVarType>
-bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar)
-{
- if (vertexVar.fields.size() != fragmentVar.fields.size())
+ if (vertexVariable.fields.size() != fragmentVariable.fields.size())
{
- infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", varName.c_str());
+ infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
return false;
}
- const unsigned int numMembers = vertexVar.fields.size();
+ const unsigned int numMembers = vertexVariable.fields.size();
for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
{
- const ShaderVarType &vertexMember = vertexVar.fields[memberIndex];
- const ShaderVarType &fragmentMember = fragmentVar.fields[memberIndex];
+ const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
+ const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
if (vertexMember.name != fragmentMember.name)
{
infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
- memberIndex, varName.c_str(), vertexMember.name.c_str(), fragmentMember.name.c_str());
+ memberIndex, variableName.c_str(),
+ vertexMember.name.c_str(), fragmentMember.name.c_str());
return false;
}
- const std::string memberName = varName.substr(0, varName.length()-1) + "." + vertexVar.name + "'";
- if (!linkValidateVariables(infoLog, memberName, vertexMember, fragmentMember))
+ const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
+ vertexMember.name + "'";
+
+ if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
{
return false;
}
@@ -1845,22 +1814,17 @@ bool ProgramBinary::linkValidateFields(InfoLog &infoLog, const std::string &varN
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
+bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
{
return false;
}
- if (!linkValidateFields<sh::Uniform>(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
+bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
{
if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
{
@@ -1873,37 +1837,30 @@ bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &v
return false;
}
- if (!linkValidateFields<sh::Varying>(infoLog, varyingName, vertexVarying, fragmentVarying))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
+bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
{
return false;
}
- if (vertexUniform.isRowMajorMatrix != fragmentUniform.isRowMajorMatrix)
+ if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
{
infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
return false;
}
- if (!linkValidateFields<sh::InterfaceBlockField>(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
-
return true;
}
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
{
+ const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+ const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
+
const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
@@ -1925,7 +1882,7 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexSha
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!linkValidateVariables(infoLog, uniformName, vertexUniform, fragmentUniform))
+ if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
@@ -1935,35 +1892,43 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, const VertexShader &vertexSha
for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = vertexUniforms[uniformIndex];
- defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShader.getUniformRegister(uniform.name));
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+ }
}
for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
{
const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
- defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShader.getUniformRegister(uniform.name));
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+ }
}
- if (!indexUniforms(infoLog))
+ if (!indexUniforms(infoLog, caps))
{
return false;
}
- initializeUniformStorage();
+ mProgram->initializeUniformStorage(mUniforms);
return true;
}
void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{
- ShShaderOutput outputType = Shader::getCompilerOutputType(shader);
+ ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(uniformRegister);
defineUniform(shader, uniform, uniform.name, &encoder);
}
-void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
+void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{
if (uniform.isStruct())
@@ -1976,7 +1941,7 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
{
- const sh::Uniform &field = uniform.fields[fieldIndex];
+ const sh::ShaderVariable &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = (fullName + elementString + "." + field.name);
defineUniform(shader, field, fieldFullName, encoder);
@@ -2027,7 +1992,7 @@ void ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &uniform,
}
}
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog)
+bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
{
ASSERT(IsSampler(uniform.type));
ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
@@ -2035,19 +2000,18 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
- &mUsedVertexSamplerRange, mRenderer->getMaxVertexTextureImageUnits()))
+ &mUsedVertexSamplerRange))
{
infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
- mRenderer->getMaxVertexTextureImageUnits());
+ mSamplersVS.size());
return false;
}
- unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() +
- mRenderer->getMaxVertexUniformVectors();
+ unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
{
infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
- mRenderer->getMaxVertexUniformVectors());
+ caps.maxVertexUniformVectors);
return false;
}
}
@@ -2055,19 +2019,18 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
if (uniform.psRegisterIndex != GL_INVALID_INDEX)
{
if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
- &mUsedPixelSamplerRange, MAX_TEXTURE_IMAGE_UNITS))
+ &mUsedPixelSamplerRange))
{
infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
- MAX_TEXTURE_IMAGE_UNITS);
+ mSamplersPS.size());
return false;
}
- unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() +
- mRenderer->getMaxFragmentUniformVectors();
+ unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
{
infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
- mRenderer->getMaxFragmentUniformVectors());
+ caps.maxFragmentUniformVectors);
return false;
}
}
@@ -2075,7 +2038,7 @@ bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &i
return true;
}
-bool ProgramBinary::indexUniforms(InfoLog &infoLog)
+bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
{
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
@@ -2083,7 +2046,7 @@ bool ProgramBinary::indexUniforms(InfoLog &infoLog)
if (IsSampler(uniform.type))
{
- if (!indexSamplerUniform(uniform, infoLog))
+ if (!indexSamplerUniform(uniform, infoLog, caps))
{
return false;
}
@@ -2101,20 +2064,20 @@ bool ProgramBinary::indexUniforms(InfoLog &infoLog)
bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
GLenum samplerType,
unsigned int samplerCount,
- Sampler *outArray,
- GLuint *usedRange,
- unsigned int limit)
+ std::vector<Sampler> &outSamplers,
+ GLuint *outUsedRange)
{
unsigned int samplerIndex = startSamplerIndex;
do
{
- if (samplerIndex < limit)
+ if (samplerIndex < outSamplers.size())
{
- outArray[samplerIndex].active = true;
- outArray[samplerIndex].textureType = GetTextureType(samplerType);
- outArray[samplerIndex].logicalTextureUnit = 0;
- *usedRange = std::max(samplerIndex + 1, *usedRange);
+ Sampler& sampler = outSamplers[samplerIndex];
+ sampler.active = true;
+ sampler.textureType = GetTextureType(samplerType);
+ sampler.logicalTextureUnit = 0;
+ *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
}
else
{
@@ -2163,8 +2126,8 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
return false;
}
- std::string uniformName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
- if (!linkValidateVariables(infoLog, uniformName, vertexMember, fragmentMember))
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
{
return false;
}
@@ -2173,8 +2136,7 @@ bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::Inter
return true;
}
-bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vertexShader,
- const FragmentShader &fragmentShader)
+bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
{
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
@@ -2205,17 +2167,29 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vert
for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
- if (!defineUniformBlock(infoLog, vertexShader, vertexInterfaceBlocks[blockIndex]))
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
- return false;
+ if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ {
+ return false;
+ }
}
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- if (!defineUniformBlock(infoLog, fragmentShader, fragmentInterfaceBlocks[blockIndex]))
+ const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
- return false;
+ if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ {
+ return false;
+ }
}
}
@@ -2225,11 +2199,10 @@ bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const VertexShader &vert
bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const
{
size_t totalComponents = 0;
- const size_t maxSeparateComponents = mRenderer->getMaxTransformFeedbackSeparateComponents();
- const size_t maxInterleavedComponents = mRenderer->getMaxTransformFeedbackInterleavedComponents();
// Gather the linked varyings that are used for transform feedback, they should all exist.
outTransformFeedbackLinkedVaryings->clear();
@@ -2251,10 +2224,10 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
- componentCount > maxSeparateComponents)
+ componentCount > caps.maxTransformFeedbackSeparateComponents)
{
infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
- linkedVaryings[j].name.c_str(), componentCount, maxSeparateComponents);
+ linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
return false;
}
@@ -2270,39 +2243,45 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
ASSERT(found);
}
- if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > maxInterleavedComponents)
+ if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
{
infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
- totalComponents, maxInterleavedComponents);
+ totalComponents, caps.maxTransformFeedbackInterleavedComponents);
return false;
}
return true;
}
-void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes)
+template <typename VarT>
+void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout)
{
for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
{
- const sh::InterfaceBlockField &field = fields[uniformIndex];
+ const VarT &field = fields[uniformIndex];
const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (field.isStruct())
{
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
encoder->enterAggregateType();
const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes);
+ defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
encoder->exitAggregateType();
}
}
else
{
- sh::BlockMemberInfo memberInfo = encoder->encodeInterfaceBlockField(field);
+ bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
+
+ sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
blockIndex, memberInfo);
@@ -2314,8 +2293,10 @@ void ProgramBinary::defineUniformBlockMembers(const std::vector<sh::InterfaceBlo
}
}
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock)
+bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
{
+ const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
+
// create uniform block entries if they do not exist
if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
{
@@ -2335,7 +2316,7 @@ bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, c
}
ASSERT(encoder);
- defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes);
+ defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
size_t dataSize = encoder->getBlockSize();
@@ -2357,50 +2338,49 @@ bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, c
}
}
- // Assign registers to the uniform blocks
- const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
- const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
- ASSERT(blockIndex != GL_INVALID_INDEX);
- ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
-
- unsigned int interfaceBlockRegister = shader.getInterfaceBlockRegister(interfaceBlock.name);
-
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+ if (interfaceBlock.staticUse)
{
- UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
- ASSERT(uniformBlock->name == interfaceBlock.name);
+ // Assign registers to the uniform blocks
+ const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+ const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+ ASSERT(blockIndex != GL_INVALID_INDEX);
+ ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
+
+ unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
- if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
- interfaceBlockRegister + uniformBlockElement))
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
{
- return false;
+ UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+ ASSERT(uniformBlock->name == interfaceBlock.name);
+
+ if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
+ interfaceBlockRegister + uniformBlockElement, caps))
+ {
+ return false;
+ }
}
}
return true;
}
-bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex)
+bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
{
if (shader == GL_VERTEX_SHADER)
{
uniformBlock->vsRegisterIndex = registerIndex;
- unsigned int maximumBlocks = mRenderer->getMaxVertexShaderUniformBuffers();
-
- if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= maximumBlocks)
+ if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
{
- infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", maximumBlocks);
+ infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
return false;
}
}
else if (shader == GL_FRAGMENT_SHADER)
{
uniformBlock->psRegisterIndex = registerIndex;
- unsigned int maximumBlocks = mRenderer->getMaxFragmentShaderUniformBuffers();
-
- if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= maximumBlocks)
+ if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
{
- infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", maximumBlocks);
+ infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
return false;
}
}
@@ -2670,10 +2650,10 @@ GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
return maxLength;
}
-void ProgramBinary::validate(InfoLog &infoLog)
+void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
{
applyUniforms();
- if (!validateSamplers(&infoLog))
+ if (!validateSamplers(&infoLog, caps))
{
mValidated = false;
}
@@ -2683,20 +2663,14 @@ void ProgramBinary::validate(InfoLog &infoLog)
}
}
-bool ProgramBinary::validateSamplers(InfoLog *infoLog)
+bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
// if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
updateSamplerMapping();
- const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
- TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
- {
- textureUnitType[i] = TEXTURE_UNKNOWN;
- }
+ std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
{
@@ -2704,19 +2678,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
unsigned int unit = mSamplersPS[i].logicalTextureUnit;
- if (unit >= maxCombinedTextureImageUnits)
+ if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
- if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+ if (textureUnitTypes[unit] != GL_NONE)
{
- if (mSamplersPS[i].textureType != textureUnitType[unit])
+ if (mSamplersPS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
@@ -2728,7 +2702,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
}
else
{
- textureUnitType[unit] = mSamplersPS[i].textureType;
+ textureUnitTypes[unit] = mSamplersPS[i].textureType;
}
}
}
@@ -2739,19 +2713,19 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
unsigned int unit = mSamplersVS[i].logicalTextureUnit;
- if (unit >= maxCombinedTextureImageUnits)
+ if (unit >= textureUnitTypes.size())
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
}
return false;
}
- if (textureUnitType[unit] != TEXTURE_UNKNOWN)
+ if (textureUnitTypes[unit] != GL_NONE)
{
- if (mSamplersVS[i].textureType != textureUnitType[unit])
+ if (mSamplersVS[i].textureType != textureUnitTypes[unit])
{
if (infoLog)
{
@@ -2763,7 +2737,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
}
else
{
- textureUnitType[unit] = mSamplersVS[i].textureType;
+ textureUnitTypes[unit] = mSamplersVS[i].textureType;
}
}
}
@@ -2771,7 +2745,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
return true;
}
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
+ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
{
}
@@ -2819,42 +2793,9 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
}
}
-void ProgramBinary::initializeUniformStorage()
-{
- // Compute total default block size
- unsigned int vertexRegisters = 0;
- unsigned int fragmentRegisters = 0;
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- if (!IsSampler(uniform.type))
- {
- if (uniform.isReferencedByVertexShader())
- {
- vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
- }
- if (uniform.isReferencedByFragmentShader())
- {
- fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
- }
- }
- }
-
- mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
- mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
-}
-
void ProgramBinary::reset()
{
- mVertexHLSL.clear();
- mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
SafeDeleteContainer(mVertexExecutables);
-
- mPixelHLSL.clear();
- mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
- mUsesFragDepth = false;
- mPixelShaderKey.clear();
SafeDeleteContainer(mPixelExecutables);
SafeDelete(mGeometryExecutable);
@@ -2862,14 +2803,9 @@ void ProgramBinary::reset()
mTransformFeedbackBufferMode = GL_NONE;
mTransformFeedbackLinkedVaryings.clear();
- for (size_t i = 0; i < ArraySize(mSamplersPS); i++)
- {
- mSamplersPS[i] = Sampler();
- }
- for (size_t i = 0; i < ArraySize(mSamplersVS); i++)
- {
- mSamplersVS[i] = Sampler();
- }
+ mSamplersPS.clear();
+ mSamplersVS.clear();
+
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mUsesPointSize = false;
@@ -2880,8 +2816,8 @@ void ProgramBinary::reset()
SafeDeleteContainer(mUniformBlocks);
mUniformIndex.clear();
mOutputVariables.clear();
- SafeDelete(mVertexUniformStorage);
- SafeDelete(mFragmentUniformStorage);
+
+ mProgram->reset();
mValidated = false;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
index f0fc431021..ad470d417b 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
@@ -10,11 +10,6 @@
#ifndef LIBGLESV2_PROGRAM_BINARY_H_
#define LIBGLESV2_PROGRAM_BINARY_H_
-#include "angle_gl.h"
-
-#include <string>
-#include <vector>
-
#include "common/RefCountObject.h"
#include "angletypes.h"
#include "common/mathutil.h"
@@ -22,25 +17,43 @@
#include "libGLESv2/Shader.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+
+#include "angle_gl.h"
+
+#include <string>
+#include <vector>
+
+// TODO(jmadill): place this in workarounds library
+#define ANGLE_WORKAROUND_ENABLED 1
+#define ANGLE_WORKAROUND_DISABLED 2
+#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED
namespace sh
{
class HLSLBlockEncoder;
}
+#include <GLES3/gl3.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <string>
+#include <vector>
+
namespace rx
{
class ShaderExecutable;
class Renderer;
struct TranslatedAttribute;
class UniformStorage;
+class ProgramImpl;
}
namespace gl
{
-class FragmentShader;
-class VertexShader;
+struct Caps;
+class Shader;
class InfoLog;
class AttributeBindings;
class Buffer;
@@ -82,9 +95,12 @@ struct LinkedVarying
class ProgramBinary : public RefCountObject
{
public:
- explicit ProgramBinary(rx::Renderer *renderer);
+ explicit ProgramBinary(rx::ProgramImpl *impl);
~ProgramBinary();
+ rx::ProgramImpl *getImplementation() { return mProgram; }
+ const rx::ProgramImpl *getImplementation() const { return mProgram; }
+
rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
@@ -93,8 +109,8 @@ class ProgramBinary : public RefCountObject
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
- GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex);
- TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
+ GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
+ GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
bool usesPointSpriteEmulation() const;
@@ -125,20 +141,21 @@ class ProgramBinary : public RefCountObject
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
- bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
- bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
- bool getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params);
+ void getUniformfv(GLint location, GLfloat *params);
+ void getUniformiv(GLint location, GLint *params);
+ void getUniformuiv(GLint location, GLuint *params);
void dirtyAllUniforms();
- void applyUniforms();
- bool applyUniformBuffers(const std::vector<Buffer*> boundBuffers);
- bool load(InfoLog &infoLog, const void *binary, GLsizei length);
- bool save(void* binary, GLsizei bufSize, GLsizei *length);
+ Error applyUniforms();
+ Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
+
+ bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
+ bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
GLint getLength();
- bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode);
+ bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
@@ -165,8 +182,8 @@ class ProgramBinary : public RefCountObject
const LinkedVarying &getTransformFeedbackVarying(size_t idx) const;
GLenum getTransformFeedbackBufferMode() const;
- void validate(InfoLog &infoLog);
- bool validateSamplers(InfoLog *infoLog);
+ void validate(InfoLog &infoLog, const Caps &caps);
+ bool validateSamplers(InfoLog *infoLog, const Caps &caps);
bool isValidated() const;
void updateSamplerMapping();
@@ -177,8 +194,8 @@ class ProgramBinary : public RefCountObject
void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; }
- const rx::UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
- const rx::UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+
+ static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
@@ -189,40 +206,43 @@ class ProgramBinary : public RefCountObject
bool active;
GLint logicalTextureUnit;
- TextureType textureType;
+ GLenum textureType;
};
void reset();
- bool linkVaryings(InfoLog &infoLog, FragmentShader *fragmentShader, VertexShader *vertexShader);
- bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
+ bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
- template <class ShaderVarType>
- bool linkValidateFields(InfoLog &infoLog, const std::string &varName, const ShaderVarType &vertexVar, const ShaderVarType &fragmentVar);
- bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable, const sh::ShaderVariable &fragmentVariable, bool validatePrecision);
+ static bool linkValidateVariablesBase(InfoLog &infoLog,
+ const std::string &variableName,
+ const sh::ShaderVariable &vertexVariable,
+ const sh::ShaderVariable &fragmentVariable,
+ bool validatePrecision);
- bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
- bool linkValidateVariables(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
- bool linkValidateVariables(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
- bool linkUniforms(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader);
+ static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
+ static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
+ static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
+ bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
- void defineUniform(GLenum shader, const sh::Uniform &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
- bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog);
- bool indexUniforms(InfoLog &infoLog);
+ void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
+ bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
+ bool indexUniforms(InfoLog &infoLog, const Caps &caps);
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
- Sampler *outArray, GLuint *usedRange, unsigned int limit);
+ std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
- bool linkUniformBlocks(InfoLog &infoLog, const VertexShader &vertexShader, const FragmentShader &fragmentShader);
+ bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings) const;
- void defineUniformBlockMembers(const std::vector<sh::InterfaceBlockField> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes);
- bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock);
- bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex);
- void defineOutputVariables(FragmentShader *fragmentShader);
- void initializeUniformStorage();
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const;
+ template <typename VarT>
+ void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout);
+ bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps);
+ bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
+ void defineOutputVariables(Shader *fragmentShader);
template <typename T>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
@@ -231,7 +251,7 @@ class ProgramBinary : public RefCountObject
void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
template <typename T>
- bool getUniformv(GLint location, GLsizei *bufSize, T *params, GLenum uniformType);
+ void getUniformv(GLint location, T *params, GLenum uniformType);
class VertexExecutable
{
@@ -259,8 +279,7 @@ class ProgramBinary : public RefCountObject
PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
~PixelExecutable();
- // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
- bool matchesSignature(const std::vector<GLenum> &signature) const { return true; /* mOutputSignature == signature; */ }
+ bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
@@ -270,17 +289,9 @@ class ProgramBinary : public RefCountObject
rx::ShaderExecutable *mShaderExecutable;
};
- rx::Renderer *const mRenderer;
- DynamicHLSL *mDynamicHLSL;
+ rx::ProgramImpl *mProgram;
- std::string mVertexHLSL;
- rx::D3DWorkaroundType mVertexWorkarounds;
std::vector<VertexExecutable *> mVertexExecutables;
-
- std::string mPixelHLSL;
- rx::D3DWorkaroundType mPixelWorkarounds;
- bool mUsesFragDepth;
- std::vector<PixelShaderOuputVariable> mPixelShaderKey;
std::vector<PixelExecutable *> mPixelExecutables;
rx::ShaderExecutable *mGeometryExecutable;
@@ -293,8 +304,8 @@ class ProgramBinary : public RefCountObject
GLenum mTransformFeedbackBufferMode;
std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
- Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
- Sampler mSamplersVS[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+ std::vector<Sampler> mSamplersPS;
+ std::vector<Sampler> mSamplersVS;
GLuint mUsedVertexSamplerRange;
GLuint mUsedPixelSamplerRange;
bool mUsesPointSize;
@@ -305,8 +316,6 @@ class ProgramBinary : public RefCountObject
std::vector<UniformBlock*> mUniformBlocks;
std::vector<VariableLocation> mUniformIndex;
std::map<int, VariableLocation> mOutputVariables;
- rx::UniformStorage *mVertexUniformStorage;
- rx::UniformStorage *mFragmentUniformStorage;
bool mValidated;
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.cpp b/src/3rdparty/angle/src/libGLESv2/Query.cpp
index 6546d06c34..4ee3525509 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Query.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
@@ -9,39 +8,38 @@
#include "libGLESv2/Query.h"
#include "libGLESv2/renderer/QueryImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
-
-Query::Query(rx::Renderer *renderer, GLenum type, GLuint id) : RefCountObject(id)
-{
- mQuery = renderer->createQuery(type);
+Query::Query(rx::QueryImpl *impl, GLuint id)
+ : RefCountObject(id),
+ mQuery(impl)
+{
}
Query::~Query()
{
- delete mQuery;
+ SafeDelete(mQuery);
}
-void Query::begin()
+Error Query::begin()
{
- mQuery->begin();
+ return mQuery->begin();
}
-void Query::end()
+Error Query::end()
{
- mQuery->end();
+ return mQuery->end();
}
-GLuint Query::getResult()
+Error Query::getResult(GLuint *params)
{
- return mQuery->getResult();
+ return mQuery->getResult(params);
}
-GLboolean Query::isResultAvailable()
+Error Query::isResultAvailable(GLuint *available)
{
- return mQuery->isResultAvailable();
+ return mQuery->isResultAvailable(available);
}
GLenum Query::getType() const
@@ -49,9 +47,4 @@ GLenum Query::getType() const
return mQuery->getType();
}
-bool Query::isStarted() const
-{
- return mQuery->isStarted();
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.h b/src/3rdparty/angle/src/libGLESv2/Query.h
index a4726a8e73..a7ec404f85 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.h
+++ b/src/3rdparty/angle/src/libGLESv2/Query.h
@@ -9,14 +9,14 @@
#ifndef LIBGLESV2_QUERY_H_
#define LIBGLESV2_QUERY_H_
-#include "angle_gl.h"
-
+#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+#include "angle_gl.h"
+
namespace rx
{
-class Renderer;
class QueryImpl;
}
@@ -26,17 +26,16 @@ namespace gl
class Query : public RefCountObject
{
public:
- Query(rx::Renderer *renderer, GLenum type, GLuint id);
+ Query(rx::QueryImpl *impl, GLuint id);
virtual ~Query();
- void begin();
- void end();
+ Error begin();
+ Error end();
- GLuint getResult();
- GLboolean isResultAvailable();
+ Error getResult(GLuint *params);
+ Error isResultAvailable(GLuint *available);
GLenum getType() const;
- bool isStarted() const;
private:
DISALLOW_COPY_AND_ASSIGN(Query);
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
index d4bfaf27a1..9406fce58d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.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,13 +9,13 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-
#include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "common/utilities.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+#include "common/utilities.h"
namespace gl
{
@@ -29,6 +28,11 @@ Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
ASSERT(mStorage);
}
+Renderbuffer::~Renderbuffer()
+{
+ SafeDelete(mStorage);
+}
+
void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
{
ASSERT(newStorage);
@@ -75,32 +79,32 @@ GLsizei Renderbuffer::getSamples() const
GLuint Renderbuffer::getRedSize() const
{
- return gl::GetRedBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).redBits;
}
GLuint Renderbuffer::getGreenSize() const
{
- return gl::GetGreenBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).greenBits;
}
GLuint Renderbuffer::getBlueSize() const
{
- return gl::GetBlueBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).blueBits;
}
GLuint Renderbuffer::getAlphaSize() const
{
- return gl::GetAlphaBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).alphaBits;
}
GLuint Renderbuffer::getDepthSize() const
{
- return gl::GetDepthBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).depthBits;
}
GLuint Renderbuffer::getStencilSize() const
{
- return gl::GetStencilBits(getActualFormat());
+ return GetInternalFormatInfo(getActualFormat()).stencilBits;
}
RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
@@ -121,11 +125,6 @@ rx::RenderTarget *RenderbufferStorage::getRenderTarget()
return NULL;
}
-rx::RenderTarget *RenderbufferStorage::getDepthStencil()
-{
- return NULL;
-}
-
GLsizei RenderbufferStorage::getWidth() const
{
return mWidth;
@@ -156,7 +155,7 @@ unsigned int RenderbufferStorage::getSerial() const
return mSerial;
}
-unsigned int RenderbufferStorage::issueSerials(GLuint count)
+unsigned int RenderbufferStorage::issueSerials(unsigned int count)
{
unsigned int firstSerial = mCurrentSerial;
mCurrentSerial += count;
@@ -247,7 +246,7 @@ DepthStencilbuffer::~DepthStencilbuffer()
}
}
-rx::RenderTarget *DepthStencilbuffer::getDepthStencil()
+rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
{
return mDepthStencil;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
index e2d0c6b0fd..71bcb0e1f8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
@@ -39,6 +39,7 @@ class Renderbuffer : public RefCountObject
{
public:
Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+ virtual ~Renderbuffer();
void setStorage(RenderbufferStorage *newStorage);
RenderbufferStorage *getStorage();
@@ -70,7 +71,6 @@ class RenderbufferStorage
virtual ~RenderbufferStorage() = 0;
virtual rx::RenderTarget *getRenderTarget();
- virtual rx::RenderTarget *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
@@ -83,7 +83,7 @@ class RenderbufferStorage
virtual bool isTexture() const;
virtual unsigned int getTextureSerial() const;
- static unsigned int issueSerials(GLuint count);
+ static unsigned int issueSerials(unsigned int count);
protected:
GLsizei mWidth;
@@ -124,7 +124,7 @@ class DepthStencilbuffer : public RenderbufferStorage
~DepthStencilbuffer();
- virtual rx::RenderTarget *getDepthStencil();
+ virtual rx::RenderTarget *getRenderTarget();
protected:
rx::RenderTarget *mDepthStencil;
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
index 3606532404..9121de1750 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
@@ -1,4 +1,3 @@
-#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
@@ -93,13 +92,9 @@ GLuint ResourceManager::createShader(GLenum type)
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
- if (type == GL_VERTEX_SHADER)
+ if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
{
- mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
- }
- else if (type == GL_FRAGMENT_SHADER)
- {
- mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
+ mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
}
else UNREACHABLE();
@@ -151,7 +146,9 @@ GLuint ResourceManager::createFenceSync()
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
- mFenceSyncMap[handle] = new FenceSync(mRenderer, handle);
+ FenceSync *fenceSync = new FenceSync(mRenderer, handle);
+ fenceSync->addRef();
+ mFenceSyncMap[handle] = fenceSync;
return handle;
}
@@ -369,27 +366,27 @@ void ResourceManager::checkBufferAllocation(unsigned int buffer)
}
}
-void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
+void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
{
if (!getTexture(texture) && texture != 0)
{
Texture *textureObject;
- if (type == TEXTURE_2D)
+ if (type == GL_TEXTURE_2D)
{
- textureObject = new Texture2D(mRenderer->createTexture2D(), texture);
+ textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
}
- else if (type == TEXTURE_CUBE)
+ else if (type == GL_TEXTURE_CUBE_MAP)
{
- textureObject = new TextureCubeMap(mRenderer->createTextureCube(), texture);
+ textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
}
- else if (type == TEXTURE_3D)
+ else if (type == GL_TEXTURE_3D)
{
- textureObject = new Texture3D(mRenderer->createTexture3D(), texture);
+ textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
}
- else if (type == TEXTURE_2D_ARRAY)
+ else if (type == GL_TEXTURE_2D_ARRAY)
{
- textureObject = new Texture2DArray(mRenderer->createTexture2DArray(), texture);
+ textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
}
else
{
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
index d646c0d3cf..7d53bd4854 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
@@ -10,14 +10,14 @@
#ifndef LIBGLESV2_RESOURCEMANAGER_H_
#define LIBGLESV2_RESOURCEMANAGER_H_
-#include "angle_gl.h"
-
-#include <unordered_map>
-
#include "common/angleutils.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/HandleAllocator.h"
+#include "angle_gl.h"
+
+#include <unordered_map>
+
namespace rx
{
class Renderer;
@@ -65,11 +65,11 @@ class ResourceManager
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
FenceSync *getFenceSync(GLuint handle);
-
+
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkBufferAllocation(unsigned int buffer);
- void checkTextureAllocation(GLuint texture, TextureType type);
+ void checkTextureAllocation(GLuint texture, GLenum type);
void checkRenderbufferAllocation(GLuint renderbuffer);
void checkSamplerAllocation(GLuint sampler);
diff --git a/src/3rdparty/angle/src/libGLESv2/Sampler.cpp b/src/3rdparty/angle/src/libGLESv2/Sampler.cpp
index ed6e29f89e..b906e65557 100644
--- a/src/3rdparty/angle/src/libGLESv2/Sampler.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Sampler.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
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index eda0298e87..e3da2b1a9e 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.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
@@ -10,27 +9,30 @@
// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
#include "libGLESv2/Shader.h"
-
-#include "GLSLANG/ShaderLang.h"
-#include "common/utilities.h"
#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/ShaderImpl.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/ResourceManager.h"
+#include "common/utilities.h"
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <sstream>
+
namespace gl
{
-void *Shader::mFragmentCompiler = NULL;
-void *Shader::mVertexCompiler = NULL;
-Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
+Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle)
+ : mShader(impl),
+ mType(type),
+ mHandle(handle),
+ mResourceManager(manager),
+ mRefCount(0),
+ mDeleteStatus(false),
+ mCompiled(false)
{
- uncompile();
- initializeCompiler();
-
- mRefCount = 0;
- mDeleteStatus = false;
- mShaderVersion = 100;
+ ASSERT(impl);
}
Shader::~Shader()
@@ -56,7 +58,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
int Shader::getInfoLogLength() const
{
- return mInfoLog.empty() ? 0 : (mInfoLog.length() + 1);
+ return mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1);
}
void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
@@ -65,8 +67,8 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
if (bufSize > 0)
{
- index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
- memcpy(infoLog, mInfoLog.c_str(), index);
+ index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
+ memcpy(infoLog, mShader->getInfoLog().c_str(), index);
infoLog[index] = '\0';
}
@@ -84,10 +86,10 @@ int Shader::getSourceLength() const
int Shader::getTranslatedSourceLength() const
{
- return mHlsl.empty() ? 0 : (mHlsl.length() + 1);
+ return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1);
}
-void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const
+void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
{
int index = 0;
@@ -112,44 +114,12 @@ void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
{
- getSourceImpl(mHlsl, bufSize, length, buffer);
+ getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
}
-unsigned int Shader::getUniformRegister(const std::string &uniformName) const
+void Shader::compile()
{
- ASSERT(mUniformRegisterMap.count(uniformName) > 0);
- return mUniformRegisterMap.find(uniformName)->second;
-}
-
-unsigned int Shader::getInterfaceBlockRegister(const std::string &blockName) const
-{
- ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0);
- return mInterfaceBlockRegisterMap.find(blockName)->second;
-}
-
-const std::vector<sh::Uniform> &Shader::getUniforms() const
-{
- return mActiveUniforms;
-}
-
-const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
-{
- return mActiveInterfaceBlocks;
-}
-
-std::vector<PackedVarying> &Shader::getVaryings()
-{
- return mVaryings;
-}
-
-bool Shader::isCompiled() const
-{
- return !mHlsl.empty();
-}
-
-const std::string &Shader::getHLSL() const
-{
- return mHlsl;
+ mCompiled = mShader->compile(mSource);
}
void Shader::addRef()
@@ -182,412 +152,54 @@ void Shader::flagForDeletion()
mDeleteStatus = true;
}
-// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void Shader::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 = MAX_VERTEX_ATTRIBS;
- resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
- resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
- resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
- resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
- resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
- 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 = mRenderer->getMaxVaryingVectors();
- resources.MaxFragmentInputVectors = mRenderer->getMaxVaryingVectors();
- resources.MinProgramTexelOffset = -8; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
- resources.MaxProgramTexelOffset = 7; // D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
-
- mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- }
- }
-}
-
-void Shader::releaseCompiler()
+const std::vector<gl::PackedVarying> &Shader::getVaryings() const
{
- ShDestruct(mFragmentCompiler);
- ShDestruct(mVertexCompiler);
-
- mFragmentCompiler = NULL;
- mVertexCompiler = NULL;
-
- ShFinalize();
+ return mShader->getVaryings();
}
-void Shader::parseVaryings(void *compiler)
-{
- if (!mHlsl.empty())
- {
- std::vector<sh::Varying> *activeVaryings;
- ShGetInfoPointer(compiler, SH_ACTIVE_VARYINGS_ARRAY, reinterpret_cast<void**>(&activeVaryings));
-
- for (size_t varyingIndex = 0; varyingIndex < activeVaryings->size(); varyingIndex++)
- {
- mVaryings.push_back(PackedVarying((*activeVaryings)[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 Shader::resetVaryingsRegisterAssignment()
-{
- for (unsigned int varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++)
- {
- mVaryings[varyingIndex].resetRegisterAssignment();
- }
-}
-
-// initialize/clean up previous state
-void Shader::uncompile()
-{
- // set by compileToHLSL
- mHlsl.clear();
- mInfoLog.clear();
-
- // set by parseVaryings
- mVaryings.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;
-
- mActiveUniforms.clear();
- mActiveInterfaceBlocks.clear();
-}
-
-void Shader::compileToHLSL(void *compiler)
-{
- // ensure the compiler is loaded
- initializeCompiler();
-
- int compileOptions = SH_OBJECT_CODE;
- std::string sourcePath;
- if (perfActive())
- {
- sourcePath = getTempPath();
- writeFile(sourcePath.c_str(), mSource.c_str(), mSource.length());
- compileOptions |= SH_LINE_DIRECTIVES;
- }
-
- int result;
- if (sourcePath.empty())
- {
- const char* sourceStrings[] =
- {
- mSource.c_str(),
- };
-
- result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions);
- }
- else
- {
- const char* sourceStrings[] =
- {
- sourcePath.c_str(),
- mSource.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 = mSource.find("\n", curPos);
- size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
-
- hlslStream << "// " << mSource.substr(curPos, len);
-
- curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
- }
- hlslStream << "\n\n";
- hlslStream << outputHLSL;
- mHlsl = hlslStream.str();
-#else
- mHlsl = outputHLSL;
-#endif
-
- delete[] outputHLSL;
-
- void *activeUniforms;
- ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
- mActiveUniforms = *(std::vector<sh::Uniform>*)activeUniforms;
-
- for (size_t uniformIndex = 0; uniformIndex < mActiveUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = mActiveUniforms[uniformIndex];
-
- unsigned int index = -1;
- bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(result);
-
- mUniformRegisterMap[uniform.name] = index;
- }
-
- void *activeInterfaceBlocks;
- ShGetInfoPointer(compiler, SH_ACTIVE_INTERFACE_BLOCKS_ARRAY, &activeInterfaceBlocks);
- mActiveInterfaceBlocks = *(std::vector<sh::InterfaceBlock>*)activeInterfaceBlocks;
-
- for (size_t blockIndex = 0; blockIndex < mActiveInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = mActiveInterfaceBlocks[blockIndex];
-
- 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 Shader::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 Shader::compareVarying(const PackedVarying &x, const 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);
-}
-
-int Shader::getShaderVersion() const
-{
- return mShaderVersion;
-}
-
-VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : Shader(manager, renderer, handle)
-{
-}
-
-VertexShader::~VertexShader()
-{
-}
-
-GLenum VertexShader::getType() const
-{
- return GL_VERTEX_SHADER;
-}
-
-void VertexShader::uncompile()
-{
- Shader::uncompile();
-
- // set by ParseAttributes
- mActiveAttributes.clear();
-}
-
-void VertexShader::compile()
-{
- uncompile();
-
- compileToHLSL(mVertexCompiler);
- parseAttributes();
- parseVaryings(mVertexCompiler);
-}
-
-int VertexShader::getSemanticIndex(const std::string &attributeName)
+const std::vector<sh::Uniform> &Shader::getUniforms() const
{
- if (!attributeName.empty())
- {
- int semanticIndex = 0;
- for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
- {
- const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
-
- if (attribute.name == attributeName)
- {
- return semanticIndex;
- }
-
- semanticIndex += VariableRegisterCount(attribute.type);
- }
- }
-
- return -1;
+ return mShader->getUniforms();
}
-void VertexShader::parseAttributes()
+const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
{
- const std::string &hlsl = getHLSL();
- if (!hlsl.empty())
- {
- void *activeAttributes;
- ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
- mActiveAttributes = *(std::vector<sh::Attribute>*)activeAttributes;
- }
+ return mShader->getInterfaceBlocks();
}
-FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
- : Shader(manager, renderer, handle)
+const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
{
+ return mShader->getActiveAttributes();
}
-FragmentShader::~FragmentShader()
+const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
{
+ return mShader->getActiveOutputVariables();
}
-GLenum FragmentShader::getType() const
+std::vector<gl::PackedVarying> &Shader::getVaryings()
{
- return GL_FRAGMENT_SHADER;
+ return mShader->getVaryings();
}
-void FragmentShader::compile()
+std::vector<sh::Uniform> &Shader::getUniforms()
{
- uncompile();
-
- compileToHLSL(mFragmentCompiler);
- parseVaryings(mFragmentCompiler);
- std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
-
- const std::string &hlsl = getHLSL();
- if (!hlsl.empty())
- {
- void *activeOutputVariables;
- ShGetInfoPointer(mFragmentCompiler, SH_ACTIVE_OUTPUT_VARIABLES_ARRAY, &activeOutputVariables);
- mActiveOutputVariables = *(std::vector<sh::Attribute>*)activeOutputVariables;
- }
+ return mShader->getUniforms();
}
-void FragmentShader::uncompile()
+std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
{
- Shader::uncompile();
-
- mActiveOutputVariables.clear();
+ return mShader->getInterfaceBlocks();
}
-const std::vector<sh::Attribute> &FragmentShader::getOutputVariables() const
+std::vector<sh::Attribute> &Shader::getActiveAttributes()
{
- return mActiveOutputVariables;
+ return mShader->getActiveAttributes();
}
-ShShaderOutput Shader::getCompilerOutputType(GLenum shader)
+std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
{
- 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);
+ return mShader->getActiveOutputVariables();
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h
index a40f415c1e..7ba3bd165c 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.h
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.h
@@ -12,19 +12,20 @@
#ifndef LIBGLESV2_SHADER_H_
#define LIBGLESV2_SHADER_H_
-#include "angle_gl.h"
+
#include <string>
#include <list>
#include <vector>
-#include "common/shadervars.h"
+#include "angle_gl.h"
+#include <GLSLANG/ShaderLang.h>
+
#include "common/angleutils.h"
#include "libGLESv2/angletypes.h"
-#include "GLSLANG/ShaderLang.h"
namespace rx
{
-class Renderer;
+class ShaderImpl;
}
namespace gl
@@ -34,13 +35,16 @@ class ResourceManager;
struct PackedVarying : public sh::Varying
{
unsigned int registerIndex; // Assigned during link
+ unsigned int columnIndex; // Assigned during link, defaults to 0
PackedVarying(const sh::Varying &varying)
: sh::Varying(varying),
- registerIndex(GL_INVALID_INDEX)
+ registerIndex(GL_INVALID_INDEX),
+ columnIndex(0)
{}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
+ bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
void resetRegisterAssignment()
{
@@ -50,16 +54,17 @@ struct PackedVarying : public sh::Varying
class Shader
{
- friend class DynamicHLSL;
-
public:
- Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
+ Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle);
virtual ~Shader();
- virtual GLenum getType() const = 0;
+ GLenum getType() const { return mType; }
GLuint getHandle() const;
+ rx::ShaderImpl *getImplementation() { return mShader; }
+ const rx::ShaderImpl *getImplementation() const { return mShader; }
+
void deleteSource();
void setSource(GLsizei count, const char *const *string, const GLint *length);
int getInfoLogLength() const;
@@ -68,122 +73,44 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
- const std::vector<sh::Uniform> &getUniforms() const;
- const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
- std::vector<PackedVarying> &getVaryings();
- virtual void compile() = 0;
- virtual void uncompile();
- bool isCompiled() const;
- const std::string &getHLSL() const;
+ void compile();
+ bool isCompiled() const { return mCompiled; }
void addRef();
void release();
unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
- int getShaderVersion() const;
- void resetVaryingsRegisterAssignment();
-
- static void releaseCompiler();
- static ShShaderOutput getCompilerOutputType(GLenum shader);
- unsigned int getUniformRegister(const std::string &uniformName) const;
- unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
-
- bool usesDepthRange() const { return mUsesDepthRange; }
- bool usesPointSize() const { return mUsesPointSize; }
- rx::D3DWorkaroundType getD3DWorkarounds() const;
-
- protected:
- void parseVaryings(void *compiler);
- void compileToHLSL(void *compiler);
-
- void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) const;
-
- static bool compareVarying(const PackedVarying &x, const PackedVarying &y);
-
- const rx::Renderer *const mRenderer;
-
- std::vector<PackedVarying> mVaryings;
-
- bool mUsesMultipleRenderTargets;
- bool mUsesFragColor;
- bool mUsesFragData;
- bool mUsesFragCoord;
- bool mUsesFrontFacing;
- bool mUsesPointSize;
- bool mUsesPointCoord;
- bool mUsesDepthRange;
- bool mUsesFragDepth;
- int mShaderVersion;
- bool mUsesDiscardRewriting;
- bool mUsesNestedBreak;
+ const std::vector<gl::PackedVarying> &getVaryings() const;
+ const std::vector<sh::Uniform> &getUniforms() const;
+ const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const;
+ const std::vector<sh::Attribute> &getActiveAttributes() const;
+ const std::vector<sh::Attribute> &getActiveOutputVariables() const;
- static void *mFragmentCompiler;
- static void *mVertexCompiler;
+ std::vector<gl::PackedVarying> &getVaryings();
+ std::vector<sh::Uniform> &getUniforms();
+ std::vector<sh::InterfaceBlock> &getInterfaceBlocks();
+ std::vector<sh::Attribute> &getActiveAttributes();
+ std::vector<sh::Attribute> &getActiveOutputVariables();
private:
DISALLOW_COPY_AND_ASSIGN(Shader);
- void initializeCompiler();
+ static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer);
+ rx::ShaderImpl *mShader;
const GLuint mHandle;
+ const GLenum mType;
+ std::string mSource;
unsigned int mRefCount; // Number of program objects this shader is attached to
bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
-
- std::string mSource;
- std::string mHlsl;
- std::string mInfoLog;
- std::vector<sh::Uniform> mActiveUniforms;
- std::vector<sh::InterfaceBlock> mActiveInterfaceBlocks;
- std::map<std::string, unsigned int> mUniformRegisterMap;
- std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
+ bool mCompiled; // Indicates if this shader has been successfully compiled
ResourceManager *mResourceManager;
};
-class VertexShader : public Shader
-{
- friend class DynamicHLSL;
-
- public:
- VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
-
- ~VertexShader();
-
- virtual GLenum getType() const;
- virtual void compile();
- virtual void uncompile();
- int getSemanticIndex(const std::string &attributeName);
-
- const std::vector<sh::Attribute> &activeAttributes() const { return mActiveAttributes; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VertexShader);
-
- void parseAttributes();
-
- std::vector<sh::Attribute> mActiveAttributes;
-};
-
-class FragmentShader : public Shader
-{
- public:
- FragmentShader(ResourceManager *manager,const rx::Renderer *renderer, GLuint handle);
-
- ~FragmentShader();
-
- virtual GLenum getType() const;
- virtual void compile();
- virtual void uncompile();
- const std::vector<sh::Attribute> &getOutputVariables() const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FragmentShader);
-
- std::vector<sh::Attribute> mActiveOutputVariables;
-};
}
#endif // LIBGLESV2_SHADER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp
index b552701727..3c03b90e56 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/State.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -10,6 +9,7 @@
#include "libGLESv2/State.h"
#include "libGLESv2/Context.h"
+#include "libGLESv2/Caps.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Query.h"
#include "libGLESv2/Framebuffer.h"
@@ -19,8 +19,18 @@
namespace gl
{
+
State::State()
{
+}
+
+State::~State()
+{
+ reset();
+}
+
+void State::initialize(const Caps& caps, GLuint clientVersion)
+{
mContext = NULL;
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -66,7 +76,7 @@ State::State()
mDepthStencil.stencilMask = -1;
mDepthStencil.stencilWritemask = -1;
mDepthStencil.stencilBackFunc = GL_ALWAYS;
- mDepthStencil.stencilBackMask = - 1;
+ mDepthStencil.stencilBackMask = -1;
mDepthStencil.stencilBackWritemask = -1;
mDepthStencil.stencilFail = GL_KEEP;
mDepthStencil.stencilPassDepthFail = GL_KEEP;
@@ -98,18 +108,24 @@ State::State()
mBlend.colorMaskBlue = true;
mBlend.colorMaskAlpha = true;
+ mActiveSampler = 0;
+
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
- for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
+ mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
+ mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
+ if (clientVersion >= 3)
{
- mSamplers[textureUnit].set(NULL);
+ // TODO: These could also be enabled via extension
+ mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
+ mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
}
- mActiveSampler = 0;
+ mSamplers.resize(caps.maxCombinedTextureImageUnits);
mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
@@ -122,15 +138,20 @@ State::State()
mDrawFramebuffer = NULL;
}
-State::~State()
+void State::reset()
{
- for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+ for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
- for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+ TextureBindingVector &textureVector = bindingVec->second;
+ for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
- mSamplerTexture[type][sampler].set(NULL);
+ textureVector[textureIdx].set(NULL);
}
}
+ for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
+ {
+ mSamplers[samplerIdx].set(NULL);
+ }
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
@@ -245,15 +266,8 @@ ClearParameters State::getClearParameters(GLbitfield mask) const
{
if (framebufferObject->getStencilbuffer() != NULL)
{
- rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
- if (!depthStencil)
- {
- ERR("Depth stencil pointer unexpectedly null.");
- ClearParameters nullClearParam = { 0 };
- return nullClearParam;
- }
-
- if (GetStencilBits(depthStencil->getActualFormat()) > 0)
+ GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
+ if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
{
clearParams.clearStencil = true;
}
@@ -591,26 +605,26 @@ unsigned int State::getActiveSampler() const
return mActiveSampler;
}
-void State::setSamplerTexture(TextureType type, Texture *texture)
+void State::setSamplerTexture(GLenum type, Texture *texture)
{
- mSamplerTexture[type][mActiveSampler].set(texture);
+ mSamplerTextures[type][mActiveSampler].set(texture);
}
-Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
+Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- GLuint texid = mSamplerTexture[type][sampler].id();
+ const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
- if (texid == 0) // Special case: 0 refers to default textures held by Context
+ if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
{
return NULL;
}
- return mSamplerTexture[type][sampler].get();
+ return binding.get();
}
-GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
+GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
{
- return mSamplerTexture[type][sampler].id();
+ return mSamplerTextures.at(type)[sampler].id();
}
void State::detachTexture(GLuint texture)
@@ -624,13 +638,15 @@ void State::detachTexture(GLuint texture)
// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
// rebound to texture object zero
- for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+ for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
- for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
+ TextureBindingVector &textureVector = bindingVec->second;
+ for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
- if (mSamplerTexture[type][sampler].id() == texture)
+ BindingPointer<Texture> &binding = textureVector[textureIdx];
+ if (binding.id() == texture)
{
- mSamplerTexture[type][sampler].set(NULL);
+ binding.set(NULL);
}
}
}
@@ -658,7 +674,7 @@ void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
GLuint State::getSamplerId(GLuint textureUnit) const
{
- ASSERT(textureUnit < ArraySize(mSamplers));
+ ASSERT(textureUnit < mSamplers.size());
return mSamplers[textureUnit].id();
}
@@ -673,11 +689,12 @@ void State::detachSampler(GLuint sampler)
// If a sampler object that is currently bound to one or more texture units is
// deleted, it is as though BindSampler is called once for each texture unit to
// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
- for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
+ for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
{
- if (mSamplers[textureUnit].id() == sampler)
+ BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
+ if (samplerBinding.id() == sampler)
{
- mSamplers[textureUnit].set(NULL);
+ samplerBinding.set(NULL);
}
}
}
@@ -1315,20 +1332,20 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_TEXTURE_BINDING_2D:
- ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
- *params = mSamplerTexture[TEXTURE_2D][mActiveSampler].id();
+ ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
- ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
- *params = mSamplerTexture[TEXTURE_CUBE][mActiveSampler].id();
+ ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_3D:
- ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
- *params = mSamplerTexture[TEXTURE_3D][mActiveSampler].id();
+ ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
+ *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
- ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
- *params = mSamplerTexture[TEXTURE_2D_ARRAY][mActiveSampler].id();
+ ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
break;
case GL_UNIFORM_BUFFER_BINDING:
*params = mGenericUniformBuffer.id();
@@ -1412,4 +1429,27 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
return true;
}
+bool State::hasMappedBuffer(GLenum target) const
+{
+ if (target == GL_ARRAY_BUFFER)
+ {
+ for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
+ {
+ const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
+ gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
+ if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ else
+ {
+ Buffer *buffer = getTargetBuffer(target);
+ return (buffer && buffer->isMapped());
+ }
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/State.h b/src/3rdparty/angle/src/libGLESv2/State.h
index 09be0b335d..5f0433136c 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.h
+++ b/src/3rdparty/angle/src/libGLESv2/State.h
@@ -24,6 +24,7 @@ namespace gl
class Query;
class VertexArray;
class Context;
+struct Caps;
class State
{
@@ -31,6 +32,9 @@ class State
State();
~State();
+ void initialize(const Caps& caps, GLuint clientVersion);
+ void reset();
+
void setContext(Context *context) { mContext = context; }
// State chunk getters
@@ -126,9 +130,9 @@ class State
// Texture binding & active texture unit manipulation
void setActiveSampler(unsigned int active);
unsigned int getActiveSampler() const;
- void setSamplerTexture(TextureType type, Texture *texture);
- Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
- GLuint getSamplerTextureId(unsigned int sampler, TextureType type) const;
+ void setSamplerTexture(GLenum type, Texture *texture);
+ Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
+ GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
void detachTexture(GLuint texture);
// Sampler object binding manipulation
@@ -238,6 +242,8 @@ class State
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
+ bool hasMappedBuffer(GLenum target) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(State);
@@ -270,7 +276,6 @@ class State
float mNearZ;
float mFarZ;
- unsigned int mActiveSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> mArrayBuffer;
Framebuffer *mReadFramebuffer;
Framebuffer *mDrawFramebuffer;
@@ -281,8 +286,15 @@ class State
VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
VertexArray *mVertexArray;
- BindingPointer<Texture> mSamplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
- BindingPointer<Sampler> mSamplers[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+ // Texture and sampler bindings
+ size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0
+
+ typedef std::vector< BindingPointer<Texture> > TextureBindingVector;
+ typedef std::map<GLenum, TextureBindingVector> TextureBindingMap;
+ TextureBindingMap mSamplerTextures;
+
+ typedef std::vector< BindingPointer<Sampler> > SamplerBindingVector;
+ SamplerBindingVector mSamplers;
typedef std::map< GLenum, BindingPointer<Query> > ActiveQueryMap;
ActiveQueryMap mActiveQueries;
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
index b0c0ee51bd..3ec492de07 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.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
@@ -10,23 +9,47 @@
// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
#include "libGLESv2/Texture.h"
-
#include "libGLESv2/main.h"
-#include "common/mathutil.h"
-#include "common/utilities.h"
+#include "libGLESv2/Context.h"
#include "libGLESv2/formatutils.h"
+#include "libGLESv2/ImageIndex.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/renderer/Image.h"
#include "libGLESv2/renderer/d3d/TextureStorage.h"
+
#include "libEGL/Surface.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/TextureImpl.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
namespace gl
{
-Texture::Texture(GLuint id, GLenum target)
+bool IsMipmapFiltered(const gl::SamplerState &samplerState)
+{
+ switch (samplerState.minFilter)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return false;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+bool IsPointSampled(const gl::SamplerState &samplerState)
+{
+ return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
+}
+
+Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
: RefCountObject(id),
+ mTexture(impl),
mUsage(GL_NONE),
mImmutable(false),
mTarget(target)
@@ -35,6 +58,7 @@ Texture::Texture(GLuint id, GLenum target)
Texture::~Texture()
{
+ SafeDelete(mTexture);
}
GLenum Texture::getTarget() const
@@ -45,6 +69,7 @@ GLenum Texture::getTarget() const
void Texture::setUsage(GLenum usage)
{
mUsage = usage;
+ getImplementation()->setUsage(usage);
}
void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
@@ -52,7 +77,7 @@ void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
*sampler = mSamplerState;
// Offset the effective base level by the texture storage's top level
- rx::TextureStorageInterface *texture = getNativeTexture();
+ rx::TextureStorage *texture = getNativeTexture();
int topLevel = texture ? texture->getTopLevel() : 0;
sampler->baseLevel = topLevel + mSamplerState.baseLevel;
}
@@ -89,9 +114,48 @@ GLenum Texture::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
}
+GLsizei Texture::getWidth(const ImageIndex &index) const
+{
+ rx::Image *image = mTexture->getImage(index);
+ return image->getWidth();
+}
+
+GLsizei Texture::getHeight(const ImageIndex &index) const
+{
+ rx::Image *image = mTexture->getImage(index);
+ return image->getHeight();
+}
+
+GLenum Texture::getInternalFormat(const ImageIndex &index) const
+{
+ rx::Image *image = mTexture->getImage(index);
+ return image->getInternalFormat();
+}
+
+GLenum Texture::getActualFormat(const ImageIndex &index) const
+{
+ rx::Image *image = mTexture->getImage(index);
+ return image->getActualFormat();
+}
+
+rx::TextureStorage *Texture::getNativeTexture()
+{
+ return getImplementation()->getNativeTexture();
+}
+
+void Texture::generateMipmaps()
+{
+ getImplementation()->generateMipmaps();
+}
+
+void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+ getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
+}
+
unsigned int Texture::getTextureSerial()
{
- rx::TextureStorageInterface *texture = getNativeTexture();
+ rx::TextureStorage *texture = getNativeTexture();
return texture ? texture->getTextureSerial() : 0;
}
@@ -102,7 +166,7 @@ bool Texture::isImmutable() const
int Texture::immutableLevelCount()
{
- return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
+ return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
}
int Texture::mipLevels() const
@@ -110,17 +174,19 @@ int Texture::mipLevels() const
return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
}
-Texture2D::Texture2D(rx::Texture2DImpl *impl, GLuint id)
- : Texture(id, GL_TEXTURE_2D),
- mTexture(impl)
+const rx::Image *Texture::getBaseLevelImage() const
+{
+ return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
+}
+
+Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
+ : Texture(impl, id, GL_TEXTURE_2D)
{
mSurface = NULL;
}
Texture2D::~Texture2D()
{
- SafeDelete(mTexture);
-
if (mSurface)
{
mSurface->setBoundTexture(NULL);
@@ -128,31 +194,10 @@ Texture2D::~Texture2D()
}
}
-rx::TextureStorageInterface *Texture2D::getNativeTexture()
-{
- return mTexture->getNativeTexture();
-}
-
-void Texture2D::setUsage(GLenum usage)
-{
- mUsage = usage;
- mTexture->setUsage(usage);
-}
-
-bool Texture2D::hasDirtyImages() const
-{
- return mTexture->hasDirtyImages();
-}
-
-void Texture2D::resetDirty()
-{
- mTexture->resetDirty();
-}
-
GLsizei Texture2D::getWidth(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level)->getWidth();
+ return mTexture->getImage(level, 0)->getWidth();
else
return 0;
}
@@ -160,7 +205,7 @@ GLsizei Texture2D::getWidth(GLint level) const
GLsizei Texture2D::getHeight(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level)->getHeight();
+ return mTexture->getImage(level, 0)->getHeight();
else
return 0;
}
@@ -168,7 +213,7 @@ GLsizei Texture2D::getHeight(GLint level) const
GLenum Texture2D::getInternalFormat(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level)->getInternalFormat();
+ return mTexture->getImage(level, 0)->getInternalFormat();
else
return GL_NONE;
}
@@ -176,25 +221,16 @@ GLenum Texture2D::getInternalFormat(GLint level) const
GLenum Texture2D::getActualFormat(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level)->getActualFormat();
+ return mTexture->getImage(level, 0)->getActualFormat();
else
return GL_NONE;
}
-void Texture2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
-{
- releaseTexImage();
-
- mTexture->redefineImage(level, internalformat, width, height);
-}
-
void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat) ? internalFormat
- : GetSizedInternalFormat(format, type);
- redefineImage(level, sizedInternalFormat, width, height);
+ releaseTexImage();
- mTexture->setImage(level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void Texture2D::bindTexImage(egl::Surface *surface)
@@ -220,129 +256,189 @@ void Texture2D::releaseTexImage()
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
- // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
- redefineImage(level, format, width, height);
+ releaseTexImage();
- mTexture->setCompressedImage(level, format, width, height, imageSize, pixels);
+ mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
}
void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(level, xoffset, yoffset, width, height, format, type, unpack, pixels);
+ mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
- mTexture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, pixels);
+ mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
}
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- GLenum sizedInternalFormat = IsSizedInternalFormat(format) ? format
- : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- redefineImage(level, sizedInternalFormat, width, height);
-
- mTexture->copyImage(level, format, x, y, width, height, source);
-}
+ releaseTexImage();
-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
- mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
+ mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
}
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
mImmutable = true;
- mTexture->storage(levels, internalformat, width, height);
+ mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
-bool Texture2D::isSamplerComplete(const SamplerState &samplerState) const
+bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
- return mTexture->isSamplerComplete(samplerState);
+ GLsizei width = getBaseLevelWidth();
+ GLsizei height = getBaseLevelHeight();
+
+ if (width <= 0 || height <= 0)
+ {
+ return false;
+ }
+
+ if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
+ {
+ return false;
+ }
+
+ bool npotSupport = extensions.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.
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
+ if (formatInfo.depthBits > 0 && clientVersion > 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 Texture2D::isCompressed(GLint level) const
{
- return IsFormatCompressed(getInternalFormat(level));
+ return GetInternalFormatInfo(getInternalFormat(level)).compressed;
}
bool Texture2D::isDepth(GLint level) const
{
- return GetDepthBits(getInternalFormat(level)) > 0;
+ return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
void Texture2D::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));
- }
+ releaseTexImage();
mTexture->generateMipmaps();
}
-const rx::Image *Texture2D::getBaseLevelImage() const
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture2D::isMipmapComplete() const
{
- return mTexture->getImage(0);
-}
+ int levelCount = mipLevels();
-unsigned int Texture2D::getRenderTargetSerial(GLint level)
-{
- return mTexture->getRenderTargetSerial(level);
-}
+ for (int level = 0; level < levelCount; level++)
+ {
+ if (!isLevelComplete(level))
+ {
+ return false;
+ }
+ }
-rx::RenderTarget *Texture2D::getRenderTarget(GLint level)
-{
- return mTexture->getRenderTarget(level);
+ return true;
}
-rx::RenderTarget *Texture2D::getDepthSencil(GLint level)
+bool Texture2D::isLevelComplete(int level) const
{
- return mTexture->getDepthSencil(level);
-}
+ if (isImmutable())
+ {
+ return true;
+ }
-TextureCubeMap::TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id)
- : Texture(id, GL_TEXTURE_CUBE_MAP),
- mTexture(impl)
-{
-}
+ const rx::Image *baseImage = getBaseLevelImage();
-TextureCubeMap::~TextureCubeMap()
-{
- SafeDelete(mTexture);
-}
+ GLsizei width = baseImage->getWidth();
+ GLsizei height = baseImage->getHeight();
-rx::TextureStorageInterface *TextureCubeMap::getNativeTexture()
-{
- return mTexture->getNativeTexture();
-}
+ if (width <= 0 || height <= 0)
+ {
+ return false;
+ }
-void TextureCubeMap::setUsage(GLenum usage)
-{
- mUsage = usage;
- mTexture->setUsage(usage);
+ // The base image level is complete if the width and height are positive
+ if (level == 0)
+ {
+ return true;
+ }
+
+ ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
+ rx::Image *image = mTexture->getImage(level, 0);
+
+ if (image->getInternalFormat() != baseImage->getInternalFormat())
+ {
+ return false;
+ }
+
+ if (image->getWidth() != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (image->getHeight() != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ return true;
}
-bool TextureCubeMap::hasDirtyImages() const
+TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
+ : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
{
- return mTexture->hasDirtyImages();
}
-void TextureCubeMap::resetDirty()
+TextureCubeMap::~TextureCubeMap()
{
- mTexture->resetDirty();
}
GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(target, level)->getWidth();
+ return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
else
return 0;
}
@@ -350,7 +446,7 @@ GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(target, level)->getHeight();
+ return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
else
return 0;
}
@@ -358,7 +454,7 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(target, level)->getInternalFormat();
+ return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
else
return GL_NONE;
}
@@ -366,76 +462,91 @@ GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(target, level)->getActualFormat();
+ return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
else
return GL_NONE;
}
void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(0, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(1, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(2, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(3, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(4, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(5, level, width, height, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
- mTexture->setCompressedImage(target, level, format, width, height, imageSize, pixels);
+ mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
}
void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(target, level, xoffset, yoffset, width, height, format, type, unpack, pixels);
+ mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
- mTexture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
-}
-
-// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
-bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState) const
-{
- return mTexture->isSamplerComplete(samplerState);
+ mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureCubeMap::isCubeComplete() const
{
- return mTexture->isCubeComplete();
+ int baseWidth = getBaseLevelWidth();
+ int baseHeight = getBaseLevelHeight();
+ GLenum baseFormat = getBaseLevelInternalFormat();
+
+ if (baseWidth <= 0 || baseWidth != baseHeight)
+ {
+ return false;
+ }
+
+ for (int faceIndex = 1; faceIndex < 6; faceIndex++)
+ {
+ const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
+
+ if (faceBaseImage->getWidth() != baseWidth ||
+ faceBaseImage->getHeight() != baseHeight ||
+ faceBaseImage->getInternalFormat() != baseFormat )
+ {
+ return false;
+ }
+ }
+
+ return true;
}
bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
{
- return IsFormatCompressed(getInternalFormat(target, level));
+ return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
}
bool TextureCubeMap::isDepth(GLenum target, GLint level) const
{
- return GetDepthBits(getInternalFormat(target, level)) > 0;
+ return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
}
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
@@ -443,214 +554,307 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
mTexture->copyImage(target, level, format, x, y, width, height, source);
}
-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
- mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
-}
-
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{
mImmutable = true;
- mTexture->storage(levels, internalformat, size);
+ mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
}
-void TextureCubeMap::generateMipmaps()
+// Tests for texture sampling completeness
+bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
- mTexture->generateMipmaps();
-}
+ int size = getBaseLevelWidth();
-const rx::Image *TextureCubeMap::getBaseLevelImage() const
-{
- // Note: if we are not cube-complete, there is no single base level image that can describe all
- // cube faces, so this method is only well-defined for a cube-complete base level.
- return mTexture->getImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
-}
+ bool mipmapping = IsMipmapFiltered(samplerState);
-unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
-{
- return mTexture->getRenderTargetSerial(target, level);
-}
+ if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
+ {
+ return false;
+ }
-rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
-{
- return mTexture->getRenderTarget(target, level);
-}
+ if (!gl::isPow2(size) && !extensions.textureNPOT)
+ {
+ if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
+ {
+ return false;
+ }
+ }
-rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
-{
- return mTexture->getDepthStencil(target, level);
+ if (!mipmapping)
+ {
+ if (!isCubeComplete())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!isMipmapComplete()) // Also tests for isCubeComplete()
+ {
+ return false;
+ }
+ }
+
+ return true;
}
-Texture3D::Texture3D(rx::Texture3DImpl *impl, GLuint id)
- : Texture(id, GL_TEXTURE_3D),
- mTexture(impl)
+int TextureCubeMap::targetToLayerIndex(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;
}
-Texture3D::~Texture3D()
+GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
{
- SafeDelete(mTexture);
+ 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 GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
-rx::TextureStorageInterface *Texture3D::getNativeTexture()
+bool TextureCubeMap::isMipmapComplete() const
{
- return mTexture->getNativeTexture();
+ 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;
}
-void Texture3D::setUsage(GLenum usage)
+bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
{
- mUsage = usage;
- mTexture->setUsage(usage);
+ ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ int baseSize = getBaseLevelWidth();
+
+ if (baseSize <= 0)
+ {
+ return false;
+ }
+
+ // "isCubeComplete" checks for base level completeness and we must call that
+ // to determine if any face at level 0 is complete. We omit that check here
+ // to avoid re-checking cube-completeness for every face at level 0.
+ if (level == 0)
+ {
+ return true;
+ }
+
+ // Check that non-zero levels are consistent with the base level.
+ const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
+
+ if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
+ {
+ return false;
+ }
+
+ if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
+ {
+ return false;
+ }
+
+ return true;
}
-bool Texture3D::hasDirtyImages() const
+
+Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
+ : Texture(impl, id, GL_TEXTURE_3D)
{
- return mTexture->hasDirtyImages();
}
-void Texture3D::resetDirty()
+Texture3D::~Texture3D()
{
- mTexture->resetDirty();
}
GLsizei Texture3D::getWidth(GLint level) const
{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level)->getWidth() : 0;
+ return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
}
GLsizei Texture3D::getHeight(GLint level) const
{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level)->getHeight() : 0;
+ return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
}
GLsizei Texture3D::getDepth(GLint level) const
{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level)->getDepth() : 0;
+ return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
}
GLenum Texture3D::getInternalFormat(GLint level) const
{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level)->getInternalFormat() : GL_NONE;
+ return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
}
GLenum Texture3D::getActualFormat(GLint level) const
{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level)->getActualFormat() : GL_NONE;
+ return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
}
bool Texture3D::isCompressed(GLint level) const
{
- return IsFormatCompressed(getInternalFormat(level));
+ return GetInternalFormatInfo(getInternalFormat(level)).compressed;
}
bool Texture3D::isDepth(GLint level) const
{
- return GetDepthBits(getInternalFormat(level)) > 0;
+ return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
{
- mTexture->setCompressedImage(level, format, width, height, depth, imageSize, pixels);
+ mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
}
void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
{
- mTexture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
}
void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
mImmutable = true;
- mTexture->storage(levels, internalformat, width, height, depth);
+ mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
}
-void Texture3D::generateMipmaps()
+bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
- mTexture->generateMipmaps();
-}
+ GLsizei width = getBaseLevelWidth();
+ GLsizei height = getBaseLevelHeight();
+ GLsizei depth = getBaseLevelDepth();
-const rx::Image *Texture3D::getBaseLevelImage() const
-{
- return mTexture->getImage(0);
-}
+ if (width <= 0 || height <= 0 || depth <= 0)
+ {
+ return false;
+ }
-void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
- mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
-}
+ if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
+ {
+ return false;
+ }
-bool Texture3D::isSamplerComplete(const SamplerState &samplerState) const
-{
- return mTexture->isSamplerComplete(samplerState);
+ if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
+ {
+ return false;
+ }
+
+ return true;
}
bool Texture3D::isMipmapComplete() const
{
- return mTexture->isMipmapComplete();
-}
+ int levelCount = mipLevels();
-unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
-{
- return mTexture->getRenderTargetSerial(level, layer);
-}
+ for (int level = 0; level < levelCount; level++)
+ {
+ if (!isLevelComplete(level))
+ {
+ return false;
+ }
+ }
-rx::RenderTarget *Texture3D::getRenderTarget(GLint level)
-{
- return mTexture->getRenderTarget(level);
+ return true;
}
-rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
+bool Texture3D::isLevelComplete(int level) const
{
- return mTexture->getRenderTarget(level, layer);
-}
+ ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
-rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
-{
- return mTexture->getDepthStencil(level, layer);
-}
+ if (isImmutable())
+ {
+ return true;
+ }
-Texture2DArray::Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id)
- : Texture(id, GL_TEXTURE_2D_ARRAY),
- mTexture(impl)
-{
-}
+ GLsizei width = getBaseLevelWidth();
+ GLsizei height = getBaseLevelHeight();
+ GLsizei depth = getBaseLevelDepth();
-Texture2DArray::~Texture2DArray()
-{
- SafeDelete(mTexture);
-}
+ if (width <= 0 || height <= 0 || depth <= 0)
+ {
+ return false;
+ }
-rx::TextureStorageInterface *Texture2DArray::getNativeTexture()
-{
- return mTexture->getNativeTexture();
-}
+ if (level == 0)
+ {
+ return true;
+ }
-void Texture2DArray::setUsage(GLenum usage)
-{
- mUsage = usage;
- mTexture->setUsage(usage);
+ rx::Image *levelImage = mTexture->getImage(level, 0);
+
+ if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
+ {
+ return false;
+ }
+
+ if (levelImage->getWidth() != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (levelImage->getHeight() != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ if (levelImage->getDepth() != std::max(1, depth >> level))
+ {
+ return false;
+ }
+
+ return true;
}
-bool Texture2DArray::hasDirtyImages() const
+Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
+ : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
{
- return mTexture->hasDirtyImages();
}
-void Texture2DArray::resetDirty()
+Texture2DArray::~Texture2DArray()
{
- mTexture->resetDirty();
}
GLsizei Texture2DArray::getWidth(GLint level) const
@@ -680,79 +884,124 @@ GLenum Texture2DArray::getActualFormat(GLint level) const
bool Texture2DArray::isCompressed(GLint level) const
{
- return IsFormatCompressed(getInternalFormat(level));
+ return GetInternalFormatInfo(getInternalFormat(level)).compressed;
}
bool Texture2DArray::isDepth(GLint level) const
{
- return GetDepthBits(getInternalFormat(level)) > 0;
+ return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
{
- mTexture->setCompressedImage(level, format, width, height, depth, imageSize, pixels);
+ mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
}
void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
{
- mTexture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
}
void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
mImmutable = true;
- mTexture->storage(levels, internalformat, width, height, depth);
+ mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
}
-void Texture2DArray::generateMipmaps()
+bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
{
- mTexture->generateMipmaps();
-}
+ GLsizei width = getBaseLevelWidth();
+ GLsizei height = getBaseLevelHeight();
+ GLsizei depth = getLayers(0);
-const rx::Image *Texture2DArray::getBaseLevelImage() const
-{
- return (mTexture->getLayerCount(0) > 0 ? mTexture->getImage(0, 0) : NULL);
-}
+ if (width <= 0 || height <= 0 || depth <= 0)
+ {
+ return false;
+ }
-void Texture2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
- mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
-}
+ if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
+ {
+ return false;
+ }
-bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState) const
-{
- return mTexture->isSamplerComplete(samplerState);
+ if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
+ {
+ return false;
+ }
+
+ return true;
}
bool Texture2DArray::isMipmapComplete() const
{
- return mTexture->isMipmapComplete();
-}
+ int levelCount = mipLevels();
-unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
-{
- return mTexture->getRenderTargetSerial(level, layer);
-}
+ for (int level = 1; level < levelCount; level++)
+ {
+ if (!isLevelComplete(level))
+ {
+ return false;
+ }
+ }
-rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
-{
- return mTexture->getRenderTarget(level, layer);
+ return true;
}
-rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
+bool Texture2DArray::isLevelComplete(int level) const
{
- return mTexture->getDepthStencil(level, layer);
+ ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ GLsizei width = getBaseLevelWidth();
+ GLsizei height = getBaseLevelHeight();
+ GLsizei layers = getLayers(0);
+
+ if (width <= 0 || height <= 0 || layers <= 0)
+ {
+ return false;
+ }
+
+ if (level == 0)
+ {
+ return true;
+ }
+
+ if (getInternalFormat(level) != getInternalFormat(0))
+ {
+ return false;
+ }
+
+ if (getWidth(level) != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (getHeight(level) != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ if (getLayers(level) != layers)
+ {
+ return false;
+ }
+
+ return true;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h
index 29f952f9f6..ca5686fde3 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.h
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.h
@@ -11,14 +11,16 @@
#ifndef LIBGLESV2_TEXTURE_H_
#define LIBGLESV2_TEXTURE_H_
-#include <vector>
-
-#include "angle_gl.h"
-
#include "common/debug.h"
#include "common/RefCountObject.h"
#include "libGLESv2/angletypes.h"
#include "libGLESv2/constants.h"
+#include "libGLESv2/renderer/TextureImpl.h"
+#include "libGLESv2/Caps.h"
+
+#include "angle_gl.h"
+
+#include <vector>
namespace egl
{
@@ -27,12 +29,7 @@ class Surface;
namespace rx
{
-class Texture2DImpl;
-class TextureCubeImpl;
-class Texture3DImpl;
-class Texture2DArrayImpl;
class TextureStorageInterface;
-class RenderTarget;
class Image;
}
@@ -40,11 +37,14 @@ namespace gl
{
class Framebuffer;
class FramebufferAttachment;
+struct ImageIndex;
+
+bool IsMipmapFiltered(const gl::SamplerState &samplerState);
class Texture : public RefCountObject
{
public:
- Texture(GLuint id, GLenum target);
+ Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
virtual ~Texture();
@@ -54,7 +54,7 @@ class Texture : public RefCountObject
SamplerState &getSamplerState() { return mSamplerState; }
void getSamplerStateWithNativeOffset(SamplerState *sampler);
- virtual void setUsage(GLenum usage);
+ void setUsage(GLenum usage);
GLenum getUsage() const;
GLint getBaseLevelWidth() const;
@@ -62,25 +62,33 @@ class Texture : public RefCountObject
GLint getBaseLevelDepth() const;
GLenum getBaseLevelInternalFormat() const;
- virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0;
+ GLsizei getWidth(const ImageIndex &index) const;
+ GLsizei getHeight(const ImageIndex &index) const;
+ GLenum getInternalFormat(const ImageIndex &index) const;
+ GLenum getActualFormat(const ImageIndex &index) const;
- virtual rx::TextureStorageInterface *getNativeTexture() = 0;
+ virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
- virtual void generateMipmaps() = 0;
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+ rx::TextureStorage *getNativeTexture();
+
+ virtual void generateMipmaps();
+ virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- virtual bool hasDirtyImages() const = 0;
- virtual void resetDirty() = 0;
unsigned int getTextureSerial();
bool isImmutable() const;
int immutableLevelCount();
+ rx::TextureImpl *getImplementation() { return mTexture; }
+ const rx::TextureImpl *getImplementation() const { return mTexture; }
+
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
protected:
int mipLevels() const;
+ rx::TextureImpl *mTexture;
+
SamplerState mSamplerState;
GLenum mUsage;
@@ -88,23 +96,18 @@ class Texture : public RefCountObject
GLenum mTarget;
+ const rx::Image *getBaseLevelImage() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
-
- virtual const rx::Image *getBaseLevelImage() const = 0;
};
class Texture2D : public Texture
{
public:
- Texture2D(rx::Texture2DImpl *impl, GLuint id);
-
- ~Texture2D();
+ Texture2D(rx::TextureImpl *impl, GLuint id);
- virtual rx::TextureStorageInterface *getNativeTexture();
- virtual void setUsage(GLenum usage);
- virtual bool hasDirtyImages() const;
- virtual void resetDirty();
+ virtual ~Texture2D();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
@@ -118,44 +121,29 @@ class Texture2D : public Texture
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
- virtual bool isSamplerComplete(const SamplerState &samplerState) const;
+ virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps();
- unsigned int getRenderTargetSerial(GLint level);
-
- protected:
- friend class Texture2DAttachment;
- rx::RenderTarget *getRenderTarget(GLint level);
- rx::RenderTarget *getDepthSencil(GLint level);
-
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
- virtual const rx::Image *getBaseLevelImage() const;
+ bool isMipmapComplete() const;
+ bool isLevelComplete(int level) const;
- void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
-
- rx::Texture2DImpl *mTexture;
egl::Surface *mSurface;
};
class TextureCubeMap : public Texture
{
public:
- TextureCubeMap(rx::TextureCubeImpl *impl, GLuint id);
-
- ~TextureCubeMap();
+ TextureCubeMap(rx::TextureImpl *impl, GLuint id);
- virtual rx::TextureStorageInterface *getNativeTexture();
- virtual void setUsage(GLenum usage);
- virtual bool hasDirtyImages() const;
- virtual void resetDirty();
+ virtual ~TextureCubeMap();
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
@@ -176,40 +164,28 @@ class TextureCubeMap : public Texture
void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei size);
- virtual bool isSamplerComplete(const SamplerState &samplerState) const;
- bool isCubeComplete() const;
-
- virtual void generateMipmaps();
+ virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
- unsigned int getRenderTargetSerial(GLenum target, GLint level);
+ bool isCubeComplete() const;
- protected:
- friend class TextureCubeMapAttachment;
- rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
- rx::RenderTarget *getDepthStencil(GLenum target, GLint level);
+ static int targetToLayerIndex(GLenum target);
+ static GLenum layerIndexToTarget(GLint layer);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
- virtual const rx::Image *getBaseLevelImage() const;
-
- rx::TextureCubeImpl *mTexture;
+ bool isMipmapComplete() const;
+ bool isFaceLevelComplete(int faceIndex, int level) const;
};
class Texture3D : public Texture
{
public:
- Texture3D(rx::Texture3DImpl *impl, GLuint id);
-
- ~Texture3D();
+ Texture3D(rx::TextureImpl *impl, GLuint id);
- virtual rx::TextureStorageInterface *getNativeTexture();
- virtual void setUsage(GLenum usage);
- virtual bool hasDirtyImages() const;
- virtual void resetDirty();
+ virtual ~Texture3D();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
@@ -225,39 +201,21 @@ class Texture3D : public Texture
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- virtual void generateMipmaps();
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState) const;
- virtual bool isMipmapComplete() const;
-
- unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
- protected:
- friend class Texture3DAttachment;
- rx::RenderTarget *getRenderTarget(GLint level);
- rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
- rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
+ virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
private:
DISALLOW_COPY_AND_ASSIGN(Texture3D);
- virtual const rx::Image *getBaseLevelImage() const;
-
- rx::Texture3DImpl *mTexture;
+ bool isMipmapComplete() const;
+ bool isLevelComplete(int level) const;
};
class Texture2DArray : public Texture
{
public:
- Texture2DArray(rx::Texture2DArrayImpl *impl, GLuint id);
+ Texture2DArray(rx::TextureImpl *impl, GLuint id);
- ~Texture2DArray();
-
- virtual rx::TextureStorageInterface *getNativeTexture();
- virtual void setUsage(GLenum usage);
- virtual bool hasDirtyImages() const;
- virtual void resetDirty();
+ virtual ~Texture2DArray();
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
@@ -273,25 +231,13 @@ class Texture2DArray : public Texture
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- virtual void generateMipmaps();
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState) const;
- virtual bool isMipmapComplete() const;
-
- unsigned int getRenderTargetSerial(GLint level, GLint layer);
-
- protected:
- friend class Texture2DArrayAttachment;
- rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
- rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
+ virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
private:
DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
- virtual const rx::Image *getBaseLevelImage() const;
-
- rx::Texture2DArrayImpl *mTexture;
+ bool isMipmapComplete() const;
+ bool isLevelComplete(int level) const;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp b/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp
index 79ce08405d..bfa7072326 100644
--- a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp
@@ -5,20 +5,24 @@
//
#include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/renderer/TransformFeedbackImpl.h"
namespace gl
{
-TransformFeedback::TransformFeedback(GLuint id)
+TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id)
: RefCountObject(id),
+ mTransformFeedback(impl),
mStarted(GL_FALSE),
mPrimitiveMode(GL_NONE),
mPaused(GL_FALSE)
{
+ ASSERT(impl != NULL);
}
TransformFeedback::~TransformFeedback()
{
+ SafeDelete(mTransformFeedback);
}
void TransformFeedback::start(GLenum primitiveMode)
@@ -26,6 +30,7 @@ void TransformFeedback::start(GLenum primitiveMode)
mStarted = GL_TRUE;
mPrimitiveMode = primitiveMode;
mPaused = GL_FALSE;
+ mTransformFeedback->begin(primitiveMode);
}
void TransformFeedback::stop()
@@ -33,6 +38,7 @@ void TransformFeedback::stop()
mStarted = GL_FALSE;
mPrimitiveMode = GL_NONE;
mPaused = GL_FALSE;
+ mTransformFeedback->end();
}
GLboolean TransformFeedback::isStarted() const
@@ -48,11 +54,13 @@ GLenum TransformFeedback::getDrawMode() const
void TransformFeedback::pause()
{
mPaused = GL_TRUE;
+ mTransformFeedback->pause();
}
void TransformFeedback::resume()
{
mPaused = GL_FALSE;
+ mTransformFeedback->resume();
}
GLboolean TransformFeedback::isPaused() const
diff --git a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h b/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h
index d6f4522e2a..885a4fe172 100644
--- a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h
+++ b/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h
@@ -12,13 +12,18 @@
#include "angle_gl.h"
+namespace rx
+{
+class TransformFeedbackImpl;
+}
+
namespace gl
{
class TransformFeedback : public RefCountObject
{
public:
- explicit TransformFeedback(GLuint id);
+ TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id);
virtual ~TransformFeedback();
void start(GLenum primitiveMode);
@@ -34,6 +39,8 @@ class TransformFeedback : public RefCountObject
private:
DISALLOW_COPY_AND_ASSIGN(TransformFeedback);
+ rx::TransformFeedbackImpl* mTransformFeedback;
+
GLboolean mStarted;
GLenum mPrimitiveMode;
GLboolean mPaused;
diff --git a/src/3rdparty/angle/src/libGLESv2/Uniform.cpp b/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
index cddc7ec7d0..bd0cd2eeec 100644
--- a/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2010-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/Uniform.h b/src/3rdparty/angle/src/libGLESv2/Uniform.h
index 24f834f3c6..633d70bb19 100644
--- a/src/3rdparty/angle/src/libGLESv2/Uniform.h
+++ b/src/3rdparty/angle/src/libGLESv2/Uniform.h
@@ -7,15 +7,15 @@
#ifndef LIBGLESV2_UNIFORM_H_
#define LIBGLESV2_UNIFORM_H_
-#include <string>
-#include <vector>
+#include "common/debug.h"
+#include "common/blocklayout.h"
+
+#include "libGLESv2/angletypes.h"
#include "angle_gl.h"
-#include "common/debug.h"
-#include "angletypes.h"
-#include "common/shadervars.h"
-#include "common/blocklayout.h"
+#include <string>
+#include <vector>
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.cpp b/src/3rdparty/angle/src/libGLESv2/VertexArray.cpp
index 120064a532..f8ca661062 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.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
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
index accd98731a..993ba042cf 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h
+++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
@@ -17,6 +17,8 @@
#include "libGLESv2/constants.h"
#include "libGLESv2/VertexAttribute.h"
+#include <vector>
+
namespace rx
{
class Renderer;
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp b/src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp
index 7d011ef758..1096856b8a 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/VertexAttribute.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
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
index bc929c7d0c..bb6425df64 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.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
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h
index 79ad810e9e..642a6ec266 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.h
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h
@@ -11,6 +11,7 @@
#include "libGLESv2/constants.h"
#include "common/RefCountObject.h"
+#include <float.h>
namespace gl
{
@@ -19,17 +20,6 @@ class ProgramBinary;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
-enum TextureType
-{
- TEXTURE_2D,
- TEXTURE_CUBE,
- TEXTURE_3D,
- TEXTURE_2D_ARRAY,
-
- TEXTURE_TYPE_COUNT,
- TEXTURE_UNKNOWN
-};
-
enum SamplerType
{
SAMPLER_PIXEL,
diff --git a/src/3rdparty/angle/src/libGLESv2/constants.h b/src/3rdparty/angle/src/libGLESv2/constants.h
index c87f92d497..69c4823fb2 100644
--- a/src/3rdparty/angle/src/libGLESv2/constants.h
+++ b/src/3rdparty/angle/src/libGLESv2/constants.h
@@ -15,12 +15,8 @@ namespace gl
enum
{
MAX_VERTEX_ATTRIBS = 16,
- MAX_TEXTURE_IMAGE_UNITS = 16,
// Implementation upper limits, real maximums depend on the hardware
- IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16,
- IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
-
IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
diff --git a/src/3rdparty/angle/src/libGLESv2/formatutils.cpp b/src/3rdparty/angle/src/libGLESv2/formatutils.cpp
index 8cc2e19a83..8674d5337f 100644
--- a/src/3rdparty/angle/src/libGLESv2/formatutils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/formatutils.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
@@ -22,24 +21,23 @@ namespace gl
// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
// format and type combinations.
-struct FormatTypeInfo
+FormatType::FormatType()
+ : internalFormat(GL_NONE),
+ colorWriteFunction(NULL)
{
- GLenum mInternalFormat;
- ColorWriteFunction mColorWriteFunction;
-
- FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
- : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
- { }
-};
+}
typedef std::pair<GLenum, GLenum> FormatTypePair;
-typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
-typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
+typedef std::pair<FormatTypePair, FormatType> FormatPair;
+typedef std::map<FormatTypePair, FormatType> FormatMap;
// A helper function to insert data into the format map with fewer characters.
static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
{
- map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
+ FormatType info;
+ info.internalFormat = internalFormat;
+ info.colorWriteFunction = writeFunc;
+ map->insert(FormatPair(FormatTypePair(format, type), info));
}
FormatMap BuildFormatMap()
@@ -145,278 +143,59 @@ FormatMap BuildFormatMap()
return map;
}
-static const FormatMap &GetFormatMap()
+Type::Type()
+ : bytes(0),
+ specialInterpretation(false)
{
- static const FormatMap formatMap = BuildFormatMap();
- return formatMap;
}
-struct FormatInfo
-{
- GLenum mInternalformat;
- GLenum mFormat;
- GLenum mType;
-
- FormatInfo(GLenum internalformat, GLenum format, GLenum type)
- : mInternalformat(internalformat), mFormat(format), mType(type) { }
-
- bool operator<(const FormatInfo& other) const
- {
- return memcmp(this, &other, sizeof(FormatInfo)) < 0;
- }
-};
-
-// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
-typedef std::set<FormatInfo> ES3FormatSet;
+// Map of sizes of input types
+typedef std::pair<GLenum, Type> TypeInfoPair;
+typedef std::map<GLenum, Type> TypeInfoMap;
-ES3FormatSet BuildES3FormatSet()
+static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
{
- ES3FormatSet set;
-
- // Format combinations from ES 3.0.1 spec, table 3.2
-
- // | Internal format | Format | Type |
- // | | | |
- set.insert(FormatInfo(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE ));
- set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
- set.insert(FormatInfo(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
- set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
- set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ));
- set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_RGBA32F, GL_RGBA, GL_FLOAT ));
- set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_FLOAT ));
- set.insert(FormatInfo(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE ));
- set.insert(FormatInfo(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT ));
- set.insert(FormatInfo(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT ));
- set.insert(FormatInfo(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT ));
- set.insert(FormatInfo(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV ));
- set.insert(FormatInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGB8_SNORM, GL_RGB, GL_BYTE ));
- set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
- set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV ));
- set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV ));
- set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_RGB32F, GL_RGB, GL_FLOAT ));
- set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_FLOAT ));
- set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT ));
- set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_FLOAT ));
- set.insert(FormatInfo(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGB8I, GL_RGB_INTEGER, GL_BYTE ));
- set.insert(FormatInfo(GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT ));
- set.insert(FormatInfo(GL_RGB16I, GL_RGB_INTEGER, GL_SHORT ));
- set.insert(FormatInfo(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_RGB32I, GL_RGB_INTEGER, GL_INT ));
- set.insert(FormatInfo(GL_RG8, GL_RG, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RG8_SNORM, GL_RG, GL_BYTE ));
- set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_RG32F, GL_RG, GL_FLOAT ));
- set.insert(FormatInfo(GL_RG16F, GL_RG, GL_FLOAT ));
- set.insert(FormatInfo(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RG8I, GL_RG_INTEGER, GL_BYTE ));
- set.insert(FormatInfo(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT ));
- set.insert(FormatInfo(GL_RG16I, GL_RG_INTEGER, GL_SHORT ));
- set.insert(FormatInfo(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_RG32I, GL_RG_INTEGER, GL_INT ));
- set.insert(FormatInfo(GL_R8, GL_RED, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_R8_SNORM, GL_RED, GL_BYTE ));
- set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_R32F, GL_RED, GL_FLOAT ));
- set.insert(FormatInfo(GL_R16F, GL_RED, GL_FLOAT ));
- set.insert(FormatInfo(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_R8I, GL_RED_INTEGER, GL_BYTE ));
- set.insert(FormatInfo(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT ));
- set.insert(FormatInfo(GL_R16I, GL_RED_INTEGER, GL_SHORT ));
- set.insert(FormatInfo(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_R32I, GL_RED_INTEGER, GL_INT ));
-
- // Unsized formats
- set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
- set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ));
- set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
+ Type info;
+ info.bytes = bytes;
+ info.specialInterpretation = specialInterpretation;
- // Depth stencil formats
- set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ));
- set.insert(FormatInfo(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
- set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT ));
- set.insert(FormatInfo(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ));
- set.insert(FormatInfo(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
-
- // From GL_EXT_sRGB
- set.insert(FormatInfo(GL_SRGB8_ALPHA8_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
-
- // From GL_OES_texture_float
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ));
- set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_FLOAT ));
-
- // From GL_OES_texture_half_float
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES ));
-
- // From GL_EXT_texture_format_BGRA8888
- set.insert(FormatInfo(GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
-
- // From GL_EXT_texture_storage
- // | Internal format | Format | Type |
- // | | | |
- set.insert(FormatInfo(GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT ));
- set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT_OES ));
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
- set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ));
-
- // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
- set.insert(FormatInfo(GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
- set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
- set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
- set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
-
- // From GL_ANGLE_depth_texture
- set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ));
-
- // Compressed formats
- // From ES 3.0.1 spec, table 3.16
- // | Internal format | Format | Type |
- // | | | |
- set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE));
-
-
- // From GL_EXT_texture_compression_dxt1
- set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
- set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
-
- // From GL_ANGLE_texture_compression_dxt3
- set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE));
-
- // From GL_ANGLE_texture_compression_dxt5
- set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE));
-
- return set;
+ map->insert(std::make_pair(type, info));
}
-static const ES3FormatSet &GetES3FormatSet()
+bool operator<(const Type& a, const Type& b)
{
- static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
- return es3FormatSet;
+ return memcmp(&a, &b, sizeof(Type)) < 0;
}
-// Map of sizes of input types
-struct TypeInfo
-{
- GLuint mTypeBytes;
- bool mSpecialInterpretation;
-
- TypeInfo()
- : mTypeBytes(0), mSpecialInterpretation(false) { }
-
- TypeInfo(GLuint typeBytes, bool specialInterpretation)
- : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
-
- bool operator<(const TypeInfo& other) const
- {
- return memcmp(this, &other, sizeof(TypeInfo)) < 0;
- }
-};
-
-typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
-typedef std::map<GLenum, TypeInfo> TypeInfoMap;
-
static TypeInfoMap BuildTypeInfoMap()
{
TypeInfoMap map;
- map.insert(TypeInfoPair(GL_UNSIGNED_BYTE, TypeInfo( 1, false)));
- map.insert(TypeInfoPair(GL_BYTE, TypeInfo( 1, false)));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT, TypeInfo( 2, false)));
- map.insert(TypeInfoPair(GL_SHORT, TypeInfo( 2, false)));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT, TypeInfo( 4, false)));
- map.insert(TypeInfoPair(GL_INT, TypeInfo( 4, false)));
- map.insert(TypeInfoPair(GL_HALF_FLOAT, TypeInfo( 2, false)));
- map.insert(TypeInfoPair(GL_HALF_FLOAT_OES, TypeInfo( 2, false)));
- map.insert(TypeInfoPair(GL_FLOAT, TypeInfo( 4, false)));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5, TypeInfo( 2, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4, TypeInfo( 2, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1, TypeInfo( 2, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV, TypeInfo( 4, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8, TypeInfo( 4, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV, TypeInfo( 4, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV, TypeInfo( 4, true )));
- map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES, TypeInfo( 4, true )));
- map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
+ InsertTypeInfo(&map, GL_UNSIGNED_BYTE, 1, false);
+ InsertTypeInfo(&map, GL_BYTE, 1, false);
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT, 2, false);
+ InsertTypeInfo(&map, GL_SHORT, 2, false);
+ InsertTypeInfo(&map, GL_UNSIGNED_INT, 4, false);
+ InsertTypeInfo(&map, GL_INT, 4, false);
+ InsertTypeInfo(&map, GL_HALF_FLOAT, 2, false);
+ InsertTypeInfo(&map, GL_HALF_FLOAT_OES, 2, false);
+ InsertTypeInfo(&map, GL_FLOAT, 4, false);
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5, 2, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4, 2, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1, 2, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8, 4, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV, 4, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV, 4, true );
+ InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES, 4, true );
+ InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
return map;
}
-static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
-{
- static const TypeInfoMap infoMap = BuildTypeInfoMap();
- TypeInfoMap::const_iterator iter = infoMap.find(type);
- if (iter != infoMap.end())
- {
- if (outTypeInfo)
- {
- *outTypeInfo = iter->second;
- }
- return true;
- }
- else
- {
- return false;
- }
-}
-
// Information about internal formats
-typedef bool(*SupportCheckFunction)(GLuint, const Extensions &);
-
static bool AlwaysSupported(GLuint, const Extensions &)
{
return true;
@@ -433,7 +212,7 @@ static bool NeverSupported(GLuint, const Extensions &)
}
template <GLuint minCoreGLVersion>
-static bool RequireESVersion(GLuint clientVersion, const Extensions &)
+static bool RequireES(GLuint clientVersion, const Extensions &)
{
return clientVersion >= minCoreGLVersion;
}
@@ -443,299 +222,294 @@ typedef bool(Extensions::*ExtensionBool);
// Check support for a single extension
template <ExtensionBool bool1>
-static bool RequireExtension(GLuint, const Extensions & extensions)
+static bool RequireExt(GLuint, const Extensions & extensions)
{
return extensions.*bool1;
}
// Check for a minimum client version or a single extension
template <GLuint minCoreGLVersion, ExtensionBool bool1>
-static bool RequireESVersionOrExtension(GLuint clientVersion, const Extensions &extensions)
+static bool RequireESOrExt(GLuint clientVersion, const Extensions &extensions)
{
return clientVersion >= minCoreGLVersion || extensions.*bool1;
}
// Check for a minimum client version or two extensions
template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
-static bool RequireESVersionOrExtensions(GLuint clientVersion, const Extensions &extensions)
+static bool RequireESOrExtAndExt(GLuint clientVersion, const Extensions &extensions)
{
- return clientVersion >= minCoreGLVersion || (extensions.*bool1 || extensions.*bool2);
+ return clientVersion >= minCoreGLVersion || (extensions.*bool1 && extensions.*bool2);
}
-// Check support for two extensions
-template <ExtensionBool bool1, ExtensionBool bool2>
-static bool RequireExtensions(GLuint, const Extensions &extensions)
+// Check for a minimum client version or at least one of two extensions
+template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireESOrExtOrExt(GLuint clientVersion, const Extensions &extensions)
{
- return extensions.*bool1 || extensions.*bool2;
+ return clientVersion >= minCoreGLVersion || extensions.*bool1 || extensions.*bool2;
}
-struct InternalFormatInfo
-{
- GLuint mRedBits;
- GLuint mGreenBits;
- GLuint mBlueBits;
-
- GLuint mLuminanceBits;
-
- GLuint mAlphaBits;
- GLuint mSharedBits;
-
- GLuint mDepthBits;
- GLuint mStencilBits;
-
- GLuint mPixelBits;
-
- GLuint mComponentCount;
-
- GLuint mCompressedBlockWidth;
- GLuint mCompressedBlockHeight;
-
- GLenum mFormat;
- GLenum mType;
-
- GLenum mComponentType;
- GLenum mColorEncoding;
-
- bool mIsCompressed;
-
- SupportCheckFunction mTextureSupportFunction;
- SupportCheckFunction mRenderSupportFunction;
- SupportCheckFunction mFilterSupportFunction;
-
- InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
- mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
- mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mTextureSupportFunction(NeverSupported),
- mRenderSupportFunction(NeverSupported), mFilterSupportFunction(NeverSupported)
- {
- }
-
- static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
- SupportCheckFunction filterSupport)
- {
- InternalFormatInfo formatInfo;
- formatInfo.mFormat = format;
- formatInfo.mTextureSupportFunction = textureSupport;
- formatInfo.mRenderSupportFunction = renderSupport;
- formatInfo.mFilterSupportFunction = filterSupport;
- return formatInfo;
- }
-
- static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
- GLenum format, GLenum type, GLenum componentType, bool srgb,
- SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
- SupportCheckFunction filterSupport)
- {
- InternalFormatInfo formatInfo;
- formatInfo.mRedBits = red;
- formatInfo.mGreenBits = green;
- formatInfo.mBlueBits = blue;
- formatInfo.mAlphaBits = alpha;
- formatInfo.mSharedBits = shared;
- formatInfo.mPixelBits = red + green + blue + alpha + shared;
- formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
- formatInfo.mFormat = format;
- formatInfo.mType = type;
- formatInfo.mComponentType = componentType;
- formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
- formatInfo.mTextureSupportFunction = textureSupport;
- formatInfo.mRenderSupportFunction = renderSupport;
- formatInfo.mFilterSupportFunction = filterSupport;
- return formatInfo;
- }
-
- static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
- SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
- SupportCheckFunction filterSupport)
- {
- InternalFormatInfo formatInfo;
- formatInfo.mLuminanceBits = luminance;
- formatInfo.mAlphaBits = alpha;
- formatInfo.mPixelBits = luminance + alpha;
- formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
- formatInfo.mFormat = format;
- formatInfo.mType = type;
- formatInfo.mComponentType = componentType;
- formatInfo.mColorEncoding = GL_LINEAR;
- formatInfo.mTextureSupportFunction = textureSupport;
- formatInfo.mRenderSupportFunction = renderSupport;
- formatInfo.mFilterSupportFunction = filterSupport;
- return formatInfo;
- }
-
- static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
- GLenum type, GLenum componentType, SupportCheckFunction textureSupport,
- SupportCheckFunction renderSupport, SupportCheckFunction filterSupport)
- {
- InternalFormatInfo formatInfo;
- formatInfo.mDepthBits = depthBits;
- formatInfo.mStencilBits = stencilBits;
- formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
- formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
- formatInfo.mFormat = format;
- formatInfo.mType = type;
- formatInfo.mComponentType = componentType;
- formatInfo.mColorEncoding = GL_LINEAR;
- formatInfo.mTextureSupportFunction = textureSupport;
- formatInfo.mRenderSupportFunction = renderSupport;
- formatInfo.mFilterSupportFunction = filterSupport;
- return formatInfo;
- }
-
- static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
- GLuint componentCount, GLenum format, GLenum type, bool srgb,
- SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
- SupportCheckFunction filterSupport)
- {
- InternalFormatInfo formatInfo;
- formatInfo.mCompressedBlockWidth = compressedBlockWidth;
- formatInfo.mCompressedBlockHeight = compressedBlockHeight;
- formatInfo.mPixelBits = compressedBlockSize;
- formatInfo.mComponentCount = componentCount;
- formatInfo.mFormat = format;
- formatInfo.mType = type;
- formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
- formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
- formatInfo.mIsCompressed = true;
- formatInfo.mTextureSupportFunction = textureSupport;
- formatInfo.mRenderSupportFunction = renderSupport;
- formatInfo.mFilterSupportFunction = filterSupport;
- return formatInfo;
- }
-};
-
-typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
-typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
+// Check support for two extensions
+template <ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireExtAndExt(GLuint, const Extensions &extensions)
+{
+ return extensions.*bool1 && extensions.*bool2;
+}
+
+InternalFormat::InternalFormat()
+ : redBits(0),
+ greenBits(0),
+ blueBits(0),
+ luminanceBits(0),
+ alphaBits(0),
+ sharedBits(0),
+ depthBits(0),
+ stencilBits(0),
+ pixelBytes(0),
+ componentCount(0),
+ compressedBlockWidth(0),
+ compressedBlockHeight(0),
+ format(GL_NONE),
+ type(GL_NONE),
+ componentType(GL_NONE),
+ colorEncoding(GL_NONE),
+ compressed(false),
+ textureSupport(NeverSupported),
+ renderSupport(NeverSupported),
+ filterSupport(NeverSupported)
+{
+}
+
+static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction renderSupport,
+ InternalFormat::SupportCheckFunction filterSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.format = format;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.renderSupport = renderSupport;
+ formatInfo.filterSupport = filterSupport;
+ return formatInfo;
+}
+
+static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
+ GLenum format, GLenum type, GLenum componentType, bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction renderSupport,
+ InternalFormat::SupportCheckFunction filterSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.redBits = red;
+ formatInfo.greenBits = green;
+ formatInfo.blueBits = blue;
+ formatInfo.alphaBits = alpha;
+ formatInfo.sharedBits = shared;
+ formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
+ formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.renderSupport = renderSupport;
+ formatInfo.filterSupport = filterSupport;
+ return formatInfo;
+}
+
+static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction renderSupport,
+ InternalFormat::SupportCheckFunction filterSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.luminanceBits = luminance;
+ formatInfo.alphaBits = alpha;
+ formatInfo.pixelBytes = (luminance + alpha) / 8;
+ formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = GL_LINEAR;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.renderSupport = renderSupport;
+ formatInfo.filterSupport = filterSupport;
+ return formatInfo;
+}
+
+static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
+ GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction renderSupport,
+ InternalFormat::SupportCheckFunction filterSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.depthBits = depthBits;
+ formatInfo.stencilBits = stencilBits;
+ formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
+ formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = GL_LINEAR;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.renderSupport = renderSupport;
+ formatInfo.filterSupport = filterSupport;
+ return formatInfo;
+}
+
+static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
+ GLuint componentCount, GLenum format, GLenum type, bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction renderSupport,
+ InternalFormat::SupportCheckFunction filterSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.compressedBlockWidth = compressedBlockWidth;
+ formatInfo.compressedBlockHeight = compressedBlockHeight;
+ formatInfo.pixelBytes = compressedBlockSize / 8;
+ formatInfo.componentCount = componentCount;
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
+ formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+ formatInfo.compressed = true;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.renderSupport = renderSupport;
+ formatInfo.filterSupport = filterSupport;
+ return formatInfo;
+}
+
+typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair;
+typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap;
static InternalFormatInfoMap BuildInternalFormatInfoMap()
{
InternalFormatInfoMap map;
// From ES 3.0.1 spec, table 3.12
- map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo()));
-
- // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable |
- map.insert(InternalFormatInfoPair(GL_R8, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_R8_SNORM, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RG8, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RG8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB10_A2, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<3>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_SRGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESVersionOrExtension<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESVersionOrExtension<3, &Extensions::sRGB>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, InternalFormatInfo::RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireESVersion<3>, RequireExtension<&Extensions::colorBufferFloat>, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB9_E5, InternalFormatInfo::RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_R8I, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_R8UI, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_R16I, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_R16UI, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_R32I, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_R32UI, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG8I, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG8UI, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG16I, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG16UI, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG32I, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RG32UI, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
-
- map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat()));
+
+ // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_R8, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_R8_SNORM, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG8, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG8_SNORM, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB565, RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA4, RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB5_A1, RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB10_A2, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_SRGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB9_E5, RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_R8I, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_R8UI, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_R16I, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_R16UI, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_R32I, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_R32UI, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG8I, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG8UI, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG16I, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG16UI, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG32I, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG32UI, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB8I, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB8UI, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB16I, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB16UI, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB32I, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB32UI, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA8I, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA8UI, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA16I, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA16UI, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA32I, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA32UI, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
+
+ map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
// Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
- // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
- // | | | | | | | type | | | | |
- map.insert(InternalFormatInfoPair(GL_R16F, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
- map.insert(InternalFormatInfoPair(GL_RG16F, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
- map.insert(InternalFormatInfoPair(GL_RGB16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
- map.insert(InternalFormatInfoPair(GL_RGBA16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
- map.insert(InternalFormatInfoPair(GL_R32F, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
- map.insert(InternalFormatInfoPair(GL_RG32F, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
- map.insert(InternalFormatInfoPair(GL_RGB32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
- map.insert(InternalFormatInfoPair(GL_RGBA32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
+ // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
+ // | | | | | | | type | | | | |
+ map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
+ map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
+ map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
+ map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
+ map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
+ map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
+ map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
+ map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
// Depth stencil formats
- // | Internal format | | D |S | X | Format | Type | Component type | Supported |
- map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireESVersion<2>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
- map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, InternalFormatInfo::DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireESVersion<3>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
- map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireESVersion<3>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
- map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>, AlwaysSupported, AlwaysSupported )));
- map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESVersionOrExtension<2, &Extensions::depthTextures>, AlwaysSupported, AlwaysSupported )));
- map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESVersion<3>, AlwaysSupported, AlwaysSupported )));
- map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, RequireESVersion<2>, AlwaysSupported, NeverSupported )));
+ // | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>)));
+ map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>)));
+ map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>)));
+ map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::depthTextures>, RequireExt<&Extensions::depthTextures>, AlwaysSupported )));
+ map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported )));
+ map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported )));
+ map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, RequireES<2>, RequireES<2>, NeverSupported )));
// Luminance alpha formats
- // | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable |
- map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+ // | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
// Unsized formats
- // | Internal format | | Format | Supported | Renderable | Filterable |
- map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RED, InternalFormatInfo::UnsizedFormat(GL_RED, RequireESVersionOrExtension<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RG, InternalFormatInfo::UnsizedFormat(GL_RG, RequireESVersionOrExtension<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_RED_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
- map.insert(InternalFormatInfoPair(GL_RG_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
- map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
- map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
- map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL, RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_SRGB_EXT, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersionOrExtension<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
- map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersionOrExtension<3, &Extensions::sRGB>, AlwaysSupported, AlwaysSupported)));
+ // | Internal format | | Format | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_ALPHA, UnsizedFormat(GL_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE, UnsizedFormat(GL_LUMINANCE, RequireES<2>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RED, UnsizedFormat(GL_RED, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RG, UnsizedFormat(GL_RG, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGB, UnsizedFormat(GL_RGB, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RGBA, UnsizedFormat(GL_RGBA, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_RED_INTEGER, UnsizedFormat(GL_RED_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
+ map.insert(InternalFormatInfoPair(GL_RG_INTEGER, UnsizedFormat(GL_RG_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
+ map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, UnsizedFormat(GL_RGB_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
+ map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, UnsizedFormat(GL_RGBA_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
+ map.insert(InternalFormatInfoPair(GL_BGRA_EXT, UnsizedFormat(GL_BGRA_EXT, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireES<2>, RequireES<2>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, UnsizedFormat(GL_DEPTH_STENCIL, RequireESOrExt<3, &Extensions::packedDepthStencil>, RequireESOrExt<3, &Extensions::packedDepthStencil>, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_SRGB_EXT, UnsizedFormat(GL_RGB, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, UnsizedFormat(GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported)));
// Compressed formats, From ES 3.0.1 spec, table 3.16
- // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
// From GL_EXT_texture_compression_dxt1
- // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported )));
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported )));
+ // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported)));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported)));
// From GL_ANGLE_texture_compression_dxt3
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported )));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported)));
// From GL_ANGLE_texture_compression_dxt5
- map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported )));
+ map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported)));
return map;
}
@@ -746,24 +520,6 @@ static const InternalFormatInfoMap &GetInternalFormatMap()
return formatMap;
}
-static bool GetInternalFormatInfo(GLenum internalFormat, InternalFormatInfo *outFormatInfo)
-{
- const InternalFormatInfoMap &map = GetInternalFormatMap();
- InternalFormatInfoMap::const_iterator iter = map.find(internalFormat);
- if (iter != map.end())
- {
- if (outFormatInfo)
- {
- *outFormatInfo = iter->second;
- }
- return true;
- }
- else
- {
- return false;
- }
-}
-
static FormatSet BuildAllSizedInternalFormatSet()
{
FormatSet result;
@@ -771,7 +527,7 @@ static FormatSet BuildAllSizedInternalFormatSet()
const InternalFormatInfoMap &formats = GetInternalFormatMap();
for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
{
- if (i->second.mPixelBits > 0)
+ if (i->second.pixelBytes > 0)
{
result.insert(i->first);
}
@@ -780,756 +536,88 @@ static FormatSet BuildAllSizedInternalFormatSet()
return result;
}
-typedef std::set<GLenum> TypeSet;
-
-struct EffectiveInternalFormatInfo
-{
- GLenum mEffectiveFormat;
- GLenum mDestFormat;
- GLuint mMinRedBits;
- GLuint mMaxRedBits;
- GLuint mMinGreenBits;
- GLuint mMaxGreenBits;
- GLuint mMinBlueBits;
- GLuint mMaxBlueBits;
- GLuint mMinAlphaBits;
- GLuint mMaxAlphaBits;
-
- EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
- GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
- GLuint minAlphaBits, GLuint maxAlphaBits)
- : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
- mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
- mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
- mMaxAlphaBits(maxAlphaBits) {};
-};
-
-typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
-
-static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
-{
- EffectiveInternalFormatList list;
-
- // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
- // linear source buffer component sizes.
- // | Source channel min/max sizes |
- // Effective Internal Format | N/A | R | G | B | A |
- list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8));
- list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0));
- list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0));
- list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1));
- list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
-
- return list;
-}
-
-
-static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
-{
- EffectiveInternalFormatList list;
-
- // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
- // linear source buffer component sizes.
- // | Source channel min/max sizes |
- // Effective Internal Format | Dest Format | R | G | B | A |
- list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
- list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
- list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX));
- list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4));
- list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1));
- list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8));
-
- return list;
-}
-
-static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
- GLenum *outEffectiveFormat)
-{
- const EffectiveInternalFormatList *list = NULL;
- GLenum targetFormat = GL_NONE;
-
- if (gl::IsSizedInternalFormat(destFormat.mFormat))
- {
- static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
- list = &sizedList;
- }
- else
- {
- static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
- list = &unsizedList;
- targetFormat = destFormat.mFormat;
- }
-
- for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
- {
- const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
- if ((formatInfo.mDestFormat == targetFormat) &&
- (formatInfo.mMinRedBits <= srcFormat.mRedBits && formatInfo.mMaxRedBits >= srcFormat.mRedBits) &&
- (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
- (formatInfo.mMinBlueBits <= srcFormat.mBlueBits && formatInfo.mMaxBlueBits >= srcFormat.mBlueBits) &&
- (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
- {
- *outEffectiveFormat = formatInfo.mEffectiveFormat;
- return true;
- }
- }
-
- return false;
-}
-
-struct CopyConversion
-{
- GLenum mTextureFormat;
- GLenum mFramebufferFormat;
-
- CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
- : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
-
- bool operator<(const CopyConversion& other) const
- {
- return memcmp(this, &other, sizeof(CopyConversion)) < 0;
- }
-};
-
-typedef std::set<CopyConversion> CopyConversionSet;
-
-static CopyConversionSet BuildValidES3CopyTexImageCombinations()
-{
- CopyConversionSet set;
-
- // From ES 3.0.1 spec, table 3.15
- set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
- set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
- set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
- set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
- set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
- set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
- set.insert(CopyConversion(GL_RED, GL_RED));
- set.insert(CopyConversion(GL_RED, GL_RG));
- set.insert(CopyConversion(GL_RED, GL_RGB));
- set.insert(CopyConversion(GL_RED, GL_RGBA));
- set.insert(CopyConversion(GL_RG, GL_RG));
- set.insert(CopyConversion(GL_RG, GL_RGB));
- set.insert(CopyConversion(GL_RG, GL_RGBA));
- set.insert(CopyConversion(GL_RGB, GL_RGB));
- set.insert(CopyConversion(GL_RGB, GL_RGBA));
- set.insert(CopyConversion(GL_RGBA, GL_RGBA));
-
- // Necessary for ANGLE back-buffers
- set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
- set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
-
- set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
- set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
- set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
- set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
- set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
- set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
- set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
- set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
- set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
- set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
-
- return set;
-}
-
-bool IsValidInternalFormat(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
- return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions);
- }
- else
- {
- return false;
- }
-}
-
-bool IsValidFormat(GLenum format, const Extensions &extensions, GLuint clientVersion)
-{
- const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
- for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
- {
- if (i->second.mFormat == format && i->second.mTextureSupportFunction(clientVersion, extensions))
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool IsValidType(GLenum type, const Extensions &extensions, GLuint clientVersion)
+const FormatType &GetFormatTypeInfo(GLenum format, GLenum type)
{
- const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
- for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
+ static const FormatMap formatMap = BuildFormatMap();
+ FormatMap::const_iterator iter = formatMap.find(FormatTypePair(format, type));
+ if (iter != formatMap.end())
{
- if (i->second.mType == type && i->second.mTextureSupportFunction(clientVersion, extensions))
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- if (!internalFormatInfo.mTextureSupportFunction(clientVersion, extensions))
- {
- return false;
- }
+ return iter->second;
}
else
{
- UNREACHABLE();
- return false;
- }
-
- if (clientVersion == 2)
- {
- static const FormatMap &formats = GetFormatMap();
- FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
- return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
- }
- else if (clientVersion == 3)
- {
- static const ES3FormatSet &formats = GetES3FormatSet();
- return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
- }
- else
- {
- UNREACHABLE();
- return false;
+ static const FormatType defaultInfo;
+ return defaultInfo;
}
}
-bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
+const Type &GetTypeInfo(GLenum type)
{
- InternalFormatInfo textureInternalFormatInfo;
- InternalFormatInfo framebufferInternalFormatInfo;
- if (GetInternalFormatInfo(textureInternalFormat, &textureInternalFormatInfo) &&
- GetInternalFormatInfo(frameBufferInternalFormat, &framebufferInternalFormatInfo))
- {
- if (clientVersion == 2)
- {
- UNIMPLEMENTED();
- return false;
- }
- else if (clientVersion == 3)
- {
- static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
- const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
- framebufferInternalFormatInfo.mFormat);
- if (conversionSet.find(conversion) != conversionSet.end())
- {
- // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
- // must both be signed, unsigned, or fixed point and both source and destinations
- // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
- // conversion between fixed and floating point.
-
- if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
- {
- return false;
- }
-
- if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
- ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
- {
- return false;
- }
-
- if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
- !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
- {
- return false;
- }
-
- // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
- // The effective internal format of the source buffer is determined with the following rules applied in order:
- // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
- // effective internal format is the source buffer's sized internal format.
- // * If the source buffer is a texture that was created with an unsized base internal format, then the
- // effective internal format is the source image array's effective internal format, as specified by table
- // 3.12, which is determined from the <format> and <type> that were used when the source image array was
- // specified by TexImage*.
- // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
- // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
- // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
- // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
- // is SRGB.
- InternalFormatInfo sourceEffectiveFormat;
- if (readBufferHandle != 0)
- {
- // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
- if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat))
- {
- sourceEffectiveFormat = framebufferInternalFormatInfo;
- }
- else
- {
- // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
- // texture. We can use the same table we use when creating textures to get its effective sized format.
- GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
- framebufferInternalFormatInfo.mType);
- gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
- }
- }
- else
- {
- // The effective internal format must be derived from the source framebuffer's channel sizes.
- // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
- if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
- {
- GLenum effectiveFormat;
- if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
- {
- gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
- }
- else
- {
- return false;
- }
- }
- else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
- {
- // SRGB buffers can only be copied to sized format destinations according to table 3.18
- if (gl::IsSizedInternalFormat(textureInternalFormat) &&
- (framebufferInternalFormatInfo.mRedBits >= 1 && framebufferInternalFormatInfo.mRedBits <= 8) &&
- (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
- (framebufferInternalFormatInfo.mBlueBits >= 1 && framebufferInternalFormatInfo.mBlueBits <= 8) &&
- (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
- {
- gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, &sourceEffectiveFormat);
- }
- else
- {
- return false;
- }
- }
- else
- {
- UNREACHABLE();
- }
- }
-
- if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat))
- {
- // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
- // component sizes of the source and destination formats must exactly match
- if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
- textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
- textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
- textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
- {
- return false;
- }
- }
-
-
- return true; // A conversion function exists, and no rule in the specification has precluded conversion
- // between these formats.
- }
-
- return false;
- }
- else
- {
- UNREACHABLE();
- return false;
- }
- }
- else
- {
- UNREACHABLE();
- return false;
- }
-}
-
-bool IsRenderingSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
- ASSERT(internalFormatInfo.mRenderSupportFunction != NULL);
- return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
- internalFormatInfo.mRenderSupportFunction(clientVersion, extensions);
- }
- else
- {
- return false;
- }
-}
-
-bool IsFilteringSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
- ASSERT(internalFormatInfo.mFilterSupportFunction != NULL);
- return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
- internalFormatInfo.mFilterSupportFunction(clientVersion, extensions);
- }
- else
- {
- return false;
- }
-}
-
-bool IsSizedInternalFormat(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mPixelBits > 0;
- }
- else
- {
- UNREACHABLE();
- return false;
- }
-}
-
-GLenum GetSizedInternalFormat(GLenum format, GLenum type)
-{
- const FormatMap &formats = GetFormatMap();
- FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
- return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
-}
-
-GLuint GetPixelBytes(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mPixelBits / 8;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetAlphaBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mAlphaBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetRedBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mRedBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetGreenBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mGreenBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetBlueBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mBlueBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetLuminanceBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mLuminanceBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetDepthBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mDepthBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetStencilBits(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mStencilBits;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetTypeBytes(GLenum type)
-{
- TypeInfo typeInfo;
- if (GetTypeInfo(type, &typeInfo))
- {
- return typeInfo.mTypeBytes;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-bool IsSpecialInterpretationType(GLenum type)
-{
- TypeInfo typeInfo;
- if (GetTypeInfo(type, &typeInfo))
- {
- return typeInfo.mSpecialInterpretation;
- }
- else
- {
- UNREACHABLE();
- return false;
- }
-}
-
-bool IsFloatOrFixedComponentType(GLenum type)
-{
- if (type == GL_UNSIGNED_NORMALIZED ||
- type == GL_SIGNED_NORMALIZED ||
- type == GL_FLOAT)
+ static const TypeInfoMap infoMap = BuildTypeInfoMap();
+ TypeInfoMap::const_iterator iter = infoMap.find(type);
+ if (iter != infoMap.end())
{
- return true;
+ return iter->second;
}
else
{
- return false;
+ static const Type defaultInfo;
+ return defaultInfo;
}
}
-GLenum GetFormat(GLenum internalFormat)
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
+ const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+ InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
+ if (iter != formatMap.end())
{
- return internalFormatInfo.mFormat;
+ return iter->second;
}
else
{
- UNREACHABLE();
- return GL_NONE;
+ static const InternalFormat defaultInternalFormat;
+ return defaultInternalFormat;
}
}
-GLenum GetType(GLenum internalFormat)
+GLuint InternalFormat::computeRowPitch(GLenum type, GLsizei width, GLint alignment) const
{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mType;
- }
- else
- {
- UNREACHABLE();
- return GL_NONE;
- }
+ ASSERT(alignment > 0 && isPow2(alignment));
+ return rx::roundUp(computeBlockSize(type, width, 1), static_cast<GLuint>(alignment));
}
-GLenum GetComponentType(GLenum internalFormat)
+GLuint InternalFormat::computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const
{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mComponentType;
- }
- else
- {
- UNREACHABLE();
- return GL_NONE;
- }
+ return computeRowPitch(type, width, alignment) * height;
}
-GLuint GetComponentCount(GLenum internalFormat)
+GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei height) const
{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
+ if (compressed)
{
- return internalFormatInfo.mComponentCount;
+ GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
+ GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
+ return (pixelBytes * numBlocksWide * numBlocksHight);
}
else
{
- UNREACHABLE();
- return false;
- }
-}
-
-GLenum GetColorEncoding(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mColorEncoding;
- }
- else
- {
- UNREACHABLE();
- return false;
- }
-}
-
-GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLsizei width, GLint alignment)
-{
- ASSERT(alignment > 0 && isPow2(alignment));
- return rx::roundUp(GetBlockSize(internalFormat, type, width, 1), static_cast<GLuint>(alignment));
-}
-
-GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height, GLint alignment)
-{
- return GetRowPitch(internalFormat, type, width, alignment) * height;
-}
-
-GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- if (internalFormatInfo.mIsCompressed)
+ const Type &typeInfo = GetTypeInfo(type);
+ if (typeInfo.specialInterpretation)
{
- GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
- GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
-
- return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
+ return typeInfo.bytes * width * height;
}
else
{
- TypeInfo typeInfo;
- if (GetTypeInfo(type, &typeInfo))
- {
- if (typeInfo.mSpecialInterpretation)
- {
- return typeInfo.mTypeBytes * width * height;
- }
- else
- {
- return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
- }
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
+ return componentCount * typeInfo.bytes * width * height;
}
}
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-bool IsFormatCompressed(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mIsCompressed;
- }
- else
- {
- UNREACHABLE();
- return false;
- }
}
-GLuint GetCompressedBlockWidth(GLenum internalFormat)
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mCompressedBlockWidth;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
-}
-
-GLuint GetCompressedBlockHeight(GLenum internalFormat)
-{
- InternalFormatInfo internalFormatInfo;
- if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
- {
- return internalFormatInfo.mCompressedBlockHeight;
- }
- else
- {
- UNREACHABLE();
- return 0;
- }
+ const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
+ return (formatInfo.pixelBytes > 0) ? internalFormat : GetFormatTypeInfo(internalFormat, type).internalFormat;
}
const FormatSet &GetAllSizedInternalFormats()
@@ -1538,11 +626,4 @@ const FormatSet &GetAllSizedInternalFormats()
return formatSet;
}
-ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
-{
- static const FormatMap &formats = GetFormatMap();
- FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
- return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/formatutils.h b/src/3rdparty/angle/src/libGLESv2/formatutils.h
index 2f592798b8..25106a52e5 100644
--- a/src/3rdparty/angle/src/libGLESv2/formatutils.h
+++ b/src/3rdparty/angle/src/libGLESv2/formatutils.h
@@ -9,12 +9,13 @@
#ifndef LIBGLESV2_FORMATUTILS_H_
#define LIBGLESV2_FORMATUTILS_H_
-#include "angle_gl.h"
-
#include "libGLESv2/Caps.h"
#include "libGLESv2/angletypes.h"
+#include "angle_gl.h"
+
#include <cstddef>
+#include <cstdint>
typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
@@ -27,61 +28,78 @@ typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth,
typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
-typedef void (*ColorReadFunction)(const void *source, void *dest);
-typedef void (*ColorWriteFunction)(const void *source, void *dest);
-typedef void (*ColorCopyFunction)(const void *source, void *dest);
+typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
-typedef void (*VertexCopyFunction)(const void *input, size_t stride, size_t count, void *output);
+typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
namespace gl
{
-typedef std::set<GLenum> FormatSet;
+struct FormatType
+{
+ FormatType();
+
+ GLenum internalFormat;
+ ColorWriteFunction colorWriteFunction;
+};
+const FormatType &GetFormatTypeInfo(GLenum format, GLenum type);
+
+struct Type
+{
+ Type();
+
+ GLuint bytes;
+ bool specialInterpretation;
+};
+const Type &GetTypeInfo(GLenum type);
-bool IsValidInternalFormat(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion);
-bool IsValidFormat(GLenum format, const Extensions &extensions, GLuint clientVersion);
-bool IsValidType(GLenum type, const Extensions &extensions, GLuint clientVersion);
+struct InternalFormat
+{
+ InternalFormat();
-bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion);
-bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion);
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
-bool IsRenderingSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion);
-bool IsFilteringSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion);
+ GLuint luminanceBits;
-bool IsSizedInternalFormat(GLenum internalFormat);
-GLenum GetSizedInternalFormat(GLenum format, GLenum type);
+ GLuint alphaBits;
+ GLuint sharedBits;
-GLuint GetPixelBytes(GLenum internalFormat);
-GLuint GetAlphaBits(GLenum internalFormat);
-GLuint GetRedBits(GLenum internalFormat);
-GLuint GetGreenBits(GLenum internalFormat);
-GLuint GetBlueBits(GLenum internalFormat);
-GLuint GetLuminanceBits(GLenum internalFormat);
-GLuint GetDepthBits(GLenum internalFormat);
-GLuint GetStencilBits(GLenum internalFormat);
+ GLuint depthBits;
+ GLuint stencilBits;
-GLuint GetTypeBytes(GLenum type);
-bool IsSpecialInterpretationType(GLenum type);
-bool IsFloatOrFixedComponentType(GLenum type);
+ GLuint pixelBytes;
-GLenum GetFormat(GLenum internalFormat);
-GLenum GetType(GLenum internalFormat);
+ GLuint componentCount;
-GLenum GetComponentType(GLenum internalFormat);
-GLuint GetComponentCount(GLenum internalFormat);
-GLenum GetColorEncoding(GLenum internalFormat);
+ bool compressed;
+ GLuint compressedBlockWidth;
+ GLuint compressedBlockHeight;
-GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLsizei width, GLint alignment);
-GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height, GLint alignment);
-GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height);
+ GLenum format;
+ GLenum type;
-bool IsFormatCompressed(GLenum internalFormat);
-GLuint GetCompressedBlockWidth(GLenum internalFormat);
-GLuint GetCompressedBlockHeight(GLenum internalFormat);
+ GLenum componentType;
+ GLenum colorEncoding;
-const FormatSet &GetAllSizedInternalFormats();
+ typedef bool (*SupportCheckFunction)(GLuint, const Extensions &);
+ SupportCheckFunction textureSupport;
+ SupportCheckFunction renderSupport;
+ SupportCheckFunction filterSupport;
-ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type);
+ GLuint computeRowPitch(GLenum type, GLsizei width, GLint alignment) const;
+ GLuint computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const;
+ GLuint computeBlockSize(GLenum type, GLsizei width, GLsizei height) const;
+};
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat);
+
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
+
+typedef std::set<GLenum> FormatSet;
+const FormatSet &GetAllSizedInternalFormats();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 5e2ec4a4ee..07f5d47473 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.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
@@ -7,10 +6,14 @@
// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
+#undef GL_APICALL
+#define GL_APICALL
+#define GL_GLEXT_PROTOTYPES
+
#include "common/version.h"
+#include "common/utilities.h"
#include "libGLESv2/main.h"
-#include "common/utilities.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
@@ -31,6 +34,7 @@
#include "libGLESv2/validationES3.h"
#include "libGLESv2/queryconversions.h"
+
extern "C"
{
@@ -41,12 +45,12 @@ void __stdcall glActiveTexture(GLenum texture)
EVENT("(GLenum texture = 0x%X)", texture);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
+ if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
context->getState().setActiveSampler(texture - GL_TEXTURE0);
@@ -58,7 +62,6 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
@@ -68,11 +71,13 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -80,17 +85,20 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
{
if (context->getProgram(shader))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
if (!programObject->attachShader(shaderObject))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
}
@@ -100,7 +108,6 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateBeginQuery(context, target, id))
@@ -108,7 +115,12 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
return;
}
- context->beginQuery(target, id);
+ gl::Error error = context->beginQuery(target, id);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -116,32 +128,35 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
{
EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
if (strncmp(name, "gl_", 3) == 0)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
programObject->bindAttributeLocation(index, name);
@@ -153,12 +168,12 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer)
EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (target)
@@ -187,8 +202,10 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer)
case GL_TRANSFORM_FEEDBACK_BUFFER:
context->bindGenericTransformFeedbackBuffer(buffer);
return;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -197,15 +214,15 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
{
EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
- if (!gl::ValidFramebufferTarget(target))
- {
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (!gl::ValidFramebufferTarget(target))
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
{
context->bindReadFramebuffer(framebuffer);
@@ -222,15 +239,15 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
- if (target != GL_RENDERBUFFER)
- {
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (target != GL_RENDERBUFFER)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
context->bindRenderbuffer(renderbuffer);
}
}
@@ -240,41 +257,37 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Texture *textureObject = context->getTexture(texture);
if (textureObject && textureObject->getTarget() != target && texture != 0)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (target)
{
case GL_TEXTURE_2D:
- context->bindTexture2D(texture);
- return;
case GL_TEXTURE_CUBE_MAP:
- context->bindTextureCubeMap(texture);
- return;
+ break;
+
case GL_TEXTURE_3D:
- if (context->getClientVersion() < 3)
- {
- return gl::error(GL_INVALID_ENUM);
- }
- context->bindTexture3D(texture);
- return;
case GL_TEXTURE_2D_ARRAY:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- context->bindTexture2DArray(texture);
- return;
+ break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
+
+ context->bindTexture(target, texture);
}
}
@@ -301,35 +314,36 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
gl::Context *context = gl::getNonLostContext();
-
- switch (modeRGB)
+ if (context)
{
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- case GL_MIN:
- case GL_MAX:
- break;
+ switch (modeRGB)
+ {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ case GL_MIN:
+ case GL_MAX:
+ break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- switch (modeAlpha)
- {
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- case GL_MIN:
- case GL_MAX:
- break;
+ switch (modeAlpha)
+ {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ case GL_MIN:
+ case GL_MAX:
+ break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- if (context)
- {
context->getState().setBlendEquation(modeRGB, modeAlpha);
}
}
@@ -345,123 +359,131 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
srcRGB, dstRGB, srcAlpha, dstAlpha);
gl::Context *context = gl::getNonLostContext();
-
- switch (srcRGB)
- {
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- case GL_SRC_ALPHA_SATURATE:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
- switch (dstRGB)
+ if (context)
{
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
-
- case GL_SRC_ALPHA_SATURATE:
- if (!context || context->getClientVersion() < 3)
+ switch (srcRGB)
{
- return gl::error(GL_INVALID_ENUM);
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ case GL_SRC_ALPHA_SATURATE:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
- switch (srcAlpha)
- {
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- case GL_SRC_ALPHA_SATURATE:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (dstRGB)
+ {
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
- switch (dstAlpha)
- {
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
+ case GL_SRC_ALPHA_SATURATE:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- case GL_SRC_ALPHA_SATURATE:
- if (!context || context->getClientVersion() < 3)
+ switch (srcAlpha)
{
- return gl::error(GL_INVALID_ENUM);
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ case GL_SRC_ALPHA_SATURATE:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (dstAlpha)
+ {
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+
+ case GL_SRC_ALPHA_SATURATE:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
- bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
- dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
- dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
+ bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
+ dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
- if (constantColorUsed && constantAlphaUsed)
- {
- ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
- return gl::error(GL_INVALID_OPERATION);
- }
+ bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
+ dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
+
+ if (constantColorUsed && constantAlphaUsed)
+ {
+ ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
+ }
- if (context)
- {
context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
}
@@ -471,51 +493,60 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
target, size, data, usage);
- if (size < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
- switch (usage)
+ if (context)
{
- case GL_STREAM_DRAW:
- case GL_STATIC_DRAW:
- case GL_DYNAMIC_DRAW:
- break;
-
- case GL_STREAM_READ:
- case GL_STREAM_COPY:
- case GL_STATIC_READ:
- case GL_STATIC_COPY:
- case GL_DYNAMIC_READ:
- case GL_DYNAMIC_COPY:
- if (context && context->getClientVersion() < 3)
+ if (size < 0)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (usage)
+ {
+ case GL_STREAM_DRAW:
+ case GL_STATIC_DRAW:
+ case GL_DYNAMIC_DRAW:
+ break;
+
+ case GL_STREAM_READ:
+ case GL_STREAM_COPY:
+ case GL_STATIC_READ:
+ case GL_STATIC_COPY:
+ case GL_DYNAMIC_READ:
+ case GL_DYNAMIC_COPY:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- if (context)
- {
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (!buffer)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- buffer->bufferData(data, size, usage);
+ gl::Error error = buffer->bufferData(data, size, usage);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -524,49 +555,59 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
target, offset, size, data);
- if (size < 0 || offset < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
- if (data == NULL)
- {
- return;
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (size < 0 || offset < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (data == NULL)
+ {
+ return;
+ }
+
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (!buffer)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (buffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// Check for possible overflow of size + offset
if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
{
- return gl::error(GL_OUT_OF_MEMORY);
+ context->recordError(gl::Error(GL_OUT_OF_MEMORY));
+ return;
}
if (size + offset > buffer->getSize())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
- buffer->bufferSubData(data, size, offset);
+ gl::Error error = buffer->bufferSubData(data, size, offset);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -574,15 +615,15 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
- if (!gl::ValidFramebufferTarget(target))
- {
- return gl::error(GL_INVALID_ENUM, 0);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (!gl::ValidFramebufferTarget(target))
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return 0;
+ }
+
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer);
return framebuffer->completeness();
@@ -596,22 +637,28 @@ void __stdcall glClear(GLbitfield mask)
EVENT("(GLbitfield mask = 0x%X)", mask);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return;
}
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
- context->clear(mask);
+ gl::Error error = context->clear(mask);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -621,7 +668,6 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
red, green, blue, alpha);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setClearColor(red, green, blue, alpha);
@@ -633,7 +679,6 @@ void __stdcall glClearDepthf(GLclampf depth)
EVENT("(GLclampf depth = %f)", depth);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setClearDepth(depth);
@@ -645,7 +690,6 @@ void __stdcall glClearStencil(GLint s)
EVENT("(GLint s = %d)", s);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setClearStencil(s);
@@ -658,7 +702,6 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo
red, green, blue, alpha);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
@@ -670,7 +713,6 @@ void __stdcall glCompileShader(GLuint shader)
EVENT("(GLuint shader = %d)", shader);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Shader *shaderObject = context->getShader(shader);
@@ -679,11 +721,13 @@ void __stdcall glCompileShader(GLuint shader)
{
if (context->getProgram(shader))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -699,7 +743,6 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
target, level, internalformat, width, height, border, imageSize, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -716,9 +759,11 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
return;
}
- if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, width, height))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (target)
@@ -743,7 +788,8 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -757,7 +803,6 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
target, level, xoffset, yoffset, width, height, format, imageSize, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -774,9 +819,11 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return;
}
- if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, width, height))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (target)
@@ -801,7 +848,8 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -813,7 +861,6 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
target, level, internalformat, x, y, width, height, border);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -853,8 +900,9 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
}
break;
- default:
- return gl::error(GL_INVALID_ENUM);
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -866,7 +914,6 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
target, level, xoffset, yoffset, x, y, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -907,7 +954,8 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -930,7 +978,6 @@ GLuint __stdcall glCreateShader(GLenum type)
EVENT("(GLenum type = 0x%X)", type);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
switch (type)
@@ -938,8 +985,10 @@ GLuint __stdcall glCreateShader(GLenum type)
case GL_FRAGMENT_SHADER:
case GL_VERTEX_SHADER:
return context->createShader(type);
+
default:
- return gl::error(GL_INVALID_ENUM, 0);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return 0;
}
}
@@ -950,22 +999,22 @@ void __stdcall glCullFace(GLenum mode)
{
EVENT("(GLenum mode = 0x%X)", mode);
- switch (mode)
+ gl::Context *context = gl::getNonLostContext();
+ if (context)
{
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
+ switch (mode)
{
- gl::Context *context = gl::getNonLostContext();
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
- if (context)
- {
- context->getState().setCullMode(mode);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
+
+ context->getState().setCullMode(mode);
}
}
@@ -973,15 +1022,15 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
context->deleteBuffer(buffers[i]);
@@ -993,15 +1042,15 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
{
EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
context->deleteFenceNV(fences[i]);
@@ -1013,15 +1062,15 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
if (framebuffers[i] != 0)
@@ -1036,24 +1085,25 @@ void __stdcall glDeleteProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
- if (program == 0)
- {
- return;
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (program == 0)
+ {
+ return;
+ }
+
if (!context->getProgram(program))
{
if(context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -1065,15 +1115,15 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
context->deleteQuery(ids[i]);
@@ -1085,15 +1135,15 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
context->deleteRenderbuffer(renderbuffers[i]);
@@ -1105,24 +1155,25 @@ void __stdcall glDeleteShader(GLuint shader)
{
EVENT("(GLuint shader = %d)", shader);
- if (shader == 0)
- {
- return;
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (shader == 0)
+ {
+ return;
+ }
+
if (!context->getShader(shader))
{
if(context->getProgram(shader))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -1134,15 +1185,15 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
{
EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
if (textures[i] != 0)
@@ -1157,26 +1208,26 @@ void __stdcall glDepthFunc(GLenum func)
{
EVENT("(GLenum func = 0x%X)", func);
- switch (func)
- {
- case GL_NEVER:
- case GL_ALWAYS:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_EQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_NOTEQUAL:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- context->getState().setDepthFunc(func);
+ switch (func)
+ {
+ case GL_NEVER:
+ case GL_ALWAYS:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_EQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_NOTEQUAL:
+ context->getState().setDepthFunc(func);
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
}
}
@@ -1185,7 +1236,6 @@ void __stdcall glDepthMask(GLboolean flag)
EVENT("(GLboolean flag = %u)", flag);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setDepthMask(flag != GL_FALSE);
@@ -1197,7 +1247,6 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setDepthRange(zNear, zFar);
@@ -1209,10 +1258,8 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
-
gl::Program *programObject = context->getProgram(program);
gl::Shader *shaderObject = context->getShader(shader);
@@ -1222,11 +1269,13 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
shaderByProgramHandle = context->getShader(program);
if (!shaderByProgramHandle)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
else
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
@@ -1235,17 +1284,20 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
gl::Program *programByShaderHandle = context->getProgram(shader);
if (!programByShaderHandle)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
else
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
if (!programObject->detachShader(shaderObject))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
}
@@ -1255,12 +1307,12 @@ void __stdcall glDisable(GLenum cap)
EVENT("(GLenum cap = 0x%X)", cap);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidCap(context, cap))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
context->getState().setEnableFeature(cap, false);
@@ -1271,15 +1323,15 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
{
EVENT("(GLuint index = %d)", index);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setEnableVertexAttribArray(index, false);
}
}
@@ -1289,15 +1341,19 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (!ValidateDrawArrays(context, mode, first, count))
+ if (!ValidateDrawArrays(context, mode, first, count, 0))
{
return;
}
- context->drawArrays(mode, first, count, 0);
+ gl::Error error = context->drawArrays(mode, first, count, 0);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -1306,15 +1362,19 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (!ValidateDrawArraysInstanced(context, mode, first, count, primcount))
+ if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
{
return;
}
- context->drawArrays(mode, first, count, primcount);
+ gl::Error error = context->drawArrays(mode, first, count, primcount);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -1324,15 +1384,20 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
mode, count, type, indices);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (!ValidateDrawElements(context, mode, count, type, indices))
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
{
return;
}
- context->drawElements(mode, count, type, indices, 0);
+ gl::Error error = context->drawElements(mode, count, type, indices, 0, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -1342,15 +1407,20 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
mode, count, type, indices, primcount);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount))
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
{
return;
}
- context->drawElements(mode, count, type, indices, primcount);
+ gl::Error error = context->drawElements(mode, count, type, indices, primcount, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -1359,12 +1429,12 @@ void __stdcall glEnable(GLenum cap)
EVENT("(GLenum cap = 0x%X)", cap);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidCap(context, cap))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
context->getState().setEnableFeature(cap, true);
@@ -1375,15 +1445,15 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
{
EVENT("(GLuint index = %d)", index);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setEnableVertexAttribArray(index, true);
}
}
@@ -1393,7 +1463,6 @@ void __stdcall glEndQueryEXT(GLenum target)
EVENT("GLenum target = 0x%X)", target);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateEndQuery(context, target))
@@ -1401,7 +1470,12 @@ void __stdcall glEndQueryEXT(GLenum target)
return;
}
- context->endQuery(target);
+ gl::Error error = context->endQuery(target);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -1410,19 +1484,20 @@ void __stdcall glFinishFenceNV(GLuint fence)
EVENT("(GLuint fence = %d)", fence);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::FenceNV *fenceObject = context->getFenceNV(fence);
if (fenceObject == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (fenceObject->isFence() != GL_TRUE)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
fenceObject->finishFence();
@@ -1434,7 +1509,6 @@ void __stdcall glFinish(void)
EVENT("()");
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->sync(true);
@@ -1446,7 +1520,6 @@ void __stdcall glFlush(void)
EVENT("()");
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->sync(false);
@@ -1458,15 +1531,15 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
"GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
- if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
- {
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
{
return;
@@ -1542,21 +1615,19 @@ void __stdcall glFrontFace(GLenum mode)
{
EVENT("(GLenum mode = 0x%X)", mode);
- switch (mode)
+ gl::Context *context = gl::getNonLostContext();
+ if (context)
{
- case GL_CW:
- case GL_CCW:
+ switch (mode)
{
- gl::Context *context = gl::getNonLostContext();
-
- if (context)
- {
- context->getState().setFrontFace(mode);
- }
+ case GL_CW:
+ case GL_CCW:
+ context->getState().setFrontFace(mode);
+ break;
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
}
}
@@ -1564,15 +1635,15 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
{
EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
buffers[i] = context->createBuffer();
@@ -1585,23 +1656,25 @@ void __stdcall glGenerateMipmap(GLenum target)
EVENT("(GLenum target = 0x%X)", target);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidTextureTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Texture *texture = context->getTargetTexture(target);
if (texture == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
GLenum internalFormat = texture->getBaseLevelInternalFormat();
const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
// GenerateMipmap should not generate an INVALID_OPERATION for textures created with
// unsized formats or that are color renderable and filterable. Since we do not track if
@@ -1615,23 +1688,26 @@ void __stdcall glGenerateMipmap(GLenum target)
internalFormat == GL_LUMINANCE8_ALPHA8_EXT ||
internalFormat == GL_ALPHA8_EXT;
- if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0 || !formatCaps.filterable ||
- (!formatCaps.renderable && !isLUMA) || gl::IsFormatCompressed(internalFormat))
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable ||
+ (!formatCaps.renderable && !isLUMA) || formatInfo.compressed)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// GL_EXT_sRGB does not support mipmap generation on sRGB textures
- if (context->getClientVersion() == 2 && gl::GetColorEncoding(internalFormat) == GL_SRGB)
+ if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// Non-power of 2 ES2 check
if (!context->getExtensions().textureNPOT && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight())))
{
ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP));
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// Cube completeness check
@@ -1640,7 +1716,8 @@ void __stdcall glGenerateMipmap(GLenum target)
gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
if (!textureCube->isCubeComplete())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
@@ -1652,15 +1729,15 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
{
EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
fences[i] = context->createFenceNV();
@@ -1672,15 +1749,15 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
framebuffers[i] = context->createFramebuffer();
@@ -1693,12 +1770,12 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (n < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (GLsizei i = 0; i < n; i++)
@@ -1712,15 +1789,15 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
renderbuffers[i] = context->createRenderbuffer();
@@ -1732,15 +1809,15 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures)
{
EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
- if (n < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (n < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
for (int i = 0; i < n; i++)
{
textures[i] = context->createTexture();
@@ -1754,32 +1831,35 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
"GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
program, index, bufsize, length, size, type, name);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
if (index >= (GLuint)programObject->getActiveAttributeCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programObject->getActiveAttribute(index, bufsize, length, size, type, name);
@@ -1792,32 +1872,36 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
"GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
program, index, bufsize, length, size, type, name);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
if (index >= (GLuint)programObject->getActiveUniformCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programObject->getActiveUniform(index, bufsize, length, size, type, name);
@@ -1829,26 +1913,28 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
program, maxcount, count, shaders);
- if (maxcount < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (maxcount < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -1856,33 +1942,34 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
}
}
-int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
+GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
{
EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
-
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
else
{
- return gl::error(GL_INVALID_VALUE, -1);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return -1;
}
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programObject->isLinked() || !programBinary)
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
return programBinary->getAttributeLocation(name);
@@ -1896,7 +1983,6 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
GLenum nativeType;
@@ -1922,17 +2008,18 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (!gl::ValidBufferParameter(context, pname))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -1940,7 +2027,8 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params
if (!buffer)
{
// A null buffer means that "0" is bound to the requested buffer target
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (pname)
@@ -1986,21 +2074,21 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
{
EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::FenceNV *fenceObject = context->getFenceNV(fence);
if (fenceObject == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (fenceObject->isFence() != GL_TRUE)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (pname)
@@ -2009,7 +2097,9 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
case GL_FENCE_CONDITION_NV:
break;
- default: return gl::error(GL_INVALID_ENUM);
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
params[0] = fenceObject->getFencei(pname);
@@ -2021,7 +2111,6 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
GLenum nativeType;
@@ -2048,12 +2137,12 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
target, attachment, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidFramebufferTarget(target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
int clientVersion = context->getClientVersion();
@@ -2065,12 +2154,15 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
break;
+
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if (clientVersion < 3 && !context->getExtensions().sRGB)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
break;
+
case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
@@ -2081,11 +2173,14 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
if (clientVersion < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
// Determine if the attachment is a valid enum
@@ -2098,7 +2193,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_DEPTH_STENCIL_ATTACHMENT:
if (clientVersion < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
break;
@@ -2110,7 +2206,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
(attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
break;
}
@@ -2122,7 +2219,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
{
if (clientVersion < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (attachment)
@@ -2131,8 +2229,10 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_DEPTH:
case GL_STENCIL:
break;
+
default:
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
else
@@ -2148,14 +2248,18 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_DEPTH_ATTACHMENT:
case GL_STENCIL_ATTACHMENT:
break;
+
case GL_DEPTH_STENCIL_ATTACHMENT:
if (framebuffer->hasValidDepthStencil())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
}
@@ -2212,7 +2316,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if (clientVersion < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = 0;
break;
@@ -2220,11 +2325,13 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
default:
if (clientVersion < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
else
{
- gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
}
@@ -2243,7 +2350,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = attachmentHandle;
break;
@@ -2251,7 +2359,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
if (attachmentObjectType != GL_TEXTURE)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = attachmentLevel;
break;
@@ -2259,7 +2368,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
if (attachmentObjectType != GL_TEXTURE)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
break;
@@ -2289,9 +2399,10 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
break;
case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- if (attachment == GL_DEPTH_STENCIL)
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
{
- gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
*params = attachmentObject->getComponentType();
break;
@@ -2303,7 +2414,8 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
if (attachmentObjectType != GL_TEXTURE)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = attachmentLayer;
break;
@@ -2335,7 +2447,6 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params)
EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
GLenum nativeType;
@@ -2362,14 +2473,14 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (context->getClientVersion() < 3)
@@ -2381,7 +2492,8 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
case GL_TRANSFORM_FEEDBACK_VARYINGS:
case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
@@ -2432,8 +2544,10 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
*params = programObject->getTransformFeedbackVaryingMaxLength();
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2443,20 +2557,21 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len
EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
program, bufsize, length, infolog);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programObject->getInfoLog(bufsize, length, infolog);
@@ -2468,12 +2583,12 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidQueryType(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -2483,7 +2598,8 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2493,31 +2609,49 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
if (!queryObject)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (context->getState().getActiveQueryId(queryObject->getType()) == id)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch(pname)
{
case GL_QUERY_RESULT_EXT:
- params[0] = queryObject->getResult();
+ {
+ gl::Error error = queryObject->getResult(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
break;
+
case GL_QUERY_RESULT_AVAILABLE_EXT:
- params[0] = queryObject->isResultAvailable();
+ {
+ gl::Error error = queryObject->isResultAvailable(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2527,17 +2661,18 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (target != GL_RENDERBUFFER)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (context->getState().getRenderbufferId() == 0)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId());
@@ -2553,15 +2688,19 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
+
case GL_RENDERBUFFER_SAMPLES_ANGLE:
if (!context->getExtensions().framebufferMultisample)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = renderbuffer->getSamples();
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2571,14 +2710,14 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Shader *shaderObject = context->getShader(shader);
if (!shaderObject)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (pname)
@@ -2601,8 +2740,10 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
*params = shaderObject->getTranslatedSourceLength();
return;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2612,20 +2753,21 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
shader, bufsize, length, infolog);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Shader *shaderObject = context->getShader(shader);
if (!shaderObject)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
shaderObject->getInfoLog(bufsize, length, infolog);
@@ -2637,36 +2779,45 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp
EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
shadertype, precisiontype, range, precision);
- switch (shadertype)
+ gl::Context *context = gl::getNonLostContext();
+ if (context)
{
- case GL_VERTEX_SHADER:
- case GL_FRAGMENT_SHADER:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
- switch (precisiontype)
- {
- case GL_LOW_FLOAT:
- case GL_MEDIUM_FLOAT:
- case GL_HIGH_FLOAT:
- // Assume IEEE 754 precision
- range[0] = 127;
- range[1] = 127;
- *precision = 23;
- break;
- case GL_LOW_INT:
- case GL_MEDIUM_INT:
- case GL_HIGH_INT:
- // Some (most) hardware only supports single-precision floating-point numbers,
- // which can accurately represent integers up to +/-16777216
- range[0] = 24;
- range[1] = 24;
- *precision = 0;
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
+ switch (shadertype)
+ {
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ case GL_MEDIUM_FLOAT:
+ case GL_HIGH_FLOAT:
+ // Assume IEEE 754 precision
+ range[0] = 127;
+ range[1] = 127;
+ *precision = 23;
+ break;
+
+ case GL_LOW_INT:
+ case GL_MEDIUM_INT:
+ case GL_HIGH_INT:
+ // Some (most) hardware only supports single-precision floating-point numbers,
+ // which can accurately represent integers up to +/-16777216
+ range[0] = 24;
+ range[1] = 24;
+ *precision = 0;
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
}
}
@@ -2675,20 +2826,21 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
shader, bufsize, length, source);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Shader *shaderObject = context->getShader(shader);
if (!shaderObject)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
shaderObject->getSource(bufsize, length, source);
@@ -2700,20 +2852,21 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize,
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
shader, bufsize, length, source);
- if (bufsize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (bufsize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Shader *shaderObject = context->getShader(shader);
if (!shaderObject)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
shaderObject->getTranslatedSource(bufsize, length, source);
@@ -2730,8 +2883,10 @@ const GLubyte* __stdcall glGetString(GLenum name)
{
case GL_VENDOR:
return (GLubyte*)"Google Inc.";
+
case GL_RENDERER:
return (GLubyte*)((context != NULL) ? context->getRendererString().c_str() : "ANGLE");
+
case GL_VERSION:
if (context->getClientVersion() == 2)
{
@@ -2741,6 +2896,7 @@ const GLubyte* __stdcall glGetString(GLenum name)
{
return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
}
+
case GL_SHADING_LANGUAGE_VERSION:
if (context->getClientVersion() == 2)
{
@@ -2750,10 +2906,16 @@ const GLubyte* __stdcall glGetString(GLenum name)
{
return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
}
+
case GL_EXTENSIONS:
return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : "");
+
default:
- return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
+ if (context)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ }
+ return NULL;
}
}
@@ -2762,14 +2924,14 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Texture *texture = context->getTargetTexture(target);
if (!texture)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -2789,7 +2951,8 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
case GL_TEXTURE_WRAP_R:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().wrapR;
break;
@@ -2800,7 +2963,8 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
case GL_TEXTURE_IMMUTABLE_LEVELS:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->immutableLevelCount();
break;
@@ -2810,68 +2974,79 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->getExtensions().textureFilterAnisotropic)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().maxAnisotropy;
break;
case GL_TEXTURE_SWIZZLE_R:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().swizzleRed;
break;
case GL_TEXTURE_SWIZZLE_G:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().swizzleGreen;
break;
case GL_TEXTURE_SWIZZLE_B:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().swizzleBlue;
break;
case GL_TEXTURE_SWIZZLE_A:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().swizzleAlpha;
break;
case GL_TEXTURE_BASE_LEVEL:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().baseLevel;
break;
case GL_TEXTURE_MAX_LEVEL:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLfloat)texture->getSamplerState().maxLevel;
break;
case GL_TEXTURE_MIN_LOD:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().minLod;
break;
case GL_TEXTURE_MAX_LOD:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().maxLod;
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -2881,14 +3056,14 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Texture *texture = context->getTargetTexture(target);
if (!texture)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -2908,7 +3083,8 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
case GL_TEXTURE_WRAP_R:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().wrapR;
break;
@@ -2919,7 +3095,8 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
case GL_TEXTURE_IMMUTABLE_LEVELS:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->immutableLevelCount();
break;
@@ -2929,68 +3106,79 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->getExtensions().textureFilterAnisotropic)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLint)texture->getSamplerState().maxAnisotropy;
break;
case GL_TEXTURE_SWIZZLE_R:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().swizzleRed;
break;
case GL_TEXTURE_SWIZZLE_G:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().swizzleGreen;
break;
case GL_TEXTURE_SWIZZLE_B:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().swizzleBlue;
break;
case GL_TEXTURE_SWIZZLE_A:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().swizzleAlpha;
break;
case GL_TEXTURE_BASE_LEVEL:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().baseLevel;
break;
case GL_TEXTURE_MAX_LEVEL:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = texture->getSamplerState().maxLevel;
break;
case GL_TEXTURE_MIN_LOD:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLint)texture->getSamplerState().minLod;
break;
case GL_TEXTURE_MAX_LOD:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*params = (GLint)texture->getSamplerState().maxLod;
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -3000,37 +3188,20 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
program, location, bufSize, params);
- if (bufSize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (program == 0)
+ if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
{
- return gl::error(GL_INVALID_VALUE);
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
+ ASSERT(programObject);
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ ASSERT(programBinary);
- if (!programBinary->getUniformfv(location, &bufSize, params))
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ programBinary->getUniformfv(location, params);
}
}
@@ -3039,31 +3210,19 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (program == 0)
+ if (!ValidateGetUniformfv(context, program, location, params))
{
- return gl::error(GL_INVALID_VALUE);
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
+ ASSERT(programObject);
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ ASSERT(programBinary);
- if (!programBinary->getUniformfv(location, NULL, params))
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ programBinary->getUniformfv(location, params);
}
}
@@ -3072,37 +3231,20 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
program, location, bufSize, params);
- if (bufSize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (program == 0)
+ if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
{
- return gl::error(GL_INVALID_VALUE);
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
+ ASSERT(programObject);
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ ASSERT(programBinary);
- if (!programBinary->getUniformiv(location, &bufSize, params))
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ programBinary->getUniformiv(location, params);
}
}
@@ -3111,65 +3253,55 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (program == 0)
+ if (!ValidateGetUniformiv(context, program, location, params))
{
- return gl::error(GL_INVALID_VALUE);
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
+ ASSERT(programObject);
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ ASSERT(programBinary);
- if (!programBinary->getUniformiv(location, NULL, params))
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ programBinary->getUniformiv(location, params);
}
}
-int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
+GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
{
EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
gl::Context *context = gl::getNonLostContext();
-
- if (strstr(name, "gl_") == name)
- {
- return -1;
- }
-
if (context)
{
+ if (strstr(name, "gl_") == name)
+ {
+ return -1;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
else
{
- return gl::error(GL_INVALID_VALUE, -1);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return -1;
}
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programObject->isLinked() || !programBinary)
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
return programBinary->getUniformLocation(name);
@@ -3183,16 +3315,16 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
- if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+ if (!gl::ValidateGetVertexAttribParameters(context, pname))
{
return;
}
@@ -3217,17 +3349,17 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
- if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+ if (!gl::ValidateGetVertexAttribParameters(context, pname))
{
return;
}
@@ -3253,17 +3385,18 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
*pointer = const_cast<GLvoid*>(context->getState().getVertexAttribPointer(index));
@@ -3274,27 +3407,35 @@ void __stdcall glHint(GLenum target, GLenum mode)
{
EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
- switch (mode)
- {
- case GL_FASTEST:
- case GL_NICEST:
- case GL_DONT_CARE:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
- switch (target)
+ if (context)
{
- case GL_GENERATE_MIPMAP_HINT:
- if (context) context->getState().setGenerateMipmapHint(mode);
- break;
- case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
- if (context) context->getState().setFragmentShaderDerivativeHint(mode);
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
+ switch (mode)
+ {
+ case GL_FASTEST:
+ case GL_NICEST:
+ case GL_DONT_CARE:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ context->getState().setGenerateMipmapHint(mode);
+ break;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ context->getState().setFragmentShaderDerivativeHint(mode);
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
}
}
@@ -3303,7 +3444,6 @@ GLboolean __stdcall glIsBuffer(GLuint buffer)
EVENT("(GLuint buffer = %d)", buffer);
gl::Context *context = gl::getNonLostContext();
-
if (context && buffer)
{
gl::Buffer *bufferObject = context->getBuffer(buffer);
@@ -3322,12 +3462,12 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
EVENT("(GLenum cap = 0x%X)", cap);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidCap(context, cap))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return GL_FALSE;
}
return context->getState().getEnableFeature(cap);
@@ -3341,7 +3481,6 @@ GLboolean __stdcall glIsFenceNV(GLuint fence)
EVENT("(GLuint fence = %d)", fence);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::FenceNV *fenceObject = context->getFenceNV(fence);
@@ -3362,7 +3501,6 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
EVENT("(GLuint framebuffer = %d)", framebuffer);
gl::Context *context = gl::getNonLostContext();
-
if (context && framebuffer)
{
gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
@@ -3381,7 +3519,6 @@ GLboolean __stdcall glIsProgram(GLuint program)
EVENT("(GLuint program = %d)", program);
gl::Context *context = gl::getNonLostContext();
-
if (context && program)
{
gl::Program *programObject = context->getProgram(program);
@@ -3400,7 +3537,6 @@ GLboolean __stdcall glIsQueryEXT(GLuint id)
EVENT("(GLuint id = %d)", id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
@@ -3414,7 +3550,6 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
EVENT("(GLuint renderbuffer = %d)", renderbuffer);
gl::Context *context = gl::getNonLostContext();
-
if (context && renderbuffer)
{
gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
@@ -3433,7 +3568,6 @@ GLboolean __stdcall glIsShader(GLuint shader)
EVENT("(GLuint shader = %d)", shader);
gl::Context *context = gl::getNonLostContext();
-
if (context && shader)
{
gl::Shader *shaderObject = context->getShader(shader);
@@ -3452,7 +3586,6 @@ GLboolean __stdcall glIsTexture(GLuint texture)
EVENT("(GLuint texture = %d)", texture);
gl::Context *context = gl::getNonLostContext();
-
if (context && texture)
{
gl::Texture *textureObject = context->getTexture(texture);
@@ -3470,15 +3603,15 @@ void __stdcall glLineWidth(GLfloat width)
{
EVENT("(GLfloat width = %f)", width);
- if (width <= 0.0f)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (width <= 0.0f)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setLineWidth(width);
}
}
@@ -3488,7 +3621,6 @@ void __stdcall glLinkProgram(GLuint program)
EVENT("(GLuint program = %d)", program);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
@@ -3497,11 +3629,13 @@ void __stdcall glLinkProgram(GLuint program)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -3514,7 +3648,6 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
switch (pname)
@@ -3522,7 +3655,8 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
case GL_UNPACK_ALIGNMENT:
if (param != 1 && param != 2 && param != 4 && param != 8)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->getState().setUnpackAlignment(param);
@@ -3531,7 +3665,8 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
case GL_PACK_ALIGNMENT:
if (param != 1 && param != 2 && param != 4 && param != 8)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->getState().setPackAlignment(param);
@@ -3551,13 +3686,15 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
case GL_PACK_SKIP_PIXELS:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
UNIMPLEMENTED();
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -3567,7 +3704,6 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
context->getState().setPolygonOffsetParams(factor, units);
@@ -3582,22 +3718,27 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
"GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
x, y, width, height, format, type, bufSize, data);
- if (width < 0 || height < 0 || bufSize < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (width < 0 || height < 0 || bufSize < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
format, type, &bufSize, data))
{
return;
}
- context->readPixels(x, y, width, height, format, type, &bufSize, data);
+ gl::Error error = context->readPixels(x, y, width, height, format, type, &bufSize, data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -3608,22 +3749,27 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
"GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
x, y, width, height, format, type, pixels);
- if (width < 0 || height < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (width < 0 || height < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
format, type, NULL, pixels))
{
return;
}
- context->readPixels(x, y, width, height, format, type, NULL, pixels);
+ gl::Error error = context->readPixels(x, y, width, height, format, type, NULL, pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -3631,7 +3777,12 @@ void __stdcall glReleaseShaderCompiler(void)
{
EVENT("()");
- gl::Shader::releaseCompiler();
+ gl::Context *context = gl::getNonLostContext();
+
+ if (context)
+ {
+ context->releaseShaderCompiler();
+ }
}
void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
@@ -3640,7 +3791,6 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
target, samples, internalformat, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
@@ -3674,20 +3824,21 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
{
EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
- if (condition != GL_ALL_COMPLETED_NV)
- {
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (condition != GL_ALL_COMPLETED_NV)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
gl::FenceNV *fenceObject = context->getFenceNV(fence);
if (fenceObject == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
fenceObject->setFence(condition);
@@ -3698,15 +3849,15 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
- if (width < 0 || height < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context* context = gl::getNonLostContext();
-
if (context)
{
+ if (width < 0 || height < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setScissorParams(x, y, width, height);
}
}
@@ -3717,8 +3868,19 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor
"const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
n, shaders, binaryformat, binary, length);
- // No binary shader formats are supported.
- return gl::error(GL_INVALID_ENUM);
+ gl::Context* context = gl::getNonLostContext();
+ if (context)
+ {
+ const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
+ if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end())
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ // No binary shader formats are supported.
+ UNIMPLEMENTED();
+ }
}
void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
@@ -3726,26 +3888,28 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const*
EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
shader, count, string, length);
- if (count < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (count < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
gl::Shader *shaderObject = context->getShader(shader);
if (!shaderObject)
{
if (context->getProgram(shader))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -3762,35 +3926,38 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint
{
EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
- switch (face)
+ gl::Context *context = gl::getNonLostContext();
+ if (context)
{
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
- switch (func)
- {
- case GL_NEVER:
- case GL_ALWAYS:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_EQUAL:
- case GL_GEQUAL:
- case GL_GREATER:
- case GL_NOTEQUAL:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- gl::Context *context = gl::getNonLostContext();
+ switch (func)
+ {
+ case GL_NEVER:
+ case GL_ALWAYS:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_EQUAL:
+ case GL_GEQUAL:
+ case GL_GREATER:
+ case GL_NOTEQUAL:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- if (context)
- {
if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
context->getState().setStencilParams(func, ref, mask);
@@ -3812,20 +3979,21 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
{
EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
- switch (face)
- {
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
context->getState().setStencilWritemask(mask);
@@ -3848,65 +4016,72 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
face, fail, zfail, zpass);
- switch (face)
+ gl::Context *context = gl::getNonLostContext();
+ if (context)
{
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
- switch (fail)
- {
- case GL_ZERO:
- case GL_KEEP:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- case GL_INCR_WRAP:
- case GL_DECR_WRAP:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- switch (zfail)
- {
- case GL_ZERO:
- case GL_KEEP:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- case GL_INCR_WRAP:
- case GL_DECR_WRAP:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (fail)
+ {
+ case GL_ZERO:
+ case GL_KEEP:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ case GL_INCR_WRAP:
+ case GL_DECR_WRAP:
+ break;
- switch (zpass)
- {
- case GL_ZERO:
- case GL_KEEP:
- case GL_REPLACE:
- case GL_INCR:
- case GL_DECR:
- case GL_INVERT:
- case GL_INCR_WRAP:
- case GL_DECR_WRAP:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- gl::Context *context = gl::getNonLostContext();
+ switch (zfail)
+ {
+ case GL_ZERO:
+ case GL_KEEP:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ case GL_INCR_WRAP:
+ case GL_DECR_WRAP:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (zpass)
+ {
+ case GL_ZERO:
+ case GL_KEEP:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ case GL_INCR_WRAP:
+ case GL_DECR_WRAP:
+ break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- if (context)
- {
if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
context->getState().setStencilOperations(fail, zfail, zpass);
@@ -3924,19 +4099,20 @@ GLboolean __stdcall glTestFenceNV(GLuint fence)
EVENT("(GLuint fence = %d)", fence);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::FenceNV *fenceObject = context->getFenceNV(fence);
if (fenceObject == NULL)
{
- return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_TRUE;
}
if (fenceObject->isFence() != GL_TRUE)
{
- return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_TRUE;
}
return fenceObject->testFence();
@@ -3953,7 +4129,6 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
target, level, internalformat, width, height, border, format, type, pixels);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -4024,7 +4199,6 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
@@ -4036,7 +4210,8 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
if (!texture)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -4073,7 +4248,6 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateTexParamParameters(context, pname, param))
@@ -4085,7 +4259,8 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
if (!texture)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -4123,12 +4298,12 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
target, levels, internalformat, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!context->getExtensions().textureStorage)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (context->getClientVersion() < 3 &&
@@ -4160,7 +4335,8 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -4174,7 +4350,6 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
target, level, xoffset, yoffset, width, height, format, type, pixels);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3 &&
@@ -4234,7 +4409,6 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_FLOAT, location, count))
@@ -4257,7 +4431,6 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_INT, location, count))
@@ -4282,7 +4455,6 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
@@ -4307,7 +4479,6 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_INT_VEC2, location, count))
@@ -4332,7 +4503,6 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
@@ -4357,7 +4527,6 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_INT_VEC3, location, count))
@@ -4382,7 +4551,6 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
@@ -4407,7 +4575,6 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_INT_VEC4, location, count))
@@ -4426,7 +4593,6 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
@@ -4445,7 +4611,6 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
@@ -4464,7 +4629,6 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
@@ -4482,7 +4646,6 @@ void __stdcall glUseProgram(GLuint program)
EVENT("(GLuint program = %d)", program);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
@@ -4491,17 +4654,20 @@ void __stdcall glUseProgram(GLuint program)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
if (program != 0 && !programObject->isLinked())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->useProgram(program);
@@ -4513,7 +4679,6 @@ void __stdcall glValidateProgram(GLuint program)
EVENT("(GLuint program = %d)", program);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
@@ -4522,15 +4687,17 @@ void __stdcall glValidateProgram(GLuint program)
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
- programObject->validate();
+ programObject->validate(context->getCaps());
}
}
@@ -4538,15 +4705,15 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
{
EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { x, 0, 0, 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4556,15 +4723,15 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { values[0], 0, 0, 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4574,15 +4741,15 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { x, y, 0, 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4592,15 +4759,15 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { values[0], values[1], 0, 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4610,15 +4777,15 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { x, y, z, 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4628,15 +4795,15 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { values[0], values[1], values[2], 1 };
context->getState().setVertexAttribf(index, vals);
}
@@ -4646,15 +4813,15 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
GLfloat vals[4] = { x, y, z, w };
context->getState().setVertexAttribf(index, vals);
}
@@ -4664,15 +4831,15 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setVertexAttribf(index, values);
}
}
@@ -4681,15 +4848,15 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->setVertexAttribDivisor(index, divisor);
}
}
@@ -4700,63 +4867,68 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
"GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
index, size, type, normalized, stride, ptr);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
- if (size < 1 || size > 4)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
- switch (type)
+ if (context)
{
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_FIXED:
- case GL_FLOAT:
- break;
- case GL_HALF_FLOAT:
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- if (context && context->getClientVersion() < 3)
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
- else
+
+ if (size < 1 || size > 4)
{
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FIXED:
+ case GL_FLOAT:
+ break;
+
+ case GL_HALF_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
break;
+
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- default:
- return gl::error(GL_INVALID_ENUM);
- }
- if (stride < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
+ if (stride < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
- if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+ {
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
+ }
- if (context)
- {
// [OpenGL ES 3.0.2] Section 2.8 page 24:
// An INVALID_OPERATION error is generated when a non-zero vertex array object
// is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
// and the pointer argument is not NULL.
if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && ptr != NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type,
@@ -4768,15 +4940,15 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
- if (width < 0 || height < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
+ if (width < 0 || height < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
context->getState().setViewportParams(x, y, width, height);
}
}
@@ -4788,12 +4960,12 @@ void __stdcall glReadBuffer(GLenum mode)
EVENT("(GLenum mode = 0x%X)", mode);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glReadBuffer
@@ -4807,12 +4979,12 @@ void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize
"const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glDrawRangeElements
@@ -4828,12 +5000,12 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL
target, level, internalformat, width, height, depth, border, format, type, pixels);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// validateES3TexImageFormat sets the error code if there is an error
@@ -4860,7 +5032,8 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -4873,12 +5046,12 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// validateES3TexImageFormat sets the error code if there is an error
@@ -4912,7 +5085,8 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -4924,12 +5098,12 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL
target, level, xoffset, yoffset, zoffset, x, y, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
@@ -4951,7 +5125,8 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
@@ -4966,17 +5141,19 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna
target, level, internalformat, width, height, depth, border, imageSize, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, width, height))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
// validateES3TexImageFormat sets the error code if there is an error
@@ -5003,7 +5180,8 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -5016,22 +5194,25 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, width, height))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (!data)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
// validateES3TexImageFormat sets the error code if there is an error
@@ -5065,8 +5246,9 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
}
break;
- default:
- return gl::error(GL_INVALID_ENUM);
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -5076,17 +5258,18 @@ void __stdcall glGenQueries(GLsizei n, GLuint* ids)
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (n < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (GLsizei i = 0; i < n; i++)
@@ -5101,17 +5284,18 @@ void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids)
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (n < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (GLsizei i = 0; i < n; i++)
@@ -5126,12 +5310,12 @@ GLboolean __stdcall glIsQuery(GLuint id)
EVENT("(GLuint id = %u)", id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
@@ -5145,19 +5329,25 @@ void __stdcall glBeginQuery(GLenum target, GLuint id)
EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateBeginQuery(context, target, id))
{
return;
}
- context->beginQuery(target, id);
+
+ gl::Error error = context->beginQuery(target, id);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -5166,12 +5356,12 @@ void __stdcall glEndQuery(GLenum target)
EVENT("(GLenum target = 0x%X)", target);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateEndQuery(context, target))
@@ -5179,7 +5369,12 @@ void __stdcall glEndQuery(GLenum target)
return;
}
- context->endQuery(target);
+ gl::Error error = context->endQuery(target);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -5188,17 +5383,18 @@ void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidQueryType(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (pname)
@@ -5208,7 +5404,8 @@ void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params)
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -5218,36 +5415,55 @@ void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
if (!queryObject)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (context->getState().getActiveQueryId(queryObject->getType()) == id)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch(pname)
{
- case GL_QUERY_RESULT:
- params[0] = queryObject->getResult();
+ case GL_QUERY_RESULT_EXT:
+ {
+ gl::Error error = queryObject->getResult(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
break;
- case GL_QUERY_RESULT_AVAILABLE:
- params[0] = queryObject->isResultAvailable();
+
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ {
+ gl::Error error = queryObject->isResultAvailable(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -5257,12 +5473,12 @@ GLboolean __stdcall glUnmapBuffer(GLenum target)
EVENT("(GLenum target = 0x%X)", target);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
return glUnmapBufferOES(target);
@@ -5276,12 +5492,12 @@ void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
glGetBufferPointervOES(target, pname, params);
@@ -5291,12 +5507,12 @@ void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
{
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
glDrawBuffersEXT(n, bufs);
@@ -5309,7 +5525,6 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
@@ -5328,7 +5543,6 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
@@ -5347,7 +5561,6 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
@@ -5366,7 +5579,6 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
@@ -5385,7 +5597,6 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
@@ -5404,7 +5615,6 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra
location, count, transpose, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
@@ -5428,7 +5638,8 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
@@ -5449,12 +5660,12 @@ void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
target, samples, internalformat, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
@@ -5473,7 +5684,6 @@ void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuin
target, attachment, texture, level, layer);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
@@ -5511,12 +5721,12 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le
target, offset, length, access);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
return glMapBufferRangeEXT(target, offset, length, access);
@@ -5530,12 +5740,12 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
glFlushMappedBufferRangeEXT(target, offset, length);
@@ -5547,12 +5757,12 @@ void __stdcall glBindVertexArray(GLuint array)
EVENT("(GLuint array = %u)", array);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::VertexArray *vao = context->getVertexArray(array);
@@ -5561,7 +5771,8 @@ void __stdcall glBindVertexArray(GLuint array)
{
// The default VAO should always exist
ASSERT(array != 0);
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->bindVertexArray(array);
@@ -5573,17 +5784,18 @@ void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (n < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
@@ -5601,17 +5813,18 @@ void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays)
EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (n < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
@@ -5626,12 +5839,12 @@ GLboolean __stdcall glIsVertexArray(GLuint array)
EVENT("(GLuint array = %u)", array);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
if (array == 0)
@@ -5653,30 +5866,40 @@ void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
target, index, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
+ const gl::Caps &caps = context->getCaps();
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index >= context->getMaxTransformFeedbackBufferBindings())
- return gl::error(GL_INVALID_VALUE);
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
break;
+
case GL_UNIFORM_BUFFER_START:
case GL_UNIFORM_BUFFER_SIZE:
case GL_UNIFORM_BUFFER_BINDING:
- if (index >= context->getMaximumCombinedUniformBufferBindings())
- return gl::error(GL_INVALID_VALUE);
+ if (index >= caps.maxCombinedUniformBlocks)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (!(context->getIndexedIntegerv(target, index, data)))
@@ -5684,10 +5907,15 @@ void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
GLenum nativeType;
unsigned int numParams = 0;
if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
- return gl::error(GL_INVALID_ENUM);
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
if (numParams == 0)
+ {
return; // it is known that pname is valid, but there are no parameters to return
+ }
if (nativeType == GL_INT_64_ANGLEX)
{
@@ -5718,12 +5946,12 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (primitiveMode)
@@ -5732,8 +5960,10 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
case GL_LINES:
case GL_POINTS:
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -5741,7 +5971,8 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
if (transformFeedback->isStarted())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (transformFeedback->isPaused())
@@ -5760,12 +5991,12 @@ void __stdcall glEndTransformFeedback(void)
EVENT("(void)");
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -5773,7 +6004,8 @@ void __stdcall glEndTransformFeedback(void)
if (!transformFeedback->isStarted())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
transformFeedback->stop();
@@ -5786,37 +6018,42 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi
target, index, buffer, offset, size);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
+ const gl::Caps &caps = context->getCaps();
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER:
- if (index >= context->getMaxTransformFeedbackBufferBindings())
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
case GL_UNIFORM_BUFFER:
- if (index >= context->getMaximumCombinedUniformBufferBindings())
+ if (index >= caps.maxUniformBufferBindings)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (buffer != 0 && size <= 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (target)
@@ -5826,7 +6063,8 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi
// size and offset must be a multiple of 4
if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
@@ -5836,9 +6074,10 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi
case GL_UNIFORM_BUFFER:
// it is an error to bind an offset not a multiple of the alignment
- if (buffer != 0 && (offset % context->getUniformBufferOffsetAlignment()) != 0)
+ if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->bindIndexedUniformBuffer(buffer, index, offset, size);
@@ -5857,32 +6096,36 @@ void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
target, index, buffer);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
+ const gl::Caps &caps = context->getCaps();
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER:
- if (index >= context->getMaxTransformFeedbackBufferBindings())
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
case GL_UNIFORM_BUFFER:
- if (index >= context->getMaximumCombinedUniformBufferBindings())
+ if (index >= caps.maxUniformBufferBindings)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
switch (target)
@@ -5909,31 +6152,35 @@ void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const
program, count, varyings, bufferMode);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (count < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
+ const gl::Caps &caps = context->getCaps();
switch (bufferMode)
{
case GL_INTERLEAVED_ATTRIBS:
break;
case GL_SEPARATE_ATTRIBS:
- if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings())
+ if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (!gl::ValidProgram(context, program))
@@ -5955,17 +6202,18 @@ void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz
program, index, bufSize, length, size, type, name);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (bufSize < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (!gl::ValidProgram(context, program))
@@ -5978,7 +6226,8 @@ void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz
if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
@@ -5991,59 +6240,63 @@ void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs
index, size, type, stride, pointer);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- }
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
- if (size < 1 || size > 4)
- {
- return gl::error(GL_INVALID_VALUE);
- }
+ if (size < 1 || size > 4)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
- switch (type)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
+ switch (type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ break;
- if (stride < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
+ default:
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
- if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ if (stride < 0)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+ {
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
+ }
- if (context)
- {
// [OpenGL ES 3.0.2] Section 2.8 page 24:
// An INVALID_OPERATION error is generated when a non-zero vertex array object
// is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
// and the pointer argument is not NULL.
if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
@@ -6057,22 +6310,23 @@ void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
index, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
- if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+ if (!gl::ValidateGetVertexAttribParameters(context, pname))
{
return;
}
@@ -6098,22 +6352,23 @@ void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
index, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
- if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion()))
+ if (!gl::ValidateGetVertexAttribParameters(context, pname))
{
return;
}
@@ -6139,17 +6394,18 @@ void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint
index, x, y, z, w);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
GLint vals[4] = { x, y, z, w };
@@ -6163,17 +6419,18 @@ void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GL
index, x, y, z, w);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
GLuint vals[4] = { x, y, z, w };
@@ -6186,17 +6443,18 @@ void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v)
EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->getState().setVertexAttribi(index, v);
@@ -6208,17 +6466,18 @@ void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v)
EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->getState().setVertexAttribu(index, v);
@@ -6231,36 +6490,19 @@ void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params)
program, location, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (context->getClientVersion() < 3)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
- if (program == 0)
+ if (!ValidateGetUniformuiv(context, program, location, params))
{
- return gl::error(GL_INVALID_VALUE);
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
+ ASSERT(programObject);
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ ASSERT(programBinary);
- if (!programBinary->getUniformuiv(location, NULL, params))
- {
- return gl::error(GL_INVALID_OPERATION);
- }
+ programBinary->getUniformuiv(location, params);
}
}
@@ -6270,30 +6512,33 @@ GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name)
program, name);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
if (program == 0)
{
- return gl::error(GL_INVALID_VALUE, -1);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return -1;
}
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return gl::error(GL_INVALID_OPERATION, -1);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return -1;
}
return programBinary->getFragDataLocation(name);
@@ -6331,7 +6576,6 @@ void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
location, count, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
@@ -6350,7 +6594,6 @@ void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
location, count, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
@@ -6369,7 +6612,6 @@ void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
location, count, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
@@ -6388,7 +6630,6 @@ void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
location, count, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
@@ -6407,7 +6648,6 @@ void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val
buffer, drawbuffer, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateClearBuffer(context))
@@ -6420,20 +6660,30 @@ void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val
case GL_COLOR:
if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
case GL_STENCIL:
if (drawbuffer != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- context->clearBufferiv(buffer, drawbuffer, value);
+ gl::Error error = context->clearBufferiv(buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -6443,7 +6693,6 @@ void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v
buffer, drawbuffer, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateClearBuffer(context))
@@ -6456,14 +6705,22 @@ void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v
case GL_COLOR:
if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- context->clearBufferuiv(buffer, drawbuffer, value);
+ gl::Error error = context->clearBufferuiv(buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -6473,7 +6730,6 @@ void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v
buffer, drawbuffer, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateClearBuffer(context))
@@ -6486,20 +6742,30 @@ void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v
case GL_COLOR:
if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
case GL_DEPTH:
if (drawbuffer != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- context->clearBufferfv(buffer, drawbuffer, value);
+ gl::Error error = context->clearBufferfv(buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -6509,7 +6775,6 @@ void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G
buffer, drawbuffer, depth, stencil);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateClearBuffer(context))
@@ -6522,14 +6787,22 @@ void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G
case GL_DEPTH_STENCIL:
if (drawbuffer != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
- context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+ gl::Error error = context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
@@ -6538,22 +6811,24 @@ const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index)
EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
if (name != GL_EXTENSIONS)
{
- return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return NULL;
}
if (index >= context->getExtensionStringCount())
{
- return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return NULL;
}
return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str());
@@ -6568,17 +6843,18 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
readTarget, writeTarget, readOffset, writeOffset, size);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
@@ -6586,32 +6862,40 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
if (!readBuffer || !writeBuffer)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
+ // Verify that readBuffer and writeBuffer are not currently mapped
if (readBuffer->isMapped() || writeBuffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (readOffset < 0 || writeOffset < 0 || size < 0 ||
static_cast<unsigned int>(readOffset + size) > readBuffer->getSize() ||
static_cast<unsigned int>(writeOffset + size) > writeBuffer->getSize())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
- // TODO: Verify that readBuffer and writeBuffer are not currently mapped (GL_INVALID_OPERATION)
-
// if size is zero, the copy is a successful no-op
if (size > 0)
{
- writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+ gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
}
@@ -6622,17 +6906,18 @@ void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const G
program, uniformCount, uniformNames, uniformIndices);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (uniformCount < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
gl::Program *programObject = context->getProgram(program);
@@ -6641,11 +6926,13 @@ void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const G
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6673,17 +6960,18 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const
program, uniformCount, uniformIndices, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (uniformCount < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
gl::Program *programObject = context->getProgram(program);
@@ -6692,11 +6980,13 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6711,15 +7001,18 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const
case GL_UNIFORM_MATRIX_STRIDE:
case GL_UNIFORM_IS_ROW_MAJOR:
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary && uniformCount > 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
@@ -6728,7 +7021,8 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const
if (index >= (GLuint)programBinary->getActiveUniformCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6745,12 +7039,12 @@ GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlo
EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_INVALID_INDEX;
}
gl::Program *programObject = context->getProgram(program);
@@ -6759,11 +7053,13 @@ GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlo
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_INVALID_INDEX;
}
else
{
- return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return GL_INVALID_INDEX;
}
}
@@ -6785,12 +7081,12 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde
program, uniformBlockIndex, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::Program *programObject = context->getProgram(program);
@@ -6798,11 +7094,13 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6810,7 +7108,8 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde
if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (pname)
@@ -6829,7 +7128,8 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -6840,12 +7140,12 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn
program, uniformBlockIndex, bufSize, length, uniformBlockName);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::Program *programObject = context->getProgram(program);
@@ -6854,11 +7154,13 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6866,7 +7168,8 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn
if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
@@ -6879,17 +7182,18 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G
program, uniformBlockIndex, uniformBlockBinding);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings())
+ if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
gl::Program *programObject = context->getProgram(program);
@@ -6898,11 +7202,13 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G
{
if (context->getShader(program))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
else
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
}
@@ -6911,7 +7217,8 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G
// if never linked, there won't be any uniform blocks
if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
@@ -6924,12 +7231,12 @@ void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL
mode, first, count, instanceCount);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glDrawArraysInstanced
@@ -6943,12 +7250,12 @@ void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
mode, count, type, indices, instanceCount);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glDrawElementsInstanced
@@ -6961,22 +7268,24 @@ GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags)
EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return 0;
}
if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
{
- return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0));
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return 0;
}
if (flags != 0)
{
- return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0));
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return 0;
}
return context->createFenceSync(condition);
@@ -6990,12 +7299,12 @@ GLboolean __stdcall glIsSync(GLsync sync)
EVENT("(GLsync sync = 0x%0.8p)", sync);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
return (context->getFenceSync(sync) != NULL);
@@ -7009,17 +7318,18 @@ void __stdcall glDeleteSync(GLsync sync)
EVENT("(GLsync sync = 0x%0.8p)", sync);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->deleteFenceSync(sync);
@@ -7032,24 +7342,26 @@ GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeou
sync, flags, timeout);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_WAIT_FAILED;
}
if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
{
- return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return GL_WAIT_FAILED;
}
gl::FenceSync *fenceSync = context->getFenceSync(sync);
if (!fenceSync)
{
- return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return GL_WAIT_FAILED;
}
return fenceSync->clientWait(flags, timeout);
@@ -7064,29 +7376,32 @@ void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
sync, flags, timeout);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (flags != 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (timeout != GL_TIMEOUT_IGNORED)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
gl::FenceSync *fenceSync = context->getFenceSync(sync);
if (!fenceSync)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
fenceSync->serverWait();
@@ -7099,12 +7414,12 @@ void __stdcall glGetInteger64v(GLenum pname, GLint64* params)
pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
GLenum nativeType;
@@ -7131,24 +7446,26 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei*
sync, pname, bufSize, length, values);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (bufSize < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
gl::FenceSync *fenceSync = context->getFenceSync(sync);
if (!fenceSync)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (pname)
@@ -7159,7 +7476,8 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei*
case GL_SYNC_FLAGS: values[0] = 0; break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -7170,30 +7488,40 @@ void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
target, index, data);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
+ const gl::Caps &caps = context->getCaps();
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index >= context->getMaxTransformFeedbackBufferBindings())
- return gl::error(GL_INVALID_VALUE);
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
break;
+
case GL_UNIFORM_BUFFER_START:
case GL_UNIFORM_BUFFER_SIZE:
case GL_UNIFORM_BUFFER_BINDING:
- if (index >= context->getMaximumCombinedUniformBufferBindings())
- return gl::error(GL_INVALID_VALUE);
+ if (index >= caps.maxUniformBufferBindings)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
+ }
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (!(context->getIndexedInteger64v(target, index, data)))
@@ -7201,7 +7529,10 @@ void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
GLenum nativeType;
unsigned int numParams = 0;
if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
- return gl::error(GL_INVALID_ENUM);
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
if (numParams == 0)
return; // it is known that pname is valid, but there are no parameters to return
@@ -7233,22 +7564,24 @@ void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (!gl::ValidBufferParameter(context, pname))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -7256,7 +7589,8 @@ void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
if (!buffer)
{
// A null buffer means that "0" is bound to the requested buffer target
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (pname)
@@ -7289,17 +7623,18 @@ void __stdcall glGenSamplers(GLsizei count, GLuint* samplers)
EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (count < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (int i = 0; i < count; i++)
@@ -7314,17 +7649,18 @@ void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers)
EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (count < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
for (int i = 0; i < count; i++)
@@ -7339,12 +7675,12 @@ GLboolean __stdcall glIsSampler(GLuint sampler)
EVENT("(GLuint sampler = %u)", sampler);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
return context->isSampler(sampler);
@@ -7358,22 +7694,24 @@ void __stdcall glBindSampler(GLuint unit, GLuint sampler)
EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (sampler != 0 && !context->isSampler(sampler))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (unit >= context->getMaximumCombinedTextureImageUnits())
+ if (unit >= context->getCaps().maxCombinedTextureImageUnits)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->bindSampler(unit, sampler);
@@ -7385,15 +7723,15 @@ void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (!gl::ValidateSamplerObjectParameter(pname))
+ if (!gl::ValidateSamplerObjectParameter(context, pname))
{
return;
}
@@ -7405,7 +7743,8 @@ void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
if (!context->isSampler(sampler))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->samplerParameteri(sampler, pname, param);
@@ -7422,15 +7761,15 @@ void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (!gl::ValidateSamplerObjectParameter(pname))
+ if (!gl::ValidateSamplerObjectParameter(context, pname))
{
return;
}
@@ -7442,7 +7781,8 @@ void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
if (!context->isSampler(sampler))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->samplerParameterf(sampler, pname, param);
@@ -7459,22 +7799,23 @@ void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* para
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (!gl::ValidateSamplerObjectParameter(pname))
+ if (!gl::ValidateSamplerObjectParameter(context, pname))
{
return;
}
if (!context->isSampler(sampler))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
*params = context->getSamplerParameteri(sampler, pname);
@@ -7486,22 +7827,23 @@ void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* pa
EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (!gl::ValidateSamplerObjectParameter(pname))
+ if (!gl::ValidateSamplerObjectParameter(context, pname))
{
return;
}
if (!context->isSampler(sampler))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
*params = context->getSamplerParameterf(sampler, pname);
@@ -7512,18 +7854,19 @@ void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor)
{
EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= gl::MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
context->setVertexAttribDivisor(index, divisor);
@@ -7535,12 +7878,12 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
switch (target)
@@ -7551,13 +7894,15 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
if (context->getTransformFeedback(id) == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
context->bindTransformFeedback(id);
@@ -7565,7 +7910,8 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -7575,12 +7921,12 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
for (int i = 0; i < n; i++)
@@ -7595,12 +7941,12 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
for (int i = 0; i < n; i++)
@@ -7615,12 +7961,12 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id)
EVENT("(GLuint id = %u)", id);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
@@ -7634,12 +7980,12 @@ void __stdcall glPauseTransformFeedback(void)
EVENT("(void)");
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -7648,7 +7994,8 @@ void __stdcall glPauseTransformFeedback(void)
// Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
if (!transformFeedback->isStarted() || transformFeedback->isPaused())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
transformFeedback->pause();
@@ -7660,12 +8007,12 @@ void __stdcall glResumeTransformFeedback(void)
EVENT("(void)");
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
@@ -7674,7 +8021,8 @@ void __stdcall glResumeTransformFeedback(void)
// Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
transformFeedback->resume();
@@ -7687,12 +8035,12 @@ void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* leng
program, bufSize, length, binaryFormat, binary);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glGetProgramBinary
@@ -7706,12 +8054,12 @@ void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid
program, binaryFormat, binary, length);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glProgramBinary
@@ -7725,12 +8073,12 @@ void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value)
program, pname, value);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// glProgramParameteri
@@ -7744,12 +8092,12 @@ void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, co
target, numAttachments, attachments);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
@@ -7757,8 +8105,11 @@ void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, co
return;
}
- GLuint maxDimension = context->getCaps().maxRenderbufferSize;
- context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+ gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+ }
}
}
@@ -7769,12 +8120,12 @@ void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
target, numAttachments, attachments, x, y, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
@@ -7782,7 +8133,11 @@ void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
return;
}
- context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height);
+ gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height);
+ }
}
}
@@ -7792,12 +8147,12 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform
target, levels, internalformat, width, height);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
@@ -7822,7 +8177,8 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform
break;
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -7834,12 +8190,12 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform
target, levels, internalformat, width, height, depth);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
@@ -7876,41 +8232,49 @@ void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenu
target, internalformat, pname, bufSize, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
if (!formatCaps.renderable)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (target != GL_RENDERBUFFER)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (bufSize < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
switch (pname)
{
case GL_NUM_SAMPLE_COUNTS:
if (bufSize != 0)
- *params = context->getNumSampleCounts(internalformat);
+ {
+ *params = formatCaps.sampleCounts.size();
+ }
break;
+
case GL_SAMPLES:
- context->getSampleCounts(internalformat, bufSize, params);
+ std::copy_n(formatCaps.sampleCounts.rbegin(), std::min<size_t>(bufSize, formatCaps.sampleCounts.size()), params);
break;
+
default:
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
}
}
@@ -7926,7 +8290,6 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
@@ -7959,29 +8322,29 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l
program, bufSize, length, binaryFormat, binary);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- if (!programBinary->save(binary, bufSize, length))
+ if (!programBinary->save(binaryFormat, binary, bufSize, length))
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
-
- *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
}
}
@@ -7992,22 +8355,23 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
program, binaryFormat, binary, length);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
- if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
+ const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
+ if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end())
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Program *programObject = context->getProgram(program);
-
if (!programObject)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
- context->setProgramBinary(program, binary, length);
+ context->setProgramBinary(program, binaryFormat, binary, length);
}
}
@@ -8016,24 +8380,26 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (context->getState().getDrawFramebuffer()->id() == 0)
{
if (n != 1)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
else
@@ -8043,7 +8409,8 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
}
}
@@ -8067,17 +8434,18 @@ void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
if (pname != GL_BUFFER_MAP_POINTER)
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
@@ -8098,32 +8466,42 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access)
EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return NULL;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (buffer == NULL)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
if (access != GL_WRITE_ONLY_OES)
{
- return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return NULL;
}
if (buffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ gl::Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return NULL;
}
- return buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+ return buffer->getMapPointer();
}
return NULL;
@@ -8134,24 +8512,30 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target)
EVENT("(GLenum target = 0x%X)", target);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return GL_FALSE;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (buffer == NULL || !buffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION, GL_FALSE);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
}
// TODO: detect if we had corruption. if so, throw an error and return false.
- buffer->unmap();
+ gl::Error error = buffer->unmap();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_FALSE;
+ }
return GL_TRUE;
}
@@ -8165,24 +8549,26 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
target, offset, length, access);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return NULL;
}
if (offset < 0 || length < 0)
{
- return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return NULL;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (buffer == NULL)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
// Check for buffer overflow
@@ -8192,7 +8578,8 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
{
- return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return NULL;
}
// Check for invalid bits in the mask
@@ -8205,18 +8592,21 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
if (access & ~(allAccessBits))
{
- return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return NULL;
}
if (length == 0 || buffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
// Check for invalid bit combinations
if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
@@ -8225,15 +8615,24 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
}
if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
{
- return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ gl::Error error = buffer->mapRange(offset, length, access);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return NULL;
}
- return buffer->mapRange(offset, length, access);
+ return buffer->getMapPointer();
}
return NULL;
@@ -8244,29 +8643,32 @@ void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsi
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
if (offset < 0 || length < 0)
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
if (!gl::ValidBufferTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM);
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
}
gl::Buffer *buffer = context->getState().getTargetBuffer(target);
if (buffer == NULL)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
{
- return gl::error(GL_INVALID_OPERATION);
+ context->recordError(gl::Error(GL_INVALID_OPERATION));
+ return;
}
// Check for buffer overflow
@@ -8276,7 +8678,8 @@ void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsi
if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
{
- return gl::error(GL_INVALID_VALUE);
+ context->recordError(gl::Error(GL_INVALID_VALUE));
+ return;
}
// We do not currently support a non-trivial implementation of FlushMappedBufferRange
@@ -8347,7 +8750,6 @@ bool __stdcall glBindTexImage(egl::Surface *surface)
surface);
gl::Context *context = gl::getNonLostContext();
-
if (context)
{
gl::Texture2D *textureObject = context->getTexture2D();
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
index 88dceb3556..33557eb1c9 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
@@ -294,6 +294,3 @@ EXPORTS
glBindTexImage @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME
-
- ; Setting up TRACE macro callbacks
- SetTraceFunctionPointers @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
index d6272c4df9..18ffcf6a0d 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
@@ -294,6 +294,3 @@ EXPORTS
glBindTexImage@4 @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME
-
- ; Setting up TRACE macro callbacks
- SetTraceFunctionPointers@8 @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
index d301aa0905..120371e013 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
@@ -294,6 +294,3 @@ EXPORTS
glBindTexImage @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME
-
- ; Setting up TRACE macro callbacks
- SetTraceFunctionPointers @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
index a82d629ae4..8c1306a703 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
@@ -294,6 +294,3 @@ EXPORTS
glBindTexImage@4 @158 NONAME
glCreateRenderer @177 NONAME
glDestroyRenderer @178 NONAME
-
- ; Setting up TRACE macro callbacks
- SetTraceFunctionPointers@8 @284
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 8820700c76..51447e273a 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.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
@@ -175,33 +174,26 @@ egl::Display *getDisplay()
void error(GLenum errorCode)
{
gl::Context *context = glGetCurrentContext();
+ context->recordError(Error(errorCode));
- if (context)
+ switch (errorCode)
{
- switch (errorCode)
- {
- case GL_INVALID_ENUM:
- context->recordInvalidEnum();
- TRACE("\t! Error generated: invalid enum\n");
- break;
- case GL_INVALID_VALUE:
- context->recordInvalidValue();
- TRACE("\t! Error generated: invalid value\n");
- break;
- case GL_INVALID_OPERATION:
- context->recordInvalidOperation();
- TRACE("\t! Error generated: invalid operation\n");
- break;
- case GL_OUT_OF_MEMORY:
- context->recordOutOfMemory();
- TRACE("\t! Error generated: out of memory\n");
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- context->recordInvalidFramebufferOperation();
- TRACE("\t! Error generated: invalid framebuffer operation\n");
- break;
- default: UNREACHABLE();
- }
+ case GL_INVALID_ENUM:
+ TRACE("\t! Error generated: invalid enum\n");
+ break;
+ case GL_INVALID_VALUE:
+ TRACE("\t! Error generated: invalid value\n");
+ break;
+ case GL_INVALID_OPERATION:
+ TRACE("\t! Error generated: invalid operation\n");
+ break;
+ case GL_OUT_OF_MEMORY:
+ TRACE("\t! Error generated: out of memory\n");
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ TRACE("\t! Error generated: invalid framebuffer operation\n");
+ break;
+ default: UNREACHABLE();
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h
index df28ea400d..c30ad3375c 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.h
+++ b/src/3rdparty/angle/src/libGLESv2/main.h
@@ -10,8 +10,8 @@
#define LIBGLESV2_MAIN_H_
#include "common/debug.h"
-#undef EGLAPI
-#define EGLAPI
+
+#include <GLES2/gl2.h>
#include <EGL/egl.h>
#ifndef Sleep
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.cpp b/src/3rdparty/angle/src/libGLESv2/precompiled.cpp
deleted file mode 100644
index 2621cd6ce3..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/precompiled.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// precompiled.cpp: Precompiled header source file for libGLESv2.
-
-#include "precompiled.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
deleted file mode 100644
index 0404eabf8a..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// precompiled.h: Precompiled header file for libGLESv2.
-
-#include "angle_gl.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <assert.h>
-#include <cstddef>
-#include <float.h>
-#include <stdint.h>
-#include <intrin.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <algorithm> // for std::min and std::max
-#include <limits>
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-#include <iterator>
diff --git a/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp b/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp
index 67578efe3a..7245902c51 100644
--- a/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
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/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index e3ec391bfa..13411ebe64 100644
--- a/src/3rdparty/angle/src/libGLESv2/DynamicHLSL.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -6,21 +6,23 @@
// DynamicHLSL.cpp: Implementation for link and run-time HLSL generation
//
-#include "precompiled.h"
-
-#include "libGLESv2/DynamicHLSL.h"
+#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/renderer/Renderer.h"
-#include "common/utilities.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);
-namespace gl_d3d
+using namespace gl;
+
+namespace
{
std::string HLSLComponentTypeString(GLenum componentType)
@@ -68,9 +70,24 @@ std::string HLSLTypeString(GLenum 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 gl
+}
+
+namespace rx
{
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
@@ -109,6 +126,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (available)
{
varying->registerIndex = r;
+ varying->columnIndex = 0;
for (int y = 0; y < registers; y++)
{
@@ -142,6 +160,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (available)
{
varying->registerIndex = r;
+ varying->columnIndex = 2;
for (int y = 0; y < registers; y++)
{
@@ -172,7 +191,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
for (int x = 0; x < 4; x++)
{
- if (space[x] >= registers && space[x] < space[column])
+ if (space[x] >= registers && (space[column] < registers || space[x] < space[column]))
{
column = x;
}
@@ -185,6 +204,7 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
if (!packing[r][column])
{
varying->registerIndex = r;
+ varying->columnIndex = column;
for (int y = r; y < r + registers; y++)
{
@@ -205,19 +225,29 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
-int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, FragmentShader *fragmentShader,
- VertexShader *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
+ rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
{
- const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
+ // TODO (geofflang): Use context's caps
+ const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
vertexShader->resetVaryingsRegisterAssignment();
fragmentShader->resetVaryingsRegisterAssignment();
std::set<std::string> packedVaryings;
- for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
+ 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 = &fragmentShader->mVaryings[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);
@@ -235,9 +265,9 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, Fragment
if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
{
bool found = false;
- for (unsigned int varyingIndex = 0; varyingIndex < vertexShader->mVaryings.size(); varyingIndex++)
+ for (unsigned int varyingIndex = 0; varyingIndex < vertexVaryings.size(); varyingIndex++)
{
- PackedVarying *varying = &vertexShader->mVaryings[varyingIndex];
+ PackedVarying *varying = &vertexVaryings[varyingIndex];
if (transformFeedbackVarying == varying->name)
{
if (!packVarying(varying, maxVaryingVectors, packing))
@@ -273,16 +303,19 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, Fragment
return registers;
}
-std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader) const
+std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
{
std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize);
std::string varyingHLSL;
- for (unsigned int varyingIndex = 0; varyingIndex < shader->mVaryings.size(); varyingIndex++)
+ const std::vector<gl::PackedVarying> &varyings = shader->getVaryings();
+
+ for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++)
{
- const PackedVarying &varying = shader->mVaryings[varyingIndex];
+ const PackedVarying &varying = varyings[varyingIndex];
if (varying.registerAssigned())
{
+ ASSERT(!varying.isBuiltIn());
GLenum transposedType = TransposeMatrixType(varying.type);
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
@@ -290,6 +323,10 @@ std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader) const
{
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;
@@ -298,7 +335,7 @@ std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader) const
default: UNREACHABLE();
}
- unsigned int semanticIndex = elementIndex * variableRows + varying.registerIndex + row;
+ unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
std::string n = Str(semanticIndex);
std::string typeString;
@@ -313,7 +350,7 @@ std::string DynamicHLSL::generateVaryingHLSL(VertexShader *shader) const
{
GLenum componentType = VariableComponentType(transposedType);
int columnCount = VariableColumnCount(transposedType);
- typeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount);
+ typeString = HLSLComponentTypeString(componentType, columnCount);
}
varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
}
@@ -335,23 +372,22 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
-
- const VertexFormat &vertexFormat = inputLayout[inputIndex];
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 += " " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
+ structHLSL += " " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
}
else
{
GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
- structHLSL += " " + gl_d3d::HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+ structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
}
structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
@@ -397,7 +433,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
return vertexHLSL;
}
-std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOuputVariable> &outputVariables,
+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();
@@ -406,17 +442,19 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string
std::string declarationHLSL;
std::string copyHLSL;
- for (size_t i = 0; i < outputVariables.size(); i++)
+
+ for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex)
{
- const PixelShaderOuputVariable& outputVariable = outputVariables[i];
- ASSERT(outputLayout.size() > outputVariable.outputIndex);
+ GLenum binding = outputLayout[layoutIndex];
- // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
- bool outputIndexEnabled = true; // outputLayout[outputVariable.outputIndex] != GL_NONE
- if (outputIndexEnabled)
+ if (binding != GL_NONE)
{
- declarationHLSL += " " + gl_d3d::HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
- " : " + targetSemantic + Str(outputVariable.outputIndex) + ";\n";
+ 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";
}
@@ -601,17 +639,19 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
}
}
-void DynamicHLSL::storeUserLinkedVaryings(const VertexShader *vertexShader,
+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->mVaryings;
+ 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));
@@ -624,11 +664,11 @@ void DynamicHLSL::storeUserLinkedVaryings(const VertexShader *vertexShader,
bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
std::string& pixelHLSL, std::string& vertexHLSL,
- FragmentShader *fragmentShader, VertexShader *vertexShader,
+ rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
const std::vector<std::string>& transformFeedbackVaryings,
std::vector<LinkedVarying> *linkedVaryings,
std::map<int, VariableLocation> *programOutputVars,
- std::vector<PixelShaderOuputVariable> *outPixelShaderKey,
+ std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const
{
if (pixelHLSL.empty() || vertexHLSL.empty())
@@ -651,7 +691,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
// Write the HLSL input/output declarations
const int shaderModel = mRenderer->getMajorShaderModel();
- const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
+
+ // TODO (geofflang): Use context's caps
+ const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
@@ -718,9 +760,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
vertexHLSL += " output.gl_FragCoord = gl_Position;\n";
}
- for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexShader->mVaryings.size(); vertVaryingIndex++)
+ const std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+ for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
{
- const PackedVarying &varying = vertexShader->mVaryings[vertVaryingIndex];
+ const PackedVarying &varying = vertexVaryings[vertVaryingIndex];
if (varying.registerAssigned())
{
for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++)
@@ -729,39 +772,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
for (int row = 0; row < variableRows; row++)
{
- int r = varying.registerIndex + elementIndex * variableRows + row;
+ int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
vertexHLSL += " output.v" + Str(r);
- bool sharedRegister = false; // Register used by multiple varyings
-
- for (int x = 0; x < 4; x++)
- {
- if (packing[r][x] && packing[r][x] != packing[r][0])
- {
- sharedRegister = true;
- break;
- }
- }
-
- if(sharedRegister)
- {
- vertexHLSL += ".";
-
- for (int x = 0; x < 4; x++)
- {
- if (packing[r][x] == &varying)
- {
- switch(x)
- {
- case 0: vertexHLSL += "x"; break;
- case 1: vertexHLSL += "y"; break;
- case 2: vertexHLSL += "z"; break;
- case 3: vertexHLSL += "w"; break;
- }
- }
- }
- }
-
vertexHLSL += " = _" + varying.name;
if (varying.isArray())
@@ -793,7 +806,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
{
for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
{
- PixelShaderOuputVariable outputKeyVariable;
+ PixelShaderOutputVariable outputKeyVariable;
outputKeyVariable.type = GL_FLOAT_VEC4;
outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
@@ -808,7 +821,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
{
defineOutputVariables(fragmentShader, programOutputVars);
- const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
+ const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++)
{
const VariableLocation &outputLocation = locationIt->second;
@@ -816,7 +829,9 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
const std::string &variableName = "out_" + outputLocation.name;
const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element));
- PixelShaderOuputVariable outputKeyVariable;
+ ASSERT(outputVariable.staticUse);
+
+ PixelShaderOutputVariable outputKeyVariable;
outputKeyVariable.type = outputVariable.type;
outputKeyVariable.name = variableName + elementString;
outputKeyVariable.source = variableName + ArrayString(outputLocation.element);
@@ -892,18 +907,20 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
}
}
- for (unsigned int varyingIndex = 0; varyingIndex < fragmentShader->mVaryings.size(); varyingIndex++)
+ const std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+ for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++)
{
- const PackedVarying &varying = fragmentShader->mVaryings[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 + elementIndex * variableRows + row);
+ std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
pixelHLSL += " _" + varying.name;
if (varying.isArray())
@@ -934,7 +951,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
}
}
}
- else UNREACHABLE();
+ else
+ {
+ ASSERT(varying.isBuiltIn() || !varying.staticUse);
+ }
}
pixelHLSL += "\n"
@@ -946,15 +966,17 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
return true;
}
-void DynamicHLSL::defineOutputVariables(FragmentShader *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
{
- const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getOutputVariables();
+ 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++)
@@ -972,14 +994,14 @@ void DynamicHLSL::defineOutputVariables(FragmentShader *fragmentShader, std::map
}
}
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, FragmentShader *fragmentShader, VertexShader *vertexShader) const
+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, FragmentShader *fragmentShader, VertexShader *vertexShader) const
+std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
{
ASSERT(registers >= 0);
ASSERT(vertexShader->mUsesPointSize);
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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
+gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset)
+gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &currentValue,
- 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 &currentValue,
+ 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
+ virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
bool directStoragePossible(const gl::VertexAttribute &attrib,
const gl::VertexAttribCurrentValueData &currentValue) 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset);
+ gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &currentValue) 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 &currentValue,
+ 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 &currentValue,
+ 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 &currentValue,
+ 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 &currentValue,
+ GLsizei count,
+ GLsizei instances) const;
+
+ void invalidateMatchingStaticData(const gl::VertexAttribute &attrib,
+ const gl::VertexAttribCurrentValueData &currentValue) const;
+
+ gl::Error storeAttribute(const gl::VertexAttribute &attrib,
+ const gl::VertexAttribCurrentValueData &currentValue,
+ TranslatedAttribute *translated,
+ GLint start,
+ GLsizei count,
+ GLsizei instances);
+
+ gl::Error storeCurrentValue(const gl::VertexAttribute &attrib,
+ const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &params);
+ gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
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 &params)
+gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
{
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 &params)
+gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
{
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 &params);
+ gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
// 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 &params, void *pixelsOut)
+void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, 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 &params, void *pixelsOut);
+ void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+ virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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, &copyVertexData<GLbyte, 1, 0>);
- addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &copyVertexData<GLbyte, 2, 0>);
- addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &copyVertexData<GLbyte, 3, 1>);
- addVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &copyVertexData<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, &copyVertexData<GLbyte, 1, 0>);
- addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &copyVertexData<GLbyte, 2, 0>);
- addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &copyVertexData<GLbyte, 3, INT8_MAX>);
- addVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &copyVertexData<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, &copyVertexData<GLubyte, 1, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &copyVertexData<GLubyte, 2, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &copyVertexData<GLubyte, 3, 1>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &copyVertexData<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, &copyVertexData<GLubyte, 1, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &copyVertexData<GLubyte, 2, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &copyVertexData<GLubyte, 3, UINT8_MAX>);
- addVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &copyVertexData<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, &copyVertexData<GLshort, 1, 0>);
- addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &copyVertexData<GLshort, 2, 0>);
- addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<GLshort, 4, 1>);
- addVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<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, &copyVertexData<GLshort, 1, 0>);
- addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &copyVertexData<GLshort, 2, 0>);
- addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &copyVertexData<GLshort, 3, INT16_MAX>);
- addVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &copyVertexData<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, &copyVertexData<GLushort, 1, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &copyVertexData<GLushort, 2, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<GLushort, 3, 1>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<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, &copyVertexData<GLushort, 1, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &copyVertexData<GLushort, 2, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &copyVertexData<GLushort, 3, UINT16_MAX>);
- addVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &copyVertexData<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, &copyVertexData<GLint, 1, 0>);
- addVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &copyVertexData<GLint, 2, 0>);
- addVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &copyVertexData<GLint, 3, 0>);
- addVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &copyVertexData<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, &copyToFloatVertexData<GLint, 1, true>);
- addVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &copyToFloatVertexData<GLint, 2, true>);
- addVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &copyToFloatVertexData<GLint, 3, true>);
- addVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyToFloatVertexData<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, &copyVertexData<GLuint, 1, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &copyVertexData<GLuint, 2, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &copyVertexData<GLuint, 3, 0>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &copyVertexData<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, &copyToFloatVertexData<GLuint, 1, true>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &copyToFloatVertexData<GLuint, 2, true>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &copyToFloatVertexData<GLuint, 3, true>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyToFloatVertexData<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, &copyFixedVertexData<1>);
- addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &copyFixedVertexData<2>);
- addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &copyFixedVertexData<3>);
- addVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyFixedVertexData<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, &copyVertexData<GLhalf, 1, 0>);
- addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &copyVertexData<GLhalf, 2, 0>);
- addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &copyVertexData<GLhalf, 3, gl::Float16One>);
- addVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &copyVertexData<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, &copyVertexData<GLfloat, 1, 0>);
- addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &copyVertexData<GLfloat, 2, 0>);
- addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &copyVertexData<GLfloat, 3, 0>);
- addVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyVertexData<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, &copyPackedVertexData<true, false, true>);
- addVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &copyPackedVertexData<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, &copyPackedVertexData<false, false, true>);
- addVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &copyPackedUnsignedVertexData);
+ 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, &copyVertexData<GLbyte, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &copyVertexData<GLbyte, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &copyVertexData<GLbyte, 3, 1>);
- addIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &copyVertexData<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, &copyVertexData<GLubyte, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &copyVertexData<GLubyte, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &copyVertexData<GLubyte, 3, 1>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &copyVertexData<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, &copyVertexData<GLshort, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &copyVertexData<GLshort, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<GLshort, 3, 1>);
- addIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &copyVertexData<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, &copyVertexData<GLushort, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &copyVertexData<GLushort, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<GLushort, 3, 1>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &copyVertexData<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, &copyVertexData<GLint, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &copyVertexData<GLint, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &copyVertexData<GLint, 3, 0>);
- addIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &copyVertexData<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, &copyVertexData<GLuint, 1, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &copyVertexData<GLuint, 2, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &copyVertexData<GLuint, 3, 0>);
- addIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &copyVertexData<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, &copyPackedVertexData<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, &copyPackedUnsignedVertexData);
+ 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset)
+gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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 &currentValue,
- GLint start, GLsizei count, GLsizei instances, unsigned int offset);
+ virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
+ 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, &currentDisplayMode);
+ 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)
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libGLESv2/validationES.cpp
index 309c4daedb..f79bc97e4f 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/validationES.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
@@ -20,6 +19,7 @@
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/TransformFeedback.h"
#include "libGLESv2/VertexArray.h"
+#include "libGLESv2/renderer/BufferImpl.h"
#include "common/mathutil.h"
#include "common/utilities.h"
@@ -168,7 +168,7 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level)
return level <= gl::log2(maxDimension);
}
-bool ValidImageSize(const gl::Context *context, GLenum target, GLint level,
+bool ValidImageSize(const Context *context, GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth)
{
if (level < 0 || width < 0 || height < 0 || depth < 0)
@@ -190,17 +190,16 @@ bool ValidImageSize(const gl::Context *context, GLenum target, GLint level,
return true;
}
-bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
+bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
{
- if (!IsFormatCompressed(internalFormat))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+ if (!formatInfo.compressed)
{
return false;
}
- GLint blockWidth = GetCompressedBlockWidth(internalFormat);
- GLint blockHeight = GetCompressedBlockHeight(internalFormat);
- if (width < 0 || (width > blockWidth && width % blockWidth != 0) ||
- height < 0 || (height > blockHeight && height % blockHeight != 0))
+ if (width < 0 || (static_cast<GLuint>(width) > formatInfo.compressedBlockWidth && width % formatInfo.compressedBlockWidth != 0) ||
+ height < 0 || (static_cast<GLuint>(height) > formatInfo.compressedBlockHeight && height % formatInfo.compressedBlockHeight != 0))
{
return false;
}
@@ -225,7 +224,7 @@ bool ValidQueryType(const Context *context, GLenum queryType)
}
}
-bool ValidProgram(const Context *context, GLuint id)
+bool ValidProgram(Context *context, GLuint id)
{
// ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the
// error INVALID_VALUE if the provided name is not the name of either a shader or program object and
@@ -238,16 +237,18 @@ bool ValidProgram(const Context *context, GLuint id)
else if (context->getShader(id) != NULL)
{
// ID is the wrong type
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
// No shader/program object has this ID
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
-bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
+bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
{
if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{
@@ -255,7 +256,8 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
if (colorAttachment >= context->getCaps().maxColorAttachments)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
else
@@ -269,19 +271,21 @@ bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment)
case GL_DEPTH_STENCIL_ATTACHMENT:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
return true;
}
-bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height,
bool angleExtension)
{
@@ -290,43 +294,44 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
case GL_RENDERBUFFER:
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (width < 0 || height < 0 || samples < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- if (!gl::IsValidInternalFormat(internalformat, context->getExtensions(), context->getClientVersion()))
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (!formatCaps.renderable)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
// ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
// sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
// only sized internal formats. The ES3 spec (section 4.4.2) does, however, state that the
// internal format must be sized and not an integer format if samples is greater than zero.
- if (!gl::IsSizedInternalFormat(internalformat))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if (formatInfo.pixelBytes == 0)
{
- return gl::error(GL_INVALID_ENUM, false);
- }
-
- GLenum componentType = gl::GetComponentType(internalformat);
- if ((componentType == GL_UNSIGNED_INT || componentType == GL_INT) && samples > 0)
- {
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
- const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
- if (!formatCaps.renderable)
+ if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
// ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
@@ -335,23 +340,34 @@ bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum ta
// internal format.
if (angleExtension)
{
- if (samples > context->getMaxSupportedSamples())
+ ASSERT(context->getExtensions().framebufferMultisample);
+ if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+
+ // Check if this specific format supports enough samples
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->recordError(Error(GL_OUT_OF_MEMORY));
+ return false;
}
}
else
{
- if (samples > context->getMaxSupportedFormatSamples(internalformat))
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
GLuint handle = context->getState().getRenderbufferId();
if (handle == 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
@@ -362,7 +378,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
{
if (!ValidFramebufferTarget(target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
@@ -370,7 +387,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (!ValidateAttachmentTarget(context, attachment))
@@ -386,7 +404,8 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ
{
if (!context->getRenderbuffer(renderbuffer))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -428,16 +447,19 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
case GL_LINEAR:
if (fromAngleExtension)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (mask == 0)
@@ -450,14 +472,16 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0))
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.");
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
// color buffer, leaving only nearest being unfiltered from above
if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id())
@@ -467,7 +491,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
ERR("Blits with the same source and destination framebuffer are not supported by this "
"implementation.");
}
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
@@ -475,12 +500,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
}
if (drawFramebuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
@@ -493,45 +520,50 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (readColorBuffer && drawColorBuffer)
{
GLenum readInternalFormat = readColorBuffer->getActualFormat();
- GLenum readComponentType = gl::GetComponentType(readInternalFormat);
+ const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat);
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
{
if (drawFramebuffer->isEnabledColorAttachment(i))
{
GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat();
- GLenum drawComponentType = gl::GetComponentType(drawInternalFormat);
+ const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat);
// The GL ES 3.0.2 spec (pg 193) states that:
// 1) If the read buffer is fixed point format, the draw buffer must be as well
// 2) If the read buffer is an unsigned integer format, the draw buffer must be as well
// 3) If the read buffer is a signed integer format, the draw buffer must be as well
- if ( (readComponentType == GL_UNSIGNED_NORMALIZED || readComponentType == GL_SIGNED_NORMALIZED) &&
- !(drawComponentType == GL_UNSIGNED_NORMALIZED || drawComponentType == GL_SIGNED_NORMALIZED))
+ if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
+ !(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (readComponentType == GL_UNSIGNED_INT && drawComponentType != GL_UNSIGNED_INT)
+ if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (readComponentType == GL_INT && drawComponentType != GL_INT)
+ if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
}
- if ((readComponentType == GL_INT || readComponentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
+ if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (fromAngleExtension)
@@ -539,7 +571,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
@@ -551,12 +584,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
}
@@ -564,7 +599,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
}
@@ -579,12 +615,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
{
if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (readDepthBuffer->getSamples() > 0 && !sameBounds)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (fromAngleExtension)
@@ -593,12 +631,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
- return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
+ context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+ return false;
}
if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
}
@@ -613,12 +653,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
{
if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (readStencilBuffer->getSamples() > 0 && !sameBounds)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (fromAngleExtension)
@@ -627,12 +669,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
- return gl::error(GL_INVALID_OPERATION, false); // only whole-buffer copies are permitted
+ context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+ return false;
}
if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
}
@@ -641,7 +685,7 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
return true;
}
-bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion)
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
{
switch (pname)
{
@@ -661,10 +705,16 @@ bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion)
return true;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
- return ((clientVersion >= 3) ? true : gl::error(GL_INVALID_ENUM, false));
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
@@ -685,7 +735,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_TEXTURE_MAX_LOD:
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -704,7 +755,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_MIRRORED_REPEAT:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
case GL_TEXTURE_MIN_FILTER:
@@ -718,7 +770,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_LINEAR_MIPMAP_LINEAR:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -729,7 +782,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_LINEAR:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -740,20 +794,23 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->getExtensions().textureFilterAnisotropic)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
// we assume the parameter passed to this validation method is truncated, not rounded
if (param < 1)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
return true;
@@ -770,7 +827,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_COMPARE_REF_TO_TEXTURE:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -788,7 +846,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_NEVER:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -806,7 +865,8 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_ONE:
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
@@ -814,16 +874,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
case GL_TEXTURE_MAX_LEVEL:
if (param < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
-bool ValidateSamplerObjectParameter(GLenum pname)
+bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname)
{
switch (pname)
{
@@ -839,7 +901,8 @@ bool ValidateSamplerObjectParameter(GLenum pname)
return true;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
@@ -851,17 +914,20 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
}
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (!framebuffer->getReadColorbuffer())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
GLenum currentInternalFormat, currentFormat, currentType;
@@ -874,20 +940,22 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
if (!(currentFormat == format && currentType == type) && !validReadFormat)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- GLenum sizedInternalFormat = IsSizedInternalFormat(format) ? format
- : GetSizedInternalFormat(format, type);
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+ const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
- GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, width, context->getState().getPackAlignment());
+ GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment());
// sized query sanity check
if (bufSize)
{
int requiredSize = outputPitch * height;
if (requiredSize > *bufSize)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -898,12 +966,14 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
{
if (!ValidQueryType(context, target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (id == 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
@@ -923,7 +993,8 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
// no query may be active for either if glBeginQuery targets either.
if (context->getState().isQueryActive())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
Query *queryObject = context->getQuery(id, true, target);
@@ -931,13 +1002,15 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
// check that name was obtained with glGenQueries
if (!queryObject)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// check for type mismatch
if (queryObject->getType() != target)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
@@ -947,19 +1020,16 @@ bool ValidateEndQuery(gl::Context *context, GLenum target)
{
if (!ValidQueryType(context, target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
const Query *queryObject = context->getState().getActiveQuery(target);
if (queryObject == NULL)
{
- return gl::error(GL_INVALID_OPERATION, false);
- }
-
- if (!queryObject->isStarted())
- {
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
@@ -970,13 +1040,15 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
{
if (count < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
if (!programBinary)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (location == -1)
@@ -987,7 +1059,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
if (!programBinary->isValidUniformLocation(location))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
LinkedUniform *uniform = programBinary->getUniformByLocation(location);
@@ -995,7 +1068,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
// attempting to write an array to a non-array uniform is an INVALID_OPERATION
if (uniform->elementCount() == 1 && count > 1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
*uniformOut = uniform;
@@ -1007,7 +1081,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
// Check for ES3 uniform entry points
if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
LinkedUniform *uniform = NULL;
@@ -1020,7 +1095,8 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT);
if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
@@ -1034,12 +1110,14 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati
int cols = VariableColumnCount(matrixType);
if (rows != cols && context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (transpose != GL_FALSE && context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
LinkedUniform *uniform = NULL;
@@ -1050,7 +1128,8 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati
if (uniform->type != matrixType)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
@@ -1060,7 +1139,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
{
if (!context->getQueryParameterInfo(pname, nativeType, numParams))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
@@ -1069,7 +1149,8 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
if (colorAttachment >= context->getCaps().maxDrawBuffers)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -1079,9 +1160,10 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_BINDING_2D_ARRAY:
- if (context->getState().getActiveSampler() >= context->getMaximumCombinedTextureImageUnits())
+ if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
@@ -1092,13 +1174,15 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
ASSERT(framebuffer);
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
if (!attachment)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
break;
@@ -1123,46 +1207,51 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (!ValidTexture2DDestinationTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (border != 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (!ValidMipLevel(context, target, level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
}
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
const gl::Caps &caps = context->getCaps();
gl::Texture *texture = NULL;
GLenum textureInternalFormat = GL_NONE;
- bool textureCompressed = false;
- bool textureIsDepth = false;
GLint textureLevelWidth = 0;
GLint textureLevelHeight = 0;
GLint textureLevelDepth = 0;
@@ -1176,8 +1265,6 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (texture2d)
{
textureInternalFormat = texture2d->getInternalFormat(level);
- textureCompressed = texture2d->isCompressed(level);
- textureIsDepth = texture2d->isDepth(level);
textureLevelWidth = texture2d->getWidth(level);
textureLevelHeight = texture2d->getHeight(level);
textureLevelDepth = 1;
@@ -1198,8 +1285,6 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (textureCube)
{
textureInternalFormat = textureCube->getInternalFormat(target, level);
- textureCompressed = textureCube->isCompressed(target, level);
- textureIsDepth = false;
textureLevelWidth = textureCube->getWidth(target, level);
textureLevelHeight = textureCube->getHeight(target, level);
textureLevelDepth = 1;
@@ -1215,8 +1300,6 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (texture2dArray)
{
textureInternalFormat = texture2dArray->getInternalFormat(level);
- textureCompressed = texture2dArray->isCompressed(level);
- textureIsDepth = texture2dArray->isDepth(level);
textureLevelWidth = texture2dArray->getWidth(level);
textureLevelHeight = texture2dArray->getHeight(level);
textureLevelDepth = texture2dArray->getLayers(level);
@@ -1232,8 +1315,6 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
if (texture3d)
{
textureInternalFormat = texture3d->getInternalFormat(level);
- textureCompressed = texture3d->isCompressed(level);
- textureIsDepth = texture3d->isDepth(level);
textureLevelWidth = texture3d->getWidth(level);
textureLevelHeight = texture3d->getHeight(level);
textureLevelDepth = texture3d->getDepth(level);
@@ -1244,33 +1325,37 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!texture)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (texture->isImmutable() && !isSubImage)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (textureIsDepth)
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+
+ if (formatInfo.depthBits > 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (textureCompressed)
+ if (formatInfo.compressed)
{
- GLint blockWidth = GetCompressedBlockWidth(textureInternalFormat);
- GLint blockHeight = GetCompressedBlockHeight(textureInternalFormat);
-
- if (((width % blockWidth) != 0 && width != textureLevelWidth) ||
- ((height % blockHeight) != 0 && height != textureLevelHeight))
+ if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) ||
+ ((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -1280,25 +1365,29 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
yoffset + height > textureLevelHeight ||
zoffset >= textureLevelDepth)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
else
{
if (IsCubemapTextureTarget(target) && width != height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- if (!IsValidInternalFormat(internalformat, context->getExtensions(), context->getClientVersion()))
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
int maxLevelDimension = (maxDimension >> level);
if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
@@ -1306,7 +1395,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return true;
}
-static bool ValidateDrawBase(const gl::Context *context, GLenum mode, GLsizei count)
+static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount)
{
switch (mode)
{
@@ -1319,71 +1408,128 @@ static bool ValidateDrawBase(const gl::Context *context, GLenum mode, GLsizei co
case GL_TRIANGLE_FAN:
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (count < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
+ const State &state = context->getState();
+
// Check for mapped buffers
- if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
+ if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- const gl::DepthStencilState &depthStencilState = context->getState().getDepthStencilState();
+ const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
- context->getState().getStencilRef() != context->getState().getStencilBackRef() ||
+ state.getStencilRef() != state.getStencilBackRef() ||
depthStencilState.stencilMask != depthStencilState.stencilBackMask)
{
// Note: these separate values are not supported in WebGL, due to D3D's limitations.
// See Section 6.10 of the WebGL 1.0 spec
ERR("This ANGLE implementation does not support separate front/back stencil "
"writemasks, reference values, or stencil mask values.");
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
+ const gl::Framebuffer *fbo = state.getDrawFramebuffer();
if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
+ }
+
+ if (state.getCurrentProgramId() == 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (context->getState().getCurrentProgramId() == 0)
+ gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+ if (!programBinary->validateSamplers(NULL, context->getCaps()))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- if (!programBinary->validateSamplers(NULL))
+ // Buffer validations
+ const VertexArray *vao = state.getVertexArray();
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
+ bool attribActive = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ if (attribActive && attrib.enabled)
+ {
+ gl::Buffer *buffer = attrib.buffer.get();
+
+ if (buffer)
+ {
+ GLint64 attribStride = static_cast<GLint64>(ComputeVertexAttributeStride(attrib));
+ GLint64 maxVertexElement = 0;
+
+ if (attrib.divisor > 0)
+ {
+ maxVertexElement = static_cast<GLint64>(primcount) / static_cast<GLint64>(attrib.divisor);
+ }
+ else
+ {
+ maxVertexElement = static_cast<GLint64>(maxVertex);
+ }
+
+ GLint64 attribDataSize = maxVertexElement * attribStride;
+
+ // [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 (attribDataSize > buffer->getSize())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+ }
+ else if (attrib.pointer == NULL)
+ {
+ // This is an application error that would normally result in a crash,
+ // but we catch it and return an error
+ context->recordError(Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer."));
+ return false;
+ }
+ }
}
// No-op if zero count
return (count > 0);
}
-bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (first < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+ const State &state = context->getState();
+ gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (!ValidateDrawBase(context, mode, count))
+ if (!ValidateDrawBase(context, mode, count, count, primcount))
{
return false;
}
@@ -1391,14 +1537,15 @@ bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GL
return true;
}
-bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (primcount < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- if (!ValidateDrawArrays(context, mode, first, count))
+ if (!ValidateDrawArrays(context, mode, first, count, primcount))
{
return false;
}
@@ -1407,7 +1554,41 @@ bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint
return (primcount > 0);
}
-bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+static bool ValidateDrawInstancedANGLE(Context *context)
+{
+ // Verify there is at least one active attribute with a divisor of zero
+ const gl::State& state = context->getState();
+
+ gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+
+ const VertexArray *vao = state.getVertexArray();
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
+ bool active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ if (active && attrib.divisor == 0)
+ {
+ return true;
+ }
+ }
+
+ context->recordError(Error(GL_INVALID_OPERATION, "ANGLE_instanced_arrays requires that at least one active attribute"
+ "has a divisor of zero."));
+ return false;
+}
+
+bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+ if (!ValidateDrawInstancedANGLE(context))
+ {
+ return false;
+ }
+
+ return ValidateDrawArraysInstanced(context, mode, first, count, primcount);
+}
+
+bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
{
switch (type)
{
@@ -1417,34 +1598,89 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
case GL_UNSIGNED_INT:
if (!context->getExtensions().elementIndexUint)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
- gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+ const State &state = context->getState();
+
+ gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// Check for mapped buffers
- if (context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
+ if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ const gl::VertexArray *vao = state.getVertexArray();
+ const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+ if (!indices && !elementArrayBuffer)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ if (elementArrayBuffer)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ const gl::Type &typeInfo = gl::GetTypeInfo(type);
+
+ GLint64 offset = reinterpret_cast<GLint64>(indices);
+ GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset;
+
+ // check for integer overflows
+ if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
+ byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
+ {
+ context->recordError(Error(GL_OUT_OF_MEMORY));
+ return false;
+ }
+
+ // Check for reading past the end of the bound buffer object
+ if (byteCount > elementArrayBuffer->getSize())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+ }
+ else if (!indices)
+ {
+ // Catch this programming error here
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- gl::VertexArray *vao = context->getState().getVertexArray();
- if (!indices && !vao->getElementArrayBuffer())
+ // Use max index to validate if our vertex buffers are large enough for the pull.
+ // TODO: offer fast path, with disabled index validation.
+ // TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
+ if (elementArrayBuffer)
+ {
+ GLint64 offset = reinterpret_cast<GLint64>(indices);
+ if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
+ {
+ const void *dataPointer = elementArrayBuffer->getImplementation()->getData();
+ const uint8_t *offsetPointer = static_cast<const uint8_t *>(dataPointer) + offset;
+ *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count);
+ }
+ }
+ else
{
- return gl::error(GL_INVALID_OPERATION, false);
+ *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count);
}
- if (!ValidateDrawBase(context, mode, count))
+ if (!ValidateDrawBase(context, mode, count, static_cast<GLsizei>(indexRangeOut->end), primcount))
{
return false;
}
@@ -1452,15 +1688,18 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
return true;
}
-bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices, GLsizei primcount)
+bool ValidateDrawElementsInstanced(Context *context,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei primcount,
+ rx::RangeUI *indexRangeOut)
{
if (primcount < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- if (!ValidateDrawElements(context, mode, count, type, indices))
+ if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut))
{
return false;
}
@@ -1469,12 +1708,24 @@ bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsi
return (primcount > 0);
}
-bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
+{
+ if (!ValidateDrawInstancedANGLE(context))
+ {
+ return false;
+ }
+
+ return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount, indexRangeOut);
+}
+
+bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
if (!ValidFramebufferTarget(target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!ValidateAttachmentTarget(context, attachment))
@@ -1488,12 +1739,14 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G
if (tex == NULL)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (level < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
@@ -1502,19 +1755,21 @@ bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, G
if (framebufferHandle == 0 || !framebuffer)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
}
-bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
// Attachments are required to be bound to level 0 in ES2
if (context->getClientVersion() < 3 && level != 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
@@ -1535,16 +1790,19 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe
{
if (level > gl::log2(caps.max2DTextureSize))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (tex->getTarget() != GL_TEXTURE_2D)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
if (tex2d->isCompressed(level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
break;
@@ -1558,26 +1816,105 @@ bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLe
{
if (level > gl::log2(caps.maxCubeMapTextureSize))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
if (texcube->isCompressed(textarget, level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
return true;
}
+bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
+{
+ if (program == 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+
+ gl::Program *programObject = context->getProgram(program);
+
+ if (!programObject || !programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+ if (!programBinary)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ if (!programBinary->isValidUniformLocation(location))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params)
+{
+ return ValidateGetUniformBase(context, program, location);
+}
+
+bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params)
+{
+ return ValidateGetUniformBase(context, program, location);
+}
+
+static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize)
+{
+ if (!ValidateGetUniformBase(context, program, location))
+ {
+ return false;
+ }
+
+ gl::Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+ // sized queries -- ensure the provided buffer is large enough
+ LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+ size_t requiredBytes = VariableExternalSize(uniform->type);
+ if (static_cast<size_t>(bufSize) < requiredBytes)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+ return ValidateSizedGetUniform(context, program, location, bufSize);
+}
+
+bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+ return ValidateSizedGetUniform(context, program, location, bufSize);
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.h b/src/3rdparty/angle/src/libGLESv2/validationES.h
index 849df36588..1fdb633cb6 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES.h
+++ b/src/3rdparty/angle/src/libGLESv2/validationES.h
@@ -9,6 +9,11 @@
#ifndef LIBGLESV2_VALIDATION_ES_H
#define LIBGLESV2_VALIDATION_ES_H
+#include "common/mathutil.h"
+
+#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
+
namespace gl
{
@@ -21,55 +26,67 @@ bool ValidFramebufferTarget(GLenum target);
bool ValidBufferTarget(const Context *context, GLenum target);
bool ValidBufferParameter(const Context *context, GLenum pname);
bool ValidMipLevel(const Context *context, GLenum target, GLint level);
-bool ValidImageSize(const gl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth);
-bool ValidCompressedImageSize(const gl::Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
-bool ValidQueryType(const gl::Context *context, GLenum queryType);
-bool ValidProgram(const gl::Context *context, GLuint id);
+bool ValidImageSize(const Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth);
+bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height);
+bool ValidQueryType(const Context *context, GLenum queryType);
+bool ValidProgram(Context *context, GLuint id);
-bool ValidateAttachmentTarget(const gl::Context *context, GLenum attachment);
-bool ValidateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+bool ValidateAttachmentTarget(Context *context, GLenum attachment);
+bool ValidateRenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height,
bool angleExtension);
-bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer);
-bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+bool ValidateBlitFramebufferParameters(Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
GLenum filter, bool fromAngleExtension);
-bool ValidateGetVertexAttribParameters(GLenum pname, int clientVersion);
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname);
-bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param);
+bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param);
-bool ValidateSamplerObjectParameter(GLenum pname);
+bool ValidateSamplerObjectParameter(Context *context, GLenum pname);
-bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
+bool ValidateReadPixelsParameters(Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels);
-bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id);
-bool ValidateEndQuery(gl::Context *context, GLenum target);
+bool ValidateBeginQuery(Context *context, GLenum target, GLuint id);
+bool ValidateEndQuery(Context *context, GLenum target);
-bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count);
-bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count,
+bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count);
+bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, GLsizei count,
GLboolean transpose);
-bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
+bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
-bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateCopyTexImageParametersBase(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border, GLenum *textureInternalFormatOut);
-bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count);
-bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
-bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices, GLsizei primcount);
+bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+
+bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
-bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateDrawElementsInstanced(Context *context, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
+bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut);
+
+bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level);
-bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
+bool ValidateGetUniformBase(Context *context, GLuint program, GLint location);
+bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params);
+bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params);
+bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params);
+
}
#endif // LIBGLESV2_VALIDATION_ES_H
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES2.cpp b/src/3rdparty/angle/src/libGLESv2/validationES2.cpp
index 1a09400322..f950454df0 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/validationES2.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
@@ -23,26 +22,28 @@
namespace gl
{
-static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
+static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
gl::Texture2D *texture)
{
if (!texture)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (compressed != texture->isCompressed(level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (format != GL_NONE)
{
- GLenum internalformat = gl::GetSizedInternalFormat(format, type);
- if (internalformat != texture->getInternalFormat(level))
+ if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -51,39 +52,43 @@ static bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei hei
if ((width % 4 != 0 && width != texture->getWidth(level)) ||
(height % 4 != 0 && height != texture->getHeight(level)))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
if (xoffset + width > texture->getWidth(level) ||
yoffset + height > texture->getHeight(level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
return true;
}
-static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
+static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
gl::TextureCubeMap *texture)
{
if (!texture)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (compressed != texture->isCompressed(target, level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (format != GL_NONE)
{
- GLenum internalformat = gl::GetSizedInternalFormat(format, type);
- if (internalformat != texture->getInternalFormat(target, level))
+ if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -92,43 +97,49 @@ static bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei h
if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
(height % 4 != 0 && height != texture->getHeight(target, 0)))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
if (xoffset + width > texture->getWidth(target, level) ||
yoffset + height > texture->getHeight(target, level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
return true;
}
-bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
if (!ValidTexture2DDestinationTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!ValidImageSize(context, target, level, width, height, 1))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (level < 0 || xoffset < 0 ||
std::numeric_limits<GLsizei>::max() - xoffset < width ||
std::numeric_limits<GLsizei>::max() - yoffset < height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (!isSubImage && !isCompressed && internalformat != format)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
const gl::Caps &caps = context->getCaps();
@@ -145,7 +156,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture2D *tex2d = context->getTexture2D();
@@ -158,7 +170,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
texture = tex2d;
}
- if (isSubImage && !validateSubImageParams2D(isCompressed, width, height, xoffset, yoffset,
+ if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
level, format, type, tex2d))
{
return false;
@@ -177,13 +189,15 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{
if (!isSubImage && width != height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::TextureCubeMap *texCube = context->getTextureCubeMap();
@@ -196,7 +210,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
texture = texCube;
}
- if (isSubImage && !validateSubImageParamsCube(isCompressed, width, height, xoffset, yoffset,
+ if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
target, level, format, type, texCube))
{
return false;
@@ -205,23 +219,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!texture)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (!isSubImage && texture->isImmutable())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// Verify zero border
if (border != 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
@@ -229,7 +247,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
switch (actualInternalFormat)
@@ -238,23 +257,27 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->getExtensions().textureCompressionDXT1)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->getExtensions().textureCompressionDXT1)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- if (!context->getExtensions().textureCompressionDXT5)
+ if (!context->getExtensions().textureCompressionDXT5)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
else
@@ -273,7 +296,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_FLOAT:
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
// validate <format> + <type> combinations
@@ -290,15 +314,17 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
- default:
- return gl::error(GL_INVALID_OPERATION, false);
+ default:
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RED:
case GL_RG:
if (!context->getExtensions().textureRG)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
switch (type)
{
@@ -307,7 +333,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RGB:
@@ -319,7 +346,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RGBA:
@@ -332,7 +360,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_HALF_FLOAT_OES:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_BGRA_EXT:
@@ -341,21 +370,24 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_BYTE:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_SRGB_EXT:
case GL_SRGB_ALPHA_EXT:
if (!context->getExtensions().sRGB)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
switch (type)
{
case GL_UNSIGNED_BYTE:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
@@ -370,7 +402,8 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_INT:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_DEPTH_STENCIL_OES:
@@ -379,11 +412,13 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_UNSIGNED_INT_24_8_OES:
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
switch (format)
@@ -392,48 +427,57 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->getExtensions().textureCompressionDXT1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->getExtensions().textureCompressionDXT3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
if (!context->getExtensions().depthTextures)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (target != GL_TEXTURE_2D)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// OES_depth_texture supports loading depth data and multiple levels,
// but ANGLE_depth_texture does not
if (pixels != NULL || level != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
default:
@@ -444,14 +488,16 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
{
if (!context->getExtensions().textureFloat)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
else if (type == GL_HALF_FLOAT_OES)
{
if (!context->getExtensions().textureHalfFloat)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
}
@@ -461,7 +507,7 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
-bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border)
{
@@ -475,7 +521,7 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
- GLenum textureFormat = gl::GetFormat(textureInternalFormat);
+ GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
// [OpenGL ES 2.0.24] table 3.9
if (isSubImage)
@@ -488,7 +534,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_LUMINANCE:
@@ -500,7 +547,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RED_EXT:
@@ -512,7 +560,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RG_EXT:
@@ -523,7 +572,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RGB:
@@ -533,7 +583,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_LUMINANCE_ALPHA:
@@ -542,19 +593,23 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
else
@@ -568,7 +623,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_LUMINANCE:
@@ -581,7 +637,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RED_EXT:
@@ -594,7 +651,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RG_EXT:
@@ -606,7 +664,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_RGB:
@@ -617,7 +676,8 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_LUMINANCE_ALPHA:
@@ -627,38 +687,45 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->getExtensions().textureCompressionDXT1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->getExtensions().textureCompressionDXT3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->getExtensions().textureCompressionDXT5)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_DEPTH_COMPONENT:
@@ -668,14 +735,17 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
case GL_DEPTH24_STENCIL8_OES:
if (context->getExtensions().depthTextures)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
else
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
@@ -683,35 +753,38 @@ bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLin
return (width > 0 && height > 0);
}
-bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height)
{
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (width < 1 || height < 1 || levels < 1)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (target == GL_TEXTURE_CUBE_MAP && width != height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- GLenum format = gl::GetFormat(internalformat);
- GLenum type = gl::GetType(internalformat);
-
- if (format == GL_NONE || type == GL_NONE)
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
const gl::Caps &caps = context->getCaps();
@@ -722,25 +795,29 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
break;
case GL_TEXTURE_CUBE_MAP:
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (levels != 1 && !context->getExtensions().textureNPOT)
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -750,19 +827,22 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->getExtensions().textureCompressionDXT1)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->getExtensions().textureCompressionDXT3)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->getExtensions().textureCompressionDXT5)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_RGBA32F_EXT:
@@ -772,7 +852,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_LUMINANCE_ALPHA32F_EXT:
if (!context->getExtensions().textureFloat)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_RGBA16F_EXT:
@@ -782,7 +863,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_LUMINANCE_ALPHA16F_EXT:
if (!context->getExtensions().textureHalfFloat)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_R8_EXT:
@@ -793,7 +875,8 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_RG32F_EXT:
if (!context->getExtensions().textureRG)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_DEPTH_COMPONENT16:
@@ -801,16 +884,19 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
case GL_DEPTH24_STENCIL8_OES:
if (!context->getExtensions().depthTextures)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (target != GL_TEXTURE_2D)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// ANGLE_depth_texture only supports 1-level textures
if (levels != 1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
break;
default:
@@ -832,19 +918,21 @@ bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (!texture || texture->id() == 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (texture->isImmutable())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
return true;
}
// check for combinations of format and type that are valid for ReadPixels
-bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type)
+bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
{
switch (format)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES2.h b/src/3rdparty/angle/src/libGLESv2/validationES2.h
index e41e345876..53a0b630ea 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES2.h
+++ b/src/3rdparty/angle/src/libGLESv2/validationES2.h
@@ -9,23 +9,25 @@
#ifndef LIBGLESV2_VALIDATION_ES2_H
#define LIBGLESV2_VALIDATION_ES2_H
+#include <GLES2/gl2.h>
+
namespace gl
{
class Context;
-bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-bool ValidateES2CopyTexImageParameters(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
+bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border);
-bool ValidateES2TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height);
-bool ValidES2ReadFormatType(gl::Context *context, GLenum format, GLenum type);
+bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
}
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp b/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
index a584a7127b..251c6ad2c4 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/validationES3.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
@@ -22,25 +21,283 @@
namespace gl
{
-bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+struct ES3FormatCombination
+{
+ GLenum internalFormat;
+ GLenum format;
+ GLenum type;
+};
+
+bool operator<(const ES3FormatCombination& a, const ES3FormatCombination& b)
+{
+ return memcmp(&a, &b, sizeof(ES3FormatCombination)) < 0;
+}
+
+typedef std::set<ES3FormatCombination> ES3FormatCombinationSet;
+
+static inline void InsertES3FormatCombo(ES3FormatCombinationSet *set, GLenum internalFormat, GLenum format, GLenum type)
+{
+ ES3FormatCombination info;
+ info.internalFormat = internalFormat;
+ info.format = format;
+ info.type = type;
+ set->insert(info);
+}
+
+ES3FormatCombinationSet BuildES3FormatSet()
+{
+ ES3FormatCombinationSet set;
+
+ // Format combinations from ES 3.0.1 spec, table 3.2
+
+ // | Internal format | Format | Type |
+ // | | | |
+ InsertES3FormatCombo(&set, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 );
+ InsertES3FormatCombo(&set, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV );
+ InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV );
+ InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 );
+ InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_RGBA32F, GL_RGBA, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT );
+ InsertES3FormatCombo(&set, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT );
+ InsertES3FormatCombo(&set, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT );
+ InsertES3FormatCombo(&set, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV );
+ InsertES3FormatCombo(&set, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB8_SNORM, GL_RGB, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 );
+ InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV );
+ InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV );
+ InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_RGB32F, GL_RGB, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT );
+ InsertES3FormatCombo(&set, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT );
+ InsertES3FormatCombo(&set, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_RGB32I, GL_RGB_INTEGER, GL_INT );
+ InsertES3FormatCombo(&set, GL_RG8, GL_RG, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RG8_SNORM, GL_RG, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_RG32F, GL_RG, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RG8I, GL_RG_INTEGER, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT );
+ InsertES3FormatCombo(&set, GL_RG16I, GL_RG_INTEGER, GL_SHORT );
+ InsertES3FormatCombo(&set, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_RG32I, GL_RG_INTEGER, GL_INT );
+ InsertES3FormatCombo(&set, GL_R8, GL_RED, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_R8_SNORM, GL_RED, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_R32F, GL_RED, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_R8I, GL_RED_INTEGER, GL_BYTE );
+ InsertES3FormatCombo(&set, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT );
+ InsertES3FormatCombo(&set, GL_R16I, GL_RED_INTEGER, GL_SHORT );
+ InsertES3FormatCombo(&set, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_R32I, GL_RED_INTEGER, GL_INT );
+
+ // Unsized formats
+ InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 );
+ InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 );
+ InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 );
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE );
+
+ // Depth stencil formats
+ InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT );
+ InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT );
+ InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 );
+ InsertES3FormatCombo(&set, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+ // From GL_EXT_sRGB
+ InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE );
+
+ // From GL_OES_texture_float
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_FLOAT );
+
+ // From GL_OES_texture_half_float
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES );
+
+ // From GL_EXT_texture_format_BGRA8888
+ InsertES3FormatCombo(&set, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE );
+
+ // From GL_EXT_texture_storage
+ // | Internal format | Format | Type |
+ // | | | |
+ InsertES3FormatCombo(&set, GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT );
+ InsertES3FormatCombo(&set, GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT_OES );
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT );
+ InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES );
+
+ // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
+ InsertES3FormatCombo(&set, GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT);
+ InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE );
+ InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT);
+ InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE );
+
+ // From GL_ANGLE_depth_texture
+ InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES );
+
+ // Compressed formats
+ // From ES 3.0.1 spec, table 3.16
+ // | Internal format | Format | Type |
+ // | | | |
+ InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE);
+
+
+ // From GL_EXT_texture_compression_dxt1
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE);
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE);
+
+ // From GL_ANGLE_texture_compression_dxt3
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE);
+
+ // From GL_ANGLE_texture_compression_dxt5
+ InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE);
+
+ return set;
+}
+
+static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type)
+{
+ // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
+ // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+
+ // The type and format are valid if any supported internal format has that type and format
+ bool formatSupported = false;
+ bool typeSupported = false;
+
+ static const ES3FormatCombinationSet es3FormatSet = BuildES3FormatSet();
+ for (ES3FormatCombinationSet::const_iterator i = es3FormatSet.begin(); i != es3FormatSet.end(); i++)
+ {
+ if (i->format == format || i->type == type)
+ {
+ const gl::InternalFormat &info = gl::GetInternalFormatInfo(i->internalFormat);
+ bool supported = info.textureSupport(context->getClientVersion(), context->getExtensions());
+ if (supported && i->type == type)
+ {
+ typeSupported = true;
+ }
+ if (supported && i->format == format)
+ {
+ formatSupported = true;
+ }
+
+ // Early-out if both type and format are supported now
+ if (typeSupported && formatSupported)
+ {
+ break;
+ }
+ }
+ }
+
+ if (!typeSupported || !formatSupported)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+
+ // Check if this is a valid format combination to load texture data
+ ES3FormatCombination searchFormat;
+ searchFormat.internalFormat = internalFormat;
+ searchFormat.format = format;
+ searchFormat.type = type;
+
+ if (es3FormatSet.find(searchFormat) == es3FormatSet.end())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
if (!ValidTexture2DDestinationTarget(context, target))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
// Validate image size
if (!ValidImageSize(context, target, level, width, height, depth))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
// Verify zero border
if (border != 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (xoffset < 0 || yoffset < 0 || zoffset < 0 ||
@@ -48,7 +305,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
std::numeric_limits<GLsizei>::max() - yoffset < height ||
std::numeric_limits<GLsizei>::max() - zoffset < depth)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
const gl::Caps &caps = context->getCaps();
@@ -66,7 +324,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture2D *texture2d = context->getTexture2D();
@@ -91,12 +350,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
{
if (!isSubImage && width != height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
@@ -118,7 +379,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture3D *texture3d = context->getTexture3D();
@@ -140,7 +402,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture2DArray *texture2darray = context->getTexture2DArray();
@@ -157,57 +420,56 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!texture)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (texture->isImmutable() && !isSubImage)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// Validate texture formats
GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
+ const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat);
if (isCompressed)
{
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (!gl::IsFormatCompressed(actualInternalFormat))
+ if (!actualFormatInfo.compressed)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (target == GL_TEXTURE_3D)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
else
{
- // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
- // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
- if (!gl::IsValidInternalFormat(actualInternalFormat, context->getExtensions(), context->getClientVersion()) ||
- !gl::IsValidFormat(format, context->getExtensions(), context->getClientVersion()) ||
- !gl::IsValidType(type, context->getExtensions(), context->getClientVersion()))
- {
- return gl::error(GL_INVALID_ENUM, false);
- }
-
- if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, context->getExtensions(), context->getClientVersion()))
+ if (!ValidateTexImageFormatCombination(context, actualInternalFormat, format, type))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ return false;
}
if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -216,7 +478,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
{
if (isCompressed != textureCompressed)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (isCompressed)
@@ -224,7 +487,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if ((width % 4 != 0 && width != textureLevelWidth) ||
(height % 4 != 0 && height != textureLevelHeight))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -235,21 +499,24 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
if (xoffset < 0 || yoffset < 0 || zoffset < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
std::numeric_limits<GLsizei>::max() - yoffset < height ||
std::numeric_limits<GLsizei>::max() - zoffset < depth)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (xoffset + width > textureLevelWidth ||
yoffset + height > textureLevelHeight ||
zoffset + depth > textureLevelDepth)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
@@ -262,17 +529,17 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
size_t widthSize = static_cast<size_t>(width);
size_t heightSize = static_cast<size_t>(height);
size_t depthSize = static_cast<size_t>(depth);
- GLenum sizedFormat = gl::IsSizedInternalFormat(actualInternalFormat) ? actualInternalFormat
- : gl::GetSizedInternalFormat(actualInternalFormat, type);
+ GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type);
- size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(sizedFormat));
+ size_t pixelBytes = static_cast<size_t>(gl::GetInternalFormatInfo(sizedFormat).pixelBytes);
if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes))
{
// Overflow past the end of the buffer
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
@@ -282,29 +549,316 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize())))
{
// Overflow past the end of the buffer
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum
// indicated by type.
- size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeBytes(type));
+ size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
if ((offset % dataBytesPerPixel) != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
// ...the buffer object's data store is currently mapped.
if (pixelUnpackBuffer->isMapped())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
return true;
}
-bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
+struct EffectiveInternalFormatInfo
+{
+ GLenum mEffectiveFormat;
+ GLenum mDestFormat;
+ GLuint mMinRedBits;
+ GLuint mMaxRedBits;
+ GLuint mMinGreenBits;
+ GLuint mMaxGreenBits;
+ GLuint mMinBlueBits;
+ GLuint mMaxBlueBits;
+ GLuint mMinAlphaBits;
+ GLuint mMaxAlphaBits;
+
+ EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
+ GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
+ GLuint minAlphaBits, GLuint maxAlphaBits)
+ : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
+ mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
+ mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
+ mMaxAlphaBits(maxAlphaBits) {};
+};
+
+typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
+
+static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
+{
+ EffectiveInternalFormatList list;
+
+ // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
+ // linear source buffer component sizes.
+ // | Source channel min/max sizes |
+ // Effective Internal Format | N/A | R | G | B | A |
+ list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8));
+ list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0));
+ list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
+
+ return list;
+}
+
+static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
+{
+ EffectiveInternalFormatList list;
+
+ // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
+ // linear source buffer component sizes.
+ // | Source channel min/max sizes |
+ // Effective Internal Format | Dest Format | R | G | B | A |
+ list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
+ list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
+ list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1));
+ list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8));
+
+ return list;
+}
+
+static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, const InternalFormat &destFormat,
+ GLenum *outEffectiveFormat)
+{
+ const EffectiveInternalFormatList *list = NULL;
+ GLenum targetFormat = GL_NONE;
+
+ if (destFormat.pixelBytes > 0)
+ {
+ static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
+ list = &sizedList;
+ }
+ else
+ {
+ static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
+ list = &unsizedList;
+ targetFormat = destFormat.format;
+ }
+
+ for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
+ {
+ const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
+ if ((formatInfo.mDestFormat == targetFormat) &&
+ (formatInfo.mMinRedBits <= srcFormat.redBits && formatInfo.mMaxRedBits >= srcFormat.redBits) &&
+ (formatInfo.mMinGreenBits <= srcFormat.greenBits && formatInfo.mMaxGreenBits >= srcFormat.greenBits) &&
+ (formatInfo.mMinBlueBits <= srcFormat.blueBits && formatInfo.mMaxBlueBits >= srcFormat.blueBits) &&
+ (formatInfo.mMinAlphaBits <= srcFormat.alphaBits && formatInfo.mMaxAlphaBits >= srcFormat.alphaBits))
+ {
+ *outEffectiveFormat = formatInfo.mEffectiveFormat;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+struct CopyConversion
+{
+ GLenum mTextureFormat;
+ GLenum mFramebufferFormat;
+
+ CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
+ : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
+
+ bool operator<(const CopyConversion& other) const
+ {
+ return memcmp(this, &other, sizeof(CopyConversion)) < 0;
+ }
+};
+
+typedef std::set<CopyConversion> CopyConversionSet;
+
+static CopyConversionSet BuildValidES3CopyTexImageCombinations()
+{
+ CopyConversionSet set;
+
+ // From ES 3.0.1 spec, table 3.15
+ set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
+ set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
+ set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
+ set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
+ set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
+ set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
+ set.insert(CopyConversion(GL_RED, GL_RED));
+ set.insert(CopyConversion(GL_RED, GL_RG));
+ set.insert(CopyConversion(GL_RED, GL_RGB));
+ set.insert(CopyConversion(GL_RED, GL_RGBA));
+ set.insert(CopyConversion(GL_RG, GL_RG));
+ set.insert(CopyConversion(GL_RG, GL_RGB));
+ set.insert(CopyConversion(GL_RG, GL_RGBA));
+ set.insert(CopyConversion(GL_RGB, GL_RGB));
+ set.insert(CopyConversion(GL_RGB, GL_RGBA));
+ set.insert(CopyConversion(GL_RGBA, GL_RGBA));
+
+ // Necessary for ANGLE back-buffers
+ set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
+ set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
+
+ set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
+ set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
+ set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
+ set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
+ set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
+ set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
+ set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
+ set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
+ set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
+ set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
+
+ return set;
+}
+
+static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle)
+{
+ const InternalFormat &textureInternalFormatInfo = GetInternalFormatInfo(textureInternalFormat);
+ const InternalFormat &framebufferInternalFormatInfo = GetInternalFormatInfo(frameBufferInternalFormat);
+
+ static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
+ if (conversionSet.find(CopyConversion(textureInternalFormatInfo.format, framebufferInternalFormatInfo.format)) != conversionSet.end())
+ {
+ // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
+ // must both be signed, unsigned, or fixed point and both source and destinations
+ // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
+ // conversion between fixed and floating point.
+
+ if ((textureInternalFormatInfo.colorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.colorEncoding == GL_SRGB))
+ {
+ return false;
+ }
+
+ if (((textureInternalFormatInfo.componentType == GL_INT) != (framebufferInternalFormatInfo.componentType == GL_INT )) ||
+ ((textureInternalFormatInfo.componentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.componentType == GL_UNSIGNED_INT)))
+ {
+ return false;
+ }
+
+ if ((textureInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+ textureInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
+ textureInternalFormatInfo.componentType == GL_FLOAT) &&
+ !(framebufferInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+ framebufferInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
+ framebufferInternalFormatInfo.componentType == GL_FLOAT))
+ {
+ return false;
+ }
+
+ // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
+ // The effective internal format of the source buffer is determined with the following rules applied in order:
+ // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
+ // effective internal format is the source buffer's sized internal format.
+ // * If the source buffer is a texture that was created with an unsized base internal format, then the
+ // effective internal format is the source image array's effective internal format, as specified by table
+ // 3.12, which is determined from the <format> and <type> that were used when the source image array was
+ // specified by TexImage*.
+ // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
+ // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
+ // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
+ // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
+ // is SRGB.
+ const InternalFormat *sourceEffectiveFormat = NULL;
+ if (readBufferHandle != 0)
+ {
+ // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
+ if (framebufferInternalFormatInfo.pixelBytes > 0)
+ {
+ sourceEffectiveFormat = &framebufferInternalFormatInfo;
+ }
+ else
+ {
+ // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
+ // texture. We can use the same table we use when creating textures to get its effective sized format.
+ const FormatType &typeInfo = GetFormatTypeInfo(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type);
+ sourceEffectiveFormat = &GetInternalFormatInfo(typeInfo.internalFormat);
+ }
+ }
+ else
+ {
+ // The effective internal format must be derived from the source framebuffer's channel sizes.
+ // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
+ if (framebufferInternalFormatInfo.colorEncoding == GL_LINEAR)
+ {
+ GLenum effectiveFormat;
+ if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
+ {
+ sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (framebufferInternalFormatInfo.colorEncoding == GL_SRGB)
+ {
+ // SRGB buffers can only be copied to sized format destinations according to table 3.18
+ if ((textureInternalFormatInfo.pixelBytes > 0) &&
+ (framebufferInternalFormatInfo.redBits >= 1 && framebufferInternalFormatInfo.redBits <= 8) &&
+ (framebufferInternalFormatInfo.greenBits >= 1 && framebufferInternalFormatInfo.greenBits <= 8) &&
+ (framebufferInternalFormatInfo.blueBits >= 1 && framebufferInternalFormatInfo.blueBits <= 8) &&
+ (framebufferInternalFormatInfo.alphaBits >= 1 && framebufferInternalFormatInfo.alphaBits <= 8))
+ {
+ sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ if (textureInternalFormatInfo.pixelBytes > 0)
+ {
+ // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
+ // component sizes of the source and destination formats must exactly match
+ if (textureInternalFormatInfo.redBits != sourceEffectiveFormat->redBits ||
+ textureInternalFormatInfo.greenBits != sourceEffectiveFormat->greenBits ||
+ textureInternalFormatInfo.blueBits != sourceEffectiveFormat->blueBits ||
+ textureInternalFormatInfo.alphaBits != sourceEffectiveFormat->alphaBits)
+ {
+ return false;
+ }
+ }
+
+
+ return true; // A conversion function exists, and no rule in the specification has precluded conversion
+ // between these formats.
+ }
+
+ return false;
+}
+
+bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
@@ -320,12 +874,14 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
}
if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer();
@@ -333,20 +889,20 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (isSubImage)
{
- if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
- context->getState().getReadFramebuffer()->id(),
- context->getClientVersion()))
+ if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
+ context->getState().getReadFramebuffer()->id()))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
else
{
- if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat,
- context->getState().getReadFramebuffer()->id(),
- context->getClientVersion()))
+ if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat,
+ context->getState().getReadFramebuffer()->id()))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
@@ -354,17 +910,19 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
return (width > 0 && height > 0);
}
-bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth)
{
if (width < 1 || height < 1 || depth < 1 || levels < 1)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
const gl::Caps &caps = context->getCaps();
@@ -379,7 +937,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
break;
@@ -390,12 +949,14 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
if (width != height)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
break;
@@ -408,7 +969,8 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
static_cast<GLuint>(height) > caps.max3DTextureSize ||
static_cast<GLuint>(depth) > caps.max3DTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
break;
@@ -421,49 +983,58 @@ bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsize
static_cast<GLuint>(height) > caps.max2DTextureSize ||
static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (!texture || texture->id() == 0)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (texture->isImmutable())
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
- if (!gl::IsValidInternalFormat(internalformat, context->getExtensions(), context->getClientVersion()))
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
- if (!gl::IsSizedInternalFormat(internalformat))
+ if (formatInfo.pixelBytes == 0)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
return true;
}
-bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (layer < 0)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
@@ -483,18 +1054,21 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target,
{
if (level > gl::log2(caps.max2DTextureSize))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
if (texArray->isCompressed(level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
break;
@@ -503,32 +1077,38 @@ bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target,
{
if (level > gl::log2(caps.max3DTextureSize))
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
{
- return gl::error(GL_INVALID_VALUE, false);
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
if (tex3d->isCompressed(level))
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
break;
default:
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
return true;
}
-bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type)
+bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type)
{
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+
switch (format)
{
case GL_RGBA:
@@ -543,7 +1123,7 @@ bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum
}
break;
case GL_FLOAT:
- if (gl::GetComponentType(internalFormat) != GL_FLOAT)
+ if (internalFormatInfo.componentType != GL_FLOAT)
{
return false;
}
@@ -556,13 +1136,13 @@ bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum
switch (type)
{
case GL_INT:
- if (gl::GetComponentType(internalFormat) != GL_INT)
+ if (internalFormatInfo.componentType != GL_INT)
{
return false;
}
break;
case GL_UNSIGNED_INT:
- if (gl::GetComponentType(internalFormat) != GL_UNSIGNED_INT)
+ if (internalFormatInfo.componentType != GL_UNSIGNED_INT)
{
return false;
}
@@ -602,7 +1182,7 @@ bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum
return true;
}
-bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments,
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments)
{
bool defaultFramebuffer = false;
@@ -617,7 +1197,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0;
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
for (int i = 0; i < numAttachments; ++i)
@@ -626,12 +1207,14 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
{
if (defaultFramebuffer)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
}
else
@@ -643,7 +1226,8 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
case GL_DEPTH_STENCIL_ATTACHMENT:
if (defaultFramebuffer)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
case GL_COLOR:
@@ -651,11 +1235,13 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
case GL_STENCIL:
if (!defaultFramebuffer)
{
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
break;
default:
- return gl::error(GL_INVALID_ENUM, false);
+ context->recordError(Error(GL_INVALID_ENUM));
+ return false;
}
}
}
@@ -663,20 +1249,33 @@ bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target
return true;
}
-bool ValidateClearBuffer(const gl::Context *context)
+bool ValidateClearBuffer(Context *context)
{
if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION, false);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
}
return true;
}
+bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params)
+{
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ return ValidateGetUniformBase(context, program, location);
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.h b/src/3rdparty/angle/src/libGLESv2/validationES3.h
index 4d068bd094..cafacca601 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES3.h
+++ b/src/3rdparty/angle/src/libGLESv2/validationES3.h
@@ -9,31 +9,35 @@
#ifndef LIBGLESV2_VALIDATION_ES3_H
#define LIBGLESV2_VALIDATION_ES3_H
+#include <GLES3/gl3.h>
+
namespace gl
{
class Context;
-bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid *pixels);
-bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
+bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat,
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
GLsizei width, GLsizei height, GLint border);
-bool ValidateES3TexStorageParameters(gl::Context *context, GLenum target, GLsizei levels, GLenum internalformat,
+bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth);
-bool ValidateFramebufferTextureLayer(const gl::Context *context, GLenum target, GLenum attachment,
+bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer);
-bool ValidES3ReadFormatType(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type);
+bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type);
-bool ValidateInvalidateFramebufferParameters(gl::Context *context, GLenum target, GLsizei numAttachments,
+bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments);
-bool ValidateClearBuffer(const gl::Context *context);
+bool ValidateClearBuffer(Context *context);
+
+bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params);
}